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:

ToolDoes
brain_searchone ranked search across memory, library, and the code index
memory_recall memory_remember memory_raterecall, record, and rate memories
library_search library_getsearch and fetch authored documents
code_searchask what a codebase contains
dispute_query dispute_recordlook up and record recorded disagreements
idea_addfile an idea

Control plane, for looking at and steering work:

ToolDoes
project_list project_resolveyour registered projects
sequence_list sequence_runwhat can run, and start one
sequence_status sequence_runsone run, or recent runs
sequence_ackanswer a gate a run is waiting on
dispatch_enqueue dispatch_status dispatch_listqueue a job, check one, list them
schedule_create schedule_listrecurring work
ideas_listthe idea backlog

The escape hatch, which is how the other ~180 CLI commands stay reachable without paying for ~180 tool schemas in every session:

ToolDoes
toryo_helpdiscover what a CLI can do
toryo_runrun 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 and toryo setup own these.
  • Destructive or interactive, forget, reset, remove, delete, dismiss, deactivate, the cleanup-* 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.

ClientWhere it landsWorth knowing
Claude Code~/.claude.jsonWired through its own CLI when that is on your PATH, by merging into the file when it is not.
Claude Desktopclaude_desktop_config.jsonCreated when absent, and needs a restart to pick the server up.
Codex~/.codex/config.tomlWritten 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.jsonCreated when absent. No restart needed: copilot reads it per session. Found by the copilot binary on your PATH.
Cursor~/.cursor/mcp.jsonCreated 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.