github-triage-mcp
# github-triage-mcp
An MCP server that answers **"what needs me right now?"** across your GitHub
issues, and returns the answer as Markdown that is already formatted.
## Why
`gh issue list` can tell you which issues are open and who they are assigned
to. It cannot tell you the thing you actually want to know, which is **whose
turn it is** — that needs the author of the most recent comment compared
against the assignee. So you end up asking an assistant to work it out, and
explaining the grouping you want, again, every time.
This server does that comparison and ships the formatting with it. The report
comes out the same shape whether you asked for "what's on my plate" or "정리해
줘".
## What you get
```
**12 open issues** involving `you` in `acme`
## 🔴 Your turn (3)
<sub>assigned to you and nothing is blocking them</sub>
| Issue | Repo | Type | Title | Last word | Idle |
|---|---|---|---|---|---|
| #412 | api | bug | retry budget is consumed before the first… | reviewer | 13d |
| #398 | api | perf | stale scan takes 71% of the time budget | opened by you | 9d |
| #77 | web | — | dark mode flashes on first paint | teammate | 2d |
## 🟡 Waiting on others (6)
## 🟠 You were pulled in (1)
## ⚪ Unassigned (2)
> Longest untouched on your side: #412 — 13d.
> No reply for 35d on #301 — worth chasing.
```
Issues are bucketed by whose turn it is, then ordered longest-idle first inside
each bucket, because the thing that has sat untouched longest is the thing most
likely to have been forgotten.
`[feat]` / `[bug]` / `[chore]` title prefixes are lifted into their own column.
On repositories that use title prefixes rather than labels — which is most of
them — that is the real taxonomy.
## Requirements
- Node.js 18+
- The [GitHub CLI](https://cli.github.com) (`gh`), authenticated: `gh auth login`
Everything goes through `gh`, so this server never stores a token of its own and
works with GitHub Enterprise wherever `gh` does.
## Install
```bash
claude mcp add --scope user github-triage -- npx -y github-triage-mcp
```
<details>
<summary>Or build from source</summary>
```bash
git clone https://github.com/yangchoi/github-triage-mcp.git
cd github-triage-mcp
npm install && npm run build
claude mcp add --scope user github-triage -- node /absolute/path/to/dist/index.js
```
</details>
## Scope
Without configuration the search covers every repository you can see, which is
slow and noisy. Narrow it:
| Variable | Example | Effect |
|---|---|---|
| `GITHUB_TRIAGE_REPOS` | `acme/api,acme/web` | Only these repositories. |
| `GITHUB_TRIAGE_ORG` | `acme` | The whole organisation. |
`GITHUB_TRIAGE_REPOS` wins when both are set, and the `repos` argument on a
call overrides both.
## Tools
| Tool | Arguments | Purpose |
|---|---|---|
| `triage` | `repos?`, `limit?` | The report above. Start here. |
| `get_issue` | `repo`, `number` | One thread in full — body and every comment, untrimmed. |
| `search_issues` | `query`, `repos?`, `state?`, `limit?` | GitHub search syntax, scope added automatically. |
| `linked_issues` | `repo`, `number` | Cross-referenced issues and the PRs that close them. |
`get_issue` deliberately does not trim. Issue threads are often where the design
actually lives — a single comment can run to several thousand characters of
specification — and a summary of a summary loses the specifics that matter.
## The `digest_issue` prompt
An MCP server has no language model inside it, and Claude Code does not support
[sampling](https://modelcontextprotocol.io/specification/server/sampling) (where
a server can ask its client to run a completion). So the server does not
summarise.
It does something better suited to it: it **owns the instruction**. The
`digest_issue` prompt tells the model reading the thread to report what was
decided, what is still open, and what happens next — with a fixed set of
headings, and an instruction not to invent a next step the thread never agreed
on. The summarising is done by the model that already has your conversation and
your project history; the *shape* of it comes from here.
## Tests
```bash
npm test
```
The suite covers the turn-taking rules, ordering, Markdown rendering, the tool
and prompt surface, and the failure modes — all against fixtures and the built
server, with no network access and no GitHub account needed.
## License
MIT
TDQS
Scored across 4 tools
Each tool serves a distinct purpose: triage provides an overview, get_issue retrieves full thread content, search_issues queries by syntax, and linked_issues discovers cross-references. There is no overlap or ambiguity between them.
get_issue and search_issues follow a clear verb_noun pattern, but triage is a bare imperative and linked_issues is a descriptive noun phrase rather than an action. The mixed conventions are still readable, but not fully consistent.
Four tools is exactly right for a focused triage server. Each tool covers a necessary step in the triage workflow without redundancy or bloat.
The tool surface covers the complete read-only triage workflow: get an overview, drill into full details, search, and trace relationships between issues and PRs. No obvious gaps exist for the stated purpose.