认证MCP服务器参考实现

一个基于Go语言的认证MCP服务器参考实现,用于AI代理学习构建MCP服务器的模式,支持OAuth 2.1授权码流、JWT验证、范围访问控制等核心功能。

  • by emergingrobotics
  • Go
  • 本地部署
  • 更新于
在 GitHub 查看 emergingrobotics/mcp-general-template

使用说明

经过身份验证的MCP服务器示例

Go中经过身份验证的MCP(模型上下文协议)服务器的工作参考实现。使用 MCP Go SDK 随着 Logto 作为OAuth 2.1/OIDC授权服务器。

预期用途

这个存储库是人工智能代理的参考实现,而不是人类的模板。

数学功能故意显得微不足道。重点不是算术——它是一个完整的、经过测试的、可工作的经过身份验证的MCP服务器示例,实现了:

  • 使用PKCE的OAuth 2.1授权代码流
  • 使用JWKS进行JWT验证
  • 基于工具范围的访问控制
  • 受保护资源元数据(RFC 9728)
  • 可流式HTTP传输(MCP 2025-06-18规范)
  • 用于本地开发和测试的模拟OAuth服务器

当用户要求AI代理(Claude Code、Cursor、Copilot等)构建新的MCP服务器时,它应该将此存储库作为资源读取。代理提取它需要的模式——身份验证中间件、作用域强制、MCP SDK连接、开发服务器结构、测试助手——并生成一个根据用户实际需求量身定制的全新项目。

这不是:

  • GitHub模板存储库(不要单击“使用此模板”)
  • 要导入的库
  • 扩展框架
  • 你分叉和修改的东西

这是:

  • AI代理阅读和学习的工作示例
  • 如何在Go MCP服务器中连接OAuth 2.1+PKCE+JWT+作用域的参考
  • 您可以运行一个可测试的实现来理解身份验证流
  • AI代理有选择地复制到新项目中的模式来源

AI代理应该从中得到什么

模式 在哪里可以找到它
JWT验证中间件 internal/auth/middleware.go
JWKS获取和缓存 internal/auth/jwks.go
受保护资源元数据(RFC 9728) internal/auth/metadata.go
工具执行前的范围执行 internal/eval/scopes.go, internal/tools/evaluate.go
MCP工具注册和处理程序接线 internal/tools/evaluate.go, internal/server/server.go
流式HTTP传输设置 internal/server/server.go
用于开发/测试的模拟OAuth/OIDC服务器 cmd/devserver/
测试JWT生成助手 internal/testauth/testauth.go
通过环境变量进行配置 internal/config/config.go
优雅的关机 cmd/server/main.go

建筑

服务器公开了一个MCP工具(evaluate)通过流式HTTP传输 /mcp身份验证使用针对JWKS端点验证的JWT承载令牌。每个数学运算(加、减、乘、除)都需要一个相应的范围(use:add, use:subtract, use:multiply, use:divide),评估前检查。

看 docs/DESIGN.md 完整的架构和设计。

包布局

cmd/server/          Production entry point
cmd/devserver/       Dev server with built-in mock OAuth (no Logto needed)
internal/
  auth/              JWT middleware, JWKS fetching, metadata endpoint, context helpers
  config/            Environment variable loading and validation
  eval/              Recursive descent parser, AST, evaluator, scope collection
  server/            HTTP mux wiring
  testauth/          Shared test JWT infrastructure
  tools/             MCP tool registration and request handling
  userpool/          YAML-based local user pool

端点

路径 身份验证 描述
GET /healthz 否 健康检查
GET /.well-known/oauth-protected-resource 否 受保护资源元数据(RFC 9728)
/mcp 是(承载JWT) MCP可流式HTTP传输

构建

make build        # Build binary to bin/mathcalc-server
make test         # Run all tests
make lint         # Run golangci-lint (if installed)
make clean        # Remove build artifacts

需要Go 1.25+。

配置

所有配置都是通过环境变量进行的。复制 .envrc.example 到 .envrc 并编辑:

变量 必填 默认 描述
MCP_SERVER_RESOURCE_URL 是 - 服务器的规范URL(OAuth 2.1资源指示符)
LOGTO_ISSUER_URL 是 - 登录OIDC发卡机构URL
LOGTO_JWKS_URL 没有 <LOGTO_ISSUER_URL>/jwks JWKS端点
MCP_SERVER_PORT 没有 8080 HTTP侦听端口
MCP_AUTH_SCOPE_SOURCE 没有 jwt jwt (生产)或 local (发展)
MCP_USERS_FILE 没有 users.yaml 本地用户池文件的路径(当作用域源为 local)

