Claude Code .mcp.json oauth.scopes: mcp:read first, mcp:write later
Claude Code's .mcp.json oauth block takes a space-separated scopes string that overrides discovery. Start Sume at mcp:read and widen to mcp:write when needed.

Claude Code lets a project pin the OAuth settings for a remote MCP server. The Claude Code MCP docs describe an oauth block in .mcp.json with clientId, callbackPort, authServerMetadataUrl and scopes, read 2026-10-03. scopes is a space-separated string that takes precedence over scopes the server advertises. Sume's hosted MCP server defines two: mcp:read, which is required and read-only, and mcp:write, which is opt-in, per the Sume OAuth page.
{
"mcpServers": {
"sume": {
"type": "http",
"url": "https://mcp.sume.com/mcp",
"oauth": { "scopes": "mcp:read" }
}
}
}Why pin the scope
If the server advertises both scopes and the client requests everything, a user may consent to write access without thinking about it. Pinning mcp:read in the project file means a teammate who clones the repo starts with read tools only. A write or paid tool under mcp:read returns insufficient_scope, which is the expected result and not a bug.
| Setting | Effect | Use |
|---|---|---|
"scopes": "mcp:read" | Read-only tools | Default for shared repos |
"scopes": "mcp:read mcp:write" | Adds create and write tools | Personal or release-owner config |
No scopes | Client uses the server's discovered scopes | Check what consent screen shows |
Widening later
The Claude Code changelog for 2.1.288 says a re-authenticate prompt now appears when a server asks for more OAuth scope. That fits the pattern: stay on mcp:read, and when a task needs a create tool, widen the scope on purpose and approve the new consent. The MCP specification changelog lists incremental scope consent via WWW-Authenticate for protocol version 2025-11-25, but the Sume docs do not say whether Sume's server uses that flow, so do not assume it.
Things to check
- Server definitions live in local, project or user scope, so check which scope an entry came from when behavior differs from the project file.
.mcp.jsonsupports${VAR}and${VAR:-default}expansion, but the page warns that some credential variables read as empty in remoteurlandheaders.- Paid and write tools still need an
idempotency_keyand honormax_spend_usdwhen provided. mcp:paiddoes not exist; do not request it.
Sources
Related posts
More in Developers
- Claude Code mod: stop paid Sume calls after N in a session
Write a Claude Code mod that counts paid Sume MCP calls with a tool.call hook, denies call N+1, and fails closed. Code, matcher, and what it cannot cap.
- Claude Code mod hook skipped and a paid Sume call still ran
A Claude Code mod hook that throws or times out is skipped, so the call runs anyway. Add .catch to fail closed, and know what a mod still cannot guarantee.
- Claude Code mod: ask before a paid Sume call (and claude -p)
A Claude Code mod can hold a paid Sume MCP call with $.ui.ask and show max_spend_usd in the question. In claude -p nobody answers, so it refuses. Code inside.
- Claude Code mcp_server_errors: fail CI when Sume never loaded
In stream-json runs Claude Code reports a skipped MCP entry in mcp_server_errors. Check it with jq before a CI job spends on Sume, then verify with mcp_health.
Written by Sume