Coderrr

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.db

Either way Coderrr connects immediately, so a wrong port or an app that is not running shows up there and not mid-task.

OptionWhat it does
-t, --transport <kind>Force http or stdio instead of inferring it from the argument
-H, --header KEY=VALUEHTTP header. Quote '${VAR}' to read a token from the environment.
-e, --env KEY=VALUEEnvironment 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 credentials

Tokens 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 run

Managing servers

CommandWhat 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 listWhat 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> --offKeep 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
KeyDefaultWhat 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 / cwdstdio transport, instead of url. The command runs on the host, outside the sandbox.
enabledtrueOff keeps the configuration but stops using the server.
timeout30.0Ceiling 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.
requiredfalseA 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.