GitHub MCP 怎么配:工具集、只读和 Issue 工件开关

GitHub 官方的 MCP 服务器(github/github-mcp-server,MIT,截至 11 月 5 日约 3.4 万星)默认就给 Agent 开了仓库、Issue、PR 三大块的读写工具。11 月 3 日的 v2.1.0 又加了一组实验工具,能把计划、链接挂到 Issue 上。工具开得越多,占的上下文越多,Agent 能误调的写操作也越多。下面按官方仓库 docs 目录(2026-11-05 北京时间查阅),把远程和本地两种接法、工具集裁剪、只读和 lockdown、新的 issue_artifacts 开关一次配好。
默认配置给得太多
不做任何配置时,服务器加载五个默认工具集:context、repos、issues、pull_requests、users。README 列出的本地工具集有 22 个,远程版另有 copilot、copilot_spaces、github_support_docs_search 三个。设成 all 就全开。
每个工具的名字、说明和参数表都要进模型上下文。官方配置指南写“只启用要用的工具”时,给的理由就是省上下文。另一层是权限:默认集里就有建 Issue、建 PR、合并 PR 的工具,你的 token 有写权限,Agent 就能调到。
先写下 Agent 在这个仓库要做哪几件事,工具集照这份清单开。
前置条件
- 一个支持 MCP 的客户端:Claude Code(2.1.1 以上用
add-json写法)、Codex CLI,或 VS Code 1.101 以上。 - 一个 GitHub 细粒度 PAT(在
github.com/settings/personal-access-tokens/new创建),只勾要用的仓库和权限。README 给的最小权限示例:repo(仓库操作)、read:packages(拉 Docker 镜像)、read:org(读组织团队)。 - 走本地版的话装好 Docker,镜像是
ghcr.io/github/github-mcp-server。 - token 放环境变量或
.env,并把.env、.mcp.json写进.gitignore。
第一步:接上服务器
远程版由 GitHub 托管,地址 https://api.githubcopilot.com/mcp/,不用自己跑进程。Claude Code 在终端里执行(官方安装指南的写法):
export GITHUB_PAT="$(grep '^GITHUB_PAT=' .env | cut -d '=' -f2-)"
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer '"$GITHUB_PAT"'"}}'
# 想跨项目用,末尾加 --scope user;之后重启 Claude Code
claude mcp list
Codex 写进 ~/.codex/config.toml,token 从环境变量读:
[mcp_servers.github]
url = "https://api.githubcopilot.com/mcp/"
bearer_token_env_var = "GITHUB_PAT_TOKEN"
等价命令是 codex mcp add github --url https://api.githubcopilot.com/mcp/ --bearer-token-env-var GITHUB_PAT_TOKEN。启动后在 TUI 里输 /mcp,能看到 github 下的工具就算接上了。
用 GitHub Enterprise Server 的团队只能走本地版,远程托管不支持 GHES。本地版用 Docker:
claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN=$GITHUB_PAT -- \
docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server
GHES 再加一个 GITHUB_HOST=https://你的域名。文档说明非 HTTPS 的主机会被拒绝,只有 localhost 例外。
第二步:只留要用的工具集
两种版本用的是同一套开关,名字不一样:
| 要做的 | 远程版(请求头 / URL) | 本地版(参数 / 环境变量) |
|---|---|---|
| 选工具集 | X-MCP-Toolsets 或 /x/{toolset} | --toolsets / GITHUB_TOOLSETS |
| 单独加工具 | X-MCP-Tools | --tools / GITHUB_TOOLS |
| 排除工具 | X-MCP-Exclude-Tools | --exclude-tools / GITHUB_EXCLUDE_TOOLS |
| 只读 | X-MCP-Readonly 或 URL 末尾 /readonly | --read-only / GITHUB_READ_ONLY |
| lockdown | X-MCP-Lockdown | --lockdown-mode / GITHUB_LOCKDOWN_MODE |
| 实验特性 | X-MCP-Features 或 ?features= | --features / GITHUB_FEATURES |
按任务挑工具集,几个常见组合:
- 只做代码审查:
context,repos,pull_requests,再配只读。 - 帮你看 CI 为什么挂:
context,repos,actions,Actions 工作流和运行记录都在actions里。 - 处理安全告警:
context,code_security,dependabot,secret_protection,分别对应代码扫描、Dependabot 和密钥扫描。 - 整理 Issue:
context,issues,labels。
官方把 context 标为强烈建议保留,它告诉 Agent 当前用户是谁、在哪个 GitHub 环境里。
一个常见的“能看能评、不能合并”的配置,Codex 这样写(http_headers 是 Codex 文档里远程 MCP 的静态请求头字段):
[mcp_servers.github]
url = "https://api.githubcopilot.com/mcp/"
bearer_token_env_var = "GITHUB_PAT_TOKEN"
http_headers = { "X-MCP-Toolsets" = "context,repos,issues,pull_requests", "X-MCP-Exclude-Tools" = "create_pull_request,merge_pull_request" }
本地 Docker 版把同样的值放进环境变量:
docker run -i --rm \
-e GITHUB_PERSONAL_ACCESS_TOKEN \
-e GITHUB_TOOLSETS="context,repos,issues,pull_requests" \
-e GITHUB_EXCLUDE_TOOLS="create_pull_request,merge_pull_request" \
ghcr.io/github/github-mcp-server
优先级记两条:排除列表压过工具集和单独加的工具;只读模式压过一切,写工具哪怕点名要了也不加载。
第三步:只读和 lockdown 分开用
只读模式是硬过滤。所有会改动 Issue、PR、仓库的工具都不注册,issues 工具集里的 create_issue 也会被拿掉。远程版最省事的写法是直接换 URL:https://api.githubcopilot.com/mcp/x/all/readonly(全部工具集只读),或 /x/issues/readonly(单个工具集只读)。
lockdown 管的是内容来源。打开后,公开仓库里只显示有推送权限的用户写的内容,私有仓库不受影响;github-actions[bot] 和 copilot 两个机器人账号写的内容始终放行。它用来减少陌生人在公开 Issue 里埋提示词注入的机会。官方文档写明:lockdown 是尽力而为的内容过滤,算不上授权边界,token 能读写的东西它不拦。
维护公开仓库的人,建议两个一起开:只读挡写操作,lockdown 挡外部内容。HTTP 部署时服务端开了 lockdown,客户端的请求头关不掉它。
第四步:打开 Issue 工件
v2.1.0 合并的 PR #3554 在 issues 工具集里加了两个实验工具:issue_artifact_read(list、get)和 issue_artifact_write(create、update、delete)。特性开关 issue_artifacts 默认关,Insiders 模式也不自动开。
# 本地版
docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN \
-e GITHUB_FEATURES=issue_artifacts ghcr.io/github/github-mcp-server
# 远程版:加一个请求头
"X-MCP-Features": "issue_artifacts"
工件类型有四种:generic、link、plan、embedded_html。每次操作都要给 owner、repo、issue_number;读单个、更新、删除还要 artifact_number,这个编号只在所属 Issue 内有效。创建时 type、name、body 必填,body 可以为空。更新不能改类型,没传的字段保持原样。
比如让 Agent 开工前先写一份 plan 工件,做完再更新进度。下一个接手的人或 Agent 读 Issue 就能看到计划,不用翻聊天记录。
常见坑
- 工具集写错不报错:远程版
X-MCP-Toolsets里拼错的工具集会被静默忽略;X-MCP-Tools里写错工具名则会直接报错、服务起不来。工具名要完全一致,get_file_contents不能写成getFileContents。 - URL 路径只能放一个工具集:
/x/{toolset}不接受逗号列表,要组合多个就改用X-MCP-Toolsets请求头。 - 开了 lockdown,工件工具用不了:工件接口的返回里没有作者信息,没法做内容可信判断,所以两个工具在 lockdown 下直接拒绝。公开仓库想用工件,得在这两者之间取舍。
- 开关不等于授权:
issue_artifacts只负责把工具暴露出来,能不能读写取决于 token 的权限和仓库访问范围。写操作失败不会自动重试,错误会原样返回给 Agent。 - 列表要自己翻页:
perPage范围 1–100,默认 30;返回条数少于perPage才算翻完。
完成标准
claude mcp list或 Codex 的/mcp里能看到 github,工具列表里只有你选的工具集。- 让 Agent 建一个 PR,它回复找不到相关工具,或明确说没有这个能力。
- 公开仓库的配置里同时有只读和 lockdown。
- 需要工件时,
issue_artifact_read能列出目标 Issue 上的工件;只读部署下看不到issue_artifact_write。
最后
先把你现在的 GitHub MCP 配置改成显式的 X-MCP-Toolsets 列表,再加一条排除合并的规则。装了一堆插件、不确定本机连着哪些 MCP 的,回头跑一遍 Agent 插件自查;v2.1.0 的更新内容见这条快讯。