MCP Servers
Connect your own MCP servers and their tools become tools Coderrr can call — Figma, Linear, Notion, or something internal. No extra install: like every provider here, the client is plain HTTP.
Adding a server
From inside a session, paste a URL and you are done. /mcp lists what is configured and offers to add one; /mcp add <url> skips the menu.
coderrr ❯ /mcp
1. Add a server
2. Done
? MCP: 1
? URL or command: http://127.0.0.1:3845/mcp
? Name for it: figma
◇ Connecting to figma...
■ figma connected — 1 tool(s): get_code
◇ Available as mcp__figma__* from your next request.A server added mid-session is picked up by your next request — no restart. Or from the shell:
# a URL is an HTTP server
coderrr mcp add figma http://127.0.0.1:3845/mcp
# after -- it's a command, run over stdio
coderrr mcp add sqlite -- npx -y @some/mcp-server --db ./app.dbEither way Coderrr connects immediately, so a wrong port or an app that is not running shows up there and not mid-task.
| Option | What it does |
|---|---|
| -t, --transport <kind> | Force http or stdio instead of inferring it from the argument |
| -H, --header KEY=VALUE | HTTP header. Quote '${VAR}' to read a token from the environment. |
| -e, --env KEY=VALUE | Environment variable for a stdio server |
| --cwd <path> | Working directory for a stdio server |
| --timeout <seconds> | Seconds per request. Default 30. |
Servers that need a login
For a server behind OAuth — Linear, Notion — adding it offers the sign-in there and then:
coderrr ❯ /mcp add https://mcp.linear.app/mcp
? Name for it: linear
◇ Connecting to linear...
◇ linear requires you to sign in.
? Open your browser to authorize now? [y/n] (y): y
◇ Opening your browser to authorize...
■ Signed in to linear (https://mcp.linear.app).Coderrr registers itself with the server, opens your browser with PKCE, catches the redirect on a loopback port, and stores the tokens. Access tokens are renewed silently when they expire, including mid-run; you only see a browser again if the refresh token itself lapses.
A browser only ever opens when you ask for it
The interactive leg is confined to mcp add, /mcp add and mcp login. Nothing during a task will open one, so agent runs never block on a window you have to go and find.
coderrr mcp login linear # sign in, or re-authorize
coderrr mcp login linear --no-browser # print the URL instead (SSH, remote dev)
coderrr mcp logout linear # discard stored credentialsTokens live in your OS keyring when one is available, otherwise ~/.coderrr/credentials.json at mode 0600 — never in config.toml, which is rewritten on save and meant to be readable and committable. A reissued refresh token is persisted immediately, since servers that rotate invalidate the old one.
The implementation covers RFC 9728 protected-resource discovery, RFC 8414 server metadata, RFC 7591 dynamic client registration, PKCE, and RFC 8707 resource indicators. For a server that uses a static token instead, skip OAuth entirely and pass the header — tokens belong in the environment, not in your config file:
coderrr mcp add notion https://mcp.notion.com/mcp -H 'Authorization=Bearer ${NOTION_TOKEN}'How the tools show up
Bridged tools are named mcp__<server>__<tool>. The prefix is not decoration — it is how the model, the terminal, and your stored approvals tell a tool that reaches an outside service apart from one that reads a local file, and it keeps two servers offering search from colliding.
They are available while planning as well as executing. Pulling a design or an issue description is usually how a plan gets grounded in the first place.
Each tool asks the first time it is used, then remembers.
figma → get_code [read-only]
? Allow mcp__figma__get_code?
1. Allow once
2. Always allow this tool
3. Deny"Always" is saved to allowed_tools for that server, so it is one question per tool rather than a prompt you learn to click through. coderrr mcp reset <name> forgets those answers, and denied_tools hides a tool entirely.
What a server claims about itself is never what decides. MCP tool annotations like readOnlyHint are hints from an unverified peer — Coderrr shows them next to the prompt and ignores them otherwise. Everything a server returns is labelled as external data in context, because a ticket body or a design comment can be written by anyone.
Two things worth knowing
A stdio server runs on your machine, outside the sandbox, with your environment. Coderrr shows the exact command and asks before saving it. Adding by URL does not ask — typing the URL is the decision.
MCP tools work during planning, so a filesystem-style server, once allowed, can write files in a mode that otherwise has no write tool. Use denied_tools to hide anything you would rather keep out of reach.
When a server is not available
By default a server that cannot be reached is reported and skipped — a coding task should not die because a design tool is down. But that silently shortens the tool list, and the same request then produces different work. If you depend on a server, say so and get an error before the run starts instead:
[mcp.servers.internal-api]
required = true # a connect or login failure aborts the runManaging servers
| Command | What it does |
|---|---|
| coderrr mcp add <name> <url> | Connect an HTTP server |
| coderrr mcp add <name> -- <command> | Connect a server run over stdio on your machine |
| coderrr mcp list | What is configured, and what is signed in |
| coderrr mcp test <name> | Connect and list its tools |
| coderrr mcp login <name> | Sign in, or re-authorize |
| coderrr mcp logout <name> | Discard stored credentials |
| coderrr mcp enable <name> --off | Keep the config, stop using it |
| coderrr mcp reset <name> | Forget the "always allow" answers |
| coderrr mcp remove <name> | Remove the server and its remembered approvals |
coderrr doctor reports how many servers are enabled and warns about any that are configured but not signed in. In a session, /mcp, /mcp add <url> and /mcp login <name> cover the same ground.
[mcp.servers.<name>]
Written by coderrr mcp add, and hand-editable. OAuth tokens are never written here.
[mcp.servers.figma]
transport = "http" # http | stdio
url = "http://127.0.0.1:3845/mcp"
auth = "auto" # auto | none — OAuth when the server asks for it
enabled = true
required = false # true: a connect/login failure aborts the run
timeout = 30.0 # seconds per request
allowed_tools = ["get_code"] # answered "always allow"
denied_tools = [] # never bridged at all
client_id = "" # only for servers without dynamic registration
scopes = [] # overrides what the server advertises| Key | Default | What it does |
|---|---|---|
| transport | "http" | Inferred by mcp add from what you pasted — a URL means HTTP, a command means stdio |
| url | "" | HTTP transport. Required when transport is http. |
| headers | {} | HTTP headers. ${VAR} is resolved from the environment at connect time. |
| command / args / env / cwd | — | stdio transport, instead of url. The command runs on the host, outside the sandbox. |
| enabled | true | Off keeps the configuration but stops using the server. |
| timeout | 30.0 | Ceiling for connect-and-list-tools, and for each individual tool call. |
| auth | "auto" | auto attempts OAuth when the server answers 401. none never does — for a static token, or no auth at all. |
| required | false | A run whose tool list silently shrank cannot be reproduced. Set true if you depend on this server. |
| allowed_tools | [] | Tool names answered "always allow" |
| denied_tools | [] | Tool names never bridged at all |
| client_id | "" | Only for servers that do not offer dynamic client registration |
| scopes | [] | Overrides the scopes the server advertises. Usually empty. |
One key sits above the server table: mcp.max_result_bytes (default 65536) caps how much of a single tool result is folded into context, since a server can return a whole design file or issue history. See Configuration for the rest of config.toml.
What is implemented
The client is written over httpx and asyncio — JSON-RPC 2.0 with Streamable HTTP and stdio transports, plus OAuth 2.1 with dynamic client registration and PKCE — for the same reason the provider adapters are: the official SDK ships its server half too, and uvicorn has no business in a CLI.
- Tools only. MCP resources and prompts are not implemented.
- Transports: Streamable HTTP and stdio.
- No extra dependency. Nothing to install alongside Coderrr to use any of this.