inspector/CONTRIBUTING.md
Cliff Hall 0742f78357
docs: replace the markdown bug template with GitHub issue forms (#1894)
* docs: replace the markdown bug template with issue forms (#1844)

Issues are the only intake channel now that external pull requests are off
(#1820), so the chooser is where the contribution policy has to be stated —
GitHub gives a would-be contributor no explanation when the "New pull request"
button isn't there.

The one existing template was a legacy **markdown** template, whose fields are
prose headings a reporter can delete or ignore. Most reports still arrive
missing the client and the transport, which are the two facts that decide where
to look. Issue forms enforce them: this replaces `bug_report.md` with
`1-bug_report.yml`, where client (web/cli/tui/core), version line (v1/v2),
Inspector version, Node version, transport, MCP server, repro, expected, and
actual are all `validations.required`. It auto-labels `bug`, and its intro says
maintainers implement the fix, so a prompt plus screenshots beats a diff —
with a field for exactly that.

Adds `2-feature_request.yml` (auto-labels `enhancement`), which puts the
problem statement first and marks the solution optional, since the problem is
what survives when a specific solution turns out not to fit.

Neither form applies a `v1`/`v2` label: GitHub can't map a form answer to a
label, so the version line is a required dropdown and a maintainer still labels
at triage. v1 takes security fixes only, so routing that answer early is the
point.

`config.yml` disables blank issues and carries the contact links. **There is
deliberately no security *template*** — a template still opens a public issue,
which is precisely what a vulnerability report must not do. The redirect is a
contact link straight to the private advisory form (`/security/advisories/new`,
verified enabled on this repo) plus one to `SECURITY.md`, which covers the v1
line too. The remaining links deflect the recurring misfiled classes: the
specification repo and the TypeScript SDK for reports that aren't about this
tool, the docs site, the contribution policy, and `#inspector-dev`.

Also fixes three links the #1884 rename left dangling — `SECURITY.md` and the
PR template still pointed at `CONTRIBUTORS.md`, which no longer exists on this
branch. A policy nobody can open is the same as no policy.

Validated against GitHub's issue-forms schema (unique ids, allowed `type`s,
`markdown` blocks carrying no `id`/`validations`, `checkboxes` marking
`required` per option rather than under `validations`).

Claude-Session: https://claude.ai/code/session_01YAt8rqxysNbhYWLhoRm3fU

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: address Copilot review on the issue forms (#1844)

- PR template said `v2` targets `main`; the v2 base branch is `v2/main`.
  Correct on its face, and the one line in that template a reader acts on.
- Scoped the Node floor on the bug form to v2, since the form serves both
  lines and v1's floor is older — reading `>= 22.19.0` as universal would
  make a legitimate v1 report look out of support.
- Both the CONTRIBUTING.md paragraph and the AGENTS.md section now say the
  chooser is served from the **default branch**, so neither claims a form
  added on `v2/main` is live before the milestone merge.

* docs: re-wrap the CONTRIBUTING chooser paragraph (#1844)

Round-2 Copilot nit: the previous wrap left a dangling "The" at end of
line, splitting a phrase mid-sentence in the raw markdown.

Claude-Session: https://claude.ai/code/session_01YAt8rqxysNbhYWLhoRm3fU

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: clarify the protocol-era prompt on the bug form (#1844)

Round-3 Copilot nit. "the protocol era (legacy / modern) if you selected
one" reads as referring to a field on this form, which has none — the era is
selected on the *connection*, in the Inspector's server settings. Reworded to
"the protocol era you connected with (auto / legacy / modern)", which also
picks up `auto`, the default the previous list omitted.

Claude-Session: https://claude.ai/code/session_01YAt8rqxysNbhYWLhoRm3fU

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs: stop describing the feature form as sharing the bug form's fields (#1844)

Round-4 Copilot nits, and it was right three times over — I had described
"client, version line, transport" as the required set for *both* forms in
CONTRIBUTING.md, AGENTS.md, and the config.yml header. The feature form has
neither a version-line dropdown nor a transport field, and cannot have the
first: v1 takes security fixes only, so a feature request is v2 by
construction.

Each of the three now distinguishes the two forms rather than generalizing
from the bug form.

Claude-Session: https://claude.ai/code/session_01YAt8rqxysNbhYWLhoRm3fU

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: declare v2 statically on the feature form (#1844)

Round-5 Copilot nit caught a real contradiction: the AGENTS.md paragraph said
no form can apply a version label, then asserted the feature form "is always
labeled v2". Both halves can't be true.

Resolved in the direction that makes the claim true rather than softer. A
form's `labels:` is static, which is only an obstacle when the value depends
on a reporter's answer — and for the feature form it doesn't: v1 takes security
fixes only, so a feature request is v2 by construction. So it now declares
`["enhancement", "v2"]` outright, which also satisfies AGENTS.md's
label-at-create-time rule without a triage step.

The bug form still can't, and shouldn't: its version line is genuinely the
reporter's to answer.

Claude-Session: https://claude.ai/code/session_01YAt8rqxysNbhYWLhoRm3fU

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 19:50:49 -04:00

7.6 KiB

Contributing to MCP Inspector

Thank you for your interest in improving the MCP Inspector. Contributors are genuinely valued — the goal of this document is to channel your input into a form we can act on quickly and consistently.

TL;DR

We accept issues, not pull requests. Design and implementation are done by the maintainers. If you've already built a fix or feature locally, share the prompt you used to produce it — not the source code. This applies to everyone outside the repo maintainers, including organization members who happen to have write access to this repository.

Why this policy exists

The Inspector v2 is developed with an AI-assisted, prompt-driven workflow built around a consistent architecture, a shared design system, and strict testing gates (see AGENTS.md). Every component follows the same conventions: "dumb" components that take data and callbacks as props, Mantine for all UI, theme variants instead of ad-hoc CSS, and a uniform per-file coverage gate of ≥ 90% on lines, statements, functions, and branches.

Accepting raw source PRs creates friction: a diff written outside this pipeline has to be reverse-engineered to fit our component/theme conventions, coverage gates, and review process — often it's faster to re-derive the change than to adapt the patch. Capturing your intent (a well-formed issue) or the prompt that generated your local change lets us reproduce the work inside our own workflow and standards, with the quality bar already baked in.

This policy is about efficiency, not gatekeeping. Your ideas, bug reports, and prompts directly shape what gets built. And if you'd like to contribute more than an issue, see Want to work on the Inspector with us? below — we'd rather bring you into the workflow than turn you away.

Who opens pull requests

Pull requests against this repository are opened by the repo maintainers only. That includes organization members with write access: being able to push a branch here isn't the same as being asked to — the constraint is the workflow described above, not permissions, so the same policy applies whether or not GitHub would let you click the button.

If you're not a repo maintainer, open a detailed issue instead and a maintainer will pick it up. If you've already prototyped the change locally, say so in the issue and include the prompt you used (see If you've already fixed it locally) — that's the fastest path from your work to a merged change.

Every pull request references an issue, including the maintainers' own. The PR body's first line is Closes #<ISSUE_NUMBER>. Work is tracked on the project board through issues, so a PR without one is invisible to the board — which is why a well-formed issue is the useful contribution here, and why writing one is never wasted effort.

How to contribute a bug report or feature request

Open a well-formed issue describing the bug or the feature you have in mind. A great issue gives us everything we need to act on it without a round-trip — see What makes a good issue or prompt submission below. That's the whole process: you describe the intent, we handle the design and implementation.

New issue offers a Bug report and a Feature request form. Blank issues are disabled, so pick one of the two. The bug form requires the facts triage needs first — which client, which version line, which transport; the feature form asks for the client and the problem you are trying to solve, and targets v2 only. (GitHub serves the chooser from the repository's default branch, so what you see when filing is whatever has reached main; a form added on v2/main appears at the next milestone merge.) The same chooser links out to the private security-advisory process, to this policy, and to the specification and SDK repositories for reports that aren't about the Inspector itself.

Which version and label?

The Inspector is maintained across two versions, each with its own base branch and version label. File your issue against the version your report or request targets:

Version Base branch Label npm tag
v1 v1/main v1 v1-latest
v2 v2/main v2 latest
  • v1 (v1/main) is the legacy Inspector — it takes security fixes only, and is published straight from that branch to the v1-latest npm tag (npx @modelcontextprotocol/inspector@v1-latest).
  • v2 (v2/main) is where all current work happens — when in doubt, target v2. v2/main is the develop branch; it is merged into main at milestone releases, and main is what publishes the latest npm tag. Nothing targets main directly.

Label by version. Every issue (and the PRs maintainers open for it) must carry the label matching the target branch — v1 for v1/main and v2 for v2/main. This mirrors the "Label by version" convention documented in AGENTS.md.

If you've already fixed it locally

Please don't send a diff or open a pull request. Instead, open an issue that includes:

  • The prompt(s) you used to generate the change — the exact text, so we can reproduce it through our own workflow.
  • A description of the behavior before and after your change.
  • How you verified it (steps you ran, tests you added, what you observed).

We'll reproduce the change through our pipeline so it lands with the right conventions, tests, and coverage.

What makes a good issue or prompt submission

A great submission gives us everything we need to act without a round-trip:

  • Clear reproduction or use case — exact steps to reproduce a bug, or a concrete description of the feature and the problem it solves.
  • Expected vs. actual behavior — what you saw, and what you expected instead.
  • Affected client — which incarnation is involved: Web, TUI, or CLI (or "all" / "core" if it's shared logic).
  • Environment details when relevant — OS, Node version, the MCP server you were inspecting, and any relevant config.
  • The exact prompt text, if you generated a local change and want us to reproduce it.

Want to work on the Inspector with us?

The issues-only policy is about how unsolicited patches are handled — it is not a closed door. If you want to contribute at a deeper level, either in general or in a specific area, we'd genuinely like to hear from you:

From there we can scope a piece of work with you and supervise it through our workflow — which is also the path toward becoming a maintainer. What we want to avoid is drive-by diffs that have to be reverse-engineered into our pipeline; what we want to encourage is sustained, coordinated contribution.

All participation is governed by the MCP Code of Conduct.

Questions

If you're unsure how to scope something, open the issue anyway and say so — we'll help shape it. Thanks for helping make the Inspector better.