GitHub
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
作者による説明(英語の原文)
MCP server for the GitHub REST API: issues, PRs, repos; read always on, write env-gated.
この3つを1つのスコアにまとめることはしません。意見、測定、人気はそれぞれ別のものだからです。
このサーバーのやさしい解説はまだ書いていません。以下はレジストリから読み取った事実です。
使っているAIアプリを選んで、設定をコピーしてください。
必要なもの
どのアプリを使っていますか?
上でアプリを選んでください。選んだアプリを覚えておくので、次からはボタンに「…にインストール」と表示されます。
Claude Desktop → Settings → Developer → Edit Config を開き、claude_desktop_config.json にこれを貼り付けます
{
"mcpServers": {
"github": {
"command": "uvx",
"args": [
"jaimenbell-github-mcp"
]
}
}
}ターミナルでこれを実行します
claude mcp add github -- uvx jaimenbell-github-mcpプロジェクトの .cursor/mcp.json、または ~/.cursor/mcp.json に貼り付けます
{
"mcpServers": {
"github": {
"command": "uvx",
"args": [
"jaimenbell-github-mcp"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
プロジェクトの .vscode/mcp.json に貼り付けます
{
"servers": {
"github": {
"type": "stdio",
"command": "uvx",
"args": [
"jaimenbell-github-mcp"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
これはパソコンで動くサーバーですが、ChatGPTがつなげるのはインターネット上のサーバーだけです。ほかのアプリを選んでください。
選んだアプリは、この端末のCookieに保存されます。アカウントは不要です。
この設定は、作者のレジストリ登録情報から作成しています。READMEと違う場合は、READMEに従ってください。
パソコンで動くサーバーです。インストールすると、ツール一覧がAIアプリに表示されます。
誰でも見られる情報をチェックしており、コードは読んでいません。当てはまらない項目は数に入れていません。 · 2026年11月6日にチェック
レジストリ名は、リポジトリを所有するGitHubアカウント jaimenbell で確認済みです
このリポジトリはまだGitHubから読み取っていません
このリポジトリはまだGitHubから読み取っていません
これはパソコンで動くため、インターネット上のエンドポイントはありません
パソコンで動き、代わりにローカルの設定を使います
パソコンで動くサーバーです。ツール一覧を読み取れるのは、インターネット上のエンドポイントがある場合だけです
レジストリでこのカテゴリにある有効なすべてのサーバーと比較しています。スターは、公開者がリポジトリの所有者である場合だけ数えます。
当てはまる基本チェック1項目のうち1項目に合格しました。コードは読んでいません。キーやトークンを追加する前に、サーバーがどんなアクセスを求めているかを確認し、必要な権限だけを持つキーを使ってください。
レジストリには必須のキーは載っていません。ただし、最初に使うときにサインインを求めるサーバーもあります。
あなたのパソコンで動きます。必要なときにAIアプリが起動し、データは作者のサーバーを通りません(サーバー自体がオンラインサービスを呼び出す場合を除きます)。
GitHubリポジトリの最終更新は–、最新バージョン(0.1.1)がレジストリに届いたのは3 か月前です。
Claude Desktop、Claude Code、Cursor、VS CodeなどのMCP対応アプリで使えます。パソコンにPython (uv)も必要です。
同じカテゴリには:GitHub, Desktop Commander, Cloudflare MCP
同じカテゴリで、ほかの作者が作ったサーバー。スターの多い順。
カードの見方:★ GitHubスターi3つの柱:レビュー · チェック · 利用状況i更新=最新バージョンをレジストリに公開した日i
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
MCP server for terminal commands, file operations, and process management
Cloudflare MCP servers
作者のリポジトリから書かれたとおりにコピーしたものです。PopNx MCPは内容を確認・推奨していません。HTML、画像、スクリプトは取り除いています。リンクはこのサイトの外へ移動します。
A public read+write MCP server over the GitHub REST API, built to the desktop-mcp/rag-mcp/mcp-factory standard (own pyproject, fastmcp server, honest README, real test suite) with env-gated tool groups (write disabled by default). Not the official GitHub MCP server -- see below.
pip install jaimenbell-github-mcp
// Add to your MCP host config (e.g. Claude Desktop/Code's mcpServers block)
{ "mcpServers": { "github-mcp": { "command": "github-mcp" } } }
The write tool group (issue/PR mutations) is off by default -- see Env vars below to enable it.
This is a reference portfolio implementation demonstrating a hardened read+write MCP server pattern over a real external SaaS API (GitHub) -- env-gated tool groups, typed error/rate-limit handling, auth that degrades gracefully, a real test suite. It exists to show, concretely, "I build read/write MCP servers over external APIs" with a link a client can click.
It is NOT the official GitHub MCP server. It does not aim for parity with GitHub's own MCP offering (GraphQL, Actions, webhooks, GitHub Apps are all out of scope -- see below). It started life as a factory-scaffolded read-only demo (mcp-factory's generated/github_read_server.py) and was hand-hardened into this standalone read+write server -- the scaffold-then-harden path is itself part of the story this repo tells.
One row per tool -- the two groups below just control default-on/off state, not what exists.
| Tool | Group | What it does |
|---|---|---|
get_repo | read | Repo metadata (stars, language, license, default branch, archived flag...) |
list_issues | read | List issues on a repo (PRs filtered out) |
get_issue | read | Fetch a single issue |
list_pull_requests | read | List pull requests on a repo |
get_pull_request | read | Fetch a single pull request |
get_file_content | read | Read a repo file's content (base64-decoded, binary detected not decoded) |
search_repos | read | Search public repositories |
get_user | read | Public user/org profile |
list_commits | read | List commits on a branch/ref |
create_issue | write | Open an issue |
comment_on_issue | write | Comment on an issue/PR |
update_issue_state | write | Open/close an issue |
add_labels | write | Add labels to an issue/PR |
create_pr_review_comment | write | Create a PR review comment on a diff line |
read is always on and works unauthenticated (GitHub's 60 req/hr tier). write is env-gated and OFF by default -- requires GITHUB_MCP_ENABLE_WRITE=1 and GITHUB_TOKEN.
A disabled write call returns a structured policy_refusal error (never a silent no-op, never a crash). A write call with the group enabled but no token returns a structured auth_required error -- the group gate and the token precondition are checked independently, both before any network call.
This is defense-in-depth, mirroring desktop-mcp's input group: harness-level permission prompts are the first gate, but the server itself refuses every write tool unless its own environment explicitly opts in with GITHUB_MCP_ENABLE_WRITE=1, and even then refuses without a GITHUB_TOKEN. A misconfigured or overly-permissive MCP host cannot turn on GitHub mutations this process wasn't deliberately configured to allow. The registration this repo ships with (see ~/.claude.json's github-mcp entry) has the write group absent from env -- enabling it is a deliberate per-registration operator choice, not a code change.
Every claim below maps to the file that implements it and the test(s) that verify it -- no capability is asserted without a corresponding implementation and test.
| Claim | Implementation | Verified by |
|---|---|---|
| Repo metadata (stars, language, license, default branch, archived flag...) | github_mcp/groups/read.py::get_repo | tests/test_read.py::TestGetRepo, live: tests/test_live_smoke.py::test_live_get_repo_real_json |
| List / fetch issues (PRs filtered from list) | github_mcp/groups/read.py::list_issues, get_issue | tests/test_read.py::TestListIssues, TestGetIssue |
| List / fetch pull requests | github_mcp/groups/read.py::list_pull_requests, get_pull_request | tests/test_read.py::TestListPullRequests, TestGetPullRequest |
| Read a repo file's content (base64-decoded, binary detected not decoded) | github_mcp/groups/read.py::get_file_content | tests/test_read.py::TestGetFileContent |
| Search public repositories | github_mcp/groups/read.py::search_repos | tests/test_read.py::TestSearchRepos |
| Public user/org profile | github_mcp/groups/read.py::get_user | tests/test_read.py::TestGetUser |
| List commits on a branch/ref | github_mcp/groups/read.py::list_commits | tests/test_read.py::TestListCommits |
| Open an issue | github_mcp/groups/write.py::create_issue | tests/test_write.py::TestCreateIssue |
| Comment on an issue/PR | github_mcp/groups/write.py::comment_on_issue | tests/test_write.py::TestCommentOnIssue |
| Open/close an issue | github_mcp/groups/write.py::update_issue_state | tests/test_write.py::TestUpdateIssueState |
| Add labels to an issue/PR | github_mcp/groups/write.py::add_labels | tests/test_write.py::TestAddLabels |
| Create a PR review comment on a diff line | github_mcp/groups/write.py::create_pr_review_comment | tests/test_write.py::TestCreatePrReviewComment |
| Write group OFF by default, structured refusal when disabled | github_mcp/config.py::group_enabled, gated_write | tests/test_config.py::TestGroupEnabled, tests/test_write.py::TestGateDisabledByDefault |
| Write tools require a token even when the group is enabled | github_mcp/config.py::check_write_preconditions | tests/test_config.py::TestCheckWritePreconditions, tests/test_write.py::TestAuthRequiredWhenGroupEnabled |
| Fine-grained PAT auth, degrades to unauthenticated tier when absent | github_mcp/client.py::_headers | tests/test_client.py::TestAuthHeaderInjection, tests/test_read.py::TestUnauthDegrade |
GitHub primary rate-limit (403 + X-RateLimit-Reset) and secondary rate-limit (403 + Retry-After, no X-RateLimit-Remaining) both surface as a typed error with reset/retry time, never a crash | github_mcp/client.py::_rate_limit_error, _is_rate_limit_response | tests/test_client.py::TestRateLimitError, tests/test_client.py::TestRateLimitError::test_secondary_rate_limit_no_ratelimit_headers_retry_after_only, tests/test_read.py::TestUnauthDegrade::test_get_repo_rate_limited_without_token_is_typed |
Malformed owner/repo/path (control chars etc.) that would raise httpx.InvalidURL surfaces as a typed error, never an uncaught exception | github_mcp/client.py::request | tests/test_client.py::TestNetworkError::test_malformed_path_raises_invalid_url_caught_as_network_error |
| Generic 4xx/5xx surfaces as a typed error, never a crash | github_mcp/client.py::_api_error | tests/test_client.py::TestApiError |
| Non-JSON / malformed responses and network failures surface as typed errors | github_mcp/client.py::_handle_response, request | tests/test_client.py::TestDecodeError, TestNetworkError |
rate_limited errors under sustained unauthenticated use; set GITHUB_TOKEN (even a read-only fine-grained PAT) to raise this considerably.limit, capped per-endpoint, is the only page-size control in v1).| Var | Effect | Default |
|---|---|---|
GITHUB_MCP_ENABLE_WRITE | enable the write tool group | unset (off) |
GITHUB_TOKEN | fine-grained PAT; read works without it (degraded unauth rate), write requires it | unset |
GITHUB_MCP_LIVE | 1 to run the real-network smoke test (see Testing) | unset (skip) |
// A tool call from the MCP host, illustrative -- not a shell command.
{"tool": "get_repo", "arguments": {"owner": "anthropics", "repo": "anthropic-sdk-python"}} // -> {"ok": true, "full_name": "anthropics/anthropic-sdk-python", "stargazers_count": 1234, ...}
// write group disabled (default): {"tool": "create_issue", "arguments": {"owner": "o", "repo": "r", "title": "bug"}} // -> {"ok": false, "error": {"type": "policy_refusal", "group": "write", "required_env": "GITHUB_MCP_ENABLE_WRITE", ...}}
// write group enabled, no token set: {"tool": "create_issue", "arguments": {"owner": "o", "repo": "r", "title": "bug"}} // -> {"ok": false, "error": {"type": "auth_required", "tool": "create_issue", ...}}
CI (.github/workflows/ci.yml) runs this suite on every push/PR and fails the build if the Tests badge above drifts from what the suite actually reports -- see scripts/check_readme_counts.py.
# unit suite (respx-mocked api.github.com, no real network touched)
python -m pytest -q
python scripts/list_tools.py
GITHUB_MCP_LIVE=1 python -m pytest -q -k live_get_repo
pip install -r requirements.txt # or: pip install .
pip install -r requirements.txt on Python 3.12+.~/.claude.json):{
"mcpServers": { "github-mcp": { "command": "C:\\Users\\ \\AppData\\Local\\Programs\\Python\\Python312\\python.exe", "args": ["C:\\Users\\ \\projects\\github-mcp\\run_server.py"], "env": { "GITHUB_TOKEN": "your-fine-grained-pat-here" // GITHUB_MCP_ENABLE_WRITE intentionally absent -- write stays off // until you deliberately opt in per-deployment. } } } }
"GITHUB_MCP_ENABLE_WRITE": "1" to that entry's env block. This is a registration-time operator decision, not a code change.Registered in ~/.claude.json as github-mcp (stdio, system Python312, `rea
冒頭だけを表示しています。続きはリポジトリで読めます