@choirhq/mcp
v0.1.0
Published
MCP server for Choir — brings the user's own Claude (Claude Code, Claude Desktop) into their Choir workspace: post messages, read channels, file and update backlog items. Bring-your-own-Claude: no Anthropic key on Choir's side.
Readme
@choirhq/mcp
MCP server for Choir. Bring-your-own-Claude — the user's Claude (Claude Code, Claude Desktop, or any MCP client) launches this locally and gets a toolset that reads and writes their Choir workspace on their behalf. Choir never holds an Anthropic API key — the Claude side of the loop lives entirely in the user's environment.
Think of it as the Slack-app equivalent: Claude ends up with the ability to post messages into channels, read recent messages, query and update backlog lists — using the user's own Claude subscription and a per-workspace API token for authorization.
Setup — Claude Code
claude mcp add choir --scope user \
-e CHOIR_BASE_URL=https://choir.example.com \
-e CHOIR_API_TOKEN=chk_... \
-- npx @choirhq/mcpSetup — Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows). Create the file if it doesn't exist:
{
"mcpServers": {
"choir": {
"command": "npx",
"args": ["-y", "@choirhq/mcp"],
"env": {
"CHOIR_BASE_URL": "https://choir.example.com",
"CHOIR_API_TOKEN": "chk_..."
}
}
}
}Then quit + restart Claude Desktop. Claude's tool picker should list choir_send_message, choir_list_item_add, and the rest.
Getting a workspace API token
- Open your Choir workspace → Workspace settings → API tokens → New token.
- Name it (e.g.
claude-desktop-<your-laptop>). - Grant the scopes you want this Claude session to have — combine as needed:
mcp:messages:write— post into channelsmcp:messages:read— read recent messagesmcp:lists:read— query listsmcp:lists:write— file / update / close backlog itemsmcp:kb:read— knowledge base search (once wired)
- Copy the
chk_...value at creation — Choir never shows it again.
Tools
| Tool | Scope | What it does |
|---|---|---|
| choir_send_message | mcp:messages:write | Post a message into a channel. |
| choir_channel_messages | mcp:messages:read | Read the last N messages in a channel. |
| choir_list_query | mcp:lists:read | Read one list's items (list_id) or every list in a channel (channel_id). |
| choir_list_item_add | mcp:lists:write | File a new backlog item. |
| choir_list_item_update | mcp:lists:write | Patch an item (body / status / assignee / due). |
| choir_list_item_check | mcp:lists:write | Toggle done ↔ pending. |
Each tool call is attributed inside Choir to the workspace admin backing the API token — every action shows up in the audit log with the token id + acting-user id.
Missing a scope?
If Claude calls a tool your token doesn't grant, Choir returns:
Error: 401 API token missing required scope: mcp:lists:writeCopy that into your prompt so Claude knows why the retry won't help, then update the token (or mint a new one) with the missing scope.
Development
cd choir-cap-starters/choir-mcp
npm install
npm run build
# Test with stdio directly
CHOIR_BASE_URL=http://localhost:4000 \
CHOIR_API_TOKEN=chk_dev... \
node dist/server.js