How to Deploy the GitHub MCP Server Using Docker: Complete Setup Guide

Deploy the GitHub MCP server by running docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_PAT -p 8082:8082 ghcr.io/github/github-mcp-server http --port 8082, which pulls the distroless image and starts the HTTP server on port 8082.

The GitHub MCP (Model Context Protocol) server enables AI assistants to interact with GitHub repositories through a standardized interface. Deploying via Docker provides an isolated, reproducible environment using the official multi-stage image hosted at ghcr.io/github/github-mcp-server. This guide covers the complete deployment process based on the actual source code structure from the github/github-mcp-server repository.

Docker Architecture and Build Process

The official Dockerfile implements a three-stage build that compiles both UI assets and the Go binary before deploying to a minimal runtime. Understanding this architecture helps troubleshoot deployment issues and optimize your configuration.

Multi-Stage Build Stages

  1. ui-build stage: Uses node:20-alpine to build frontend assets with Vite, outputting to pkg/github/ui_dist/
  2. build stage: Uses golang:1.25.7-alpine to compile the server binary with embedded version metadata via ldflags
  3. Runtime stage: Deploys to gcr.io/distroless/base-debian12, containing only the compiled binary at /server/github-mcp-server

The build process embeds version information directly into the binary:

CGO_ENABLED=0 go build \
    -ldflags="-s -w -X main.version=${VERSION} \
              -X main.commit=$(git rev-parse HEAD) \
              -X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
    -o /bin/github-mcp-server ./cmd/github-mcp-server

Key source files governing Docker behavior include:

  • cmd/github-mcp-server/main.go: Parses environment variables via Viper and routes to stdio or http subcommands
  • pkg/http/server.go: Implements the HTTP listener on 0.0.0.0:8082
  • Dockerfile: Defines the distroless runtime and exposes port 8082

Prerequisites

Before deploying the GitHub MCP server using Docker, ensure you have:

  • Docker installed and running on your host system
  • A GitHub Personal Access Token with at least the repo scope (additional scopes required for specific toolsets like security or actions)
  • (Optional) Familiarity with MCP toolsets to customize which GitHub features are exposed

Deployment Methods

The container supports two primary execution modes controlled by subcommands in cmd/github-mcp-server/main.go.

HTTP Mode (Production)

For network-accessible deployments, use the http subcommand to expose the server on port 8082:

docker run -i --rm \
  -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_PAT \
  -p 8082:8082 \
  ghcr.io/github/github-mcp-server http \
  --port 8082

Command breakdown:

  • -i keeps STDIN open for JSON-RPC communication
  • --rm removes the container after stopping
  • -e GITHUB_PERSONAL_ACCESS_TOKEN passes authentication to the server (read via viper.GetString("personal_access_token"))
  • -p 8082:8082 maps the internal port to your host
  • http invokes the HTTP server defined in pkg/http/server.go

stdio Mode (Local Development)

For local testing or integration with hosts expecting standard I/O communication:

docker run -i --rm \
  -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_PAT \
  ghcr.io/github/github-mcp-server stdio

Since CMD ["stdio"] is the default entrypoint in the Dockerfile, you can omit the subcommand:

docker run -i --rm \
  -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_PAT \
  ghcr.io/github/github-mcp-server

Configuration and Environment Variables

The server uses Viper for configuration management, mapping environment variables to command flags. Set these via -e flags in your docker run commands:

Environment Variable Purpose Source Reference
GITHUB_PERSONAL_ACCESS_TOKEN Authentication for GitHub API calls main.go (initConfig)
GITHUB_TOOLSETS Comma-separated list of enabled tools (default: context,repos,issues,pull_requests,users) main.go
GITHUB_READ_ONLY Boolean to disable write operations Flag parsing in main.go
GITHUB_DYNAMIC_TOOLSETS Enables runtime toolset discovery tools Tool configuration

Example with custom toolsets and read-only mode:

docker run -i --rm \
  -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_PAT \
  -e GITHUB_TOOLSETS="repos,issues,actions,code_security" \
  -e GITHUB_READ_ONLY=true \
  ghcr.io/github/github-mcp-server http

Docker Compose Configuration

For persistent deployments, use this docker-compose.yml structure:

version: "3.9"
services:
  github-mcp-server:
    image: ghcr.io/github/github-mcp-server
    container_name: github-mcp-server
    restart: unless-stopped
    environment:
      GITHUB_PERSONAL_ACCESS_TOKEN: ${GITHUB_PAT}
      GITHUB_TOOLSETS: "repos,issues,pull_requests"
      GITHUB_DYNAMIC_TOOLSETS: "true"
    ports:
      - "8082:8082"
    command: http --port 8082

Start with: docker-compose up -d

Verifying Your Deployment

Confirm the server is running correctly by checking the embedded version metadata:

docker run -i --rm \
  -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_PAT \
  ghcr.io/github/github-mcp-server --version

Expected output includes the version, commit SHA, and build date injected during the Docker build process:


Version: dev
Commit: a1b2c3d4...
Build Date: 2024-07-30T12:34:56Z

For HTTP mode, verify connectivity by checking port 8082 responds to MCP protocol requests.

Summary

  • The GitHub MCP server is distributed as a multi-stage Docker image at ghcr.io/github/github-mcp-server using a distroless runtime for security
  • Authentication requires setting the GITHUB_PERSONAL_ACCESS_TOKEN environment variable parsed by Viper in cmd/github-mcp-server/main.go
  • Two execution modes exist: stdio for local JSON-RPC over standard I/O (default), and http for network-accessible deployments on port 8082
  • Configuration happens via environment variables that map to Cobra flags, including toolset selection and read-only restrictions
  • The Dockerfile embeds build metadata via Go ldflags and deploys to gcr.io/distroless/base-debian12 to minimize attack surface

Frequently Asked Questions

What is the difference between stdio and http modes in the GitHub MCP server?

stdio mode runs the server over standard input/output using JSON-RPC, which is ideal for local development and integration with VS Code or other editors that spawn the container as a subprocess. http mode exposes the server as a web service on port 8082 (defined in pkg/http/server.go), making it suitable for remote deployments or microservice architectures where the MCP client connects over TCP/IP.

How do I securely handle the GitHub Personal Access Token in Docker?

Never hardcode your PAT in docker run commands stored in shell history. Instead, use Docker secrets, environment files, or your shell's variable substitution (e.g., -e GITHUB_PERSONAL_ACCESS_TOKEN=$GITHUB_PAT). For Docker Compose, reference the variable in your .env file and ensure the file has restricted permissions (0600). The token is read by the Viper configuration in cmd/github-mcp-server/main.go and passed to the GitHub API client.

Can I customize which GitHub tools are available in the container?

Yes. Set the GITHUB_TOOLSETS environment variable to a comma-separated list of enabled categories. Available toolsets include context, repos, issues, pull_requests, users, actions, and code_security. This configuration is parsed in the initConfig function of main.go and controls which handlers are registered in the server. You can also enable GITHUB_DYNAMIC_TOOLSETS=true to expose helper tools that list available capabilities at runtime.

Why does the Docker image use a distroless base?

The distroless image (gcr.io/distroless/base-debian12) contains only the Go runtime and the compiled github-mcp-server binary, removing package managers, shells, and unnecessary system libraries. This significantly reduces the attack surface and image size compared to Alpine or Debian bases. As defined in the Dockerfile, the final stage copies only the binary to /server/github-mcp-server and sets it as the entrypoint, ensuring the container runs with minimal privileges.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →