Skip to content

Add authorization examples in documentation #1315

Open

Description

@Kehrlann

Our documentation lacks guidance and examples around authorization.

We should explain at a high-level, with code examples:

  • how to make authentication obtained outside the SDK available to the server handlers, repositories, and filters
  • how to use the client-side hooks to plug the client into an existing OAuth2 framework

Initially reported in #1313

Activity

  1. media-ctrl commented on Nov 9, 2026

    @media-ctrl

    The server half of this is now partly documented in docs/server.md under "Filtering the Tool Listing per Request" (transport contextExtractor, McpTransportContext.create(Map), addToolFilter), so the remaining work is narrower than the issue text. Three pieces, in the order a reader would hit them.

    1. The docs stop at advertisement. That section warns that a filter controls listing only and that a hidden tool called by name still executes, but it never shows how to reach the same extracted context inside the call handler, which is where enforcement has to happen. The context is already there: McpSyncServerExchange.transportContext() (mcp-core/src/main/java/io/modelcontextprotocol/server/McpSyncServerExchange.java:61). A short example reading exchange.transportContext().get("perms") inside callHandler would close the loop that the warning opens, and it is the exact thing a reader cannot infer from the filter examples.

    2. Thread the principal through the repository argument rather than a thread local. On the modern server the repositories already receive it: list(McpRequestContext ctx, String cursor) and find(McpRequestContext ctx, String name) in docs/server-modern.md. This follows from the doc's own note that sync filters run on a shared scheduler thread where SecurityContextHolder is not visible: a repository that reads request state from a thread local will look correct in tests and be wrong under concurrent load.

    3. The client side, which is the genuinely undocumented half. The only OAuth mention in docs/client.md is ElicitationCompleteNotification for out-of-band URL flows. Nothing says how to wire a transport into an existing OAuth2 framework: where a request customizer or header supplier is applied, how a 401 from the server is meant to reach the client's token refresh, and what the transport does with the refreshed token on retry. For anyone on Spring Security that is the blocking gap, not the server-side explanation.

    One caveat worth placing next to the first examples: with STDIO the context is McpTransportContext.EMPTY, so an authorization path has to degrade to an explicit no-op instead of failing closed, which is the opposite of what most readers will write first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions