Sign inSign up

nickytonline/github-mcp-http

By nickytonline

Updated 12 months ago

GitHub MCP Server with HTTP streamable transport and OAuth support

Image
0

988

nickytonline/github-mcp-http repository overview

GitHub MCP Server - HTTP Streamable Transport

This is a fork of the official GitHub MCP Server. The official version only supports stdio transport. This fork implements HTTP streamable transport with per-request OAuth authentication for self-hosted enterprise deployments.

Why This Fork?

GitHub offers a closed-source hosted HTTP MCP server with OAuth, but it cannot be self-hosted. The official open-source server only supports stdio with single-user PATs. This fork bridges the gap by providing:

  • Self-Hosted HTTP + OAuth - Get the benefits of GitHub's hosted server (HTTP transport, multi-user OAuth) while maintaining full control over your deployment
  • Multi-User Support - Different users authenticate with their own GitHub credentials via OAuth
  • Zero-Trust Deployments - Run behind proxies like Pomerium that handle OAuth flows and inject tokens per-request
  • Stateless Architecture - No token storage or OAuth complexity in the MCP server; a proxy, like Pomerium manages all OAuth flows, token refresh, and sessions
  • Fine-Grained Authorization - Pomerium policies can control access to individual MCP tools beyond OAuth scopes (e.g., allow repo scope but block create_repository tool)
  • Audit & Compliance - Every GitHub API call is attributable to a specific authenticated user

Architecture

This fork uses an external OAuth proxy (Pomerium) to handle authentication and inject GitHub OAuth tokens into each request:

sequenceDiagram
 actor U as User
 participant C as MCP Client
 participant O as GitHub OAuth
 participant P as Pomerium
 participant S as MCP Server
 U ->> C: Adds server URL
 C ->> P: Registers client, initiates auth
 P ->> C: Sign-in URL
 C ->> U: Redirect to sign-in URL
 U ->> P: Sign-in
 P ->> U: Redirect to GitHub OAuth
 U ->> O: Authenticate with GitHub
 O ->> P: Return GitHub Token
 P ->> C: Redirect to client
 C ->> P: Obtain External Token (TE)
 C ->> P: GET https://mcp-server Authorization: Bearer (TE)
 P ->> O: Refresh GitHub token if necessary
 P ->> S: Proxy request to MCP Server with GitHub token

The MCP server receives GitHub tokens from Pomerium and uses them to make API calls on behalf of authenticated users. All OAuth flows, token refresh, and session management happen in Pomerium - the MCP server is stateless.


Quick Start

Prerequisites
Build from source
go build -o github-mcp-http ./cmd/github-mcp-http
./github-mcp-http http --listen :8080

Important: This server does NOT manage OAuth tokens. It requires an external OAuth proxy (like Pomerium) to:

  1. Handle GitHub OAuth flows - Configure a GitHub OAuth App in your GitHub organization
  2. Manage token lifecycle - Handle token acquisition, refresh, and expiration
  3. Inject tokens per-request - Add Authorization: Bearer <token> headers to each request
  4. Manage user sessions - Track user authentication state

The MCP server is purely a stateless token consumer - it receives tokens in request headers and uses them to call GitHub APIs. Unlike GitHub's closed-source remote server which manages tokens internally, this server delegates all token management to the gateway/proxy layer.

Production deployment with Pomerium:

Configure Pomerium with upstream OAuth to GitHub. See Pomerium's MCP with Upstream OAuth guide for complete setup instructions.

Example Pomerium route configuration:

routes:
  - from: https://mcp.example.com
    to: http://github-mcp-http:8080

    # Pomerium handles GitHub OAuth and injects tokens
    upstream_oauth2:
      client_id: ${GITHUB_OAUTH_CLIENT_ID}
      client_secret: ${GITHUB_OAUTH_CLIENT_SECRET}
      scopes:
        - read:user
        - user:email
        - repo
        - read:org
      endpoint:
        auth_url: https://github.com/login/oauth/authorize
        token_url: https://github.com/login/oauth/access_token
Docker

The MCP server is available on Docker Hub and GitHub Container Registry:

docker pull nickytonline/github-mcp-http:1
# Or from GitHub Container Registry:
# docker pull ghcr.io/nickytonline/github-mcp-server:1
Docker Compose
services:
  github-mcp:
    image: nickytonline/github-mcp-http:1
    # Or from GitHub Container Registry:
    # image: ghcr.io/nickytonline/github-mcp-server:1
    # Or build from source:
    # build:
    #   context: https://github.com/nickytonline/github-mcp-http.git
    #   dockerfile: Dockerfile
    pull_policy: always
    container_name: github-mcp
    restart: unless-stopped
    networks:
      - main

