Claude Code MCP insufficient_scope: re-authenticate to grant write
Sume's hosted MCP starts read-only. If Claude Code pins oauth.scopes, add mcp:write, run /mcp and re-authenticate, or the new token still lacks write.

Add mcp:write to the server's oauth.scopes in your Claude Code config, run /mcp, and choose Re-authenticate on the Sume server. Then turn Write on at Sume's consent page. Skip either step and the new token is still read-only.
Why it happens
Sume's hosted MCP requires mcp:read and treats mcp:write as opt-in. A read-only session sees only read tools, and a call that changes data returns insufficient_scope. Claude Code's docs describe the matching client side: if a server returns a 403 insufficient_scope and the scope is not in your pinned oauth.scopes, you add it and authenticate again, because Claude Code requests the pinned scopes rather than the scope the server named.
Claude Code stores local-scope servers in its user configuration file by default, and project scope writes to a .mcp.json file that your team can commit. Pin scopes in the place that matches how widely you want the write grant shared.
Pin both scopes
Connect first with the command from the docs, then pin scopes in config if you want to control them:
A quick way to confirm the grant worked: after re-authenticating, ask the agent to list Sume's tools. A write session sees the tools that change data and the paid tools, while a read-only session sees only read tools. If the list did not grow, the token you hold is the old one, so check that the pinned scopes string includes both values separated by a space.
claude mcp add --transport http sume https://mcp.sume.com/mcp
{
"mcpServers": {
"sume": {
"type": "http",
"url": "https://mcp.sume.com/mcp",
"oauth": { "scopes": "mcp:read mcp:write" }
}
}
}Order of operations
| Step | Where | What to check |
|---|---|---|
| 1 | Config | oauth.scopes lists mcp:write; oauth.scopes wins over scopes the server discovers |
| 2 | /mcp in Claude Code | Pick Re-authenticate on the sume server |
| 3 | Sume consent page | Read is locked on; flip the Write toggle, then continue |
| 4 | First paid call | Include an idempotency_key; dry_run previews cost first |
What re-authentication will not fix
Sume does not issue refresh tokens: access tokens last one hour and a refresh_token grant is ignored. Claude Code says it refreshes a token after a 401 and retries once, but with Sume that leads to another sign-in, not a silent refresh. For unattended work, give the agent an API key header instead of OAuth, and set max_spend_usd on each paid call so one runaway loop cannot drain the wallet. Sume's allow_write and allow_paid legacy flags cannot bypass a missing mcp:write scope, so do not bother adding them.
Sources
More in Developers
- Claude Code PreToolUse hook: block paid Sume calls without a spend cap
A PreToolUse hook that denies Sume generate and TTS tools when max_spend_usd or idempotency_key is missing. Python hook with the settings.json matcher, tested.
- Claude Code .mcp.json project scope: keep your Sume API key out of git
Project scope writes .mcp.json for your team via version control. Never put a Sume key in its header; use OAuth, or a local-scope server, for the credential.
- Claude Code tool.check ceiling and agentId: gate paid Sume tool calls
Claude Code 2.1.290 adds ceiling and agentId to tool.check, so a hook can tell subagents apart. Pair it with Sume's dry_run and max_spend_usd on paid tools.
- CloudEvents envelope for a Sume run webhook: field mapping
Map Sume's agent.run.terminal webhook to CloudEvents 1.0: request_id to id, event to type, created_at to time, with a runnable Python wrapper.
Written by Sume