本仓库演示了如何构建一个具有HTTP传输和JWT认证的MCP(模型上下文协议)服务器,并通过迭代步骤逐步实现。
该仓库是与深入的分步博客文章“MCP授权”配套的。请参阅以下内容:
下表显示了主要身份提供商对MCP授权规范所需OAuth RFC的支持情况。
| 身份提供商 | PKCE | RFC 8414 | RFC 7591 | RFC 8707 |
|---|---|---|---|---|
| Okta | 是 | 是 | 是 | 否 |
| Auth0 | 是 | 是 | 基本支持 | 否 |
| Keycloak | 是 | 是 | 是 | 否 |
| Ping Federate | 是 | 是 | 是 | 是 |
| ForgeRock | 是 | 是 | 是 | 基本支持 |
| Google OAuth | 是 | 否 | 否 | 否 |
| Microsoft Entra | 是 | 是 | 否 | 否 |
该项目展示了如何构建一个安全的MCP服务器,包括:
http-transport-steps/src/mcp_http/step1.py/health)http-transport-steps/src/mcp_http/step2.py/mcp端点用于MCP协议通信http-transport-steps/src/mcp_http/step3.pyecho,get_time)greeting,help)http-transport-steps/src/mcp_http/step4.pyhttp-transport-steps/src/mcp_http/step5.py/.well-known/jwks.json)generate_token.py)http-transport-steps/src/mcp_http/step6.py/mcp端点的认证强制执行http-transport-steps/src/mcp_http/step7.py/.well-known/oauth-protected-resource端点/.well-known/oauth-authorization-server端点http-transport-steps/src/mcp_http/step8.pycheck_permission方法进行范围验证JWT令牌包括:
mcp:read,mcp:tools,mcp:prompts)admin,user,guest)每个步骤都包含一个对应的测试脚本(test_stepX.sh),验证:
uv:https://docs.astral.sh/uv/getting-started/installation/http-transport-steps目录uv运行步骤# 使用`uv run`运行任意步骤
uv run step1
uv run step2
uv run step3
# ...等等
步骤10支持基于环境的配置,用于Keycloak和MCP服务器URL。你可以使用--env标志指定一个env文件(不是.env),或者默认使用keycloak_direct.env。
提供了两个示例env文件:
keycloak_direct.env(用于直接访问位于localhost:8080的Keycloak)keycloak_proxy.env(用于访问位于localhost:9090的代理)示例用法:
# 使用特定的env文件(例如,代理)运行步骤10
uv run step10 --env keycloak_proxy.env
如果env文件或环境变量丢失,服务器将回退到合理的默认值(如localhost:8080等)。
uv run step11
要使用mcp-inspector:
关于mcp范围的问题: https://github.com/modelcontextprotocol/inspector/issues/587
对于需要JWT认证的步骤5-8,可以使用generate_token.py脚本生成令牌:
uv run python generate_token.py --username alice --scopes mcp:read,mcp:tools
uv run python generate_token.py --username bob --scopes mcp:read,mcp:prompts
uv run python generate_token.py --username admin --scopes mcp:read,mcp:tools,mcp:prompts
uv run python generate_token.py --username guest --scopes ""
快速获取用于测试步骤9/Keycloak的令牌:
curl -X POST "http://localhost:8080/realms/mcp-realm/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=mcp-test-client" \
-d "username=mcp-admin" \
-d "password=admin123" \
-d "scope=openid profile email mcp:read mcp:tools mcp:prompts" | jq -r '.access_token'
该脚本将输出一个JWT令牌,可以在Authorization: Bearer <token>头部用于认证请求。
项目使用uv进行依赖管理,并使用pyproject.toml配置。