MCP

Configure as many MCP servers as you want — tool schemas never enter the model context.

phi connects to MCP the mcptoon way: configure as many servers as you want; tool schemas never enter the model context.

That is the main difference from hosts that dump every tools/list schema into the prompt — ten or a hundred servers will not burn tens of thousands of tokens before you ask a question.

Why this is a highlight

Pain Typical MCP host phi
Context All schemas injected at startup Model sees only three meta-tools
Many servers Uninstall / reload Tetris Always configured; call on demand
Permissions Separate system or wide open Same Gate / Ask / Extensions as builtins
Footprint Heavy SDKs, always-on processes Hand-rolled Go stdio client, lazy start

Agent-facing tools:

  • mcp_list — list tool names on one server (compact text)
  • mcp_inspect — slim parameter summary for one tool
  • mcp_call — actually invoke

Configured server names are listed in the system prompt (like Skills), so the model knows what exists without calling mcp_list first. Schemas still stay out of context.

Typical rhythm: pick a server from the prompt → mcp_list(server=…)mcp_inspectmcp_call.

Interaction flow

Start TUI / phi run
  → load ~/.phi/mcp.json + <cwd>/.phi/mcp.json
  → build Pool (no subprocess yet)
  → tool list += mcp_list / mcp_inspect / mcp_call
  → system prompt += MCP catalog (server names only)

User prompt
  → model may call mcp_list(server=…) directly from the catalog
  → lazy Client → spawn → initialize → tools/list → names only
  → mcp_inspect → compact param summary
  → mcp_call → Executor → ExtensionPre → Gate → tools/call → result to model

Human CLI and the agent share the same internal/mcp stack:

phi mcp doctor|call  ──┐
                       ├──► Pool ──► Client (stdio JSON-RPC)
model mcp_* ───────────┘

Sub-agents do not inherit MCP meta-tools by default. Disable with PHI_MCP=off.

Quick start

Config file: ~/.phi/mcp.json (project <cwd>/.phi/mcp.json overrides same-named servers).

{
  "servers": {
    "browsermcp": {
      "transport": "stdio",
      "command": ["npx"],
      "args": ["@browsermcp/mcp@latest"]
    },
    "remote": {
      "transport": "http",
      "url": "http://127.0.0.1:3001/mcp",
      "headers": { "Authorization": "Bearer …" }
    }
  }
}

Or via CLI:

phi mcp add browsermcp -- npx @browsermcp/mcp@latest
phi mcp list
phi mcp doctor

Note: restart phi after config changes — the Pool loads at startup.

Migrating from Claude Desktop config

Claude / Cursor style:

{
  "mcpServers": {
    "browsermcp": {
      "command": "npx",
      "args": ["@browsermcp/mcp@latest"]
    }
  }
}

phi equivalent:

{
  "servers": {
    "browsermcp": {
      "transport": "stdio",
      "command": ["npx"],
      "args": ["@browsermcp/mcp@latest"]
    }
  }
}

mcpServersservers; string command becomes the first element of the command array.

CLI

phi mcp list                         list configured servers
phi mcp add <name> -- <cmd> [args…]  write ~/.phi/mcp.json
phi mcp remove <name>                remove from user config
phi mcp call <server> <tool> [json]  call a tool directly
phi mcp doctor                       check config + connectivity

Logs: ~/.phi/logs/mcp/<name>.log (override with PHI_MCP_LOG_DIR).

Limits (v1)

  • Transports: stdio and http (POST JSON / SSE data: bodies, Mcp-Session-Id)
  • MCP tools are not registered individually into the model tool list (by design)
  • Dead subprocesses reconnect on the next call; no elaborate self-heal state machine
  • Some third-party packages may crash on start — use doctor + logs.