All projects

MoaLLM Board

A desk where you and an AI agent study side by side. It explains, examines you and marks the paper, keeps your notes as plain Markdown you own, and finds them in Arabic or English with an embedding model I trained for it.

Context
My own product, 2026, ongoing
Role
Designed and built it alone
Built with
TypeScript, React, Node, MCP, Python, libSQL, ONNX Runtime, Model2Vec, Electron, Cloudflare Workers
Ships as
A desktop app, a one-step installer for Linux and macOS, and a hosted AI plan with a free trial
The MoaLLM wordmark: the M and the final M are drawn as two figures holding hands.

The name plays on مُعَلِّم (teacher) and LLM.

MoaLLM Board in its Tide look: a 3Blue1Brown video on attention linked to the session, where the learner asks in Egyptian Arabic and a multiple-choice answer is marked in pen, the note the agent wrote on the right, and the graph of the notes below the video.
The running Board in its Tide look: a video, the session, the note it wrote and your graph.

Everything you study, on one desk.

The agent explains, asks and runs exams in a session window, and it opens the exact page, note, chart or video it is talking about beside the conversation, with a labelled line back to it. You arrange all of it. Eleven kinds of window share the canvas.

The graph window in Live view: notes glow in the colour of their kind and the links of the picked note stand out.
Graph, Live view
A YouTube window playing 3Blue1Brown's video on attention, with its bar saying the agent cannot see this video until it is shared.
YouTube video
The session window: an Arabic question from the learner, the agent's Arabic answer, and a multiple-choice question marked with a red-pen strike and the right answer.
Session
A bar chart the agent drew from the PDF page: the softmax of the scores 2, 1 and 0.1.
Chart
A note on scaled dot-product attention with its formula and a section written in Arabic.
Note
A handwriting sheet with the agent's question typed at the top and the learner's working in blue pen.
Handwriting sheet
The Overview: how many concept notes have survived an unaided retrieval, recent attempts, open questions and notes changed lately.
Overview

The Board in 26 seconds.

A silent product film built from the running Board: the agent fills the desk, a question is answered and marked, and the graph switches from Map to Live. Every screen in it is a real capture. There is also a vertical cut.

Bring an agent, or start with ours.

There are three ways to bring the thinking, and all three look the same on the canvas. MoaLLM's own plan opens a session with one click and no sign-up, as a free trial. An agent you already use connects over MCP. Or you paste an API key and the built-in agent answers the sessions you start.

Every tool is defined once: its name, the description the agent reads, its arguments and the call it makes. There are 60, from opening a session to writing an exam or reading a past paper. The built-in agent does not carry them all: a small model reads each message and loads only the groups it needs, a core of about 5k tokens instead of 14k.

MoaLLM's plan

A free trial on one computer, then a monthly plan. Buying keeps the same key, and the agent settings say how much is left.

  • One click
  • No sign-up
  • Nothing to install

Over MCP

Start your agent in the notes folder. The folder already holds what connects it, and an AGENTS.md that tells it how to teach you.

  • Claude Code
  • Codex
  • opencode
  • Antigravity
  • pi
  • any MCP client

With your own key

Pick a provider and a model that accepts tools, paste a key, and press Save and test.

  • OpenRouter
  • OpenAI
  • Ollama
  • LM Studio
  • any OpenAI-compatible server

A gateway behind the plan. MoaLLM's plan runs through a gateway I built on Cloudflare Workers. It checks the licence key, tries the model providers in order and moves to the next before a word reaches the learner, and counts each reply's cost against the plan. It never stores what was said, and it answers only requests that carry the Board's tools, so a key is not a general model API.

Keys stay on your computer. Your own keys live in ~/.config/moallm/agent.json, readable by you only, never in a vault and never sent back to the browser.

The status is always true. The agent streams its words as it writes them. Rate limits and dropped connections are retried, but only before the model has said anything, so no words appear twice.

