scrumdo-mcp
Connect Claude Code, Codex, Cursor, OpenCode, Antigravity, GitHub Copilot, and other MCP hosts to your ScrumDo / Spryng boards over local stdio.
The default connection is a personal smcp_ token and the collaborate
tool profile: read, comment, propose, and follow events as you. A broad
organization API key is not equivalent human identity.
Full setup and host-specific guidance: ScrumDo MCP documentation.
Installation
pip install scrumdo-mcp
Requires Python 3.11+. The process speaks MCP over stdio (scrumdo-mcp).
That local path is the supported compatibility floor.
The hosted Django endpoint
POST https://app.spryng.io/api/scrumdo/organizations/<org>/mcp/rpc/ is a
transitional bearer beta. It is not OAuth and is not official
Streamable HTTP general availability. Prefer stdio until remote GA.
Get a personal token
- Sign in at https://app.spryng.io.
- Open your organization → Settings → MCP Tokens.
- Create a named personal connection and copy the secret once.
Personal tokens start with smcp_. Do not use Settings → API Tokens
(OrgAPIKey) for human AI-client collaboration.
Your org and project slugs are the path segments in
app.spryng.io/my-company/engineering.
Local stdio (supported)
Replace the placeholder. Never commit a real token.
Cursor — ~/.cursor/mcp.json
{
"mcpServers": {
"scrumdo": {
"command": "scrumdo-mcp",
"env": {
"SCRUMDO_TOKEN": "smcp_YOUR_PERSONAL_TOKEN",
"SCRUMDO_ORG": "your-org-slug",
"SCRUMDO_PROJECT": "your-default-project-slug",
"SCRUMDO_BASE_URL": "https://app.spryng.io",
"SCRUMDO_MCP_PROFILE": "collaborate",
"SCRUMDO_CLIENT_NAME": "cursor"
}
}
}
}
Claude Code — ~/.claude.json
Same mcpServers shape as Cursor. Prefer the CLI so you do not edit
~/.claude/claude.json by mistake:
claude mcp add scrumdo \
-e SCRUMDO_TOKEN=smcp_YOUR_PERSONAL_TOKEN \
-e SCRUMDO_ORG=your-org-slug \
-e SCRUMDO_PROJECT=your-default-project-slug \
-e SCRUMDO_BASE_URL=https://app.spryng.io \
-e SCRUMDO_MCP_PROFILE=collaborate \
-e SCRUMDO_CLIENT_NAME=claude-code \
-- scrumdo-mcp
Codex — ~/.codex/config.toml
[mcp_servers.scrumdo]
command = "scrumdo-mcp"
[mcp_servers.scrumdo.env]
SCRUMDO_TOKEN = "smcp_YOUR_PERSONAL_TOKEN"
SCRUMDO_ORG = "your-org-slug"
SCRUMDO_PROJECT = "your-default-project-slug"
SCRUMDO_BASE_URL = "https://app.spryng.io"
SCRUMDO_MCP_PROFILE = "collaborate"
SCRUMDO_CLIENT_NAME = "codex"
Restart Codex after changing the token so the stdio process picks up the new env.
OpenCode — opencode.json
OpenCode uses a top-level mcp object (not mcpServers):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"scrumdo": {
"type": "local",
"command": ["scrumdo-mcp"],
"enabled": true,
"environment": {
"SCRUMDO_TOKEN": "smcp_YOUR_PERSONAL_TOKEN",
"SCRUMDO_ORG": "your-org-slug",
"SCRUMDO_PROJECT": "your-default-project-slug",
"SCRUMDO_BASE_URL": "https://app.spryng.io",
"SCRUMDO_MCP_PROFILE": "collaborate",
"SCRUMDO_CLIENT_NAME": "opencode"
}
}
}
}
Antigravity
Use the same mcpServers shape as Cursor and set
SCRUMDO_CLIENT_NAME=antigravity. The connector still enforces the personal
smcp_ credential and collaborate profile server-side.
GitHub Copilot Chat — .vscode/mcp.json
Use Copilot Chat in Agent mode with a local stdio server:
{
"servers": {
"scrumdo": {
"type": "stdio",
"command": "scrumdo-mcp",
"env": {
"SCRUMDO_TOKEN": "smcp_YOUR_PERSONAL_TOKEN",
"SCRUMDO_ORG": "your-org-slug",
"SCRUMDO_PROJECT": "your-default-project-slug",
"SCRUMDO_BASE_URL": "https://app.spryng.io",
"SCRUMDO_MCP_PROFILE": "collaborate",
"SCRUMDO_CLIENT_NAME": "github-copilot-vscode"
}
}
}
}
GitHub Copilot CLI — ~/.copilot/mcp-config.json
{
"mcpServers": {
"scrumdo": {
"type": "stdio",
"command": "scrumdo-mcp",
"args": [],
"env": {
"SCRUMDO_TOKEN": "smcp_YOUR_PERSONAL_TOKEN",
"SCRUMDO_ORG": "your-org-slug",
"SCRUMDO_PROJECT": "your-default-project-slug",
"SCRUMDO_BASE_URL": "https://app.spryng.io",
"SCRUMDO_MCP_PROFILE": "collaborate",
"SCRUMDO_CLIENT_NAME": "github-copilot-cli"
}
}
}
}
GitHub Copilot cloud agent is not this personal-machine flow. Do not put a
person's smcp_ token into a shared repository or organization Agent secret.
Hosted remote (beta, not GA)
You can point a remote-capable host at:
https://app.spryng.io/api/scrumdo/organizations/<org>/mcp/rpc/
with Authorization: Bearer smcp_….
This is the current Workbench bearer JSON-RPC POST. It is not OAuth 2.1, Protected Resource Metadata, or full Streamable HTTP GA. Treat it as beta. Local stdio remains the compatibility floor.
Microsoft 365 Copilot through Copilot Studio is not supported by this beta endpoint. It requires the planned standards-conformant Streamable HTTP endpoint and delegated per-user OAuth; a shared API key is not equivalent human identity.
Tool profiles
| Profile | Env | What the model sees |
|---|---|---|
| collaborate (default) | SCRUMDO_MCP_PROFILE=collaborate or unset |
Identity/capability discovery; card search/read and handoff brief; comments and blackboard notes; spec read and publish-as-proposal; proposal read/revise/request-changes; decision inbox and challenge status; run read/status; events.wait / events.ack |
| compat | SCRUMDO_MCP_PROFILE=compat |
All registered tools, including card mutation, deletes, webhooks, inbox wait_for_notifications, direct spec writes, and run/loop writes. Aliases: full, legacy, all. |
Call get_mcp_capabilities() for the exact tool_count and names on your
process. This package version registers 56 tools on collaborate and
135 on compat (the previous 133 plus events.wait / events.ack).
Compat restores the large surface only when you opt in.
Deprecated / inbox-coupled: wait_for_notifications stays in compat
only. New clients should use events.wait / events.ack (connection cursor,
independent of the web inbox).
Identity
- Personal
smcp_token →credential_kind=personal_mcp, human collaboration. - Broad OrgAPIKey →
org_api_key. The server refuses to start unless you setSCRUMDO_ALLOW_ORG_API_KEY=1. That flag is an explicit, documented compatibility mode. It does not make the key equivalent to a person. SCRUMDO_AGENT_RUN_IDdescribes a run-scoped session, not human identity.
Events
events.wait(after?, timeout_s, limit) and events.ack(cursor) follow the
frozen connection-cursor contract. Envelopes are schema_version 1 with a
safe_summary only. If the cursor is behind the 30-day retention floor the
adapter returns cursor_expired plus a handoff instruction.
Security
- Create and revoke tokens at Settings → MCP Tokens, not API Tokens.
- The secret is shown once. Do not put a real token in chat, git, tests, or docs.
- Default collaborate omits deletes, webhook admin, org config, secrets, deployment, and direct accepted-spec writes.
- Remote API origins must use HTTPS. Plain HTTP is accepted only for localhost and loopback addresses used during local development.
- Compat-profile local attachment uploads are disabled until
SCRUMDO_ATTACHMENT_ROOTSexplicitly allows one or more directories. Resolved paths outside those roots, including symlink escapes, are rejected. - Concurrent writes that this package translates carry
Idempotency-Key/expected_version(andIf-Match) when callers supply them. Closed error codes includenot_found_or_denied,wrong_organization,connection_revoked,grant_required,human_step_up_required,stale_resource,duplicate_command,rate_limited,cursor_expired,unsupported_client_capability. - Revoke a connection if a machine is lost. The next operation fails.
Environment variables
| Variable | Default | Description |
|---|---|---|
SCRUMDO_TOKEN |
— | Required. Personal smcp_ token from Settings → MCP Tokens |
SCRUMDO_ORG |
— | Organization slug |
SCRUMDO_PROJECT |
— | Default project slug |
SCRUMDO_BASE_URL |
https://app.spryng.io |
API base URL |
SCRUMDO_MCP_PROFILE |
collaborate |
collaborate or compat |
SCRUMDO_ALLOW_ORG_API_KEY |
unset | Deprecated opt-in to start with an OrgAPIKey |
SCRUMDO_AGENT_RUN_ID |
— | Optional run attribution header |
SCRUMDO_CLIENT_NAME |
mcp |
Host name (codex, claude-code, cursor, opencode, antigravity, github-copilot-vscode, or github-copilot-cli) |
SCRUMDO_ATTACHMENT_ROOTS |
unset | Compat-only local attachment allowlist; use the platform path separator for multiple directories |
SPRYNG_LOOP_ID |
— | Optional loop attribution |
Legacy SPRYNG_* names are still accepted as aliases.
What you can do (collaborate)
"What cards need my attention?"
"Read ENG-42 and the handoff brief"
"Comment on ENG-42 that the proposal is up"
"Publish this spec as a proposal on ENG-42"
"Wait for the next board event for this connection"
Direct column moves, webhook admin, and accepted-spec overwrites are not on the default profile.
Live conformance (opt-in)
The package includes a stdio-protocol harness (python -m spryng_mcp.conformance).
The default hermetic mode launches two real scrumdo-mcp processes against an
in-process HTTP fixture. It does not talk to Django.
The two-user live run is opt-in and fail-closed. It never reads tokens from
source or fixtures. Export personal smcp_ values only in the process
environment (never commit them):
| Variable | Required for live | Purpose |
|---|---|---|
SCRUMDO_LIVE_CONFORMANCE |
yes (1) |
Opt-in gate |
SCRUMDO_ALICE_TOKEN |
yes | Personal connection A |
SCRUMDO_BOB_TOKEN |
yes | Personal connection B |
SCRUMDO_READONLY_TOKEN |
yes | Read-only / guest control |
SCRUMDO_UNRELATED_TOKEN |
yes | Unrelated-room control |
SCRUMDO_REVOKED_TOKEN |
yes | Already-revoked personal token |
SCRUMDO_TARGET_RUN_ID |
yes | AgentRun id under test (do not reuse SCRUMDO_AGENT_RUN_ID) |
SCRUMDO_BASE_URL |
no | Default http://127.0.0.1:8018 |
SCRUMDO_ORG |
no | Default test-account-a |
SCRUMDO_PROJECT |
no | Default room project slug |
SCRUMDO_CARD_REF |
no | Default AG-2 |
SCRUMDO_FOREIGN_ORG |
no | Other-org slug for closed denial |
SCRUMDO_ALICE_CLIENT / SCRUMDO_BOB_CLIENT |
no | Distinct client names |
SCRUMDO_COPILOT_TOKEN |
no | Defaults to Alice; use with Copilot client name |
SCRUMDO_ORG_API_KEY |
no | Negative OrgAPIKey case |
SCRUMDO_WEB_SESSIONID |
no | Django session cookie for s8 web-inbox independence |
SCRUMDO_WEB_CSRFTOKEN |
no | CSRF token paired with the web session |
SCRUMDO_WEB_SESSION_COOKIE_NAME |
no | Session cookie name; defaults to sessionid (Spryng uses sprsession) |
python -m spryng_mcp.conformance hermetic
SCRUMDO_LIVE_CONFORMANCE=1 python -m spryng_mcp.conformance live
If a required live name is missing, the command exits 2 with a missing-fixture message that lists names only.
Development (maintainers)
pip install -e ".[dev]"
pytest tests/ -v
python -m spryng_mcp.conformance hermetic
Source access is restricted to maintainers. Package users should install the public wheel from PyPI and use the public documentation linked above.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file scrumdo_mcp-0.5.3-py3-none-any.whl.
File metadata
- Download URL: scrumdo_mcp-0.5.3-py3-none-any.whl
- Upload date:
- Size: 105.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ce2ccdd9c28f67a661f91a9119820b622508c8c81d3b2080815a1325fb28130
|
|
| MD5 |
c467fbc4dcadaf906263c7bf340b3d94
|
|
| BLAKE2b-256 |
60eeceb0b8493e3301eb60fa4c9611dbac78096dece08b8e9ed01aefd607ac54
|
Provenance
The following attestation bundles were made for scrumdo_mcp-0.5.3-py3-none-any.whl:
Publisher:
publish.yml on ScrumDoLLC/scrumdo-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
scrumdo_mcp-0.5.3-py3-none-any.whl -
Subject digest:
4ce2ccdd9c28f67a661f91a9119820b622508c8c81d3b2080815a1325fb28130 - Sigstore transparency entry: 2615976701
- Sigstore integration time:
-
Permalink:
ScrumDoLLC/scrumdo-mcp@f3aa28240c45478ef8e6ebf1c3305e7da39bdc59 -
Branch / Tag:
refs/tags/v0.5.3 - Owner: https://github.com/ScrumDoLLC
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f3aa28240c45478ef8e6ebf1c3305e7da39bdc59 -
Trigger Event:
workflow_dispatch
-
Statement type: