Is one-auth-configuration-per-server a deliberate constraint?

未關閉
#3,488 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

評估

難度
5/5
預估耗時
一週以上
新手友好度
35/100
Issue 類型
功能
描述清晰度
基本清楚
活躍度
活躍
技術堆疊
python

研究方向

從 server/mcpserver/server.py:1207 中的 AuthSettings 和 authorization_servers 發布開始,然後追蹤 MCPServer 上的單一 token_verifier。查看所參照行中的 client/auth/oauth2.py,以了解目前的首次進入行為及其 TODO;完成條件應是形成一項有文件記錄的決定,或定義出支援兩種驗證設定的設計。

由索引模型根據 Issue 內容生成。

描述

Initial Checks
Release line

2.x (current stable)

Description

Hi! Is one-auth-configuration-per-server in the Python SDK a deliberate constraint, or just something nobody has needed yet?

Use case

I have an MCP server for text search that enforces per-user article permissions from our main system. One deployment needs to serve two kinds of caller:

  1. Service-to-service (internal). Our frontend authenticates the user, the backend receives only the user's token and passes it to the MCP server — this avoids redirect-based logins between internal services. The MCP server then exchanges that token with our SSO for a token valid for a third system, so it needs a confidential client with a client_secret.
  2. Interactive (external). I'd like the same server to also expose a "public" entry point, so a user can add it to Claude Desktop / Codex and go through normal OAuth with a public client (PKCE, no secret).

Today AuthSettings allows exactly one configuration

  • issuer_url is a single AnyHttpUrl, and the server always publishes it as a one-element list — server/mcpserver/server.py:1207:
authorization_servers=[self.settings.auth.issuer_url]
  • the client only ever reads the first entry — client/auth/oauth2.py:349 and :630, with a # todo: try all authorization_servers to find the OASM
  • and there is one token_verifier per MCPServer.

The workaround, and why it doesn't hold up

The obvious approach is two MCPServer instances sharing the tool functions (see Example Code below). Stacking the decorators is fine (tool() returns the function unchanged). Mounting is where it falls apart. Both apps can't be mounted at / — the first one matches everything and the second is never reached. And once the second is mounted under a prefix, its RFC 9728 metadata route (generated from resource_server_url) is served from under that prefix:

200  /public/.well-known/oauth-protected-resource/public/mcp   <- where it actually is
404  /.well-known/oauth-protected-resource/public/mcp          <- where the client looks

So the second server is undiscoverable unless I re-register the well-known route at the app root by hand. That's the part that feels like it should be SDK support rather than a workaround.

Question

Is one auth config per server intentional — and if so, what's the recommended way to cover both cases? Or would you be open to multiple auth configurations / multiple token verifiers per server? Happy to put up a PR if there's interest.

Example Code
mcp = MCPServer(token_verifier=JwtTokenVerifier(),
                auth=AuthSettings(resource_server_url="https://host/mcp", ...))
mcp_public = MCPServer(token_verifier=PublicJwtTokenVerifier(),
                       auth=AuthSettings(resource_server_url="https://host/public/mcp", ...))

@mcp.tool()
@mcp_public.tool()
async def search(...): ...
Python & MCP Python SDK
Python 3.14.2
MCP Python SDK 2.0.0
主要語言
Python
星號
24.3k
分支
4k
平均合併
1 天 1 小時
30 天內合併 PR
31

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

modelcontextprotocol/python-sdk 的其他 Issue

查看 modelcontextprotocol/python-sdk 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。