Skip to main content
Glama

简体中文

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).

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.


Related MCP server: @cloud9-labs/mcp-github

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

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • An MCP server that gives your AI access to the source code and docs of all public github repos

  • MCP server exposing the Backtest360 engine API as tools for AI agents.

  • A MCP server built for developers enabling Git based project management with project and personal…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JohnXu22786/github-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server