| Slug | github-app |
| Category | DevOps |
| Maturity | Beta |
| Auth Type | GitHub App (PEM private key → RS256 JWT → installation access token) |
Summary
Full-surface MCP integration with the GitHub REST API and GraphQL API, authenticated as a GitHub App installation rather than a user. Lets a Prospector Studio agent walk and act on the repositories the App is installed on: list repos, manage issues and comments, list pull requests, manage labels, walk sub-issue hierarchies, and operate Projects v2 boards (items, fields, statuses).
The host owns the auth flow: it signs an RS256 JWT with the App's PEM private key (10-minute lifetime, iss = App ID), exchanges the JWT for an installation access token at POST /app/installations/{id}/access_tokens, and injects that token as the Authorization: Bearer … egress header. Refresh is automatic — installation tokens last one hour, and the host re-mints on expiry.
This plugin is read-write. It creates issues and comments, updates issues, mutates labels, adds and removes sub-issues, and adds/removes/updates Projects v2 items. Bind it to agents only when that level of authority is intended.
Capabilities
- Repositories — list repos accessible to the installation; list org repos; get repo details.
- Issues — list, get, create, update; list comments; add comments.
- Pull requests — list and get (read-only surface).
- Labels — list repo labels; add and remove labels via GraphQL (node IDs).
- Sub-issues — add and remove parent ↔ child relationships.
- Projects v2 — list org projects; get a project, its views, fields, and items; get a single item by ID; add and remove project items; update project item field values (status, dates, numbers, text).
- GraphQL
get_issue_detail— fetch an issue together with its sub-issues, parent, labels, assignees, and project items in a single round trip.
Required Headers
| Header | Required | Description |
|---|---|---|
X-GitHub-App-PEM |
yes | RSA private key (.pem contents) downloaded from GitHub App settings → General → Private keys. The host signs an RS256 JWT with this key — the raw PEM never leaves the host. |
X-GitHub-App-ID |
yes | Numeric App ID from GitHub App settings → General. Used as the JWT iss claim. |
X-GitHub-Installation-ID |
yes | Numeric installation ID for the org or user the App is installed on (find it in the URL of Org settings → GitHub Apps → Configure, e.g. …/installations/12345678). The host calls POST /app/installations/{id}/access_tokens to exchange the JWT for the installation token used on subsequent calls. |
Credential Permissions
GitHub App permissions are declared on the App itself (in the App's settings under Permissions & events) and granted at installation time to a specific repository scope (all repos in an org, or a selected list). The installation access token the host mints inherits exactly those declared permissions, intersected with the installations's repository selection — there is no per-token scope; the App's manifest is the contract.
Permissions are organized by resource (Issues, Pull requests, Contents, Metadata, Pages, Projects, Single file, etc.) and graded as Read, Read & write, or No access. For agent use, declare only the permissions the bound tools actually need. The minimum permission set for this plugin's tool surface is:
- Repository permissions → Metadata: Read (always required; gates
list_repos,get_repo,list_org_repos). - Issues: Read & write for issue CRUD, comments, sub-issues, and label changes on issues.
- Pull requests: Read for
list_pulls,get_pull. Bump to Read & write if you later add PR mutation tools. - Organization permissions → Projects: Read & write for the Projects v2 tools. Use Projects: Read if you only need to read boards.
For read-only agent behavior, set every permission to Read (Issues: Read, Pull requests: Read, Projects: Read) and skip the write-flavored tools when binding to the agent. Reduce blast radius further by installing the App on a curated repo list rather than "all repositories" — installation scope is enforced server-side and cannot be bypassed by the token.
References: Choosing permissions for a GitHub App · Authenticating as a GitHub App installation.
Allowed Hosts
api.github.com
Tools
The plugin advertises 27 MCP tools, organized by capability domain. The REST tools call GitHub's REST API (/repos/..., /orgs/...); the Projects v2, label-by-node-id, sub-issue, and get_issue_detail tools call GraphQL (POST /graphql).
Repositories
| Tool | Action | Surface | Purpose |
|---|---|---|---|
list_repos |
read | REST | Repos visible to the App installation. |
list_org_repos |
read | REST | Repos for an org with filter / sort. |
get_repo |
read | REST | Repository details by owner/repo. |
Issues & Comments
| Tool | Action | Surface | Purpose |
|---|---|---|---|
list_issues |
read | REST | List issues with state / label / assignee / sort filters. |
get_issue |
read | REST | Get an issue by number. |
create_issue |
write | REST | Create an issue (title, body, labels, assignees). |
update_issue |
write | REST | Update title / body / state / labels / assignees. |
list_issue_comments |
read | REST | List comments on an issue. |
create_issue_comment |
write | REST | Add a comment to an issue. |
get_issue_detail |
read | GraphQL | Issue + sub-issues + parent + labels + assignees + project items in one call. |
Pull Requests
| Tool | Action | Surface | Purpose |
|---|---|---|---|
list_pulls |
read | REST | List PRs with state / head / base / sort filters. |
get_pull |
read | REST | Get a PR by number. |
Labels & Sub-Issues
| Tool | Action | Surface | Purpose |
|---|---|---|---|
list_labels |
read | REST | List labels in a repo (use node_id for the GraphQL tools below). |
add_labels |
write | GraphQL | Add labels to an issue or PR by node IDs. |
remove_labels |
write | GraphQL | Remove labels from an issue or PR by node IDs. |
add_sub_issue |
write | GraphQL | Nest a child issue under a parent. |
remove_sub_issue |
write | GraphQL | Detach a child issue from its parent. |
Projects v2
| Tool | Action | Surface | Purpose |
|---|---|---|---|
list_org_projects |
read | GraphQL | List Projects v2 for an org. |
get_project |
read | GraphQL | Get a project by org + project number. |
get_project_views |
read | GraphQL | List boards / tables / roadmaps for a project. |
get_project_fields |
read | GraphQL | List custom fields and their options (status, iteration, single-select). |
get_project_items |
read | GraphQL | List items with field values, linked content (issues / PRs / draft issues), labels, assignees. |
get_project_item |
read | GraphQL | Get a single project item by node ID. |
add_project_item |
write | GraphQL | Add an issue or PR to a project. |
remove_project_item |
write | GraphQL | Remove an item from a project. |
update_project_item_field |
write | GraphQL | Update a field value on a project item. |
Invocation Examples
Create an issue:
{
"name": "create_issue",
"arguments": {
"owner": "strike48",
"repo": "construct",
"title": "Construct: clarify failure mode for stale tool discovery",
"body": "When the Atlassian MCP gateway is unreachable at refresh time, document what agents see.",
"labels": ["docs"]
}
}
Move a project item to a new status (single-select field):
{
"name": "update_project_item_field",
"arguments": {
"projectId": "PVT_kwDOABcdEf4ABCDE",
"itemId": "PVTI_lADOABcdEf4ABCDEzgABCDEF",
"fieldId": "PVTSSF_lADOABcdEf4ABCDEzgABCDxx",
"value": {"singleSelectOptionId": "f75ad846"}
}
}
Operational Notes
- No user identity. Installation tokens act as the App, not as any user.
/userreturns 403 Resource not accessible by integration and is intentionally not exposed. App-level endpoints (/app,/app/installations) require a JWT, not an installation token, and are also out of scope. - REST
node_id↔ GraphQL. GraphQL mutations (add_labels,remove_labels,add_sub_issue, project tools) take node IDs, not numeric IDs or names. Most REST list/get responses include anode_idfield — use it directly. For labels, calllist_labelsand pullnode_id; for issues, callget_issueand pullnode_id; for projects, walklist_org_projects→get_project→get_project_itemsto get the IDs you need. - GraphQL field-value shape.
update_project_item_fieldaccepts a polymorphicvalueobject:{"singleSelectOptionId": "..."}for status / single-select,{"number": 1}for number fields,{"date": "2024-01-15"}for date fields,{"text": "..."}for text fields. The shape must match the field'sdataTypefromget_project_fields. - Pagination. REST endpoints take
page(1-indexed) andper_page(max 100). GraphQL endpoints takefirst(max 100) andafter(cursor frompageInfo.endCursor). - Rate limits. GitHub App installation tokens have a higher REST rate limit ceiling than personal tokens (5,000 req/hr scaled by repo count, capped at 12,500/hr). GraphQL is point-cost-based — each request consumes points proportional to the data fetched. The plugin does not rate-limit on its own; pace agent calls accordingly.
- Reference docs. GitHub REST API reference · GitHub GraphQL API reference · GitHub App permissions.