> ## Documentation Index
> Fetch the complete documentation index at: https://mcpjam-mintlify-docs-update-pr-3762-1786137034119.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Tasks Conformance

> Validate MCP Tasks wire behavior — legacy and SEP-2663 extension — from the CLI

The `tasks conformance` command validates the MCP Tasks wire your server exposes: which wire the connection resolves to, whether declaration hygiene holds for that wire, and whether the server honours the observable parts of the contract (result-type discipline, `-32003` on undeclared requests, TTL shapes, inline results, and `Mcp-Name` routing for HTTP transports).

<Note>
  Tasks conformance provokes and then polls a real task, so it requires a
  persistent connection. It is not available in hosted mode.
</Note>

## Quick start

```bash theme={"theme":"css-variables"}
mcpjam tasks conformance --url https://your-server.com/mcp
```

For a local stdio server:

```bash theme={"theme":"css-variables"}
mcpjam tasks conformance --command node --args server.js --cwd /path/to/project
```

On the extension wire you must name the probe tool. Auto-selection reads `execution.taskSupport`, which the 2026-07-28 `ToolSchema` strips, so a tasks-extension server cannot advertise which tool creates a task. Without `--tool-name` the six task-dependent checks cannot run and the command reports `"outcome": "incomplete"` (exit code `3`) rather than a green run:

```bash theme={"theme":"css-variables"}
mcpjam tasks conformance \
  --url https://your-server.com/mcp \
  --tool-name long_job
```

A `--tool-name` the server does not list is treated the same way: the run is incomplete, and the message names both the tool you asked for and the tools the server actually lists.

Emit CI-friendly JUnit XML:

```bash theme={"theme":"css-variables"}
mcpjam tasks conformance \
  --url https://your-server.com/mcp \
  --reporter junit-xml > tasks-report.xml
```

## What it checks

| Check id                               | Category    | What it asserts                                                                                                                                                                                                                                                               |
| -------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tasks-wire-resolvable`                | `dispatch`  | The negotiated protocol version and capabilities resolve to exactly one tasks wire.                                                                                                                                                                                           |
| `tasks-declaration-hygiene`            | `dispatch`  | Outbound requests carry `params.task` only on the legacy wire and the extension declaration only on the extension wire.                                                                                                                                                       |
| `tasks-result-type-discipline`         | `creation`  | A task-eligible `tools/call` returns either a normal tool result or a flat `CreateTaskResult` with `resultType: "task"` and a non-empty `taskId`. The discriminator is required whether absent or wrong — it is the only signal that separates a task from a standard result. |
| `tasks-undeclared-creation-refused`    | `creation`  | On the extension wire, a `tools/call` that did not carry the extension declaration must not come back as a `CreateTaskResult`; the server must answer normally or reject with `-32003`.                                                                                       |
| `tasks-ttl-shape`                      | `lifecycle` | TTL and poll interval use the era-native shapes: `ttlMs`/`pollIntervalMs` on the extension, `ttl`/`pollInterval` on the legacy wire.                                                                                                                                          |
| `tasks-inline-result`                  | `lifecycle` | A completed extension task carries its result inline on `tasks/get`; a legacy task exposes it via `tasks/result`.                                                                                                                                                             |
| `tasks-mcp-name-routing`               | `lifecycle` | Over HTTP, `tasks/get` is sent with `Mcp-Name` set to the task id.                                                                                                                                                                                                            |
| `tasks-undeclared-capability-rejected` | `lifecycle` | `tasks/get`, `tasks/update`, `tasks/cancel` and a task-filtered `subscriptions/listen` sent WITHOUT the extension declaration must each be rejected with `-32003`.                                                                                                            |

## Categories and check ids

Three categories are available:

* `dispatch`
* `creation`
* `lifecycle`

Use `--category` to run a subset by category, or `--check-id` to run specific checks:

```bash theme={"theme":"css-variables"}
# Dispatch checks only
mcpjam tasks conformance \
  --url https://your-server.com/mcp \
  --category dispatch

# Specific checks
mcpjam tasks conformance \
  --url https://your-server.com/mcp \
  --check-id tasks-ttl-shape \
  --check-id tasks-inline-result
```

<Note>
  If you pass both `--category` and `--check-id`, the explicit `--check-id`
  selection wins.
</Note>

## Options

| Flag                    | Description                                                                                                |
| ----------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--category <category>` | Check category to run. Repeat for multiple. Default: all.                                                  |
| `--check-id <id>`       | Specific check id to run. Repeat for multiple. Default: all.                                               |
| `--tool-name <tool>`    | Tool used to provoke a task. Required for servers whose tools carry no task metadata (the extension wire). |
| `--tool-args <json>`    | Tool arguments as a JSON object.                                                                           |
| `--poll-timeout <ms>`   | How long to poll a created task for a terminal status. Default: `30000`.                                   |
| `--reporter <reporter>` | Structured reporter output: `json-summary` or `junit-xml`.                                                 |

