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.
three things you can build today
Section titled “three things you can build today”- cursor publishes your changelog from a merged pr. Drop a post-merge step into your cursor workflow:
publish_changelog_entryagainst 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.1invocation 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.
setup in under five minutes
Section titled “setup in under five minutes”- 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. - Open the “use this with claude, cursor, or codex →” disclosure in the post-mint dialog and click copy mcp config.
- Paste the snippet into your client’s mcp config (see the tab for your client below).
- Fully quit the client (cmd-Q on macos — closing the window is not enough) and relaunch.
- Ask the agent
who am i on spirby?. Ifwhoamireturns 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.
copy-paste configs
Section titled “copy-paste configs”claude desktop
Section titled “claude desktop”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.
cursor
Section titled “cursor”In settings → mcp, add a server:
{ "name": "spirby", "command": "npx", "args": ["-y", "@spirby/mcp@^0.1"], "env": { "SPIRBY_MCP_TOKEN": "spk_<your_key>" }}codex cli
Section titled “codex cli”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.
use from scripts
Section titled “use from scripts”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.
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \ | SPIRBY_MCP_TOKEN=spk_... npx -y @spirby/mcp@^0.1Python with mcp-python-sdk:
from mcp.client.stdio import stdio_client, StdioServerParametersimport 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())scopes
Section titled “scopes”| scope | reads | writes | typical agent use |
|---|---|---|---|
read | yes | no | summarisers, weekly digests, dashboards |
read:write | yes | yes | triage 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.
rate limits
Section titled “rate limits”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.
errors
Section titled “errors”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.
| code | when |
|---|---|
ERR_INVALID_TOKEN | token missing, revoked, expired, or for another env |
ERR_SCOPE_INSUFFICIENT | read key invoked a write tool |
ERR_RATE_LIMITED | per-key budget exceeded |
ERR_BILLING_READONLY | workspace trial expired or subscription canceled |
ERR_BILLING_TRIAL_ONLY | feature requires a paid plan |
ERR_VALIDATION | tool input failed schema validation |
ERR_NOT_FOUND | resource id does not exist or is not in your org |
ERR_CONFLICT | duplicate (already voted, etc.) |
ERR_INTERNAL | unexpected — see status.spirby.com |
troubleshooting
Section titled “troubleshooting”- claude doesn’t show the tools. Fully quit (cmd-Q) and relaunch. Window-close keeps the mcp child alive with the old config.
npxfails. Runnode --version. We test on node 20+ via the published package’senginesfield.- 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.remainingfromwhoamifirst, or waitretry_after_secfrom 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 calltools/listagain — the server returns an empty list once the token is revoked.
tool reference
Section titled “tool reference”See the tools section for one page per tool with example prompts.