Skip to main content

issue-triage

Triage this repo's inflow — sweep unboarded issues onto the Servers V2 board (#43) as Incoming, score Priority with the rubric and post the score, classify outside PRs and spam (server listings, new servers, duplicates, no-ops) and close them with their canned comments, and run the board audit. Use for "triage new issues" or "triage the PRs"; when scoring an issue's Priority; when answering or closing an outside PR; or when auditing the board for drift.

ソース情報

リポジトリ
modelcontextprotocol/servers
ソースの最終更新活動
2026年10月7日 19:18
検出された SKILL.md の言語
英語
スター
91,295
フォーク
11,788

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
2 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
issue-triage
description
Triage this repo's inflow — sweep unboarded issues onto the Servers V2 board (#43) as Incoming, score Priority with the rubric and post the score, classify outside PRs and spam (server listings, new servers, duplicates, no-ops) and close them with their canned comments, and run the board audit. Use for "triage new issues" or "triage the PRs"; when scoring an issue's Priority; when answering or closing an outside PR; or when auditing the board for drift.
disable-model-invocation
false
# Triaging issues and outside PRs This repository receives far more outside issues and pull requests than it opens itself, much of it misdirected (server listings, new servers, questions for the SDK) and much of it racing (several PRs for the same bug). This skill is the procedure for all of it: classify first, answer the classes that do not belong here with a canned response, sweep the rest onto the board unapproved, and check the board afterwards. The **rules** it carries out are in [`AGENTS.md`](../../../AGENTS.md), under **Contributing** and **Issue-driven work style**. The board's IDs, and the recipes that add, move and delete cards, are in `board-ops`, and only there: **load `board-ops` before the first board write.** Labels for an issue you file come from `issue-create`. The plan for the outside-PR backlog is [`docs/contribution-model.md`](../../../docs/contribution-model.md), "The plan"; [Outside PRs](#outside-prs) below is how it is carried out. **"Triage new issues" means:** the [class check](#step-0--classify-before-boarding) and [pass 1](#pass-1--sweep-onto-the-board-no-approval-implied) over every unboarded open issue, then the [board audit](#the-board-audit). **"Triage the PRs" means:** snapshot and classify the open outside PRs into a manifest and stop for a maintainer's review ([Outside PRs](#outside-prs)). Pass 2 and every close of an outside PR need a human, and neither is done unprompted. The one-time sweep of the existing backlog is tracked in #4875 (#4876 for issues, #4877 for PRs). It uses this skill's classes and responses, plus the conventions that tracker sets for the sweep, such as a close label and a reference to #4875 in each close comment. ## Outward-facing actions Every label, comment and close lands on someone else's issue or PR, and a reporter is notified of each one. So: - **A batch of closes happens only after a maintainer has reviewed the manifest** that lists each item, its class, and the issue it will point at. A wrong class is cheap to fix in a file and expensive to fix after a notification went out. Closing a single item the maintainer named is fine. - **Pace every write loop**: a few seconds between calls, and **stop on the first failed call** rather than carrying on blind. GitHub's secondary rate limit on content creation trips well before its primary one, and a loop that keeps going after a 403 leaves a half-applied batch nobody can see. - **Never restate a vulnerability in public**, not even to summarize a report that was already filed publicly. See [Security reports](#security-reports). - **Keep dumps outside the repository.** Every snapshot and manifest below goes in a `mktemp -d` directory. The board is private, and a dump left in the working tree is one `git add -A` away from being published. ## Step 0 — classify before boarding Read each unboarded issue before sweeping it in. Most are real reports, but some belong elsewhere, and boarding one of those would park it in a review queue for work this repository does not do. A class whose Action is **Close** is closed with its [canned response](#canned-responses), gets **no card** (`Done` means shipped, and closed-not-planned work never goes on the board), and needs no labels. A security report is never closed by triage. | Class | Recognized by | Action | Response | | --- | --- | --- | --- | | **Server listing or submission** | Asks for a server to be listed here, in the README or `ADDITIONAL.md` | Close, `not planned` | [Registry, issue](#registry-issue) | | **New server request** | Asks this repository to build or host a new server | Close, `not planned` | [Registry, issue](#registry-issue) | | **Archived server** | About a server in [`servers-archived`](https://github.com/modelcontextprotocol/servers-archived) (GitHub, Slack, Postgres, Puppeteer, …) | Close, `not planned` | [Archived](#archived) | | **SDK or specification** | Reproduces against the SDK directly, or asks for a protocol change | Close, `not planned` | [Elsewhere](#elsewhere) | | **Duplicate** | An open or closed issue already reports it (search all states, as in `issue-create` step 0) | Close as `duplicate` (the `board-ops` API call); delete its card if it has one | [Duplicate](#duplicate) | | **Spam or empty** | No content, unrelated or generated content | Close, `not planned` | None | | **Security report** | Describes a vulnerability in one of the seven servers | **Stop. A maintainer decides** | [Security reports](#security-reports) | | **Everything else** | A bug, a usability problem, an enhancement, a question about these servers | [Pass 1](#pass-1--sweep-onto-the-board-no-approval-implied) | None; the score comment | When a class is a judgment call (a feature a maintainer might still take, a report that could be the SDK or the server), sweep it in rather than closing it. Pass 1 approves nothing, and a maintainer reading `Incoming` can still close it; a wrong close cannot be quietly undone. For the same reason, closes follow [Outward-facing actions](#outward-facing-actions): when a run finds more than one, list them with their classes for a maintainer to confirm, and go on with pass 1 for the rest meanwhile. ```sh # The run's temp dir; create it once, before the first close, and reuse it. D=${D:-$(mktemp -d)} # Copy the class's response from Canned responses into "$D/response.md" (the # text inside the quote, with #ORIGINAL or the SDK link filled in) first. # Close as not planned, with that response (body in a file, so quoting is # safe). NOT for a duplicate: post the Duplicate response with `gh issue # comment`, close it with the `board-ops` state_reason=duplicate call, and # delete its card if it has one (`board-ops`, Delete a card). An empty or missing response stops here instead of closing silently. BODY=$(cat "$D/response.md") && [ -n "$BODY" ] \ && gh issue close <N> --repo modelcontextprotocol/servers --reason "not planned" --comment "$BODY" \ || { echo "no response or close failed for #<N> — stop and check it" >&2; false; } # Spam or empty, the one class with no response: gh issue close <N> --repo modelcontextprotocol/servers --reason "not planned" ``` ## Pass 1 — sweep onto the board (no approval implied) **An issue needs triage when it has no card on #43, whoever filed it.** The test is about state, not authorship. An outside reporter cannot board anything, but a maintainer who opens an issue in the web UI instead of through `issue-create` leaves it unboarded too, and write access makes the board reachable, not automatic. The milestone is not part of the test; it decides where the card lands. For each unboarded open issue left after step 0: 1. **Labels.** `v2`, **exactly one** type label (`bug` / `enhancement` / `documentation` / `chore` / `question`; the table is in `issue-create`), and the server's **scope label** (`server-<name>`) when it concerns one server. The issue forms apply `v2` and `bug` or `enhancement` on their own, but not the scope label, which triage reads off the form's server dropdown. Check the preset type too: a "bug report" that is a usage question is `question`. 2. **Board it** with the `board-ops` add-card recipe, Status **`Incoming`**. 3. **Priority** from [the rubric](#the-priority-rubric), and **post the score as a comment** ([Recording the score](#recording-the-score)). That is an assessment for ordering the queue, not an approval. 4. **Leave the milestone unset.** An empty milestone is what marks it as awaiting review. **The one exception is an unboarded issue that already has a milestone.** Someone recorded the approval and only the card is missing, so it goes straight into **`Todo`**, keeping the milestone. Otherwise triage would silently un-approve work a maintainer had already scheduled. ### Finding the unboarded ones ```sh D=$(mktemp -d); R=modelcontextprotocol/servers # --limit has headroom over the repo's open issues, and a listing that fills it # is treated as truncated: gh does not say when it stops early. gh issue list --repo $R --state open --limit 5000 \ --json number,title,milestone,labels > "$D/open.json" jq -e 'length < 5000' "$D/open.json" >/dev/null \ || { echo "issue listing truncated or failed — raise --limit" >&2; rm -f "$D/open.json"; } # item-list truncates SILENTLY past --limit, and a card missing from the dump # reads as an unboarded issue that then gets a second card. gh project item-list 43 --owner modelcontextprotocol --format json --limit 2000 > "$D/b43.json" jq -e '(.items | length) == .totalCount' "$D/b43.json" >/dev/null \ || { echo "board #43 listing INCOMPLETE — raise --limit and re-run" >&2; rm -f "$D/b43.json"; } # An org board can hold other repositories' issues; keep this repo's only. jq -r --slurpfile b "$D/b43.json" --arg R "$R" ' [$b[0].items[] | select(.content.type=="Issue" and .content.repository==$R) | .content.number] as $boarded | .[] | select(.number as $n | $boarded | index($n) | not) | "#\(.number)\t→ \(if .milestone then "Todo (has milestone \(.milestone.title))" else "Incoming" end)\t\(.title[0:70])"' \ "$D/open.json" ``` A failed or truncated listing deletes its file, so the last step fails on the missing file instead of reporting every issue as unboarded. The finder is only half the resume point. An issue whose card was added but whose Priority or score comment then failed has left the finder's list, and the audit catches a missing Priority but not a missing comment. So after an interrupted batch, **finish the last issue you were working on first** (read its card back with `board-ops` and check its comments), then resume from the finder's output, never from memory. ## Pass 2 — approve what should ship A maintainer reads the `Incoming` column and, for each issue worth doing, **assigns a milestone** and moves the card to **`Todo`** (or **`In Progress`** when picking it up now). That is the whole approval gesture. **Pass 2 is reserved for a human.** Deciding what ships in which release is not something to infer from a rubric score, so never promote a card out of `Incoming` as part of a routine sweep. An issue that should not ship stays in `Incoming` or is closed, and a closed one has its card deleted. ## The priority rubric Score it rather than assert it: rate two axes 1–5, add the signal bonuses, and read the band off the table. Two people triaging the same issue should land in the same place, and the reasoning should survive in a form someone can argue with later. **Axis 1: severity and impact (1–5).** How bad is it when it happens? | Score | Means | | --- | --- | | 1 | Cosmetic: a typo in a README or a tool description, a wording nit. | | 2 | Minor friction with an easy workaround. | | 3 | A tool, resource or prompt is broken or missing, and the workaround is annoying or partial. | | 4 | A server's core function is unusable, or a server **reports something false about the protocol** (a result or schema a conforming client rejects or misreads). | | 5 | Data loss; a security vulnerability, such as an operation that **escapes an allowed root**, SSRF, or command or argument injection; or a release broken on arrival for everyone. | **Axis 2: urgency and staleness (1–5).** How time-sensitive or neglected is it? | Score | Means | | --- | --- | | 1 | No time pressure; nothing waits on it. | | 2 | Wanted eventually. | | 3 | Wanted this milestone, or has sat more than 90 days with no activity. | | 4 | Blocking other work, or tied to a dated external dependency (an SDK release, a spec revision's date). | | 5 | Blocking a release, or hurting users of a published version right now. | **Signal bonuses (+1 each, not an axis of their own).** Corroborating evidence the two axes may have undercounted: - Carries the `bug` label, or concerns security. - Has a milestone, meaning it is **already approved**. This is the _re-scoring_ case: an issue scored in pass 1 has no milestone by rule, so it never earns this bonus. If every issue in a batch is earning it, the milestone is being treated as a formality. - High engagement (many comments, reactions, or linked outside PRs racing to fix it). - Assigned to someone. - A sub-issue of a larger tracker. - The reporter set **Fields → Priority** to `Urgent` or `High`: **+1, flat**, whichever of the two. **Bands.** The axes give 2–10 and there are six bonuses, so totals run 2–16. | Total | Priority | Meaning | | --- | --- | --- | | 12+ | **Urgent** | Drop what you're doing. | | 9–11 | **High** | Next up after current work. | | 6–8 | **Medium** | Scheduled normally. | | ≤5 | **Low** | Nice to have; may sit. | Severity alone does not reach Urgent: a 5/5 with no corroborating signal totals 10 and lands **High**. Urgent is for a severe problem that something _else_ also says is burning. Override the band when it is plainly wrong, and say why in the score comment; a rubric nobody may overrule is a rubric people route around. ### Trust boundary: who can set what **Board #43 is private.** Its Status and Priority are visible only to people with project access. It is the maintainers' working queue, not a published commitment. The **score comment** below is public, though: it is how the reasoning survives, so write it for the reporter to read too. **Fields → Priority** on the issue page is the opposite: an org-level issue field, public, and settable by people outside maintainer triage (the two fields are compared in `board-ops`). A value there is a preference, not an assessment, so it earns the flat +1 and nothing more. It can lift an issue at most one band, and nothing a reporter sets reaches Urgent by itself, because Urgent needs 12 and the issue would already need 11 from the maintainer-assessed axes (at most 10) plus at least one other bonus. **Never copy the value across:** a reporter choosing `Urgent` does not make the card Urgent, or the queue would sort by assertiveness instead of impact. ### Recording the score The board stores only the result, and the board is private. So **post the arithmetic as a comment on the issue**; without it, a later re-scoring cannot tell a considered judgment from a guess. ```sh gh issue comment <N> --repo modelcontextprotocol/servers --body \ '**Triage:** Priority **Medium** (total 7) - Severity 3: `directory_tree` fails on a symlinked root; workaround is listing by hand - Urgency 2: wanted eventually, nothing blocked on it - Bonuses: +1 `bug` label, +1 reporter set Fields → Priority to High Board: Servers V2 (#43), Status `Incoming`, awaiting maintainer review (no milestone yet).' ``` Name each bonus you claimed rather than only summing them. The milestone bonus in particular should be conspicuously absent from a pass-1 comment; a comment that lists it shows the approval semantics were misapplied. ## Security reports A vulnerability in one of the seven servers is reported privately, through the [advisory form](https://github.com/modelcontextprotocol/servers/security/advisories/new), and worked in the `security-advisory` flow (#4870). When one arrives as a public issue or a public PR anyway: - **Do not restate or discuss the details**, in a comment, in a harvest issue, or in a triage score. The score comment for such an issue names only the bands. - **Check the private advisory backlog first** (a maintainer, or an agent with access, reads it; the listing is private data and stays out of the repo). A public report of something already under advisory must not be answered in a way that confirms the advisory. - **Hand it to a maintainer.** Whether to close it, move it into a private advisory, or fix it in the open is theirs to decide. The response below is the one they usually post. <a id="security-response"></a> > Thank you for reporting this. Please don't add further details here: this > repository takes vulnerability reports privately, through > [the advisory form](https://github.com/modelcontextprotocol/servers/security/advisories/new). > A maintainer will follow up. ## Outside PRs **An outside PR is closed, not reviewed or merged**, with a pointer to the issue flow, after anything worth keeping in it is tracked by an issue (`AGENTS.md`, Contributing). An outside PR is any open PR whose author is **not a repository maintainer and not Dependabot**. A maintainer is an author whose role on this repository is `admin` or `maintain`; write access alone is not enough, which is the policy's point. **A Dependabot PR should not exist.** Dependency updates are issue-driven (`AGENTS.md`, Dependencies): `.github/dependabot.yml` is gone and security-update PRs are switched off, and three scheduled sweeps file issues instead. One that appears anyway means a config came back or the `automated-security-fixes` setting was switched on again. Close it with a pointer to the sweep issue that covers the same bump, and raise the cause with a maintainer. If no sweep issue covers it yet, do **not** file one with `issue-create`: the sweeps trust only issues the automation wrote, so the next run would file a duplicate beside it. Dispatch the sweep instead (`gh workflow run dependabot-alerts.yml`, or `dependency-refresh.yml` for a version bump) and point at the issue it files. ⚠️ **Until the milestone merge carries the sweeps to `main`**, none of this applies yet: a workflow can only be dispatched or scheduled from the default branch, and `main` still has `dependabot.yml`. Leave Dependabot PRs open until then. The merge PR closes them, each with the pointer #5065 records. Not touched by triage: - **Maintainer-authored PRs.** List any that target `main` for their authors to retarget or close; do nothing else with them. - **An outside PR an open issue already names as the thing to decide** (for example #3260 under #4860). That issue owns its fate; leave the PR open and name it in the report. ### 1. Snapshot and pre-classify ```sh D=$(mktemp -d); R=modelcontextprotocol/servers
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る