modelcontextprotocol / modelcontextprotocol/typescript-sdk
Server SDK support for scope challenges on tool calls
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 13.4k
- Forks
- 2.2k
- Avg merge
- 3d 15h
- Merged PRs (30d)
- 4
Description
Summary
Server SDK authors currently have no ergonomic way to trigger OAuth scope challenges during tool execution. While the MCP spec (SEP-835) supports returning 403 responses with WWW-Authenticate headers to request additional scopes, server SDKs don't provide facilities to easily declare required scopes per tool or dynamically trigger scope challenges during tool execution.
Use Case
Consider a server like GitHub's MCP server that wraps an API with granular permissions:
- A user connects with a valid OAuth token but minimal/no scopes
- They call a tool that may or may not need additional scopes depending on the specific resource (e.g., accessing a public vs private repo)
- The server makes a request to its backend service, which responds indicating more scopes are needed
- The server wants to pass this back as a scope challenge rather than a failed tool call
Currently, server authors must implement this entirely outside SDK land:
- Parse raw JSON-RPC
- Match tool names
- Check required scopes against active scopes
- Manually construct and return the 403 response with WWW-Authenticate header
Proposed Features
1. Declare required scopes when registering a tool (minimum viable)
server.registerTool(
'get_private_repo',
{
description: 'Get private repository details',
inputSchema: { ... },
requiredScopes: ['repo:read'] // New field
},
async (args) => { ... }
);
The SDK would automatically check scopes before tool execution and return a 403 scope challenge if the token lacks required scopes.
2. Dynamically trigger scope challenge during tool execution (ideal)
server.registerTool(
'get_repo_issue',
{
description: 'Get repository issue',
inputSchema: { ... }
},
async (args, context) => {
const response = await fetchFromBackend(args);
if (response.needsAdditionalScopes) {
// Trigger scope challenge mid-execution
throw new ScopeChallengeError(['repo:read']);
// or: context.requestScopes(['repo:read']);
}
return { content: [...] };
}
);
This would allow servers to defer scope decisions to downstream services and pass through their authorization requirements.
Additional Considerations
- Scope hierarchy: Some OAuth systems have hierarchical scopes (e.g.,
repoincludesrepo:read). SDKs may need to support scope resolution/comparison utilities. - Access to current scopes: Tool handlers need a way to inspect what scopes the current token has (perhaps via context parameter).
Related
- SEP-835 (Scope Challenge Handling): https://modelcontextprotocol.io/specification/draft/basic/authorization#scope-challenge-handling
- Conformance test for client-side handling: https://github.com/modelcontextprotocol/conformance/blob/main/src/scenarios/client/auth/scope-handling.ts#L237
- Python SDK client implementation: https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/client/auth/oauth2.py#L591-L608
Context
Discussion from Discord with @sammorrowdrums (GitHub MCP server author) about server-side SDK support for scope challenges.
https://discord.com/channels/1358869848138059966/1441013745496227870
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with SEP-835 and the linked Python SDK OAuth implementation to understand scope-challenge semantics, then locate the TypeScript SDK's tool-registration and server authorization entry points; the issue names no TypeScript files or tests. Define and test both declared tool scopes and dynamic challenges, including the 403 response and WWW-Authenticate header behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, authentication, authorization
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100