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. Usehttps://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
| Transport | How it works | When to use |
|---|---|---|
stdio | Koda spawns a child process and communicates over stdin/stdout | Local tools, CLI-wrapped servers |
http | Koda connects to a running HTTP endpoint (MCP 2025-03-26 spec) | Remote or shared servers, cloud APIs |
Timeouts
| Setting | Default | Description |
|---|---|---|
startup_timeout_sec | 30 s | Time allowed for the server to respond to initialize |
tool_timeout_sec | 120 s | Time 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 removeupdates the block in the next turn — there’s no stale-prompt window.
What this means for MCP server authors
- The
instructionsfield in yourInitializeResultreaches 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
| Symptom | Fix |
|---|---|
Server shows failed on /mcp list | Check the command/URL, then /mcp reconnect <name> |
| Tools not appearing after add | The server may have taken longer than startup_timeout_sec to start — /mcp reconnect or restart Koda |
__ in server name rejected | Use - instead: my-server not my__server |
| HTTP server SSRF error | Private/loopback URLs are blocked — use a public or VPN-accessible URL |