Small jobs go to small models

  1. Loads the toolsReads each message and loads only the tool groups it needs.
  2. Screens what the agent readsFinds words written to an AI in a web page, a PDF or a library section, in English or Arabic, and warns the agent they are not your request.
  3. Checks saved notesAsks each note an agent saves against your own conventions ("no emojis", "keep notes short") and sends back what it breaks.
  4. Homes orphansSays which nearby notes a new or unlinked note belongs with.
  5. Notices confusionHears "I still don't get it" or "تهت" and has the agent explain another way.
  6. Names sessionsTitles each session after what you first asked, in English or Egyptian Arabic.
A session window with a marked question: choice C, 64, is struck through in red with 'Not this one', and choice B, 8, has a dashed green edge and 'The answer'. The agent explains that 64 is the variance.
The agent marked the answer. The verdict always pairs a pen colour with an icon and a word.

It asks. You answer. It marks.

Questions and exams arrive in the session window as widgets you can tap, fill or flip. You answer, the agent grades, and the Board draws its verdict in pen.

A wrong pick is struck through in red and the right one gets a dashed green edge, each with an icon and a word, so the verdict never rests on colour alone.

A handwriting sheet works the same way. The agent opens one with its question typed at the top, and you work the answer out with a tablet pen or a mouse. Use sheet with agent saves first and shares a picture of exactly what was saved, so the agent never reads a half-written sheet.

  • Multiple choice
  • Matching
  • Cloze
  • Two-tier
  • Scenario
  • Error hunt
  • Viva
  • Teach-back
  • Free text
  • Flashcards

Ask for an exam. Get a paper.

Say "examine me on that" and the agent writes the whole exam in one call: choice, matching, put in order, fill the gaps and written answers, opened as one paper beside the session. One paper costs one model request, not one per question.

You answer in any order and change your mind until you hand in. A clock is there if you want one; nothing is timed by default.

The Board keeps the answer key, so it marks everything with one right answer itself the moment you hand in, and shows the right answers. The agent marks only the written answers, with a comment. A question can name the notes it tests, so each mark lands in your record of those notes.

Past papers make it sharper: a course's mock exam follows the topics, the share of marks and the kinds of question its real papers use.

An exam window after hand-in, 4 of 5 right: the multiple-choice answer marked correct with the explanation that 64 is the variance, the matching marked right, the order question marked not right with the correct order listed, the gaps filled with weights and 1, and the written answer marked right by the agent with its comment.
An exam on the demo vault after hand-in. The Board marked four questions; the agent marked the written one.
The Practice window asking 'Why divide by √dk?', with a box to type the answer or answer in your head, Show answer and Check buttons, and a line saying the agent opened it and hears how it went.
Practice opened by the agent from a note's cards. The card least likely to be recalled comes first.

Cards, with no model in the loop.

A note can carry cards as front ::: back lines, the format Obsidian's Spaced Repetition plugin uses. The Practice window asks the cards you are least likely to recall first, estimated with FSRS from your own answers. Nothing is ever due.

A typed answer is checked on your computer: an accent or a hamza slip is a near miss, and short Arabic vowels never count against you. A card you answer in your head, you grade yourself.

When the agent opened the practice, it hears how it went and teaches the cards you missed.

Your notes, as a graph you own.

Your vault is a folder of plain Markdown. You can write in it from the Board, with the note drawn as you type; an agent saves a note through a step that validates it, reindexes it and can be undone. Layout never goes into Markdown.

Recall is a record, not a schedule. The Overview counts the notes that survived an unaided retrieval, and an unaided grade has to carry a receipt: the sentence the learner actually said. Nothing counts down or keeps a streak.

The graph window draws the vault from that Markdown on each request. Shape says what a note is and lines say how notes link. What breaks the vault's rules is judged in red pen and named: an orphan nothing links to, a prerequisite not written yet, a link that only goes one way.

Map is the drawing. Path puts what to learn first at the top, each note below what it needs. Time lays dated notes on a ruler that ticks from centuries down to days: spans as bars, causes as curves to what they led to, Hijri years one switch away. Live is the notes in motion: dragging one pulls its neighbours like a spring web, and under reduced motion it holds still.

1 not written, 2 one-way links in this demo vault of 59 notes.