networks:
  main:

Note: This example shows only the MCP server. You'll need to add Pomerium to the same compose file with the upstream OAuth configuration shown above. See docs/pomerium-example.md for a complete reference configuration with both services.


Additional Documentation

For detailed information about specific features and deployment scenarios, see:


Tool Configuration

This fork inherits all toolset configuration options from the official GitHub MCP Server. The server supports enabling or disabling specific groups of functionalities via the --toolsets flag. This allows you to control which GitHub API capabilities are available to your AI tools. Enabling only the toolsets that you need can help the LLM with tool choice and reduce the context size.

Toolsets are not limited to Tools. Relevant MCP Resources and Prompts are also included where applicable.

Available Toolsets

The following sets of tools are available (all are on by default):

ToolsetDescription
contextStrongly recommended: Tools that provide context about the current user and GitHub context you are operating in
actionsGitHub Actions workflows and CI/CD operations
code_securityCode security related tools, such as GitHub Code Scanning
dependabotDependabot tools
discussionsGitHub Discussions related tools
experimentsExperimental features that are not considered stable yet
gistsGitHub Gist related tools
issuesGitHub Issues related tools
notificationsGitHub Notifications related tools
orgsGitHub Organization related tools
projectsGitHub Projects related tools
pull_requestsGitHub Pull Request related tools
reposGitHub Repository related tools
secret_protectionSecret protection related tools, such as GitHub Secret Scanning
security_advisoriesSecurity advisories related tools
usersGitHub User related tools

Tools

Actions
  • cancel_workflow_run - Cancel workflow run

    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • delete_workflow_run_logs - Delete workflow logs

    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • download_workflow_run_artifact - Download workflow artifact

    • artifact_id: The unique identifier of the artifact (number, required)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
  • get_job_logs - Get job logs

    • failed_only: When true, gets logs for all failed jobs in run_id (boolean, optional)
    • job_id: The unique identifier of the workflow job (required for single job logs) (number, optional)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • return_content: Returns actual log content instead of URLs (boolean, optional)
    • run_id: Workflow run ID (required when using failed_only) (number, optional)
    • tail_lines: Number of lines to return from the end of the log (number, optional)
  • get_workflow_run - Get workflow run

    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • get_workflow_run_logs - Get workflow run logs

    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • get_workflow_run_usage - Get workflow usage

    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • list_workflow_jobs - List workflow jobs

    • filter: Filters jobs by their completed_at timestamp (string, optional)
    • owner: Repository owner (string, required)
    • page: Page number for pagination (min 1) (number, optional)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • list_workflow_run_artifacts - List workflow artifacts

    • owner: Repository owner (string, required)
    • page: Page number for pagination (min 1) (number, optional)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • list_workflow_runs - List workflow runs

    • actor: Returns someone's workflow runs. Use the login for the user who created the workflow run. (string, optional)
    • branch: Returns workflow runs associated with a branch. Use the name of the branch. (string, optional)
    • event: Returns workflow runs for a specific event type (string, optional)
    • owner: Repository owner (string, required)
    • page: Page number for pagination (min 1) (number, optional)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Repository name (string, required)
    • status: Returns workflow runs with the check run status (string, optional)
    • workflow_id: The workflow ID or workflow file name (string, required)
  • list_workflows - List workflows

    • owner: Repository owner (string, required)
    • page: Page number for pagination (min 1) (number, optional)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Repository name (string, required)
  • rerun_failed_jobs - Rerun failed jobs

    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • rerun_workflow_run - Rerun workflow run

    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • run_id: The unique identifier of the workflow run (number, required)
  • run_workflow - Run workflow

    • inputs: Inputs the workflow accepts (object, optional)
    • owner: Repository owner (string, required)
    • ref: The git reference for the workflow. The reference can be a branch or tag name. (string, required)
    • repo: Repository name (string, required)
    • workflow_id: The workflow ID (numeric) or workflow file name (e.g., main.yml, ci.yaml) (string, required)
