github-mcp
GitHub v3 REST API MCP (Model Context Protocol) server, generated by mcpify.
Exposes exactly 3 tools — search, get, call — backed by an embedded semantic database (mcp_store.db), so an LLM never needs the full API surface in context.
Install
Prebuilt binaries for macOS, Linux, and Windows are attached to each GitHub Release, along with a shell/PowerShell installer script.
Setup
Interactively collects the API URL and the credentials your chosen auth method needs, then lets you persist them as a .env file, a config.yml file (local ./github-mcp.config.yml or global ~/.github-mcp/config.yml), or a ready-to-run CLI invocation.
GHES deployments must append /api/v3 to GITHUB_MCP_URL (e.g. https://ghe.example.com/api/v3). api.github.com/GHEC deployments need no suffix — use the bare host (e.g. https://api.github.com).
Usage
Terminal Client (default)
# 1. Semantic search over all 1,194 operations in the default GitHub.com store
# 2. Inspect the exact method, path, and input/output schemas before calling
# method: GET
# path: /repos/{owner}/{repo}/issues/{issue_number}
# 3. Path parameters are fields in one --args JSON object
# Request payloads are nested under body in that same object
call accepts one JSON object through --args (or -a), not arbitrary per-operation CLI flags. Use get <operationId> to see the accepted field names and which ones are required.
Harness Server
Other Commands
This project bundles semantic stores for multiple GitHub API spec versions (GitHub.com, GHEC, and several GHES releases). Set GITHUB_MCP_API_VERSION (or the api_version field in your config file) to select one; github-mcp versions lists the available labels and which one is active.
Observability & Resilience
Structured logging
GITHUB_MCP_LOG_LEVEL (default info) sets the log level. Logs always go to stderr — stdout is reserved for the MCP stdio transport's JSON-RPC frames — as structured JSON, switching to pretty-printed text automatically when stderr is an interactive TTY (src/core/logger.rs, src/core/log_transport.rs).
GITHUB_MCP_LOG_LEVEL=debug
Secret redaction (src/core/sanitizer.rs) replaces any JSON key containing password/token/secret/authorization/api_key/credential with [REDACTED]. It isn't wired in as an automatic log filter; today the only caller is github-mcp config, which sanitizes the resolved configuration before printing it.
OpenTelemetry tracing
Every Harness Server start (start or http) builds an OTLP/HTTP trace exporter unconditionally — there's no flag to turn it off (src/core/otel.rs). Point it at a collector with the standard OTel environment variables:
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
If OTEL_EXPORTER_OTLP_ENDPOINT/OTEL_EXPORTER_OTLP_TRACES_ENDPOINT aren't set, the exporter defaults to http://localhost:4318/v1/traces; if nothing is listening there, export attempts just fail silently in the background rather than crashing the server. Only traces are exported this way — there's no OpenTelemetry metrics pipeline.
Metrics
GET /metrics (HTTP transport only; no stdio equivalent) returns Prometheus text format (src/http/metrics.rs). Currently it tracks a single counter, http_requests_total.
Retries, timeout, rate limiting, circuit breaker
Set via env var (or the equivalent key in a github-mcp.config.yml):
GITHUB_MCP_RATE_LIMIT=20 # max outbound API calls per rolling 1s window (default 100; window is fixed, not configurable)
GITHUB_MCP_TIMEOUT_MS=10000 # per-request timeout against the target API (default 30000)
GITHUB_MCP_RETRY_ATTEMPTS=5 # immediate retries after a transport-level failure, no backoff (default 3)
Two things exist in the code but currently have no operator-facing knob:
- The circuit breaker (
src/core/circuit_breaker.rs) wraps every outbound API call and opens after 5 consecutive failures, resetting after 30 seconds — both values are hardcoded (CircuitBreaker::default()), with no env var or config field to change them. GITHUB_MCP_CACHE_SIZE/cache_size(default500) is accepted and parsed but has no effect:src/core/cache_manager.rsexists but isn't wired into the request path.
Health checks
HealthCheckManager (src/core/health_check_manager.rs) runs registered checks every 30 seconds with a 5-second timeout — both hardcoded. Today the only registered check is store (confirms mcp_store.db opens).
&
/healthz only exists under HTTP transport. For stdio deployments (no HTTP endpoint to probe), the separate github-mcp-healthcheck binary — used by the Dockerfile's HEALTHCHECK instruction — just checks that mcp_store.db is present and readable; it does not check API connectivity.
Credential storage
github-mcp setup always saves your credentials to src/core/credential_storage.rs's store, independent of whichever .env/config.yml/CLI-invocation option you pick for the non-secret settings (URL, auth method, API version, transport). It tries the OS-native keychain first (macOS Keychain / Windows Credential Manager / Linux Secret Service, via the keyring crate); if no backend is available (e.g. no D-Bus secret-service daemon in a minimal container), it falls back automatically to an AES-256-GCM-encrypted file at ~/.github-mcp/credentials.enc (mode 0600, directory 0700 on Unix), keyed from $HOME so the fallback file isn't portable to another machine.
stdio transport loads credentials from this store on demand at runtime. http transport never touches it: every request must carry its own credential header (which one depends on the configured auth method — github-mcp setup prints the exact shape for your deployment), and a request without one is a hard error rather than a fallback to local config/keychain.
Testing
Coverage
Profiling
profile/bottleneck-report.md combines coverage gaps with the hottest CPU functions in one small text file — paste it into an LLM (or hand it to another tool) to find and fix bottlenecks. Requires samply (cargo install samply).
License
MIT — see LICENSE.
Generated by mcpify — do not hand-edit generated files; re-run mcpify against an updated OpenAPI spec instead.