MCP Release QA
Test the server that users will run. A schema review or a passing unit test is
not runtime evidence.
This skill complements security review. It focuses on protocol behavior,
published-contract drift, transport correctness, and reproducible release
evidence.
When to invoke
- "Run release QA for this MCP server."
- "Verify this MCP tool catalog before shipping."
- "Check MCP runtime capabilities against the README."
- "Smoke-test the MCP install path and protocol session."
Rules
- Run checks against a fresh server process built from the candidate revision.
- Keep
initialize, notifications/initialized, discovery, and invocation in
the same session. A new process is a new STDIO session.
- Treat source registrations as implementation truth and public documentation
as a contract that must match it.
- Record exact commands and raw responses. Do not replace missing evidence with
"looks correct."
- Do not invoke mutation-capable tools against production data. Use fixtures, a
sandbox, or stop and name the missing safe test environment.
- Derive the expected capability inventory from the candidate source on every
run.
1. Establish the release surface
Identify:
- candidate commit and build command;
- server entry point and transport: STDIO, Streamable HTTP, or SSE;
- supported MCP protocol versions;
- source files that register tools, resources, resource templates, and prompts;
- generated catalogs, manifests, README tables, and install instructions;
- existing protocol, integration, and smoke-test commands.
Prefer repository-native commands. Inspect package.json, pyproject.toml,
Makefile, CI workflows, and contributor instructions before inventing a test
harness.
2. Start a clean server
Build the candidate and start the documented entry point with test-safe
configuration. Capture:
- the exact command;
- commit SHA;
- environment variable names, with values redacted;
- stdout, stderr, and exit status;
- the endpoint or child-process transport used by the client.
For STDIO, stdout is protocol-only. Logs, banners, and stack traces belong on
stderr. For HTTP transports, record the status, relevant MCP headers, and
session identifier handling without printing credentials.
If the server cannot start from its documented instructions, report that as a
release failure and preserve the startup error verbatim.
3. Exercise one complete session
Run this sequence through a real MCP client or the repository's integration
harness:
initialize with a protocol version the server claims to support.
- Confirm the negotiated version and advertised capabilities.
- Send
notifications/initialized.
- Call
ping.
- Call each supported discovery method:
tools/list
resources/list
resources/templates/list
prompts/list
- Exercise at least one representative read-only item from every advertised
capability class.
- Follow pagination until no cursor remains when a list method is paginated.
Do not send post-initialization requests through separate one-shot processes.
That accidentally tests several incomplete sessions instead of one valid
session.
4. Prove inventory parity
Build four inventories from current evidence:
| Surface |
Evidence |
| Source |
Registered tool, resource, template, and prompt definitions |
| Runtime |
Results from the live discovery methods |
| Generated metadata |
Catalogs, manifests, or generated indexes |
| Documentation |
README, reference pages, and install output |
Compare by stable identifier. Report:
- source entries missing at runtime;
- runtime entries absent from metadata or documentation;
- stale names, descriptions, arguments, URIs, or prompt parameters;
- documented install commands that do not start the candidate server.
Regenerate derived files with the repository's own build command, then fail if
the working tree still contains unexplained generated changes.
5. Check published contracts
For every discovered item, verify the runtime definition against its source:
Tools
- Name and description are stable and specific.
inputSchema defines types, required fields, enums, and bounds where needed.
- Unknown properties are rejected when the tool contract is closed.
- Mutation, idempotence, read-only, and open-world annotations match behavior.
- Successful calls conform to
outputSchema when one is published.
- Errors are protocol errors or structured tool failures, not leaked stack
traces.
Resources and templates
- URIs and MIME types match the registered definitions.
- Static resources are readable.
- Template parameters are validated before resolution.
- Missing or forbidden resources fail explicitly.
Prompts
- Required and optional arguments match discovery output.
prompts/get returns usable messages for valid arguments.
- Missing required arguments and unknown prompt names fail explicitly.
6. Test failure paths
At minimum, probe:
- a request before initialization completes;
- malformed JSON or an invalid JSON-RPC envelope;
- an unknown method;
- an unsupported protocol version;
- repeated initialization;
- unknown tool, resource, and prompt names;
- missing, extra, wrong-type, and out-of-bounds arguments;
- a request at the documented transport-size limit and one beyond it;
- a controlled internal failure with credentials and stack traces redacted.
Verify that each response has the correct request ID, a useful error message,
and no successful side effect. For STDIO, also confirm every stdout line is a
complete protocol message and a healthy session leaves stderr clean unless the
server explicitly documents diagnostic output.
7. Smoke-test installation
When the project publishes an install command:
- Create a temporary destination outside the source checkout.
- Run the public install command exactly as documented.
- Start the installed artifact without relying on files from the source tree.
- Repeat initialization, discovery, and one read-only invocation.
- Remove the temporary destination after preserving the command output.
An install string that was only inspected is unverified.
Output template
Use this format:
# MCP Release QA
Candidate: [commit]
Transport: [STDIO | Streamable HTTP | SSE]
Verdict: PASS | PASS WITH CAVEATS | FAIL
## Commands and results
- `[exact command]` — [exit status and result]
## Session transcript
- initialize: [result]
- discovery: [result]
- representative calls: [result]
- negative paths: [result]
## Parity
| Identifier | Source | Runtime | Metadata | Docs | Result |
|---|---|---|---|---|---|
## Findings
| Severity | Evidence | Impact | Narrowest fix |
|---|---|---|---|
## Missing evidence
- [check that could not run and why]
Use FAIL for a server that cannot start, complete a valid session, keep the
transport parseable, or safely reject invalid input. Use PASS WITH CAVEATS
only for bounded documentation or metadata drift that does not misrepresent a
dangerous capability. Otherwise use PASS.
Quality gate
1---2name: mcp-release-qa-23description: Verify an MCP server before release by exercising a real protocol session, comparing runtime capabilities with source and documentation, testing failure paths, and recording reproducible evidence. Use when shipping or reviewing an MCP server, tool, resource, prompt, catalog, or install path.4---56# MCP Release QA78Test the server that users will run. A schema review or a passing unit test is9not runtime evidence.1011This skill complements security review. It focuses on protocol behavior,12published-contract drift, transport correctness, and reproducible release13evidence.1415## When to invoke1617- "Run release QA for this MCP server."18- "Verify this MCP tool catalog before shipping."19- "Check MCP runtime capabilities against the README."20- "Smoke-test the MCP install path and protocol session."2122## Rules2324- Run checks against a fresh server process built from the candidate revision.25- Keep `initialize`, `notifications/initialized`, discovery, and invocation in26 the same session. A new process is a new STDIO session.27- Treat source registrations as implementation truth and public documentation28 as a contract that must match it.29- Record exact commands and raw responses. Do not replace missing evidence with30 "looks correct."31- Do not invoke mutation-capable tools against production data. Use fixtures, a32 sandbox, or stop and name the missing safe test environment.33- Derive the expected capability inventory from the candidate source on every34 run.3536## 1. Establish the release surface3738Identify:3940- candidate commit and build command;41- server entry point and transport: STDIO, Streamable HTTP, or SSE;42- supported MCP protocol versions;43- source files that register tools, resources, resource templates, and prompts;44- generated catalogs, manifests, README tables, and install instructions;45- existing protocol, integration, and smoke-test commands.4647Prefer repository-native commands. Inspect `package.json`, `pyproject.toml`,48`Makefile`, CI workflows, and contributor instructions before inventing a test49harness.5051## 2. Start a clean server5253Build the candidate and start the documented entry point with test-safe54configuration. Capture:5556- the exact command;57- commit SHA;58- environment variable names, with values redacted;59- stdout, stderr, and exit status;60- the endpoint or child-process transport used by the client.6162For STDIO, stdout is protocol-only. Logs, banners, and stack traces belong on63stderr. For HTTP transports, record the status, relevant MCP headers, and64session identifier handling without printing credentials.6566If the server cannot start from its documented instructions, report that as a67release failure and preserve the startup error verbatim.6869## 3. Exercise one complete session7071Run this sequence through a real MCP client or the repository's integration72harness:73741. `initialize` with a protocol version the server claims to support.752. Confirm the negotiated version and advertised capabilities.763. Send `notifications/initialized`.774. Call `ping`.785. Call each supported discovery method:79 - `tools/list`80 - `resources/list`81 - `resources/templates/list`82 - `prompts/list`836. Exercise at least one representative read-only item from every advertised84 capability class.857. Follow pagination until no cursor remains when a list method is paginated.8687Do not send post-initialization requests through separate one-shot processes.88That accidentally tests several incomplete sessions instead of one valid89session.9091## 4. Prove inventory parity9293Build four inventories from current evidence:9495| Surface | Evidence |96|---|---|97| Source | Registered tool, resource, template, and prompt definitions |98| Runtime | Results from the live discovery methods |99| Generated metadata | Catalogs, manifests, or generated indexes |100| Documentation | README, reference pages, and install output |101102Compare by stable identifier. Report:103104- source entries missing at runtime;105- runtime entries absent from metadata or documentation;106- stale names, descriptions, arguments, URIs, or prompt parameters;107- documented install commands that do not start the candidate server.108109Regenerate derived files with the repository's own build command, then fail if110the working tree still contains unexplained generated changes.111112## 5. Check published contracts113114For every discovered item, verify the runtime definition against its source:115116### Tools117118- Name and description are stable and specific.119- `inputSchema` defines types, required fields, enums, and bounds where needed.120- Unknown properties are rejected when the tool contract is closed.121- Mutation, idempotence, read-only, and open-world annotations match behavior.122- Successful calls conform to `outputSchema` when one is published.123- Errors are protocol errors or structured tool failures, not leaked stack124 traces.125126### Resources and templates127128- URIs and MIME types match the registered definitions.129- Static resources are readable.130- Template parameters are validated before resolution.131- Missing or forbidden resources fail explicitly.132133### Prompts134135- Required and optional arguments match discovery output.136- `prompts/get` returns usable messages for valid arguments.137- Missing required arguments and unknown prompt names fail explicitly.138139## 6. Test failure paths140141At minimum, probe:142143- a request before initialization completes;144- malformed JSON or an invalid JSON-RPC envelope;145- an unknown method;146- an unsupported protocol version;147- repeated initialization;148- unknown tool, resource, and prompt names;149- missing, extra, wrong-type, and out-of-bounds arguments;150- a request at the documented transport-size limit and one beyond it;151- a controlled internal failure with credentials and stack traces redacted.152153Verify that each response has the correct request ID, a useful error message,154and no successful side effect. For STDIO, also confirm every stdout line is a155complete protocol message and a healthy session leaves stderr clean unless the156server explicitly documents diagnostic output.157158## 7. Smoke-test installation159160When the project publishes an install command:1611621. Create a temporary destination outside the source checkout.1632. Run the public install command exactly as documented.1643. Start the installed artifact without relying on files from the source tree.1654. Repeat initialization, discovery, and one read-only invocation.1665. Remove the temporary destination after preserving the command output.167168An install string that was only inspected is unverified.169170## Output template171172Use this format:173174```markdown175# MCP Release QA176177Candidate: [commit]178Transport: [STDIO | Streamable HTTP | SSE]179Verdict: PASS | PASS WITH CAVEATS | FAIL180181## Commands and results182- `[exact command]` — [exit status and result]183184## Session transcript185- initialize: [result]186- discovery: [result]187- representative calls: [result]188- negative paths: [result]189190## Parity191| Identifier | Source | Runtime | Metadata | Docs | Result |192|---|---|---|---|---|---|193194## Findings195| Severity | Evidence | Impact | Narrowest fix |196|---|---|---|---|197198## Missing evidence199- [check that could not run and why]200```201202Use `FAIL` for a server that cannot start, complete a valid session, keep the203transport parseable, or safely reject invalid input. Use `PASS WITH CAVEATS`204only for bounded documentation or metadata drift that does not misrepresent a205dangerous capability. Otherwise use `PASS`.206207## Quality gate208209- [ ] A fresh candidate server was built and started from documented instructions.210- [ ] Initialization, discovery, and invocation ran in one valid MCP session.211- [ ] Source, runtime, metadata, and documentation inventories were compared by stable identifier.212- [ ] Negative paths returned useful protocol errors without side effects or leaked secrets.213- [ ] Published install commands were smoke-tested or missing evidence was reported.