Code Security
  • get_code_scanning_alert - Get code scanning alert

    • alertNumber: The number of the alert. (number, required)
    • owner: The owner of the repository. (string, required)
    • repo: The name of the repository. (string, required)
  • list_code_scanning_alerts - List code scanning alerts

    • owner: The owner of the repository. (string, required)
    • ref: The Git reference for the results you want to list. (string, optional)
    • repo: The name of the repository. (string, required)
    • severity: Filter code scanning alerts by severity (string, optional)
    • state: Filter code scanning alerts by state. Defaults to open (string, optional)
    • tool_name: The name of the tool used for code scanning. (string, optional)
Context
  • get_me - Get my user profile

    • No parameters required
  • get_team_members - Get team members

    • org: Organization login (owner) that contains the team. (string, required)
    • team_slug: Team slug (string, required)
  • get_teams - Get teams

    • user: Username to get teams for. If not provided, uses the authenticated user. (string, optional)
Dependabot
  • get_dependabot_alert - Get dependabot alert

    • alertNumber: The number of the alert. (number, required)
    • owner: The owner of the repository. (string, required)
    • repo: The name of the repository. (string, required)
  • list_dependabot_alerts - List dependabot alerts

    • owner: The owner of the repository. (string, required)
    • repo: The name of the repository. (string, required)
    • severity: Filter dependabot alerts by severity (string, optional)
    • state: Filter dependabot alerts by state. Defaults to open (string, optional)
Discussions
  • get_discussion - Get discussion

    • discussionNumber: Discussion Number (number, required)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
  • get_discussion_comments - Get discussion comments

    • after: Cursor for pagination. Use the endCursor from the previous page's PageInfo for GraphQL APIs. (string, optional)
    • discussionNumber: Discussion Number (number, required)
    • owner: Repository owner (string, required)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Repository name (string, required)
  • list_discussion_categories - List discussion categories

    • owner: Repository owner (string, required)
    • repo: Repository name. If not provided, discussion categories will be queried at the organisation level. (string, optional)
  • list_discussions - List discussions

    • after: Cursor for pagination. Use the endCursor from the previous page's PageInfo for GraphQL APIs. (string, optional)
    • category: Optional filter by discussion category ID. If provided, only discussions with this category are listed. (string, optional)
    • direction: Order direction. (string, optional)
    • orderBy: Order discussions by field. If provided, the 'direction' also needs to be provided. (string, optional)
    • owner: Repository owner (string, required)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Repository name. If not provided, discussions will be queried at the organisation level. (string, optional)
