repogate

repogate

MCP server that wraps the GitHub REST API into tools for repo queries, issue/PR management, code review, search, and authentication, letting coding agents operate GitHub directly in conversations.

Category
访问服务器

README

简体中文

repogate — GitHub Developer Workbench (agent tool set)

repogate is a GitHub workbench for coding agents: it wraps the GitHub REST API into a set of MCP (Model Context Protocol) tools, letting agents perform repo queries, issue management, PR creation and merging, code review, search, and other common operations directly in a conversation.

  • Zero runtime dependencies: uses only built-in Node.js capabilities (fetch, node:test); no packages need to be installed to run;
  • Standard MCP stdio server: works with any MCP-capable client (dsh, Claude Code, Codex, opencode, etc.);
  • Built for dsh: ships a dsh bundle (cordis.patch.yml + a self-developed bridge plugin), connected with dsh plugin add in one step — tools appear automatically in the model's tool list (mcp__repogate__*);
  • Dual auth channels: personal access token (PAT) and OAuth device authorization flow, with local token caching;
  • Read-only mode: blocks all write operations with one switch, ideal for research-only sessions;
  • Actionable errors: rate limits, invalid tokens, insufficient permissions, rejected parameters — every error includes a Chinese fix guide;
  • Slim output for models: lists/search return concise summaries instead of full JSON, saving context tokens.

Quick Start

Option A: connect directly from any MCP client

# requires Node.js ≥ 18.17
REPOGATE_TOKEN=ghp_yourtoken node src/entry.js

Example config line using the official dsh bridge (also works in Claude Code / Codex MCP configs):

# dsh: insert into $DSH_HOME/profiles/<profile>/cordis.patch.yml
- insert:
    - id: mcp-repogate
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: repogate
        transport: stdio
        command: node
        args: ['/absolute/path/to/src/entry.js']
        env:
          REPOGATE_TOKEN: !!js process.env.REPOGATE_TOKEN ?? ''

After connecting, the model sees 23 tools such as gh_issue_fetch and gh_pr_merge (generic MCP clients see bare names; under dsh they carry the mcp__repogate__ prefix, see below).

Option B: install as a dsh plugin bundle (recommended)

This plugin is declared as a dsh bundle (the dsh.bundle field in package.json). In the plugin checkout directory run:

dsh plugin --profile web add .
  • On first use it initializes the web profile automatically and adds this package to dsh.profile.bundles;
  • The repogate/bridge plugin defined in the package's cordis.patch.yml launches this MCP server directly inside the dsh process, and after the handshake registers all tools into ctx.toolsno manual config changes needed;
  • The token is inherited from the dsh process environment by default (REPOGATE_TOKEN or GITHUB_TOKEN);
  • Uninstall: dsh plugin --profile web remove repogate.

After installing, restart dsh and simply say in a session:

"Look at the open issues of the octo/hello repo, close #12, then comment 'fixed, waiting for verification' on #12."

The corresponding tool call chain: mcp__repogate__gh_issue_browsemcp__repogate__gh_issue_fetchmcp__repogate__gh_issue_editmcp__repogate__gh_issue_respond.

Note: dsh does not enable any MCP server by default (each server command is trusted code executed outside the sandbox); this plugin's bundle line is the "enable" action itself; only install trusted plugins.


Installing in DSH

dsh plugin --profile demo add github:JohnXu22786/github-mcp

A single command installs this plugin into the dsh demo profile from the GitHub repository. Integration, auth, and lifecycle details follow in the "dsh integration" section below.


dsh Integration (how a plugin-style harness loads it)

dsh uses the Cordis plugin framework; the unit of composition is a bundle: an npm package + a patch layer. The loading chain is as follows:

package.json (dsh.bundle.patch → ./cordis.patch.yml)
  └─ a line in cordis.patch.yml: name: 'repogate/bridge'
       └─ src/bridge/plugin.js (Cordis plugin, inject: ['tools'])
            ├─ spawns src/entry.js (the MCP server child process, stdio) using Node itself
            ├─ completes the initialize / tools/list handshake
            └─ registers each tool as mcp__repogate__<tool name> into ctx.tools
  • Tool interface: the tool name visible to the model = mcp__<serverName>__<original tool name>, serverName defaults to repogate;
  • Events/skills: this plugin registers no events or skills; it only exposes capabilities through the ctx.tools tool interface;
  • Lifecycle: handshake and registration happen during the plugin's apply; on unload it kills the child process and unregisters all tools automatically (cleanup registered via ctx.effect, so hot reloads/unloads leave no residue);
  • Two bridges to choose from: the bundle's built-in bridge repogate/bridge (zero dependencies, works out of the box) and the official dsh @deepseek-ai/dsh-mcp-client config line (see examples/overlay-for-dsh.yml.example); the tools are named and behave identically — pick either one, do not enable both;
  • Environment variables: dsh filters credential-type variables from the MCP child process environment, so the official bridge line needs the token written into the env config; the built-in bridge's child process inherits the host environment, so REPOGATE_TOKEN is passed through automatically.