## Example output

```bash theme={"theme":"css-variables"}
mcpjam tasks conformance \
  --url https://your-server.com/mcp \
  --tool-name long_job \
  --format json
```

Typical success summary:

```json theme={"theme":"css-variables"}
{
  "passed": true,
  "outcome": "passed",
  "summary": "8/8 checks passed, 0 failed, 0 could not run, 0 not applicable",
  "discovery": {
    "protocolVersion": "2026-07-28",
    "wire": "extension",
    "toolCount": 3,
    "taskCapableToolCount": 1,
    "probedTool": "long_job",
    "createdTaskId": "task-abc123"
  }
}
```

## Outcomes: passed, failed, incomplete

A run reports one of three outcomes, and `passed` is `true` only for the first:

| `outcome`    | Exit code | Meaning                                                                                                      |
| ------------ | --------- | ------------------------------------------------------------------------------------------------------------ |
| `passed`     | `0`       | Every selected check either ran and passed, or does not apply to this server.                                |
| `failed`     | `1`       | At least one check found a violation.                                                                        |
| `incomplete` | `3`       | Nothing failed, but at least one selected check could not be run, so the run does not establish conformance. |

Every skipped check says which kind of skip it is in `skipReason`:

* `not-applicable` — the check cannot apply here (an extension-only check on a legacy connection, `Mcp-Name` routing over stdio, any task check on a connection with no tasks wire). These never hold a run back.
* `could-not-run` — the check applies but was never exercised (no probe tool resolved, the named tool is not listed, the tool produced no task, the task never became readable). These make the run `incomplete`.

An incomplete run carries a root `incompleteReason` naming the checks that did not run and what to change; non-quiet runs also print it to stderr. A skipped check can never add up to a passing verdict.

## Shared connection flags

`tasks conformance` uses the same shared target flags as the rest of the CLI:

| Flag                           | Description                                                   |
| ------------------------------ | ------------------------------------------------------------- |
| `--transport <transport>`      | Explicit transport type (`http` or `stdio`)                   |
| `--url <url>`                  | HTTP MCP server URL                                           |
| `--access-token <token>`       | Bearer access token                                           |
| `--oauth-access-token <token>` | OAuth bearer access token                                     |
| `--refresh-token <token>`      | OAuth refresh token                                           |
| `--client-id <id>`             | OAuth client ID (with `--refresh-token`)                      |
| `--client-secret <secret>`     | OAuth client secret (with `--refresh-token`)                  |
| `--header <header>`            | HTTP header in `Key: Value` format (repeatable)               |
| `--client-capabilities <json>` | Client capabilities as inline JSON, `@path`, or `-` for stdin |
| `--command <command>`          | Command for a stdio server                                    |
| `--args <arg...>`              | Preferred stdio command arguments                             |
| `--command-args <arg>`         | Legacy stdio command argument (repeatable)                    |
| `-e, --env <env...>`           | Stdio environment `KEY=VALUE` values                          |
| `--cwd <path>`                 | Working directory for the stdio child process                 |

`--transport` is optional; without it, `--url` implies HTTP and `--command` implies stdio.

## Notes

* Exit codes are CI-friendly: `0` when all selected checks pass, `1` when any check fails, `2` for invalid command usage, and `3` when the run is incomplete because a selected check could not be run.
* Declaration hygiene is asserted against captured outbound JSON-RPC bytes, not re-derived from intent.
* The undeclared-request checks (`tasks-undeclared-creation-refused`, `tasks-undeclared-capability-rejected`) apply to the extension wire only and are skipped on the legacy wire.
* `tasks-undeclared-capability-rejected` needs a live task to probe with, so it is reported as `could-not-run` (and the run as incomplete) when no task could be provoked. Its probes run last, after every check that reads the task, because a server that wrongly accepts an undeclared `tasks/update` or `tasks/cancel` would otherwise mutate the very task the other checks inspect. If the server does not implement `subscriptions/listen` at all (`-32601`), that sub-probe is reported as a warning instead of a failure.
* The `tasks-mcp-name-routing` check applies to HTTP transports only and is skipped for stdio servers.
* Checks that require a created task cannot run when no probe tool resolves. That is a `could-not-run` skip, so the command exits `3` instead of reporting a pass — pass `--tool-name` to fix it.

## Related commands

* [Apps conformance](/cli/apps-conformance) for MCP Apps surface validation
* [Server inspection](/cli/server-inspection) for breadth-first connectivity and capability triage
* [Command reference](/cli/reference) for the full flag list
