GitHub MCP Server with HTTP streamable transport and OAuth support
988
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.
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:
repo scope but block create_repository tool)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.
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:
Authorization: Bearer <token> headers to each requestThe 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
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
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.
For detailed information about specific features and deployment scenarios, see:
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.
The following sets of tools are available (all are on by default):
| Toolset | Description |
|---|---|
context | Strongly recommended: Tools that provide context about the current user and GitHub context you are operating in |
actions | GitHub Actions workflows and CI/CD operations |
code_security | Code security related tools, such as GitHub Code Scanning |
dependabot | Dependabot tools |
discussions | GitHub Discussions related tools |
experiments | Experimental features that are not considered stable yet |
gists | GitHub Gist related tools |
issues | GitHub Issues related tools |
notifications | GitHub Notifications related tools |
orgs | GitHub Organization related tools |
projects | GitHub Projects related tools |
pull_requests | GitHub Pull Request related tools |
repos | GitHub Repository related tools |
secret_protection | Secret protection related tools, such as GitHub Secret Scanning |
security_advisories | Security advisories related tools |
users | GitHub User related tools |
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)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)get_me - Get my user profile
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)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)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)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)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)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 notificatioContent type
Image
Digest
sha256:3b6022603…
Size
14.1 MB
Last updated
12 months ago
docker pull nickytonline/github-mcp-http