OAuth保护的MCP服务器

一个使用Go语言实现的、通过OAuth 2.1保护的模型上下文协议(MCP)服务器示例,展示了如何集成Keycloak授权服务器和MCP Go SDK。

  • by wadahiro
  • Go
  • 本地部署
  • 3 星标
  • 更新于
在 GitHub 查看 wadahiro/go-mcp-server-example

使用说明

OAuth保护的MCP服务器示例(Go语言)

使用Go语言编写的OAuth 2.1保护的模型上下文协议(MCP)服务器的示例实现。

这个项目展示了如何使用OAuth保护来实现一个MCP服务器 MCP Go SDK 并且 Keycloak(可直接作为专有名词使用,无需翻译,若需解释性翻译则为“密钥圈/密钥管理平台”,但通常保留原名) 作为授权服务器。

特点/特性

  • OAuth 2.0 受保护资源实施(方案/措施) RFC 9728(OAuth 2.0 受保护资源元数据)
  • JWT访问令牌验证使用JWKS进行本地验证
  • 可流式传输的HTTP传输可远程访问的MCP服务器
  • 简单回声工具用于演示的基本MCP工具
  • Keycloak 集成使用Keycloak 26.4作为授权服务器,支持动态客户端注册(DCR)

建筑学

                    OAuth 2.1 Flow (DCR, Authorization Code)
    ┌───────────────────────────────────────────────────────────┐
    │                                                           │
    │                                                           ▼
┌───┴─────────┐   HTTP + Bearer Token   ┌─────────────┐   ┌───────────────┐
│ MCP Client  │────────────────────────►│ MCP Server  │   │  Keycloak     │
│ (Inspector) │                         │ (This repo) │   │ (AuthZ Server)│
└─────────────┘                         └─────────────┘   └───────────────┘
                                              │                   │
                                              │◄──────────────────┘
                                              │   JWKS (RS256 Public Key)
                                              │
                                              ▼
                                    JWT Access Token Validation:
                                    • Signature verification
                                    • iss, exp, aud claims
                                    • scope claim

先决条件

  • Go 1.25或更高版本
  • Docker 和 Docker Compose(用于运行 Keycloak)

快速入门

1. 启动Keycloak

cd authz-server
docker-compose up -d

Keycloak 将提供在 http://localhost (管理员/管理员)。

2. 配置 Keycloak

  1. 创建一个名为(新名称)的新领域 demo
  2. 创建一个名为(此处应填写具体名称)的客户端范围 mcp:tools:
    • 在令牌作用域中包含: On
    • 添加受众映射器:
      • 姓名: audience-config
      • 包含的自定义受众: http://localhost:8000
  3. 配置客户端策略:
    • 删除默认的“受信任主机”策略
    • 更新“允许的客户端范围”策略以包含 mcp:tools
  4. 创建一个测试用户

3. 运行MCP服务器

go run . \
  -authz-server-url="http://localhost/realms/demo" \
  -jwks-url="http://localhost/realms/demo/protocol/openid-connect/certs" \
  -resource-url="http://localhost:8000"

4. 使用MCP Inspector进行测试

跑 MCP 检查器 并连接到 http://localhost:8000。

MCP检查器将:

  1. 从(某处)获取受保护资源的元数据 http://localhost:8000/.well-known/oauth-protected-resource
  2. 发现授权服务器元数据
  3. 使用动态客户端注册(DCR)注册为客户端
  4. 启动OAuth授权码流程
  5. 将您重定向到Keycloak登录页面
  6. 获取访问令牌并连接到MCP服务器

项目结构

.
├── authz-server/              # Keycloak setup
│   ├── docker-compose.yml
│   └── nginx.conf
├── main.go                    # MCP server implementation
├── oauth_middleware.go        # OAuth middleware & JWT Access Token validation
└── README.md

实施亮点

OAuth 2.0 受保护资源元数据

服务器在(某个位置)暴露元数据 /.well-known/oauth-protected-resource:

{
  "resource": "http://localhost:8000",
  "authorization_servers": ["http://localhost/realms/demo"],
  "scopes_supported": ["mcp:tools"]
}

JWT访问令牌验证

中间件进行验证:

  1. 签名使用来自授权服务器的JWKS(RS256)
  2. 标准索赔:
    • iss (发行者):必须与授权服务器URL匹配
    • exp (过期时间):令牌不得已过期
    • aud (观众):必须包含此服务器的URL
  3. 自定义声明:
    • scope必须包含 mcp:tools

MCP 工具

提供了一个简单的 echo 一个返回输入消息的工具。

配置选项

标志 描述 默认值
项目 描述 类型
-jwks-url http://localhost/realms/demo/protocol/openid-connect/certs JWKS 端点 URL
-resource-url http://localhost:8000 此服务器的URL

|

限制与注意事项

RFC 8707 支持 Keycloak 26.4 尚不支持RFC 8707(OAuth 2.0的资源指示符) mcp:tools 作为一种权宜之计,此实现方案使用了受众映射器(Audience Mapper)在 aud 范围以设定

声明;索赔;主张。

CORS 临时解决方案 由于一个Keycloak 26.4中的已知问题

nginx 被用作反向代理,为 DCR 端点添加 CORS 头信息。

RFC 8707:OAuth 2.0 的资源指示符

Keycloak(可译为“密钥圈”或保持原名,根据上下文决定是否需要翻译)

许可证