Skip to content

mcp server

Your roadmap is now ai-writable. The spirby mcp server exposes feedback boards, posts, votes, comments, and changelog entries to any agent that speaks the model context protocol. Tokens are scoped (read or read:write), per-key rate-limited, and the same spk_* key works across rest, tRPC, and mcp.

  • cursor publishes your changelog from a merged pr. Drop a post-merge step into your cursor workflow: publish_changelog_entry against the draft cursor wrote from the pr body.
  • claude desktop triages a flood of feedback into board statuses. Point claude at a board, ask it to dedupe and assign statuses, watch the dashboard update in real time.
  • codex cli runs a weekly digest of top-voted posts. A one-shot npx -y @spirby/mcp@^0.1 invocation plus a couple of tool calls is a full digest pipeline.

Each of these is documented under tools with the agent prompt next to the io schema.

  1. Mint an spk_* key. Sign in to <your-subdomain>.spirby.com/app, open settings → api keys, mint a key with the smallest scope the integration needs.
  2. Open the “use this with claude, cursor, or codex →” disclosure in the post-mint dialog and click copy mcp config.
  3. Paste the snippet into your client’s mcp config (see the tab for your client below).
  4. Fully quit the client (cmd-Q on macos — closing the window is not enough) and relaunch.
  5. Ask the agent who am i on spirby?. If whoami returns your org id and scope, you’re connected.

If step 5 fails, run npx -y --package @spirby/mcp@^0.1 mcp-doctor --token spk_<your_key> in a terminal — it prints the same payload whoami would and a one-line hint if the token is wrong.

The server hits https://api.spirby.com by default. To point at a different deployment (staging, a self-hosted instance), set SPIRBY_API_URL in the same env block as SPIRBY_MCP_TOKEN.

Path: ~/Library/Application Support/Claude/claude_desktop_config.json (macos) or the equivalent on your platform.

{
"mcpServers": {
"spirby": {
"command": "npx",
"args": ["-y", "@spirby/mcp@^0.1"],
"env": { "SPIRBY_MCP_TOKEN": "spk_<your_key>" }
}
}
}

Merge with existing mcpServers entries — don’t replace the whole file. Restart claude desktop with cmd-Q, not just window-close.

In settings → mcp, add a server:

{
"name": "spirby",
"command": "npx",
"args": ["-y", "@spirby/mcp@^0.1"],
"env": { "SPIRBY_MCP_TOKEN": "spk_<your_key>" }
}
Terminal window
codex --mcp-server spirby='npx -y @spirby/mcp@^0.1' \
--env spirby:SPIRBY_MCP_TOKEN='spk_<your_key>'

Pin @^0.1 until you’re ready to handle a minor bump. The mcp sdk is pre-1.0 and we’ll telegraph any breaking change on the mcp changelog before bumping the minor.

The published binary is a plain stdio process — pipe json-rpc into it to use without an mcp-aware client. Useful for ci pipelines, lambda handlers, or python.

Terminal window
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
| SPIRBY_MCP_TOKEN=spk_... npx -y @spirby/mcp@^0.1

Python with mcp-python-sdk:

from mcp.client.stdio import stdio_client, StdioServerParameters
import asyncio
async def main():
params = StdioServerParameters(
command="npx",
args=["-y", "@spirby/mcp@^0.1"],
env={"SPIRBY_MCP_TOKEN": "spk_..."},
)
async with stdio_client(params) as (read, write):
# use the standard mcp client api from here
...
asyncio.run(main())
scopereadswritestypical agent use
readyesnosummarisers, weekly digests, dashboards
read:writeyesyestriage agents, post creators, status updaters, changelog

A read key never sees the write tools in tools/list. A direct call to a write tool with a read key returns ERR_SCOPE_INSUFFICIENT. Revoking the key in settings → api keys invalidates open sessions within one tool call — authorization is re-checked on every tools/call, not just at handshake.

Every key gets the same 1000 requests/hour budget rest does, and the budget is shared between rest and mcp on a per-key basis. Hit the cap and the next call returns ERR_RATE_LIMITED with retry_after_sec in the details. The whoami tool’s response includes the current rate_limit.remaining so a polite agent can pre-emptively back off.

Every error response is the same envelope, encoded into the mcp text-content frame for the agent to read. The agent gets code, message, and hint — hints are written so an llm can self-correct without a human.

codewhen
ERR_INVALID_TOKENtoken missing, revoked, expired, or for another env
ERR_SCOPE_INSUFFICIENTread key invoked a write tool
ERR_RATE_LIMITEDper-key budget exceeded
ERR_BILLING_READONLYworkspace trial expired or subscription canceled
ERR_BILLING_TRIAL_ONLYfeature requires a paid plan
ERR_VALIDATIONtool input failed schema validation
ERR_NOT_FOUNDresource id does not exist or is not in your org
ERR_CONFLICTduplicate (already voted, etc.)
ERR_INTERNALunexpected — see status.spirby.com
  • claude doesn’t show the tools. Fully quit (cmd-Q) and relaunch. Window-close keeps the mcp child alive with the old config.
  • npx fails. Run node --version. We test on node 20+ via the published package’s engines field.
  • wrong org’s data. The token is bound to the org of the user that minted it. Mint a separate key per workspace.
  • agent loops on a rate limit. It hit the per-key budget. Tell it to read rate_limit.remaining from whoami first, or wait retry_after_sec from the last error.
  • revocation didn’t propagate. It does on the next tools/call, never mid-call. If the client cached the tools list, ask it to call tools/list again — the server returns an empty list once the token is revoked.

See the tools section for one page per tool with example prompts.