MCP
toryo speaks Model Context Protocol, so an agent session can search your
knowledge plane, look at what is running, and start work, without a /-command
or the board.
toryo mcp install # wire it into the MCP clients you have
toryo mcp list # what is wired where
toryo mcp uninstall # remove it
toryo setup offers to do the install as a prompted step. It is an offer rather
than a service: these are config files toryo does not own, so an unattended run
never edits them silently.
The server runs as a child process over stdio. Nothing listens on a port and nothing is exposed to the network.
What you get#
Roughly twenty-five tools in three groups.
Knowledge, reading and writing the same stores your agent runs use:
| Tool | Does |
|---|---|
brain_search | one ranked search across memory, library, and the code index |
memory_recall memory_remember memory_rate | recall, record, and rate memories |
library_search library_get | search and fetch authored documents |
code_search | ask what a codebase contains |
dispute_query dispute_record | look up and record recorded disagreements |
idea_add | file an idea |
Control plane, for looking at and steering work:
| Tool | Does |
|---|---|
project_list project_resolve | your registered projects |
sequence_list sequence_run | what can run, and start one |
sequence_status sequence_runs | one run, or recent runs |
sequence_ack | answer a gate a run is waiting on |
dispatch_enqueue dispatch_status dispatch_list | queue a job, check one, list them |
schedule_create schedule_list | recurring work |
ideas_list | the idea backlog |
The escape hatch, which is how the other ~180 CLI commands stay reachable without paying for ~180 tool schemas in every session:
| Tool | Does |
|---|---|
toryo_help | discover what a CLI can do |
toryo_run | run a CLI command |
What toryo_run reaches is derived from the contract manifest, so a command
added to any app widens it automatically.
What it will not run#
toryo_run withholds two classes of command, by role rather than by name:
- Process lifecycle,
migrate,start,daemon,serve,watch,up,down,restart, and the rest. foreman andtoryo setupown these. - Destructive or interactive,
forget,reset,remove,delete,dismiss,deactivate, thecleanup-*family,psql. These stay behind a terminal, where you can see what you are about to run.
A refusal names the shell command to run instead, so it redirects rather than dead-ends.
cancel is deliberately reachable. It is recoverable, and it is the stop button
you want when you are looking at a run from Claude Desktop and it is going
somewhere wrong.
Claude Code, Claude Desktop, Codex, GitHub Copilot and Cursor#
toryo mcp install wires every one of them it finds. Narrow it with
--client claude-code|claude-desktop|codex|copilot|cursor.
| Client | Where it lands | Worth knowing |
|---|---|---|
| Claude Code | ~/.claude.json | Wired through its own CLI when that is on your PATH, by merging into the file when it is not. |
| Claude Desktop | claude_desktop_config.json | Created when absent, and needs a restart to pick the server up. |
| Codex | ~/.codex/config.toml | Written by codex mcp add, which corrects a stale entry in place and leaves your comments and unrelated tables alone. Found by the codex binary on your PATH. |
| GitHub Copilot | ~/.copilot/mcp-config.json | Created when absent. No restart needed: copilot reads it per session. Found by the copilot binary on your PATH. |
| Cursor | ~/.cursor/mcp.json | Created when absent. A written server still needs enabling in Cursor's Customize sidebar, and Cursor caps tools at roughly 40 across all servers, which toryo's twenty-five eat most of. |
Every JSON config goes through one backup-then-merge path: your other MCP servers survive, and every mutating write is preceded by a timestamped backup. Codex is the exception, because its config is TOML and its own CLI owns the write.
~/.claude.json is never created from nothing. That file holds much more than
MCP servers, so if it is absent, Claude Code has not run on this machine yet, and
creating it would be toryo inventing state for another tool.
Project scoping differs by client#
A session with a working directory (Claude Code, Codex, GitHub Copilot, Cursor) has that directory resolved to a project at startup. Best effort: an unregistered directory leaves the pin unset rather than failing to start.
Claude Desktop has no meaningful working directory, so there is nothing to
resolve. Operator tools therefore take an optional project argument (a slug or
a UUID) and fall back to the session pin. Ask about a project by name and it
works; ask an unqualified question and you get global scope.
To pin one, set TORYO_BRAIN_PROJECT in the server's env block in the Desktop
config, and get the id from:
toryo project get <name>
Skills or tools?#
Both surfaces exist and they overlap.
Skills (/toryo-code, /toryo-status, …) are a harness-side surface:
toryo skills install writes them into both user-level skills roots
(~/.claude/skills, ~/.agents/skills). They read files, run shell, and hold a
multi-turn flow, so they are the richer path for anything needing judgement or
file access on the way in.
Tools work in every wired client (Claude Code, Claude Desktop, Codex, GitHub Copilot and Cursor), and are the only surface Claude Desktop has: it is an app, not a harness with a skills root. They are one typed call with a structured result.
Where a gesture exists as both, prefer the skill in Claude Code.
The rule underneath all of it#
The MCP is a second facade over the CLI, not a parallel API. Nothing exists in a tool that a CLI command cannot already do, which is why the escape hatch can be generated from the contract rather than hand-maintained. If you are building something on toryo, build on the CLI: see Building on toryo.
When something is missing#
The tools are not there. Run toryo mcp list to see what is wired. Restart
Claude Desktop after any change; it does not reload config.
Everything comes back global. No project pin and no project argument. See
above.
Searches return nothing. Check services with toryo foreman check. The
server starts even when Postgres is down. It just has nothing to read.
A command is refused. It is in one of the withheld classes. The refusal names the shell command to run instead.