Configuring an MCP server
Add one[mcp_servers.<name>] block per server to your ~/.hiroshi/config.toml. Each block names the executable to run and the arguments to pass it:
Fields
The executable to run. This can be any program that speaks JSON-RPC 2.0 over stdin/stdout — for example
npx, python, or uvx.Arguments passed directly to
command when the child process is spawned.How MCP tools become available
When the Hiroshi daemon starts, it works through every entry inmcp_servers in sequence:
- Spawn — Hiroshi spawns the server process with
stdin,stdout, andstderrall piped. - Handshake — Hiroshi sends an
initializerequest (protocol version2024-11-05) and waits for acknowledgement. - Discovery — Hiroshi calls
tools/listand collects every tool the server advertises. - Skill reflection — Each discovered tool is automatically materialised as a skill folder at
~/.hiroshi/skills/<server>__<tool>/. - Execution — The agent can call any MCP tool just like any other skill. Hiroshi routes the call back to the correct server using the namespaced name.
Namespaced tool names
To prevent name collisions between servers, Hiroshi prefixes every MCP tool name with the server key you defined inconfig.toml:
query on the my_postgres server becomes my_postgres__query. This namespaced form is what you will see in skill folders and in the agent’s tool list.
Popular MCP servers
| Server | npm package | What it provides |
|---|---|---|
| Filesystem | @modelcontextprotocol/server-filesystem | Read/write access to local directories |
| PostgreSQL | @modelcontextprotocol/server-postgres | SQL query and schema inspection |
| GitHub | @modelcontextprotocol/server-github | Repo, PR, and issue management |
| Brave Search | @modelcontextprotocol/server-brave-search | Web search via the Brave API |
| Fetch | @modelcontextprotocol/server-fetch | HTTP fetch and web scraping |
| SQLite | @modelcontextprotocol/server-sqlite | Local SQLite database access |
MCP server processes are kept running in the background for the entire lifetime of the Hiroshi daemon. They are not restarted between requests — the same long-lived child process handles all calls to that server.