mcp-server-github
GitHub operations MCP server
mcp-server-github is an MCP (Model Context Protocol) server package that exposes GitHub operations as MCP tools. It exists to centralize and standardize GitHub API access (via @octokit/rest) for agents in the AGENTS ecosystem, providing configurable transports (stdio, HTTP) and dependency-injected services so agents can call GitHub-related tools without embedding GitHub credentials or client logic.
Architecture
Section titled “Architecture”- Startup sequence (src/index.ts):
- Reads MCP_TRANSPORT_TYPE (env) to decide STDIO vs other transports; disables ANSI colors in STDIO mode per MCP spec.
- Composes the dependency injection container via composeContainer() (DI is provided by tsyringe).
- Creates an MCP server instance with all tools registered by calling createMcpServerInstance().
- Starts the selected transport via startTransport(server, createMcpServerInstance). For HTTP transports, a factory is passed to create per-session server instances.
- Key components:
- composeContainer (from ’@/container/index.js’): registers services and bindings required by tools (HTTP client factory, Octokit wrapper, token provider, etc).
- createMcpServerInstance (from ’@/mcp-server/server.js’): builds and registers the MCP server and the GitHub toolset with the MCP runtime.
- startTransport (from ’@/mcp-server/transports/manager.js’): transport manager that wires MCP runtime to STDIO, HTTP, or other transports supported by the platform.
- config (from ’@/config/index.js’): central configuration object used by startup and components (mcpServerName, mcpServerVersion, mcpTransportType, githubHost, githubApiUrl, githubToken).
- logger (from ’@/utils/index.js’): structured logging (pino) used for startup and runtime logs.
- Data flow:
- Agent (client) -> Transport (stdio/http) -> MCP server instance -> registered GitHub tools -> @octokit/rest -> GitHub API.
- How it fits in AGENTS:
- Acts as a centralized server for GitHub-related abilities. Agents request GitHub operations via MCP calls; the server enforces credential usage and throttling and mutates GitHub through Octokit.
Tools / API
Section titled “Tools / API”The package exposes (or wires up) the following programmatic API and runtime entry points. These are the primary integration points when modifying or extending the server.
| Name | Description | Key parameters / notes |
|---|---|---|
| composeContainer() | Initialize and register application dependencies into the DI container (tsyringe). | No parameters. Called once at startup before creating server instances. |
| createMcpServerInstance() | Create and return a configured MCP server instance with GitHub tools registered. | Returns Promise |
| startTransport(serverOrFactory, factory?) | Start transport layer that accepts MCP requests and routes them to server instances. | First arg: a server instance used in single-instance modes. Second arg: optional factory function (createMcpServerInstance) used to create per-session servers (HTTP). |
| logger | Structured logger used across the package. | Methods used in index.ts include logger.info() and logger.error(). Backed by pino/pino-pretty in development. |
| config | Central configuration object. | Fields referenced in code: mcpServerName, mcpServerVersion, mcpTransportType, githubHost, githubApiUrl, githubToken. |
Note: The concrete GitHub tools (the individual operations exposed to agents, e.g., listPullRequests, createComment, etc.) are registered inside createMcpServerInstance (src/mcp-server/server.js). Inspect that module to see tool names and parameters; those are the “abilities” agents call through the MCP runtime.
Configuration
Section titled “Configuration”The server uses a config module and environment variables. The code references camelCase config keys; map those to your configuration source (config.toml, env, or secrets).
Recommended config.toml fields (keys as available through config module):
- mcpServerName: string — human name printed at startup
- mcpServerVersion: string — version printed at startup
- mcpTransportType: string — transport type (e.g., “stdio”, “http”)
- githubHost: string | undefined — optional GitHub host (enterprise)
- githubApiUrl: string | undefined — optional API base URL
- githubToken: string | undefined — GitHub token; should come from secrets storage
Environment variables:
- MCP_TRANSPORT_TYPE — overrides transport selection; used directly by startup to detect stdio mode.
- NODE_ENV — runtime mode (agent.json build sets NODE_ENV=production).
- (Prefer) GITHUB_TOKEN or equivalent — your secret provider should populate config.githubToken.
Secrets / vault:
- The server expects GitHub credentials to be provided securely. Recommended secret names (examples; adapt to your vault conventions):
- secret/mcp-server-github/github-token -> mapped to config.githubToken
- The code prints a masked token at startup (only last 4 chars) via config.githubToken if present. Do not log full secrets.
Notes:
- The build container (agent.json) sets NODE_ENV=production for builds.
- STDIO mode disables ANSI colors by setting NO_COLOR=1 and FORCE_COLOR=0 to comply with MCP spec.
Code Examples
Section titled “Code Examples”Key startup logic (src/index.ts). This is the entrypoint; modifying startup behavior, logging, or transport selection should start here.
#!/usr/bin/env node/** * @fileoverview Entry point for the GitHub MCP Server. * Follows the same startup pattern as mcp-server-git. */
// Disable ANSI colors in STDIO mode (MCP spec requirement)const transportType = process.env.MCP_TRANSPORT_TYPE?.toLowerCase();const isStdioMode = !transportType || transportType === 'stdio';if (isStdioMode) { process.env.NO_COLOR = '1'; process.env.FORCE_COLOR = '0';}
import 'reflect-metadata';import { composeContainer } from '@/container/index.js';import { createMcpServerInstance } from '@/mcp-server/server.js';import { startTransport } from '@/mcp-server/transports/manager.js';import { logger } from '@/utils/index.js';import { config } from '@/config/index.js';
async function main(): Promise<void> { logger.info('============================================================'); logger.info(`Starting ${config.mcpServerName} v${config.mcpServerVersion}`); logger.info('============================================================'); logger.info(`Transport: ${config.mcpTransportType}`); logger.info(`GitHub API: ${config.githubHost || config.githubApiUrl}`); logger.info(`Token: ${config.githubToken ? '***' + config.githubToken.slice(-4) : 'NOT SET'}`); logger.info('');
// Initialize DI container composeContainer();
// Create MCP server with all tools registered const server = await createMcpServerInstance();
// Start the selected transport // For HTTP, pass the factory so each session gets a fresh server instance await startTransport(server, createMcpServerInstance);}
// Graceful shutdownconst shutdown = (signal: string) => { logger.info(`${signal} received, shutting down...`); process.exit(0);};
process.on('SIGTERM', () => shutdown('SIGTERM'));process.on('SIGINT', () => shutdown('SIGINT'));process.on('uncaughtException', (error) => { logger.error({ error: error.message, stack: error.stack }, 'Uncaught exception'); process.exit(1);});
main().catch((error) => { // In STDIO mode, write to stderr if (isStdioMode) { process.stderr.write(`Fatal: ${error.message}\n`); } else { logger.error({ error: error.message }, 'Fatal startup error'); } process.exit(1);});Developer tips:
- To add or change GitHub tools, modify src/mcp-server/server.js (where createMcpServerInstance is implemented and registers tool handlers).
- To add dependencies to the DI container (e.g., a caching layer or rate limiter), update composeContainer in src/container/index.js.
- To modify transports or add a new transport type (e.g., WebSocket), extend src/mcp-server/transports/manager.js and wire the transport into startTransport.
Dependencies
Section titled “Dependencies”Runtime dependencies (from package manifest):
- @octokit/rest — primary GitHub API client
- express — used by HTTP transport layers or wrapper servers
- pino, pino-pretty — logging
- reflect-metadata — required for decorators/tsyringe DI runtime
Dev / build dependencies:
- @hono/mcp, @hono/node-server — MCP runtime integrations and server adapters
- @modelcontextprotocol/sdk — MCP SDK types and helpers
- tsyringe — DI container used by composeContainer
- dotenv, hono, typescript, zod, @types/* — build/test toolchain
What depends on this package:
- Any AGENTS or MCP-compatible agents that require GitHub functionality should connect to this MCP server to call GitHub tools (via the MCP runtime/transport). Other internal MCP servers/services may call into or coordinate with mcp-server-github for GitHub-related operations.
Agent & ability notes:
- Abilities exposed to agents are the GitHub tool functions registered in createMcpServerInstance. Agents act as clients that make MCP calls over the configured transport; the MCP server authenticates and forwards calls to GitHub via Octokit.
- When adding or changing abilities, ensure tool signatures are stable and documented for agent implementers.
Build / container notes
Section titled “Build / container notes”- agent.json build block demonstrates the build image and steps:
- Uses node:20-alpine, installs bun, runs bun build on src/index.ts targeting node, externalizes pino and @octokit/rest to reduce bundle size, prunes dev dependencies.
- NODE_ENV is set to production during build.
If you need deeper code pointers (e.g., the exact tool names registered), open src/mcp-server/server.js and src/container/index.js to see DI bindings and tool registration points.