Common dsh issues

Symptom Treatment
Tools don't appear in the list Check whether the cordis.patch.yml line took effect (dsh --profile <name> --dump-config to inspect layers), confirm no errors in the startup log
401 invalid token Check the env.REPOGATE_TOKEN config; or ask the model to call mcp__repogate__gh_auth_login in the session to use OAuth
Want read-only Configure args: ['--read-only'] on the bridge line, or append --read-only to the official line's args
pnpm ≥10 rejects prepare scripts on git installs This plugin is pure JS with no build script, so it's not affected; install from checkout or tarball

Tool List (23 tools)

Domain Tool Purpose Write op
Repo gh_repo_fetch Repo details: default branch, stars, language, visibility
Repo gh_repo_browse List user/org/own repos (paginated)
Issue gh_issue_open Create an issue (title required, optional labels/assignee)
Issue gh_issue_fetch View full issue info
Issue gh_issue_browse Filter by state/labels/assignee/author (pages may exclude PRs)
Issue gh_issue_edit Edit title/body/state/assignee/labels
Issue gh_issue_respond Post a comment (works in PR threads too)
PR gh_pr_open Create a pull request (head/base/draft)
PR gh_pr_fetch PR details: mergeability, changed stats, review count
PR gh_pr_browse Filter by state/branch, sort, paginate
PR gh_pr_edit Edit title/body/state/draft/base branch
PR gh_pr_merge Merge (method/commit message/delete source branch)
Review gh_review_submit Submit a full review: approve / request_changes / comment
Review gh_review_comment Line-level diff comments (including range comments)
Review gh_review_fetch List all line-level comments
Review gh_review_browse List submitted full reviews
Search gh_search_repos Search repos with GitHub search syntax
Search gh_search_issues Search issues/PRs (type:pr distinguishes)
Search gh_search_code Search code (requires token, returns file hits)
Account gh_whoami Current identity, token source, read-only mode, API quota
Auth gh_auth_login Start OAuth device authorization (requires configured clientId)
Auth gh_auth_check Poll authorization result once
Auth gh_auth_logout Clear the local token cache

All tools take JSON Schema inputs (name/description/inputSchema) that models can discover on their own; write tools are intercepted with a clear message in read-only mode.


Configuration

Priority: CLI flags > environment variables > config file > defaults. The config file is JSON, its path given by --config or REPOGATE_CONFIG; see examples/repogate.config.json.example.

Config item Environment variable Default
Access token REPOGATE_TOKEN (also accepts GITHUB_TOKEN / GH_TOKEN) none
API base URL (enterprise instances) REPOGATE_BASE_URL https://api.github.com
Read-only mode REPOGATE_READ_ONLY (1/true/yes/on) false
Per-request timeout (ms) REPOGATE_TIMEOUT_MS 30000
OAuth Client ID REPOGATE_OAUTH_CLIENT_ID none
OAuth token cache file REPOGATE_TOKEN_FILE ~/.repogate/token.json when oauth.clientId is configured
Config file path REPOGATE_CONFIG none
Debug logging (stderr) REPOGATE_DEBUG false

CLI flags: --config --token --read-only --base-url --timeout-ms --oauth-client-id --token-file --debug --version --help.


Authentication

Personal access token (PAT)

Generate one in GitHub's Developer settings (check the repo permissions needed on a fine-grained token), then choose any of:

REPOGATE_TOKEN=ghp_xxx node src/entry.js          # environment variable
node src/entry.js --token ghp_xxx                 # CLI flag
node src/entry.js --config repogate.config.json   # config file (token field)

Windows PowerShell 下环境变量写法:

$env:REPOGATE_TOKEN = 'ghp_xxx'
node src/entry.js

Token resolution order: --token > REPOGATE_TOKEN > GITHUB_TOKEN > GH_TOKEN > config file > cache file.

OAuth device authorization (token-free interactive login)

