ci-triage-mcp
README.md
# ci-triage-mcp
MCP server for **GitHub Actions CI failure triage**. Wraps the `gh` CLI to fetch PR checks, failed jobs, and tail/grep failed job logs — with ANSI/timestamp stripping and root-cause extraction. Zero runtime dependencies; stdio JSON-RPC.
Built to turn a 5–10 minute "open the run, find the failed job, scroll the raw log" ritual into a single tool call.
## Tools
| Tool | Input | Returns |
| --- | --- | --- |
| `get_pr_checks` | `repo`, `prNumber` | Aggregated check rollup: failed / pending / success + merge state |
| `get_failed_jobs` | `repo`, `runId` | Jobs with `conclusion=failure`: name, databaseId, url, timestamps |
| `get_job_logs_tail` | `repo`, `jobId`, `lines?` | Last N log lines, ANSI + timestamp prefixes stripped |
| `grep_job_logs` | `repo`, `jobId`, `pattern`, `maxMatches?` | Matching lines + 2 lines context. Use when failure is mid-log (E2E, build errors) |
| `summarize_pr_failure` | `repo`, `prNumber` | End-to-end: failed checks → failed jobs → log tail → extracted error lines + file:line |
All `repo` inputs validated as `owner/repo` (alphanumerics, `.`, `-`, `_`). `lines` capped at 500, `maxMatches` at 200.
## Install
### One-click install
Click a badge → opens the install page → click the button → your IDE prompts to install.
[](https://aamar-shahzad.github.io/ci-triage-mcp/)
[](https://aamar-shahzad.github.io/ci-triage-mcp/)
> GitHub strips custom protocol schemes (`cursor://`, `vscode://`) from markdown links for security, so the badges route through a hosted install page on GitHub Pages with real `<a href>` buttons. The page also covers Claude Code, Claude Desktop, Cline, Windsurf, Zed, and LM Studio.
The install page registers the server under the name `ci-triage` via `npx -y github:aamar-shahzad/ci-triage-mcp` (works now, no npm registry publish needed). After install, restart your IDE if the tools don't appear immediately.
### Manual install — per client
The server config is the same everywhere; only the file location differs.
**Cursor** — `~/.cursor/mcp.json`:
```jsonc
{
"mcpServers": {
"ci-triage": {
"command": "npx",
"args": ["-y", "github:aamar-shahzad/ci-triage-mcp"],
"env": {}
}
}
}
```
**VS Code / GitHub Copilot** — `~/.vscode/mcp.json` (or workspace `.vscode/mcp.json`):
```jsonc
{
"mcpServers": {
"ci-triage": {
"command": "npx",
"args": ["-y", "github:aamar-shahzad/ci-triage-mcp"],
"env": {}
}
}
}
```
**Claude Desktop** — `claude_desktop_config.json`:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
```jsonc
{
"mcpServers": {
"ci-triage": {
"command": "npx",
"args": ["-y", "github:aamar-shahzad/ci-triage-mcp"],
"env": {}
}
}
}
```
**Claude Code** (CLI):
```bash
claude mcp add ci-triage npx -- -y github:aamar-shahzad/ci-triage-mcp
```
**Cline / Roo Code / Continue / Windsurf** — same `mcpServers` shape as Cursor, in their respective MCP config files:
- Cline: `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` (macOS)
- Windsurf: `~/.codeium/windsurf/mcp_config.json`
- Continue: `~/.continue/config.json` under `experimental.mcpServers`
**Zed** — `~/.config/zed/settings.json`:
```jsonc
{
"context_servers": {
"ci-triage": {
"command": "npx",
"args": ["-y", "github:aamar-shahzad/ci-triage-mcp"],
"env": {}
}
}
}
```
**LM Studio** — deep link:
```
lmstudio://add_mcp?name=ci-triage&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImdpdGh1YjphYW1hci1zaGFoemFkL2NpLXRyaWFnZS1tY3AiXSwiZW52Ijp7fX0=
```
### Option C — clone + run directly
For local development or to avoid `npx` cold-install delay:
```bash
git clone https://github.com/aamar-shahzad/ci-triage-mcp.git ~/src/ci-triage-mcp
```
Then in your MCP config:
```jsonc
{
"mcpServers": {
"ci-triage": {
"command": "node",
"args": ["/Users/you/src/ci-triage-mcp/src/index.mjs"]
}
}
}
```
### Regenerate install links
```bash
node scripts/gen-install-links.mjs # prints markdown
node scripts/gen-install-links.mjs --json # prints raw links as JSON
```
## Authentication
No token stored in MCP config. Uses your existing `gh` CLI authentication (keyring / config file from `gh auth login`). The server shells out to `gh`; nothing else.
Requirements:
- `gh` CLI on PATH — install from https://cli.github.com
- Authenticated: `gh auth login` (scopes: `repo`, `workflow` for CI logs)
- Node ≥ 20
On `initialize`, the server probes `gh --version` and emits a `_warning` in `serverInfo` if `gh` is missing.
## Why
Generic GitHub MCPs return raw JSON and stop at the check rollup. This server is opinionated about the triage workflow:
1. **Failed-check discovery** — `get_pr_checks` filters to `conclusion=FAILURE` only.
2. **Job drilldown** — `get_failed_jobs` maps a run to its failed job IDs (the part you usually copy by hand).
3. **Clean logs** — `get_job_logs_tail` strips ANSI escapes and the `2026-07-09T20:34:56.5281699Z ` timestamp prefix that buries the actual line.
4. **Mid-log grep** — `grep_job_logs` finds errors anywhere in the log with context. E2E / build failures live mid-log, not at the tail. Tail-only tools miss them.
5. **Root-cause extraction** — `summarize_pr_failure` chains all of the above and extracts error lines + `file:line` in one call.
Example: a 725-line Cypress job log → `grep_job_logs` with pattern `AssertionError|Timed out` returns 1 match with 2 lines context, surfacing `Expected to find element: [data-testid="inviteUserButton"], but never found it` in one call.
## Smoke test
```bash
node scripts/smoke.mjs
```
Runs `tools/list` + a `grep_job_logs` call against a known public failed job. Requires `gh` auth.
## Development
```bash
git clone https://github.com/aamar-shahzad/ci-triage-mcp.git
cd ci-triage-mcp
node src/index.mjs # starts stdio JSON-RPC server
```
No build step. Pure ESM `.mjs`, no dependencies.
## License
MIT
TDQS
A4.2/5.0
Scored across 5 tools
Disambiguation5/5
Each tool has a distinct purpose: listing failed jobs, fetching log tails, listing all checks, searching logs, and summarizing failures. No overlap or ambiguity.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern in snake_case (e.g., get_failed_jobs, grep_job_logs), making it predictable.
Tool Count5/5
Five tools is appropriate for CI triage—covers listing, log access, searching, and summarization without being excessive or insufficient.
Completeness5/5
The tool set covers the full triage workflow: identify failures, retrieve logs, search logs, and generate summaries. No obvious gaps for the stated purpose.
Maintenance
ActivityStale
ResponsivenessNo issues