1. FastMCP 2.x 集成 GitHub 认证到底解决什么问题
FastMCP 2.x 集成 GitHub 认证,本质上是给你的 MCP 服务器加一道"门禁":只有通过 GitHub OAuth 授权的人,才能调用你暴露出来的工具、资源和提示模板。它适合谁?适合那些把 MCP 服务部署到公网、又不想自己造一套账号体系的开发者。你不需要写登录页、不需要存密码、不需要处理找回密码,GitHub 帮你把"这个人是谁"这件事办完了,你只管拿结果。
为什么 FastMCP 要单独做一个 GitHubProvider?因为 GitHub 的 OAuth 实现和标准 MCP 认证要求之间有落差。MCP 规范期望的是带动态客户端注册的 OAuth 流程,而 GitHub 并不支持动态注册,它只认你在后台手动创建的那个 OAuth App。FastMCP 的做法是引入一个 OAuth 代理层,把 GitHub 的传统 OAuth 流程"翻译"成 MCP 客户端能理解的形态。你作为服务端开发者,感知到的就是一个GitHubProvider对象,剩下的握手细节它替你处理。
这里有个容易被忽略的点:认证和模型调用是两件事。GitHub 认证管的是"谁能进你的 MCP 服务器",而你的 MCP 工具内部如果要调用大模型,那是另一条链路。很多同学把这两件事混在一起,结果认证跑通了,工具一执行就报模型端点连不上。所以这篇笔记我会分两条线走:前半段把 GitHub 认证从 OAuth App 注册到端到端验证跑通,后半段把工具内部的模型调用端点统一改到 TaoToken 的 Key/API 通道,让认证和模型调用各归各位。
我试过在本地把这两条链路拆开调,先确认 GitHub 认证能拿到用户身份,再确认模型调用能返回结果,最后合到一起。这样出问题时定位特别快——是认证没过去,还是模型端点配错了,一眼就能分清。下面按这个顺序展开,每一步都给可复制的配置。
2. TaoToken 统一 Key 通道前置准备与 GitHub OAuth 应用注册
在动手写 FastMCP 代码之前,有两件前置工作要做:一是把 TaoToken 的 Key 通道准备好,二是把 GitHub OAuth App 注册好。这两件事互不依赖,可以并行。
先说 TaoToken 这边。它的作用是给你的 MCP 工具提供一个统一的模型调用入口,你不需要在代码里散落各家厂商的 Key,也不用为每个模型单独配端点。你需要拿到两样东西:API Key 和 Base URL。API Key 在控制台的 API Keys 页面创建,Base URL 固定是https://taotoken.net/api。创建 Key 的时候建议按用途命名,比如fastmcp-github-demo,方便以后排查是哪个服务在用。拿到 Key 之后先别急着写进代码,放到环境变量里,后面配置片段会用到。
再说 GitHub OAuth App。登录 GitHub,进入 Settings → Developer settings → OAuth Apps,点 "New OAuth App"。这里有几个字段要填对:
应用名称随便起,用户授权时能看到,起个能认出来的就行,比如 "My FastMCP Server"。主页 URL 填你的应用主页或文档地址,本地开发填http://localhost:8000也可以。最关键的是授权回调 URL,它必须和你 FastMCP 服务里配置的redirect_path完全一致。默认路径是/auth/callback,所以本地开发填http://localhost:8000/auth/callback。GitHub 对 localhost 是放行的,但生产环境必须用 HTTPS,这点没有商量余地。
创建完成后,你会看到 Client ID,形如Ov23liAbcDefGhiJkLmN,这是公开标识符,可以出现在前端。然后点 "Generate a new client secret" 生成客户端密钥,这个值只显示一次,务必立刻保存。密钥泄露等于别人可以冒充你的应用,所以千万别提交到 Git 仓库,用环境变量或密钥管理器存。
这里有个坑我踩过:回调 URL 的路径大小写和结尾斜杠都算数。你 GitHub 后台填的是/auth/callback,代码里redirect_path写成/auth/Callback,授权回来就会报 redirect_uri 不匹配。所以两边复制粘贴,别手敲。如果你确实想用自定义路径,比如/auth/github/callback,那 GitHub 后台和GitHubProvider的redirect_path参数必须同时改,缺一个都不行。
3. FastMCP GitHubProvider 可复制配置片段与模型端点改造
前置准备好之后,进入代码环节。先给一份最小可运行的 FastMCP 服务端配置,把 GitHub 认证挂上,同时把工具内部的模型调用指向 TaoToken。
先看认证部分。GitHubProvider接收client_id、client_secret、base_url三个核心参数,redirect_path有默认值/auth/callback,不改就不用传。base_url必须和 OAuth App 里配的地址对得上,本地就是http://localhost:8000。
from fastmcp import FastMCP from fastmcp.server.auth.providers.github import GitHubProvider auth_provider = GitHubProvider( client_id="Ov23liAbcDefGhiJkLmN", client_secret="你的客户端密钥", base_url="http://localhost:8000", # redirect_path="/auth/callback" # 默认值,自定义时才需要显式传 ) mcp = FastMCP(name="GitHub Secured App", auth=auth_provider)生产环境不要硬编码凭证,用环境变量。FastMCP 2.12.1 之后支持通过环境变量自动装配 GitHub 提供者,代码可以简化到只剩一行FastMCP(name=...)。对应的.env文件长这样:
FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.github.GitHubProvider FASTMCP_SERVER_AUTH_GITHUB_CLIENT_ID=Ov23liAbcDefGhiJkLmN FASTMCP_SERVER_AUTH_GITHUB_CLIENT_SECRET=你的客户端密钥 FASTMCP_SERVER_AUTH_GITHUB_BASE_URL=https://your-server.com FASTMCP_SERVER_AUTH_GITHUB_REQUIRED_SCOPES=user,repoREQUIRED_SCOPES决定你向 GitHub 申请哪些权限范围。user能读基本资料,repo能读仓库。按最小权限原则,只申请你真正需要的,别一股脑全要,用户授权时看到一堆权限会犹豫。
接下来是模型端点改造。你的 MCP 工具内部如果要调模型,把端点统一指向 TaoToken。下面这个工具既返回 GitHub 用户信息,又演示了模型调用的配置方式:
import os from openai import OpenAI from fastmcp.server.dependencies import get_access_token # 统一模型调用客户端,指向 TaoToken 通道 llm = OpenAI( api_key=os.environ["TAOTOKEN_API_KEY"], base_url="https://taotoken.net/api", ) @mcp.tool async def get_user_info() -> dict: """返回已认证 GitHub 用户的信息。""" token = get_access_token() return { "github_user": token.claims.get("login"), "name": token.claims.get("name"), "email": token.claims.get("email"), } @mcp.tool async def summarize_repos() -> str: """用模型总结当前用户的仓库列表。""" token = get_access_token() login = token.claims.get("login") resp = llm.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": f"用一句话概括 {login} 的仓库情况"}], ) return resp.choices[0].message.content注意base_url是https://taotoken.net/api,Key 从环境变量读。模型 ID 按你实际开通的填,这里只是示例。这样认证走 GitHub,模型走 TaoToken,两条链路互不干扰。
如果你用 Claude Code 或 Cline 这类客户端连你的 MCP 服务,配置里要写全三件套:Base URL、Key、Model ID。以 Claude Code 的settings.json为例:
{ "mcpServers": { "github-secured": { "url": "http://localhost:8000/mcp", "auth": "oauth" } }, "env": { "TAOTOKEN_API_KEY": "你的Key", "OPENAI_BASE_URL": "https://taotoken.net/api", "OPENAI_MODEL": "gpt-4o-mini" } }Base URL 指向 TaoToken,Key 用你创建的,Model ID 按需替换。三件套齐了,客户端才知道去哪调、用什么身份、调哪个模型。
4. 启动服务与端到端验证请求成功结果
配置写完,启动服务。用 HTTP 传输才能触发 OAuth 流程,stdio 模式没有回调地址,认证跑不起来:
fastmcp run server.py --transport http --port 8000看到服务监听在 8000 端口就对了。然后写一个测试客户端,验证整条链路:
from fastmcp import Client import asyncio async def main(): async with Client("http://localhost:8000/mcp", auth="oauth") as client: print("已通过 GitHub 认证") result = await client.call_tool("get_user_info") print(f"GitHub 用户:{result['github_user']}") summary = await client.call_tool("summarize_repos") print(f"模型总结:{summary}") if __name__ == "__main__": asyncio.run(main())首次运行客户端时,浏览器会自动打开 GitHub 授权页。你点授权,页面重定向回http://localhost:8000/auth/callback,客户端拿到令牌,后续请求就带着身份走了。终端里应该能看到两行输出:一行是 GitHub 用户名,一行是模型返回的总结。这两行同时出现,说明认证链路和模型链路都通了。
客户端会在本地缓存令牌,第二次运行不会再弹授权页,除非令牌过期或你手动清了缓存。验证成功的关键标志是get_user_info返回的github_user和你登录的 GitHub 账号一致,如果返回 None,说明令牌里的 claims 没取到,多半是 scope 没申请对。
5. FastMCP GitHub 认证常见报错排查对照
认证跑不通时,报错信息往往比较隐晦。下面按真实遇到的错误对照排查。
401 Unauthorized出现在客户端调用工具时。先看服务端日志有没有invalid token。常见原因是client_secret填错,或者 GitHub OAuth App 里生成密钥后没保存、重新生成了新的导致旧密钥失效。另一个可能是base_url和 OAuth App 里的回调地址域名不一致,令牌签发和验证对不上。
redirect_uri mismatch出现在浏览器授权后跳回时。这是回调地址不匹配,逐字符对比 GitHub 后台的 Authorization callback URL 和代码里的redirect_path。注意协议(http/https)、端口、路径大小写、结尾斜杠。本地开发用http://localhost:8000/auth/callback,生产用https://你的域名/auth/callback,别混用。
local proxy failed或连接被拒。检查服务是不是用--transport http启动的,stdio 模式没有 HTTP 端点,OAuth 回调无处可去。另外确认端口没被占用,防火墙没拦。
reading choices报错,通常出现在模型调用环节而不是认证环节。说明llm.chat.completions.create返回结构不对,多半是base_url配错了,请求打到了非预期端点。确认base_url是https://taotoken.net/api,Key 有效,模型 ID 是你账号下真实可用的。
OAuth callback timeout出现在授权后长时间无响应。检查FASTMCP_SERVER_AUTH_GITHUB_TIMEOUT_SECONDS,默认 10 秒,网络慢可以调大。也可能是 GitHub API 调用超时,看服务端日志里有没有 GitHub 请求失败的记录。
invalid_client出现在令牌交换阶段。Client ID 和 Client Secret 不匹配,或者 Secret 里有空格、换行。从 GitHub 复制时注意别带上多余字符,环境变量里也别加引号。
排查顺序建议:先确认服务启动方式对不对,再确认回调地址匹配,然后确认凭证正确,最后看模型端点。一层一层往下,别跳步。
6. 把认证与模型通道固定下来的实践建议
跑通之后,有几件事值得固定成习惯。凭证一律走环境变量,.env加进.gitignore,生产环境用密钥管理器。REQUIRED_SCOPES按最小权限申请,用户授权时更放心。生产部署记得配jwt_signing_key和client_storage,否则服务重启后令牌丢失,用户要重新授权。用FernetEncryptionWrapper包一层存储,避免令牌明文落盘。
模型调用这条链路,统一走 TaoToken 的 Key 通道,好处是换模型不用改代码结构,只改 Model ID。Base URL 固定https://taotoken.net/api,Key 在控制台管理,轮换方便。如果你要长期跑编码类 Agent,可以看看 Coding Plan 的额度方案;只是验证模型连通性,用模型对话页面快速试一下就行。接入细节和参数说明在接入文档里,遇到认证或端点问题优先查 API Keys 和文档两处。
最后留一个实用技巧:本地调试时把FASTMCP_SERVER_AUTH_GITHUB_TIMEOUT_SECONDS调到 30,网络抖动时不容易误报超时。等稳定了再调回默认值。