Gists
  • create_gist - Create Gist

    • content: Content for simple single-file gist creation (string, required)
    • description: Description of the gist (string, optional)
    • filename: Filename for simple single-file gist creation (string, required)
    • public: Whether the gist is public (boolean, optional)
  • list_gists - List Gists

    • page: Page number for pagination (min 1) (number, optional)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • since: Only gists updated after this time (ISO 8601 timestamp) (string, optional)
    • username: GitHub username (omit for authenticated user's gists) (string, optional)
  • update_gist - Update Gist

    • content: Content for the file (string, required)
    • description: Updated description of the gist (string, optional)
    • filename: Filename to update or create (string, required)
    • gist_id: ID of the gist to update (string, required)
Issues
  • add_issue_comment - Add comment to issue

    • body: Comment content (string, required)
    • issue_number: Issue number to comment on (number, required)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
  • add_sub_issue - Add sub-issue

    • issue_number: The number of the parent issue (number, required)
    • owner: Repository owner (string, required)
    • replace_parent: When true, replaces the sub-issue's current parent issue (boolean, optional)
    • repo: Repository name (string, required)
    • sub_issue_id: The ID of the sub-issue to add. ID is not the same as issue number (number, required)
  • assign_copilot_to_issue - Assign Copilot to issue

    • issueNumber: Issue number (number, required)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
  • create_issue - Open new issue

    • assignees: Usernames to assign to this issue (string[], optional)
    • body: Issue body content (string, optional)
    • labels: Labels to apply to this issue (string[], optional)
    • milestone: Milestone number (number, optional)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • title: Issue title (string, required)
    • type: Type of this issue (string, optional)
  • get_issue - Get issue details

    • issue_number: The number of the issue (number, required)
    • owner: The owner of the repository (string, required)
    • repo: The name of the repository (string, required)
  • get_issue_comments - Get issue comments

    • issue_number: Issue number (number, required)
    • owner: Repository owner (string, required)
    • page: Page number for pagination (min 1) (number, optional)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Repository name (string, required)
  • list_issue_types - List available issue types

    • owner: The organization owner of the repository (string, required)
  • list_issues - List issues

    • after: Cursor for pagination. Use the endCursor from the previous page's PageInfo for GraphQL APIs. (string, optional)
    • direction: Order direction. If provided, the 'orderBy' also needs to be provided. (string, optional)
    • labels: Filter by labels (string[], optional)
    • orderBy: Order issues by field. If provided, the 'direction' also needs to be provided. (string, optional)
    • owner: Repository owner (string, required)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Repository name (string, required)
    • since: Filter by date (ISO 8601 timestamp) (string, optional)
    • state: Filter by state, by default both open and closed issues are returned when not provided (string, optional)
  • list_sub_issues - List sub-issues

    • issue_number: Issue number (number, required)
    • owner: Repository owner (string, required)
    • page: Page number for pagination (default: 1) (number, optional)
    • per_page: Number of results per page (max 100, default: 30) (number, optional)
    • repo: Repository name (string, required)
  • remove_sub_issue - Remove sub-issue

    • issue_number: The number of the parent issue (number, required)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • sub_issue_id: The ID of the sub-issue to remove. ID is not the same as issue number (number, required)
  • reprioritize_sub_issue - Reprioritize sub-issue

    • after_id: The ID of the sub-issue to be prioritized after (either after_id OR before_id should be specified) (number, optional)
    • before_id: The ID of the sub-issue to be prioritized before (either after_id OR before_id should be specified) (number, optional)
    • issue_number: The number of the parent issue (number, required)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • sub_issue_id: The ID of the sub-issue to reprioritize. ID is not the same as issue number (number, required)
  • search_issues - Search issues

    • order: Sort order (string, optional)
    • owner: Optional repository owner. If provided with repo, only issues for this repository are listed. (string, optional)
    • page: Page number for pagination (min 1) (number, optional)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • query: Search query using GitHub issues search syntax (string, required)
    • repo: Optional repository name. If provided with owner, only issues for this repository are listed. (string, optional)
    • sort: Sort field by number of matches of categories, defaults to best match (string, optional)
  • update_issue - Edit issue

    • assignees: New assignees (string[], optional)
    • body: New description (string, optional)
    • duplicate_of: Issue number that this issue is a duplicate of. Only used when state_reason is 'duplicate'. (number, optional)
    • issue_number: Issue number to update (number, required)
    • labels: New labels (string[], optional)
    • milestone: New milestone number (number, optional)
    • owner: Repository owner (string, required)
    • repo: Repository name (string, required)
    • state: New state (string, optional)
    • state_reason: Reason for the state change. Ignored unless state is changed. (string, optional)
    • title: New title (string, optional)
    • type: New issue type (string, optional)
Notifications
  • dismiss_notification - Dismiss notification

    • state: The new state of the notification (read/done) (string, optional)
    • threadID: The ID of the notification thread (string, required)
  • get_notification_details - Get notification details

    • notificationID: The ID of the notification (string, required)
  • list_notifications - List notifications

    • before: Only show notifications updated before the given time (ISO 8601 format) (string, optional)
    • filter: Filter notifications to, use default unless specified. Read notifications are ones that have already been acknowledged by the user. Participating notifications are those that the user is directly involved in, such as issues or pull requests they have commented on or created. (string, optional)
    • owner: Optional repository owner. If provided with repo, only notifications for this repository are listed. (string, optional)
    • page: Page number for pagination (min 1) (number, optional)
    • perPage: Results per page for pagination (min 1, max 100) (number, optional)
    • repo: Optional repository name. If provided with owner, only notifications for this repository are listed. (string, optional)
    • since: Only show notifications updated after the given time (ISO 8601 format) (string, optional)
  • manage_notification_subscription - Manage notification subscription

    • action: Action to perform: ignore, watch, or delete the notification subscription. (string, required)
    • notificationID: The ID of the notification thread. (string, required)
  • manage_repository_notification_subscription - Manage repository notification subscription

    • action: Action to perform: ignore, watch, or delete the repository notification subscription. (string, required)
    • owner: The account owner of the repository. (string, required)
    • repo: The name of the repository. (string, required)
  • mark_all_notifications_read - Mark all notifications as read

    • lastReadAt: Describes the last point that notifications were checked (optional). Default: Now (string, optional)
    • owner: Optional repository owner. If provided with repo, only notificatio

Tag summary

Content type

Image

Digest

sha256:3b6022603

Size

14.1 MB

Last updated

12 months ago

docker pull nickytonline/github-mcp-http