The graph window in Map view: hubs drawn as rings, concepts as dots, sources as squares, questions as open rings and an exam as a diamond, with red-pen marks on a note not written yet and on one-way links. The Path view of the Attention hub: the notes to learn first at the top and each note below what it needs, with a dashed red line marking a one-way link from Causal masking to Self-attention. The Time view of the History of attention hub: Bahdanau attention in 2014, Luong attention, the Transformer in 2017, BERT, GPT-2, the Vision Transformer and FlashAttention on a ruler, with the years of recurrent encoder-decoders as a bar and curves from each idea to what it led to.

Your notes and your videos, in one space.

The Meaning view lays every note out by what it means, as search sees it: each note's passages are embedded, averaged, and brought down to a flat map (or a 3D one you can turn) with PCA and UMAP. Notes on the same idea sit together whatever language they are written in, and colour says which hub they belong to.

Bring in your YouTube watch history from Google Takeout and every video you watched joins the map, placed among the notes it is near. Videos near none of your notes gather in a ring around them, named by their most watched channel. Thousands show as soft regions, then dots, then YouTube's thumbnails as you zoom in. Point at one and lines go to its notes; keep one and it becomes a source note.

Ctrl+K searches what was said in those videos too, and a result opens the video at that second.

The Meaning view of the demo vault in groups: separate glowing islands of notes for astronomy, the human body, Egyptian history in Arabic, web development, baking, attention, computer vision and optimization, each island coloured and named in the legend.
The notes fall into islands by meaning, and each group is named after the subject most of its notes belong to.
Zoomed in on the astronomy island: the notes Mars, The Sun, Comets, Neutron stars, Black holes and Dark matter, with the thumbnails of the videos about space and science placed around them.
Closer in, around the astronomy notes, the dots become thumbnails.
The same map in 3D with about 700 watched videos as hollow dots: they gather around the islands they are about, and off-topic channels sit apart at the edges.
With the watch history: videos settle around the notes they are about.

Thousands of videos stay readable. Far out, they are soft coloured regions with counts; nearer, dots that fill in once you write your line about a video; close in, YouTube's own thumbnails. Filter by this week or month, by channel, or only the videos near your notes.

The demo vault adds a few subjects far apart from machine learning, so the islands are easy to see. The watch history is about 450 real public videos from twelve channels plus the Board's own made-up sample.

An embedding model I trained for it.

A good multilingual embedding model is slow on a laptop. EmbeddingGemma takes about 175 ms a query on the CPU, too slow for a search box that answers on every key. So the Board has its own: Qatra (قطرة, "a drop"; Arabic's word for distillation shares its root).

Qatra is a static model: a table of token vectors, averaged per text, so no neural network runs when you search. I distilled it with Model2Vec from two teachers, EmbeddingGemma 2 and IBM's granite-embedding-311m-multilingual, over a corpus I built from documentation, lecture transcripts, parallel Arabic and English pairs, and generated learner questions and notes in English and Egyptian Arabic. Then I reweighted it so common words count less, and quantised it to int8.

One model now does what two did before, one for English and one for Arabic, with no language router in front.

0.3 msa query on a laptop CPU, against about 175 ms for EmbeddingGemma
0.78of 64 fresh questions find the right passage in the top 10 with BM25 beside it; EmbeddingGemma: 0.83
0.76for Arabic questions over English notes, against 0.50 for the two models it replaced
99 MBat int8, with the vocabulary cut to what Arabic and English text can produce

Measured on questions it never saw. The training run picked its checkpoint on its own test suites, so I benchmarked it again on 64 questions written before any trained model ran on them, half in English and half in Egyptian Arabic or code-switched, over four documentation sites, and again against 47k distractor passages. With 64 questions, gaps under about 0.12 are noise, and the numbers above are read that way.

Each model where it is right. Qatra answers the instant searches: the Ctrl+K box while you type, a library's find box, what was said in a video. EmbeddingGemma still has the last word on anything a learner acts on, and exact phrases go to keywords alone.

Search runs twice. SQLite full-text search finds exact terms, and a vector index finds meaning. The two lists are merged by rank, not by score, because a BM25 score and a cosine distance are not on the same scale.

The careful tier runs EmbeddingGemma 2's 4-bit text model directly on ONNX Runtime, with no PyTorch. Its vectors are centred on the vault's mean before they are stored, because raw cosines between unrelated texts sit well above zero. Embeddings are cached by the content's hash, so unchanged text is never embedded twice.

BM25Full-text search in SQLite FTS5 for exact terms and snippets
VectorsQatra while you type; 768 dimensions from EmbeddingGemma 2, centred, in a libSQL DiskANN index, for the rest
Reciprocal rank fusionEach result scores the sum of 1 / (60 + its rank) across both lists

Your exams on a calendar, your past papers in the plan.

Tell your agent a date ("my final is on 21 December") or share a syllabus, and it proposes the dates. Each waits at the top of the Calendar until you tick it; only ticked dates count down, in the heads of the course's hubs and on the Overview. Your university's .ics comes in, and "Save as .ics" takes the dates to your phone.

Add a past paper and the agent splits it into its questions, each with its page, marks and kind. The Board checks each question on its page, matches it to a note on your computer, and from every paper of a course writes a pattern note: per topic, how many papers asked it and its share of the marks. Nothing reminds you, and nothing is due.

The Calendar window: three dates the agent proposed for a Deep Learning course, an Attention quiz, a project deadline and the final exam worth 50% of the grade, waiting for the learner's tick, above a week grid with today marked and the course's hubs Attention and Transformers.
Dates the agent proposed for a course, waiting for the learner's tick.

A desk that stays in order.

Sections are named frames that hold windows, like the parts of a map: drag one and its windows come along. Ask the agent to tidy the desk and it groups what belongs together.

Dock a session as a full-height panel on the right and read on the left; a window the agent opens lands beside the panel, not under it.

Looks change the whole Board: Air, Graphite, Earth, Tide and Summer, each light and dark, any colour theme on any look, and nine accents. Notes can also draw their Mermaid blocks in place, as clean shapes in the Board's colours.

The session docked as a full-height panel on the right, with the paper and its diagram in a blue section called The paper and the note in a green section called My notes on the desk to the left.
The session docked on the right; the paper and the note filed in sections.
The same Board in its Air look, with the paper and its diagram filed in a section called The paper and the note under My notes.
The same Board in Air, with sections.
A note with a callout on why to divide by √dk, a Mermaid flowchart drawn in place showing queries and keys scored, the softmax weights and the weighted sum of values, a code block and the note's cards.
A note's Mermaid block, drawn in place.

A bridge that tells the truth about delivery.

An agent over MCP reaches the Board through a local discovery file, readable by you only, and a loopback server on a random port.

Every request carries an ID, so a retry returns the original result instead of a second message. Each canvas change carries the revision it was based on: if you dragged a window after the agent read the scene, the agent's move fails as stale instead of overwriting yours. The status line shows only states that are true.

  1. ConnectedThe agent has the session open.
  2. Waiting for youThe agent is listening for your answer.
  3. Question openA question is waiting, but the agent is not listening right now.
  4. Reply sentYour answer is queued until the agent collects it.
  5. Reply receivedThe agent collected it; it stays retrievable until acknowledged.
  6. Session endedThe window shows the saved transcript, read-only.

Arabic is first-class, not a fallback.

Many learners write in Arabic and English, often in one line. Every surface resolves its own direction: each paragraph, list item, heading, title and input carries dir="auto", while code and math stay left-to-right.

Right-to-left blocks get more line height, 1.85 instead of 1.6, so the dots and marks have room.

A note with its English idea and formula followed by a section headed بالعربي, written in Egyptian Arabic mixed with the English terms query, keys and softmax, reading right to left.
A note mixing Arabic and English in one line.

Tested the way it is used.

1,147 automated tests, counted on 20 October 2026, run on every push on Ubuntu and macOS together with the installer. A browser scenario drives a real Chromium through an Arabic session, a marked question, a shared PDF page, a sheet written with a pen, the built-in agent streaming from a fake model server, and a server restart. The web suite also checks text contrast in every theme.

500server, protocol, MCP and module tests
403web app tests, including every theme's contrast
244Python tests for search, the graph, ingest and the records
64held-out questions behind the embedding numbers above

Study side by side with your agent, and keep the notes.