Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

MCP servers (Model Context Protocol)

Koda can connect to external MCP servers as a client, expanding its toolset with anything exposed over the MCP protocol — Playwright for browser automation, database drivers, Slack, internal APIs, and more.

Quick start

# Add a stdio server (spawns a child process)
/mcp add playwright npx -y @playwright/mcp

# Add an HTTP server
/mcp add-http my-api https://api.example.com/mcp

# Add an HTTP server with bearer-token auth
/mcp add-http my-api https://api.example.com/mcp --token sk-mytoken

# List all configured servers and their status
/mcp list

# Reconnect a server without restarting Koda
/mcp reconnect playwright

# Remove a server
/mcp remove playwright

Slash commands

/mcp list

Shows every configured MCP server, its transport (stdio / http), and its current connection status (connected / failed / disconnected).

/mcp add <name> <command> [args...]

Add a stdio MCP server. Koda spawns <command> with the given arguments and communicates over stdin/stdout.

/mcp add playwright  npx -y @playwright/mcp
/mcp add db-tools    uvx koda-db --dsn postgresql://localhost/mydb

Name rules: letters, digits, hyphens, and underscores only ([a-zA-Z0-9_-]). Double-underscore (__) is reserved as Koda’s internal tool-routing separator and is not allowed.

/mcp add-http <name> <url> [--token <bearer>]

Add an HTTP MCP server using the MCP 2025-03-26 Streamable HTTP transport.

/mcp add-http my-api  https://api.example.com/mcp
/mcp add-http my-api  https://api.example.com/mcp --token sk-abc123

Security note: Bearer tokens sent over plaintext http:// are logged as a warning. Use https:// in production. Koda also blocks connections to private/loopback addresses (SSRF protection).

/mcp reconnect <name>

Disconnect and re-connect a running server without restarting Koda. Useful after updating the server binary or rotating credentials.

#/mcp remove `

Permanently delete the server config from the local keystore and disconnect it immediately. The server process (if stdio) is cleaned up automatically.

Tool naming

MCP tools appear in Koda’s tool registry as <server>__<tool>. For example, a tool named navigate on the playwright server becomes playwright__navigate.

The model can call these tools directly. No extra configuration is required.

Tool filtering

To limit which tools a server exposes, edit ~/.config/koda/mcp.json manually or use koda config (future release). Example snippet:

{
  "playwright": {
    "transport": "stdio",
    "command": "npx",
    "args": ["-y", "@playwright/mcp"],
    "enabled_tools": ["navigate", "click", "screenshot"]
  }
}

enabled_tools is an allowlist; disabled_tools is a denylist. If both are set, enabled_tools wins.

Transport reference

TransportHow it worksWhen to use
stdioKoda spawns a child process and communicates over stdin/stdoutLocal tools, CLI-wrapped servers
httpKoda connects to a running HTTP endpoint (MCP 2025-03-26 spec)Remote or shared servers, cloud APIs

Timeouts

SettingDefaultDescription
startup_timeout_sec30 sTime allowed for the server to respond to initialize
tool_timeout_sec120 sTime allowed for a single tool call to complete

Persistence

MCP server configs are stored in the local SQLite keystore (~/.local/share/koda/koda.db) under the mcp: key prefix. They survive session restarts and are loaded automatically on each startup.

Server-supplied instructions

The MCP spec lets each server return a free-form instructions string in its initialize response telling the model how to use it best — for example, “Prefer locator-based queries over CSS selectors” for a Playwright server, or “Always use parameterized queries” for a Postgres server.

Koda surfaces these into the system prompt of every turn, in a dedicated block that comes after Koda’s own behavioral mandates:

# MCP Server Instructions

---[start of server instructions from playwright]---
Prefer locator-based queries over CSS selectors.
---[end of server instructions from playwright]---

---[start of server instructions from postgres]---
Always use parameterized queries.
---[end of server instructions from postgres]---

What this means for users

  • Zero token cost when no MCP servers are configured. The block is omitted entirely.
  • No config required. If you’ve added a server with /mcp add, its instructions surface automatically the next turn after it connects.
  • Hot-reload friendly. Adding or removing a server mid-session via /mcp add / /mcp remove updates the block in the next turn — there’s no stale-prompt window.

What this means for MCP server authors

  • The instructions field in your InitializeResult reaches the model verbatim. Treat it like a short README aimed at the LLM, not at humans.
  • Be concise — every byte costs tokens for every turn the user runs against your server.
  • Don’t try to override Koda’s own behavioral mandates. The provenance framing (---[start of server instructions from <name>]---) makes it obvious to the model that your block comes from your server, not from Koda itself, so impersonation attempts are visible.

Security note

Server-supplied instructions are untrusted content from the perspective of the user’s session — they originate from whoever runs the MCP server. Koda passes them through verbatim (no sanitization) but wraps them in clearly-labelled provenance markers so a malicious or compromised server can’t masquerade as Koda’s own mandates.

If you connect to MCP servers you don’t fully trust, prefer the stdio transport (which still flows through the OS sandbox for tool calls) and review the instructions block via your model’s tracing/debug output before granting Auto mode.

Troubleshooting

SymptomFix
Server shows failed on /mcp listCheck the command/URL, then /mcp reconnect <name>
Tools not appearing after addThe server may have taken longer than startup_timeout_sec to start — /mcp reconnect or restart Koda
__ in server name rejectedUse - instead: my-server not my__server
HTTP server SSRF errorPrivate/loopback URLs are blocked — use a public or VPN-accessible URL