For those who'd rather not assemble a token by hand. You first need a GitHub App's Client ID (the device flow only requires a public client_id):

  1. Configure oauth.clientId (config file or REPOGATE_OAUTH_CLIENT_ID);
  2. Ask the model to call gh_auth_login → returns an authorization URL and a one-time code;
  3. The user opens the URL in a browser, enters the code, and confirms;
  4. The model calls gh_auth_check (may be called multiple times; each call checks once) → once granted, the token is written to the cache file, and all tools become available; the cached token survives process restarts;
  5. gh_auth_logout clears the cache.

Note: the device authorization endpoint always uses github.com; for enterprise instances (custom baseUrl) use a PAT. The token cache file is written with 0600 permissions; do not commit the cache file to version control.


Read-only Mode

node src/entry.js --read-only          # or REPOGATE_READ_ONLY=1

When enabled, the 8 write tools (gh_issue_open / gh_issue_edit / gh_issue_respond / gh_pr_open / gh_pr_edit / gh_pr_merge / gh_review_submit / gh_review_comment) are intercepted after argument validation and return a [readonly] error explaining how to turn it off; query, search, and auth tools are unaffected.


Error Handling

All failures are returned as structured errors (MCP isError: true + structuredContent.error) in the form [error code] reason. Common error codes and typical scenarios:

Error code Scenario Guide
auth Token missing/invalid (401) Configure a token or use OAuth device authorization
ratelimit Quota exhausted (403/429) Report reset time or Retry-After seconds
http 404/403/422/409 etc. Explain the specific cause (not found/no permission/params rejected/conflict)
validation Argument validation failed Point out which argument is invalid
readonly Read-only mode blocks a write Explain how to disable
timeout Request timeout Suggest increasing timeoutMs
network Network-layer failure Check the network and baseUrl

The gateway automatically retries once on 502/503/504 and network jitter (idempotent read requests only; writes are not retried to avoid duplicate side effects); if a 5xx still fails after retry, it returns an http error instead of failing silently.


Architecture and Layout

src/
├── entry.js              entry: config parsing → assembly → start the stdio session
├── protocol/             protocol layer (MCP over stdio, line-delimited JSON-RPC 2.0)
│   ├── jsonrpc.js        message encoding/decoding and classification
│   ├── transport.js      stdin/stdout read/write loop (logs go to stderr only)
│   └── engine.js         session engine: initialize / ping / tools/list / tools/call
├── core/                 core layer
│   ├── config.js         layered config merge (flag > env > config file > defaults)
│   ├── auth.js           credential hub: token resolution + OAuth device auth state machine + cache
│   ├── gateway.js        REST gateway: request assembly/retry/timeout/status-code mapping
│   └── errors.js         unified error model with actionable hints
├── tools/                tool layer
│   ├── registry.js       registry: argument validation (JSON Schema subset) + read-only gate + dispatch
│   ├── repo.js / issue.js / pull.js / review.js / search.js / account.js
│   └── index.js          assembles the 23 tools
├── bridge/               dsh integration
│   ├── client.js         MCP stdio client (initialize/list/call, cancellation and timeout)
│   └── plugin.js         Cordis plugin: spawns the server and registers tools into ctx.tools
└── util/format.js        output shaping: entity summaries, pagination detection, URL building

test/                     tests (node:test, zero dependencies)
├── helpers/              fake fetch and a local mock API service
└── *.test.js             protocol/gateway/config/auth/registry/tool/end-to-end (128 test cases)

Design highlights:

  • Layered one-way dependencies: protocol layer → core layer → tool layer; tools don't know protocol details, and the protocol doesn't know API details;
  • On-demand token resolution: OAuth authorization takes effect after completion without restart (the gateway holds a tokenResolver rather than a static token);
  • One codebase, both ends: bridge/client.js and the server share the same JSON-RPC vocabulary, so handshake and call logic are consistent.

Development and Testing

node --test          # run all 128 tests (including real child-process end-to-end)
node src/entry.js --help

Test coverage: protocol handshake and error paths (including interception of uninitialized sessions), gateway retry (idempotent methods only) and status-code mapping, the full OAuth state machine (including expiry), config priority, argument validation, the read-only gate, request construction and output shaping for all 23 tools, and an end-to-end chain of "real child process + local mock API".

Security Notes

  • A token has the same power as the account; do not write it into logs, commit it to version control, or leak it to untrusted conversations;
  • Under dsh, MCP server commands are trusted code outside the sandbox; install this plugin only from trusted sources;
  • Read-only mode significantly reduces the risk of misuse; research-only sessions are recommended to enable it.

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选