跑步

开发服务器(建议用于本地开发)

开发服务器将模拟OAuth/OIDC服务器与MCP服务器捆绑在一起。无需Logto或外部服务:

make run-devserver

默认情况下,URL使用系统主机名,因此OAuth浏览器流可以在网络上的任何机器上工作。启动横幅会打印确切的URL和 claude mcp add 复制命令。

四个测试用户的范围不断扩大:

用户 范围
爱丽丝 use:add
鲍勃 use:add, use:subtract
卡罗尔 use:add, use:subtract, use:divide
戴夫 use:add, use:subtract, use:multiply, use:divide

要覆盖主机名或端口,请设置环境变量(或复制 .envrc.example 到 .envrc 和编辑):

变量 默认值 描述
DEV_HOST 系统主机名 所有URL中使用的主机名
DEV_MCP_PORT 8081 MCP服务器侦听端口
DEV_OAUTH_PORT 9001 模拟OAuth服务器侦听端口

使用Claude代码进行测试

开发服务器和Claude Code可以在不同的机器上运行。所有URL中的主机名必须是服务器和客户端浏览器都可以访问的可解析FQDN。使用 localhost 只有当所有东西都在同一台机器上运行时才有效。

在服务器计算机上

  1. 使用以下命令启动开发服务器 DEV_HOST 设置为计算机的FQDN:

    DEV_HOST=myserver.example.com make run-devserver
    

    创业横幅上印有确切的 claude mcp add 命令使用。

  2. 验证服务器是否可访问:

    curl http://myserver.example.com:8081/healthz
    

在客户端机器上(运行Claude Code的地方)

  1. 注册MCP服务器(一次性设置)。主机名 必须匹配 DEV_HOST 确切地:

    claude mcp add mathcalc --transport http http://myserver.example.com:8081/mcp
    
  2. 启动克劳德代码:

    claude
    

    Claude Code连接到MCP服务器,发现模拟OAuth服务器,并将浏览器打开到用户选择器页面。

  3. 在浏览器中选择一个用户。选择Alice、Bob、Carol或Dave,然后单击 授权浏览器重定向回来,Claude Code建立MCP会话。

  4. 让Claude Code计算表达式。请尝试以下操作来验证作用域执行:

    "what is 9+2"           -> 11 (works for any user)
    "what is 9/3"           -> access_denied for Alice (lacks use:divide)
    "what is 3-1"           -> access_denied for Alice (lacks use:subtract)
    "what is (2+1)*3"       -> 9 (works for Dave, denied for Alice/Bob/Carol)
    "what is ((2+1)*3)/3+1" -> 4 (works for Dave, requires all four scopes)
    
  5. 要测试其他用户,请断开连接并重新进行身份验证:

    /mcp disconnect
    /mcp
    

    在浏览器中选择其他用户,查看范围限制如何更改。

删除注册

claude mcp remove mathcalc

故障排除

  • “受保护的资源不匹配”:中的主机名 claude mcp add 不匹配 DEV_HOST。它们必须相同(例如,两者 myserver.example.com,不 myserver 对比 myserver.example.com).
  • “无法连接”:无法从客户端访问服务器。检查一下 DEV_HOST 解析,端口8081没有防火墙。
  • 浏览器无法打开:OAuth授权URL使用 DEV_HOST。如果浏览器机器无法解析该主机名,则身份验证流将失败。

与Logto(生产)

启动Logto和PostgreSQL:

podman compose -f deployments/podman/logto-compose.yaml up -d

配置Logto资源和角色:

./scripts/setup-logto.sh

然后使用以下命令运行服务器 MCP_AUTH_SCOPE_SOURCE=jwt.

容器

make container-build
podman run -p 8080:8080 --env-file .envrc mathcalc-server

测试

make test         # Unit tests
make test-e2e     # End-to-end test (in-process, no external services)

测试涵盖了解析器(13例)、评估器(9例)、作用域集合(7例)、用户池(4例)、配置(7例”)、身份验证中间件(9例“)、元数据(1例“)和工具处理程序(10例“)。看 docs/TEST-PLAN.md 对于完整的测试策略。

发展

make help          # List all available targets
make run-devserver # Build and start dev server with mock OAuth

该项目遵循标准的Go惯例 internal/ 包装布局。所有依赖关系都通过以下方式管理 go.mod.

许可证

根据Apache许可证2.0版授权。看 许可证 全文。