github-triage-mcp
Provides read-only access to GitHub issues for triage via the GitHub REST API. Exposes tools to list, fetch, search, and summarize repository issues and activity, retrieve repository labels, and generate a triage prompt for open issues, while enforcing a repository allowlist and strict input validation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@github-triage-mcptriage the open issues in kenzoob/github-triage-mcp and suggest labels and priorities"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
github-triage-mcp
Let an AI assistant read and triage your GitHub issues — without giving it the keys to the kingdom.
Read-only access · a repository allowlist · strict input validation · untrusted-content marking — four independent layers standing between a manipulated model and your repos.
Contents
Related MCP server: GitHub MCP Server
Why this exists
Issue trackers are open to the internet. Anything in an issue body or comment — including text engineered to hijack an AI reading it — can end up in your model's context. github-triage-mcp is built around that threat model from line one: every tool is read-only, every repository must be explicitly allowlisted, every input is validated before it touches the network, and every piece of third-party text is fenced off and labeled as untrusted before it reaches the model.
What is MCP?
The Model Context Protocol is an open protocol that connects AI applications to tools and data. An MCP server exposes tools (functions the model can call), resources (data it can read) and prompts (reusable instructions). An MCP client, such as Claude Desktop or Claude Code, discovers them and calls them when needed.
Features
Tools
Tool | Inputs | Returns |
|
| Number, title, labels, author, date and comment count. Pull requests are excluded. |
|
| The issue body and its 20 most recent comments |
|
| Issues matching the search query |
|
| Issues opened and closed, and pull requests merged over the period |
Prompt
triage_issues: lists the open issues of a repository, groups them by theme, suggests a label and a priority for each one, and flags likely duplicates.
Resource
github://{owner}/{repo}/labels: the labels defined in a repository.
Security model
Issue content is written by anyone on the internet, and an AI model reads it. This server is designed with that in mind.
Risk | Mitigation |
Overly broad access | A fine-grained GitHub token with read-only Issues and Metadata permissions |
The model is manipulated into reading other repositories |
|
Malformed or abusive inputs | Every input is validated with Zod (repository name format, bounded |
Prompt injection hidden in issues | Issue and comment text is wrapped in clear delimiters and preceded by a warning that it is untrusted content; long texts are truncated |
Rate limits | When GitHub's rate limit is reached, the tool returns a clear message with the reset time instead of failing |
Secret leakage | The token never appears in logs or tool output, and a test checks this |
No single measure stops prompt injection completely. The goal is defense in depth: even if the model is manipulated, it can only read issues from approved repositories.
Tech stack
TypeScript (strict), Node.js 22+
Official MCP TypeScript SDK (
@modelcontextprotocol/sdk, stdio transport)Zod for input schemas
Native
fetchfor the GitHub REST APIVitest, MCP Inspector, GitHub Actions
Getting started
1. Create a GitHub token
In GitHub, go to Settings → Developer settings → Fine-grained tokens, and create a token with:
Repository access: only the repositories you want to triage
Permissions: Issues: Read-only and Metadata: Read-only
2. Install and build
git clone https://github.com/kenzoob/github-triage-mcp.git
cd github-triage-mcp
npm install
npm run build3. Configure
Copy .env.example to .env (or export these directly in your MCP client config):
Variable | Description | Example |
| Read-only fine-grained token |
|
| Comma-separated allowlist |
|
| Truncation limit for issue text (optional, default |
|
The server validates these at startup and exits immediately with a clear error if anything is missing or malformed — no silent misconfiguration.
4. Connect it to an MCP client
Claude Desktop: open Settings → Developer → Edit Config and add:
{
"mcpServers": {
"github-triage": {
"command": "node",
"args": ["/absolute/path/to/github-triage-mcp/dist/index.js"],
"env": {
"GITHUB_TOKEN": "github_pat_...",
"ALLOWED_REPOS": "kenzoob/My-Engine,facebook/react"
}
}
}
}Restart Claude Desktop, then ask: "Triage the open issues of facebook/react."
Claude Code:
claude mcp add --transport stdio \
--env GITHUB_TOKEN=github_pat_... \
--env ALLOWED_REPOS=kenzoob/My-Engine \
github-triage -- node /absolute/path/to/github-triage-mcp/dist/index.js5. Inspect it manually
npx @modelcontextprotocol/inspector node dist/index.jsHow it works
MCP client (Claude Desktop, Claude Code, ...)
│ stdio, JSON-RPC
▼
┌──────────────────────────────────────────┐
│ github-triage-mcp │
│ index.ts server, tools, prompt │
│ ├─ config.ts env validation at boot │
│ ├─ guard.ts allowlist + Zod │
│ ├─ github.ts REST client, PR filter, │
│ │ rate-limit handling │
│ └─ format.ts output text, truncation,│
│ untrusted-content tags │
└──────────────────────────────────────────┘
│ HTTPS, read-only token
▼
GitHub REST APIGitHub endpoints used:
Purpose | Endpoint |
List issues |
|
Get one issue |
|
Issue comments |
|
Search |
|
The /issues endpoint also returns pull requests. They are identified by their pull_request field and filtered out.
Project structure
github-triage-mcp/
├── src/
│ ├── index.ts # server setup, tools, prompt, resource, stdio transport
│ ├── config.ts # environment validation at startup
│ ├── guard.ts # allowlist and Zod input schemas
│ ├── github.ts # GitHub REST client, error handling
│ └── format.ts # output formatting and untrusted-content wrapping
├── test/
│ ├── github.test.ts # PR filtering, 404s, rate limits, token non-leakage
│ ├── guard.test.ts # allowlist enforcement, input bounds
│ └── format.test.ts # untrusted-content wrapping and truncation
├── .github/workflows/ci.yml
└── .env.exampleTesting
npm testAll tests use a mocked fetch; none call the real GitHub API. They check that:
list_issuesexcludes pull requestsRepositories outside the allowlist are rejected
limitabove 50 is rejectedIssue text is marked as untrusted and truncated
Rate-limit errors return the reset time
A
404returns "issue or repository not found"The token never appears in any output
Design decisions
stdio transport: for a local tool, it is the simplest and safest option, with no open port. A shared remote deployment would use the Streamable HTTP transport with authentication.
Allowlist on top of a read-only token: defense in depth. The token might still see private repositories; the allowlist limits what the model can reach.
Validation at the boundary: every tool input is checked before any network call.
Fail fast at startup: missing or malformed configuration stops the server immediately with a clear message, instead of failing confusingly on the first tool call.
Roadmap
Four read-only tools, triage prompt and labels resource
Security guards and tests
60-second in-memory cache
Optional write tools (add labels, comment) behind an explicit opt-in flag
Streamable HTTP transport with OAuth for remote use
License
Available Tools
4 toolsget_issueGet issueB
Returns an issue's body and its 20 most recent comments.
| Name | Required | Description | Default |
|---|---|---|---|
| repo | Yes | ||
| owner | Yes | ||
| number | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that only the 20 most recent comments are returned, which is a real behavioral constraint, but it omits auth requirements, error behavior for missing issues, and any rate-limit context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. Every word earns its place, and the key return-content fact is stated immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter read tool with no annotations and no output schema, the description covers the return shape but leaves auth, error handling, and parameter semantics undocumented. It is minimally adequate but has clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so owner, repo, and number have no documented meaning anywhere. The description adds no parameter detail at all, failing to compensate for the coverage gap, though the parameter names themselves are somewhat self-explanatory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Returns an issue's body and its 20 most recent comments.' This clearly identifies the operation and scope. However, it does not differentiate itself from siblings like list_issues, search_issues, or repo_activity, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus alternatives such as list_issues or search_issues. The description only says what is returned, leaving route selection entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_issuesList issuesC
Lists issues (not pull requests) for an allowlisted repository, with labels, author, date and comment count.
| Name | Required | Description | Default |
|---|---|---|---|
| repo | Yes | ||
| limit | No | ||
| owner | Yes | ||
| state | No | open | |
| labels | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It adds one useful constraint (allowlisted repository, implying a scoping/permission restriction) but omits pagination behavior, how the limit parameter is applied, ordering, and rate limits for what is clearly a paged read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact sentence with the resource scope front-loaded and no filler. Efficient, though it spends words on return fields while leaving the actual parameters unexplained.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with 0% schema description coverage, no annotations, and no output schema, the description is too thin. It partially covers return fields but leaves state/limit/owner/repo semantics and pagination entirely undocumented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 5 parameters. The description names only 'labels' (a real parameter) while owner, repo, limit, and state are undocumented anywhere; 'author, date and comment count' are output fields, not parameters, so they do not compensate for the input gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Lists) and resource (issues), and explicitly excludes pull requests, which is the most common ambiguity for this resource type. However it does not distinguish itself from sibling tools like search_issues or get_issue, so an agent cannot route between them from this text alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance is given. The description never states when to prefer this over search_issues (filtered/query-based listing) or get_issue (single-item retrieval), and gives no prerequisites besides the allowlist mention.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
repo_activityRepository activityC
Summarizes issues opened and closed, and pull requests merged, over a recent period.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | ||
| repo | Yes | ||
| owner | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations and no output schema, the description carries the full behavioral burden, yet it only names the categories aggregated. It does not disclose whether results are counts or breakdowns, whether the window is inclusive, or what happens for repos with no activity. "Recent period" is also vague against a days parameter with a 7-day default.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact sentence front-loads the verb and resource, and every clause carries information about what is summarized. It is efficient, though it is short at the expense of the details an agent actually needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only aggregation the description covers the essential 'what,' but with no annotations and no output schema the agent has no sense of the return shape or the time-window semantics. The missing pieces are moderate rather than severe given the tool's low complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across all three parameters, so the description must compensate and largely fails to. "Over a recent period" loosely gestures at the days parameter but never names it, cites its default (7), or explains the 1–90 bound; owner and repo receive no clarification beyond their self-evident names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("summarizes") over a concrete resource set (issues opened/closed, PRs merged) with a time scope, which is clearly distinguishable from the item-level siblings list_issues/get_issue. It stops short of naming those siblings or contrasting itself with them, so the differentiation is implicit rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance at all – nothing says to prefer this over list_issues or search_issues when the agent wants aggregate counts rather than individual items. The only contextual hint is the vague phrase "over a recent period," which leaves the selection decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_issuesSearch issuesC
Searches issues in an allowlisted repository matching a query.
| Name | Required | Description | Default |
|---|---|---|---|
| repo | Yes | ||
| owner | Yes | ||
| query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it gives almost nothing. It hints at a scoping constraint ('allowlisted repository') but omits pagination, result caps, sorting, auth requirements, and whether the query uses GitHub search syntax or free text.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. It is efficient, though the tightness comes at the cost of specificity rather than being paired with adequate detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter, all-required search tool with no annotations, no output schema, and no parameter documentation, this is too thin. The undefined query syntax and the owner/repo relationship leave real gaps an agent would hit at call time.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does not. It gestures at 'repository' and 'query' but never explains the owner/repo split, the query syntax or operators, or the length and character constraints enforced by the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Searches') and resource ('issues') with a scoping constraint ('in an allowlisted repository matching a query'). It is clear what the tool does, but it does not differentiate itself from the sibling search-like tools list_issues or get_issue, so an agent must infer the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance and no mention of alternatives such as list_issues or get_issue. 'Matching a query' only weakly implies the search use case; nothing tells the agent when this is preferred over listing all issues.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
get_issue - First observed
list_issues - First observed
repo_activity - First observed
search_issues
TDQS
Scored across 4 tools
list_issues, get_issue, and search_issues all target issues and could be confused at the margins, but the descriptions draw clear lines (enumerate vs. fetch one vs. query-match), and repo_activity is unmistakably distinct as a period summary.
Three tools follow a clean verb_noun pattern (list_issues, get_issue, search_issues), but repo_activity breaks it with a noun-only form, a minor deviation from an otherwise predictable convention.
Four tools is a tight, well-scoped set for a triage-focused server; each earns its place, though the surface arguably sits at the thin end given the absence of any action tools.
The toolset is entirely read-only: it can list, fetch, search, and summarize issues but offers no way to label, comment on, assign, or close them, which are core actions for an actual triage workflow.
Maintenance
Related MCP Connectors
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
Screens public GitHub repos and PRs to generate risk maps, findings, and merge-readiness signals.
Read-only AI coding tools for change verification, release readiness, capacity, and guidance.
Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analy…
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables AI assistants to inspect local Git repositories and interact with the GitHub API for reading commits, diffs, files, issues, comments, pull requests, and project boards.10155 npm-
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to interact with GitHub through the GitHub REST API, supporting repository, file, issue, pull request, branch, commit, search, and label operations with explicit confirmation for write operations.-
- AlicenseAqualityBmaintenanceConnects AI assistants to GitHub repositories, pull requests, issues, commits, and code search while enabling repository visibility controls, CI/CD monitoring, sandboxed local filesystem access, and code quality/security analysis.131MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to search and inspect code repositories, manage issues and pull requests, and analyze user contributions.13MIT