GitHub (MCP)¶
The GitHub MCP server provides access to GitHub repositories, pull requests, issues, and GitHub Actions. It enables Holmes to investigate CI/CD failures, search code, review changes, and delegate tasks to GitHub Copilot.
Overview¶
Holmes supports two authentication methods for GitHub. Both deploy a self-hosted MCP server pod in your cluster that wraps the official GitHub MCP server:
- Personal Access Token (PAT): Uses the standard
github-mcpimage. The PAT is passed directly to the MCP server. - GitHub App: Uses the
github-app-mcpimage which automatically generates and caches short-lived installation tokens from GitHub App credentials. One App installed on several organizations can be served from a single deployment via multi-organization support (alpha).
Both methods support GitHub.com and GitHub Enterprise Server.
Prerequisites¶
Before deploying the GitHub MCP server, you need a GitHub Personal Access Token (PAT). GitHub offers two types of PATs:
| Type | Best For | Expiration |
|---|---|---|
| Classic | Simple setup, broad access | Up to no expiration |
| Fine-grained | Production, least-privilege | Max 1 year |
Write permissions are optional
Write permissions (for Contents, Issues, Pull requests, Actions) are only required if you want HolmesGPT to be able to open PRs, create issues, or trigger workflows. For read-only investigations, read permissions are sufficient.
- Go to github.com/settings/tokens
- Click Generate new token → Generate new token (classic)
- Set a descriptive name (e.g., "Holmes MCP Server")
- Set expiration (90 days recommended)
- Select the following scopes:
- ✅ repo - Full control of private repositories
- ✅ workflow - Update GitHub Action workflows
- ✅ read:org - Read organization membership (optional)
- Click Generate token
- Copy the token immediately - it won't be shown again
- Go to github.com/settings/tokens?type=beta
- Click Generate new token
- Set a descriptive name and expiration
- Under Resource owner, select your organization or personal account
- Under Repository access, choose:
- All repositories, or
- Only select repositories (for restricted access)
- Under Permissions → Repository permissions, set:
- Actions: Read and write (to view and trigger workflows)
- Contents: Read and write (to push code changes)
- Commit statuses: Read-only
- Issues: Read and write (to create issues and delegate to Copilot)
- Pull requests: Read and write (to create PRs and request reviews)
- Metadata: Read-only (automatically selected)
- Click Generate token
- Copy the token immediately - it won't be shown again
Configuration¶
Using a Personal Access Token¶
For CLI usage, you need to deploy the GitHub MCP server first, then configure Holmes to connect to it.
Step 1: Create the GitHub PAT Secret
First, create a namespace and secret for the GitHub MCP server:
kubectl create namespace holmes-mcp
kubectl create secret generic github-mcp-token \
--from-literal=token=<YOUR_GITHUB_PAT> \
-n holmes-mcp
Step 2: Deploy the GitHub MCP Server
Create a file named github-mcp-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: github-mcp-server
namespace: holmes-mcp
spec:
replicas: 1
selector:
matchLabels:
app: github-mcp-server
template:
metadata:
labels:
app: github-mcp-server
spec:
containers:
- name: github-mcp
image: me-west1-docker.pkg.dev/robusta-development/development/github-mcp:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
name: http
env:
- name: GITHUB_PERSONAL_ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: github-mcp-token
key: token
# Uncomment for GitHub Enterprise:
# - name: GITHUB_HOST
# value: "https://github.mycompany.com"
# For self-signed certs, see "SSL Certificate Verification Errors" in Troubleshooting.
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
readinessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 10
periodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: github-mcp-server
namespace: holmes-mcp
spec:
selector:
app: github-mcp-server
ports:
- port: 8000
targetPort: 8000
protocol: TCP
name: http
Deploy it to your cluster:
Step 3: Configure Holmes CLI
Add the MCP server configuration to ~/.holmes/config.yaml:
mcp_servers:
github:
description: "GitHub MCP Server - access repositories, pull requests, issues, and GitHub Actions"
config:
url: "http://github-mcp-server.holmes-mcp.svc.cluster.local:8000/sse"
mode: "sse"
Step 4: Port Forwarding (Optional for Local Testing)
If running Holmes CLI locally and need to access the MCP server:
Then update the URL in config.yaml to:
Basic Configuration
First, create a Kubernetes secret with your GitHub PAT:
kubectl create secret generic github-mcp-token \
--from-literal=token=<YOUR_GITHUB_PAT> \
-n <NAMESPACE>
Then add the following to your values.yaml:
GitHub Enterprise Configuration
For GitHub Enterprise Server, add the host configuration:
mcpAddons:
github:
enabled: true
auth:
secretName: "github-mcp-token"
config:
host: "https://github.mycompany.com"
Then deploy or upgrade your Holmes installation:
Basic Configuration
First, create a Kubernetes secret with your GitHub PAT:
kubectl create secret generic github-mcp-token \
--from-literal=token=<YOUR_GITHUB_PAT> \
-n <NAMESPACE>
Then add the following to your generated_values.yaml:
GitHub Enterprise Configuration
holmes:
mcpAddons:
github:
enabled: true
auth:
secretName: "github-mcp-token"
config:
host: "https://github.mycompany.com"
Then deploy or upgrade your Robusta installation:
Using a GitHub App¶
Instead of a Personal Access Token, you can authenticate using a GitHub App. This deploys the github-app-mcp image which wraps the official GitHub MCP server with automatic installation token generation and caching — including support for a single App installed on multiple organizations (see "Multi-organization support" below).
Step 1: Create a GitHub App
Follow Creating a GitHub App with these settings:
- GitHub App name: e.g., "Holmes MCP"
- Homepage URL: any valid URL
- Webhook: uncheck "Active" (not needed)
- Permissions → Repository permissions:
- Actions: Read-only
- Contents: Read-only (or Read and write if Holmes should push code)
- Commit statuses: Read-only
- Issues: Read and write
- Metadata: Read-only
- Pull requests: Read and write
- Click Create GitHub App
Step 2: Generate a private key
On the App settings page, scroll to Private keys and click Generate a private key. A .pem file will be downloaded. See Managing private keys for details.
Step 3: Install the App
Install the App on your organization or repositories:
- Go to the App settings → Install App
- Select the account/organization
- Choose All repositories or Only select repositories
- Click Install
Note the Installation ID from the URL after installation: https://github.com/settings/installations/<INSTALLATION_ID> (on GitHub Enterprise Server, the same path on your own host). See Authenticating as a GitHub App installation for more details.
To reach more than one organization from a single deployment, see Multi-organization support (alpha).
Step 4: Note the App ID
Find the App ID on the App's settings page (under "About").
Step 5: Configure Holmes
For CLI usage, deploy the github-app-mcp server in your cluster and connect Holmes to it.
Create the Kubernetes secret:
kubectl create namespace holmes-mcp # if not already created
kubectl create secret generic holmes-github-app \
--from-literal=GITHUB_APP_ID=<YOUR_APP_ID> \
--from-literal=GITHUB_APP_INSTALLATION_ID=<YOUR_INSTALLATION_ID> \
--from-file=GITHUB_APP_PRIVATE_KEY=/path/to/private-key.pem \
-n holmes-mcp
Deploy the GitHub App MCP server:
apiVersion: apps/v1
kind: Deployment
metadata:
name: github-mcp-server
namespace: holmes-mcp
spec:
replicas: 1
selector:
matchLabels:
app: github-mcp-server
template:
metadata:
labels:
app: github-mcp-server
spec:
containers:
- name: github-mcp
# For multi-org (alpha) use github-app-mcp:2.0.0 and drop the args below
image: us-central1-docker.pkg.dev/genuine-flight-317411/mcp/github-app-mcp:1.0.7
ports:
- containerPort: 8000
args:
- "--stdio"
- "python3 /app/wrapper.py"
- "--port"
- "8000"
- "--outputTransport"
- "streamableHttp"
env:
- name: GITHUB_APP_ID
valueFrom:
secretKeyRef:
name: holmes-github-app
key: GITHUB_APP_ID
- name: GITHUB_APP_INSTALLATION_ID
valueFrom:
secretKeyRef:
name: holmes-github-app
key: GITHUB_APP_INSTALLATION_ID
- name: GITHUB_APP_PRIVATE_KEY
valueFrom:
secretKeyRef:
name: holmes-github-app
key: GITHUB_APP_PRIVATE_KEY
Then add the MCP server to ~/.holmes/config.yaml:
Create the Kubernetes secret:
kubectl create secret generic holmes-github-app \
--from-literal=GITHUB_APP_ID=<YOUR_APP_ID> \
--from-literal=GITHUB_APP_INSTALLATION_ID=<YOUR_INSTALLATION_ID> \
--from-file=GITHUB_APP_PRIVATE_KEY=/path/to/private-key.pem \
-n <NAMESPACE>
Add to your values.yaml:
A self-hosted MCP server pod is deployed using the github-app-mcp image, which generates and caches installation tokens internally.
Create the Kubernetes secret:
kubectl create secret generic holmes-github-app \
--from-literal=GITHUB_APP_ID=<YOUR_APP_ID> \
--from-literal=GITHUB_APP_INSTALLATION_ID=<YOUR_INSTALLATION_ID> \
--from-file=GITHUB_APP_PRIVATE_KEY=/path/to/private-key.pem \
-n <NAMESPACE>
Add to your generated_values.yaml:
A self-hosted MCP server pod is deployed using the github-app-mcp image, which generates and caches installation tokens internally.
Multi-organization support (alpha)¶
A GitHub App installation token is scoped to a single installation — one organization or user account — so by default the server serves the one installation named by GITHUB_APP_INSTALLATION_ID.
Setting multiOrg: true switches to the alpha github-app-mcp:2.0.0 image, which serves every organization the App is installed on from one deployment:
mcpAddons:
github:
enabled: true
auth:
githubApp:
secretName: "holmes-github-app"
multiOrg: true # alpha
- Install the same App on every organization or user account Holmes should reach, and omit
GITHUB_APP_INSTALLATION_IDfrom the secret. - The server discovers all installations at startup, and re-checks whenever a request names an organization it hasn't seen, so installing the App on a new organization requires no restart or config change.
- Each tool call is routed to the right organization's credentials based on the
owner/orgit targets. - Requests that don't name an owner — and owners the App isn't installed on — use the first discovered installation.
- Keeping
GITHUB_APP_INSTALLATION_IDin the secret pins the server to that one installation even withmultiOrg: true.
Alpha
Multi-org routing is not covered by the stable release. Leave multiOrg unset to keep the single-organization image, which is unchanged.
Restart after editing the secret
The pod only re-reads the secret on start, and the deployment's checksum tracks Helm values rather than secret contents. After adding or removing GITHUB_APP_INSTALLATION_ID, roll the pod so the change takes effect:
How token management works
The github-app-mcp image handles token management internally:
- Generates a JWT signed with the App's private key
- Exchanges it for a short-lived (1 hour) installation token, on demand
- Injects the token into each request to the underlying MCP server
- Caches each token and mints a fresh one when it is within 5 minutes of expiry
Available Tools¶
By default, the GitHub MCP server enables 4 toolsets that provide comprehensive access to GitHub functionality:
| Toolset | Tools | Description |
|---|---|---|
repos |
~24 | Repository operations, file access, commits, branches, code search |
issues |
~11 | Issue management, labels, comments, Copilot delegation |
pull_requests |
~10 | PR operations, reviews, comments, merging |
actions |
~14 | Workflow runs, job logs, artifacts, CI/CD management |
Key Tools by Category¶
Repository & Code:
get_file_contents- Get contents of a file in a repositoryget_repository_tree- Get the file/directory structurelist_commits/get_commit- View commit history and detailssearch_code/search_repositories- Search across GitHub
Pull Requests:
list_pull_requests/pull_request_read- View PR details, diffs, reviewscreate_pull_request- Create new pull requestscreate_branch/push_files- Create branches and push changesrequest_copilot_review- Request Copilot to review a PR
GitHub Actions:
list_workflows- List workflow definitionslist_workflow_runs/get_workflow_run- View workflow run statusget_workflow_run_logs/get_job_logs- Get CI/CD logs for debugging
Issues & Copilot:
list_issues/search_issues- Find and view issuesissue_write/add_issue_comment- Create and update issuesassign_copilot_to_issue- Delegate tasks to GitHub Copilot
Customizing Toolsets¶
HolmesGPT exposes two config knobs that control which tools the MCP server makes available:
config.toolsets— comma-separated list of toolset groups. Every tool in each selected group becomes available.config.tools— comma-separated list of individual tool names. When set, this is a hard allowlist and takes precedence overtoolsets(Holmes only gets exactly these tools regardless of what toolsets are configured). Leave empty to expose every tool from the selected toolsets.
Example — restrict by toolset group:
mcpAddons:
github:
enabled: true
auth:
secretName: "github-mcp-token"
config:
# Only enable specific toolsets
toolsets: "pull_requests,actions"
Example — restrict to specific tools (bypasses toolsets):
mcpAddons:
github:
enabled: true
auth:
secretName: "github-mcp-token"
config:
# `tools` is a hard allowlist — `toolsets` is ignored when this is set.
tools: "get_file_contents,list_commits,list_workflow_runs,get_job_logs"
For the full list of available tools and toolsets, see the GitHub MCP Server documentation.
Testing the Connection¶
After deploying the GitHub MCP server, verify it's working:
Test 1: Check Pod Status¶
# For Helm deployments
kubectl get pods -n YOUR_NAMESPACE -l app.kubernetes.io/name=github-mcp-server
# For manual CLI deployments
kubectl get pods -n holmes-mcp -l app=github-mcp-server
Test 2: Check Logs¶
# For Helm deployments
kubectl logs -n YOUR_NAMESPACE -l app.kubernetes.io/name=github-mcp-server
# For manual CLI deployments
kubectl logs -n holmes-mcp -l app=github-mcp-server
Test 3: Ask Holmes¶
Common Use Cases¶
- "The CI build failed on PR #123 in myorg/myrepo. What went wrong?"
- "What changes were made to the authentication module in the last week?"
- "Find all usages of the deprecated API endpoint /v1/users in our codebase"
- "Create an issue to add retry logic to the payment service and assign it to Copilot"
Troubleshooting¶
Authentication Issues¶
Problem: Pod logs show authentication errors
Solution: Verify the secret exists and contains a valid PAT
# Check secret exists
kubectl get secret github-mcp-token -n YOUR_NAMESPACE
# Verify PAT has correct permissions (test locally with your token)
curl -H "Authorization: token <YOUR_GITHUB_PAT>" https://api.github.com/user
Rate Limiting¶
Problem: Getting 403 rate limit errors
Solution: GitHub has API rate limits (5000 requests/hour for authenticated requests). If you're hitting limits:
- Reduce the frequency of investigations
- Use a GitHub App instead of PAT for higher limits
- Consider using multiple PATs for different repositories
GitHub Enterprise Connection Issues¶
Problem: Can't connect to GitHub Enterprise Server
Solutions:
- Verify the hostname is correct and accessible from the cluster
- Check if SSL certificates are valid
- Ensure network policies allow egress to your GitHub Enterprise Server
# Test connectivity from the pod
kubectl exec -n YOUR_NAMESPACE deployment/github-mcp-server -- \
curl -I https://github.mycompany.com/api/v3
SSL Certificate Verification Errors¶
Problem: Getting SSL certificate verification errors when connecting to GitHub Enterprise with self-signed or internal CA certificates
Solution: Provide your organization's CA certificate to properly validate the connection:
Step 1: Create a Kubernetes secret with your CA certificate:
kubectl create secret generic github-ca-cert \
--from-file=ca.crt=/path/to/your/ca-certificate.crt \
-n <NAMESPACE>
Step 2: Configure the GitHub MCP addon to use the CA certificate:
Add volume, volumeMount, and environment variables to your deployment:
spec:
containers:
- name: github-mcp
env:
- name: GITHUB_PERSONAL_ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: github-mcp-token
key: token
- name: GITHUB_HOST
value: "https://github.mycompany.com"
- name: SSL_CERT_FILE
value: /etc/ssl/certs/ca.crt
- name: SSL_CERT_DIR
value: /etc/ssl/certs
volumeMounts:
- name: ca-cert
mountPath: /etc/ssl/certs
readOnly: true
volumes:
- name: ca-cert
secret:
secretName: github-ca-cert
defaultMode: 420
Tool Not Found Errors¶
Problem: Holmes reports a tool is not available
Solution: Verify the config.toolsets setting includes the toolset containing your tool. The default toolsets are repos,issues,pull_requests,actions. For individual tool control, use config.tools.