github-mcp

leelakanakala/github-mcp
0 starsCommunity

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

A production-ready MCP server providing all 26 official GitHub tools, deployed on Cloudflare Workers with GitHub OAuth 2.0 authentication.

README.md

GitHub MCP Server on Cloudflare Workers

![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/?url=https://github.com/leelakanakala/github-mcp)

A production-ready Model Context Protocol (MCP) server providing all 26 official GitHub tools, deployed on Cloudflare Workers with GitHub OAuth 2.0 authentication.

Features

  • All 26 official GitHub tools — files, repos, issues, PRs, search, commits
  • GitHub OAuth 2.0 — per-user authentication, no shared API keys
  • Cloudflare Workers — global edge deployment, serverless, auto-scaling
  • Durable Objects — stateful per-user sessions with encrypted token storage
  • Cloudflare Access ready — optional team-level authentication layer
  • Security — CSRF protection, state validation, secure cookies, Zod input validation

Compared to the Official GitHub MCP Server

| Feature | Official Server | This Server | |---------|----------------|-------------| | Deployment | Local process | Cloudflare Workers (global) | | Auth | PAT (long-lived) | OAuth (short-lived, per-user) | | Transport | STDIO | HTTP + SSE | | Multi-user | No | Yes (Durable Objects) | | Access Control | N/A | Cloudflare Access integration | | Scalability | One user | Unlimited users |

Quick Start

1. Install Dependencies

npm install

2. Login to Cloudflare

npx wrangler login
npx wrangler whoami  # Note your subdomain (e.g., yourname.workers.dev)

3. Create GitHub OAuth Apps

Go to https://github.com/settings/developers and create two OAuth Apps:

Production:

  • Homepage URL: https://github-mcp-server.<your-subdomain>.workers.dev
  • Callback URL: https://github-mcp-server.<your-subdomain>.workers.dev/callback

Development:

  • Homepage URL: http://localhost:8788
  • Callback URL: http://localhost:8788/callback

Note the Client ID and Client Secret for each.

4. Configure Local Environment

cp .dev.vars.example .dev.vars
openssl rand -hex 32  # Generate encryption key

Edit .dev.vars with your development credentials: `` GITHUB_CLIENT_ID=your_dev_client_id GITHUB_CLIENT_SECRET=your_dev_client_secret COOKIE_ENCRYPTION_KEY=your_generated_key ``

5. Create KV Namespace

npx wrangler kv namespace create "OAUTH_KV"

Copy the id from the output into wrangler.jsonc: ``jsonc "kv_namespaces": [ { "binding": "OAUTH_KV", "id": "your_kv_namespace_id" } ] ``

Also update account_id in wrangler.jsonc with your Cloudflare account ID.

6. Test Locally

npm run dev

Visit http://localhost:8788. Test with MCP Inspector: ``bash npx @modelcontextprotocol/inspector@latest ` Enter http://localhost:8788/sse` and click Connect.

7. Deploy to Production

npx wrangler secret put GITHUB_CLIENT_ID       # Paste PRODUCTION client ID
npx wrangler secret put GITHUB_CLIENT_SECRET    # Paste PRODUCTION client secret
npx wrangler secret put COOKIE_ENCRYPTION_KEY   # Paste encryption key

npm run deploy

Your server will be live at https://github-mcp-server.<your-subdomain>.workers.dev.

Usage

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://github-mcp-server.<your-subdomain>.workers.dev/sse"
      ]
    }
  }
}

Restart Claude Desktop. A browser window will open for GitHub OAuth on first use.

Cursor

In Cursor settings, add: `` Type: Command Command: npx -y mcp-remote https://github-mcp-server.<your-subdomain>.workers.dev/sse ``

MCP Inspector

npx @modelcontextprotocol/inspector@latest

Enter your server URL: https://github-mcp-server.<your-subdomain>.workers.dev/sse

Tools

All 26 official GitHub MCP tools are included:

| Category | Tools | |----------|-------| | Files (3) | create_or_update_file, push_files, get_file_contents | | Repos (4) | search_repositories, create_repository, fork_repository, create_branch | | Issues (5) | create_issue, list_issues, update_issue, add_issue_comment, get_issue | | PRs (10) | create_pull_request, list_pull_requests, get_pull_request, merge_pull_request, create_pull_request_review, get_pull_request_files, get_pull_request_status, update_pull_request_branch, get_pull_request_comments, get_pull_request_reviews | | Search (3) | search_code, search_issues, search_users | | Commits (1) | list_commits |

For full parameter details and examples, see TOOLS.md.

Cloudflare Access (Optional)

Add a team-level authentication layer in front of the server. See CLOUDFLARE_ACCESS.md for the full setup guide.

The dual-auth flow:

  1. Cloudflare Access — "Can this person access the server?" (email, SSO, GitHub org, etc.)
  2. GitHub OAuth — "What can they do on GitHub?" (operates with the user's own permissions)

Project Structure

github-mcp-server/
├── src/
│   ├── index.ts                 # Main MCP server with all 26 tools
│   ├── github-handler.ts        # OAuth authorization flow
│   ├── utils.ts                 # GitHub OAuth utilities
│   ├── workers-oauth-utils.ts   # Security & CSRF protection
│   └── types.ts                 # TypeScript types
├── wrangler.jsonc               # Cloudflare Workers config
├── package.json                 # Dependencies
├── tsconfig.json                # TypeScript config
├── .dev.vars.example            # Local environment template
├── TOOLS.md                     # Complete tools reference
└── CLOUDFLARE_ACCESS.md         # Access integration guide

Key Dependencies

  • @cloudflare/workers-oauth-provider — OAuth 2.1 server
  • agents — MCP with Durable Objects
  • hono — Web framework
  • octokit — GitHub API client
  • zod — Schema validation

Adding Custom Tools

Edit src/index.ts:

this.server.tool(
  "my_custom_tool",
  "Description of what it does",
  {
    param1: z.string().describe("Parameter description"),
  },
  async ({ param1 }) => {
    const octokit = new Octokit({ auth: this.props!.accessToken });
    // Your implementation
    return {
      content: [{ type: "text", text: "Result" }]
    };
  }
);

Development Commands

npm run dev          # Local development server (http://localhost:8788)
npm run deploy       # Deploy to Cloudflare Workers
npm run type-check   # TypeScript type checking
npx wrangler tail    # View live production logs
npx wrangler secret list  # Verify secrets are set

Troubleshooting

| Problem | Solution | |---------|----------| | "Not logged in" | Run npx wrangler login | | Certificate errors | export NODE_TLS_REJECT_UNAUTHORIZED=0 (dev only) | | OAuth redirect fails | Verify callback URLs match exactly in GitHub OAuth app settings | | KV namespace not found | Ensure id in wrangler.jsonc matches npx wrangler kv namespace create "OAUTH_KV" output | | Tools not showing | Check npx wrangler tail logs, verify GitHub token scopes, restart your MCP client | | Access token expired | Clear browser cookies for your worker domain, re-authenticate |

Cost

| Service | Free Tier | Paid | |---------|-----------|------| | Workers | 100K requests/day | $5/mo for 10M requests | | Durable Objects | 1M operations/month | $0.15/million | | KV | 100K reads/day | $0.50/million reads | | Access | Up to 50 users | $3/user/month |

For typical personal/team use, the free tier is sufficient.

GitHub API Scopes

The server requests: repo, read:user, read:org. Users grant these during OAuth.

Resources

License

MIT

Related MCP servers

Browse all →