Develop with a coding agent
Tokori is built to be hacked on. The plugin SDK, the local HTTP API, and the bundled MCP server compose into a comfortable loop for extending the app with the help of a coding agent — Claude Code, Codex, opencode, Cursor, or anything else that speaks MCP.
This guide assumes you've already wired up the Tokori MCP server. If you haven't, do that first — every recipe below relies on the agent being able to read your live workspace.
The loop
- Open the cloned repo in your terminal.
- Launch your agent.
- Ask it to do something — write a study plugin, add a reader feature, scrape vocab from a source.
- The agent reads your live state via the MCP tools, edits files in
src/, and tells you what to test. - You hit
npm run tauri dev, try it, give feedback. Loop.
The MCP server is what makes step 4 useful: the agent doesn't need to guess what your data looks like, it can call list_workspaces, list_collections, list_vocab and see.
Recipe 1 — write a new study plugin
Plugins live under src/lib/study/plugins/. The contract is in Plugin SDK — short version: export a StudyPlugin with a StudyView React component, register it in src/lib/study/registry.ts.
A productive prompt looks like this:
"I want a new study plugin for the Reverse Cloze drill — show the sentence with one word blanked out, the user types the missing word. Pull example sentences from existing vocab entries'
cardNotesfield. Usectx.reviewVocabfor grading. Look atsrc/lib/study/plugins/vocab-recall.tsxfor the lifecycle pattern. Also calllist_vocabfor my Chinese workspace so you know what words I have."
The agent will read the existing plugin, sample your live vocab via MCP, draft the new plugin, and walk you through registering it.
Recipe 2 — bulk-curate a collection
You don't need to write code at all to use the MCP surface. With the Tokori MCP server installed, just ask:
"Pull every Chinese word from this Wikipedia article that I don't already know, fill in pinyin and English glosses from CC-CEDICT, and save them as a collection called 'Beijing Subway System'."
The agent will:
- Fetch the article (web tool or pasted text).
- Tokenise into Chinese words.
- Call
list_vocabwithqto skip what you already have. - Call
search_dictper remaining word to fill readings/glosses. - Call
import_collectiononce with the full batch.
Counts from the response are the source of truth — the agent reports { added, existed, skipped } so you know what actually changed.
Recipe 3 — extend the local HTTP API
The MCP server is a thin proxy over the local HTTP API in src-tauri/src/api_server.rs. To expose a new capability to the agent you change two files in lockstep:
- Add the route in
api_server.rsunder/v1/. - Add a matching tool in
mcp-server/src/index.ts(and a typed wrapper inmcp-server/src/api.ts).
A productive prompt:
"Add a
/v1/workspaces/:id/vocab/:vidPATCH endpoint that updates theglossandfront_extrafields. Mirror it as anupdate_vocabtool inmcp-server/src/index.ts. Match the validation pattern used bycreate_vocab."
The agent edits both surfaces, you cargo check + npm run build in the two directories, restart the desktop app + the MCP server, and the new tool appears in your MCP client.
Recipe 4 — debug a bug with live state
"When I open the character detail page for 餐, the stroke order panel never loads. Look at
src/components/character-detail.tsxand tell me where the loader is. Also calllist_vocabfor my Chinese workspace and find a word containing 餐 — I want to test against a real entry."
The agent has the code, your live data, and the codebase conventions all in one place. Most "hunt the bug" sessions collapse to a 5-minute exchange.
What the agent should always do
- Use
npm run devfor fast UI iteration; switch tonpm run tauri devonly when touching Rust. - Run
npm run build+cargo checkbefore declaring a feature done. - Run
npm testif it touched anything insrc/lib/.
What the agent should never do
- Mutate your DB without asking. The MCP server intentionally exposes no delete endpoints — if the agent wants to clean up a botched import, it should ask you to delete the collection from the desktop UI.
- Fabricate readings or glosses. If
search_dictreturns nothing, leave the field empty. - Hard-code provider keys. Provider config flows through the
ChatProviderabstraction; never write a provider URL or key into a plugin.
Next steps
- Plugin SDK reference — every method on
ctx, the lifecycle, and the helpers used by the built-in plugins. - Architecture overview — where things live and why.
- Local HTTP API reference — the surface the MCP server wraps.