Skip to content

Add SEP-2663 Tasks Extension conformance scenarios #260

@panyam

Description

@panyam

Proposal

Add server-conformance scenarios for SEP-2663 (Tasks Extension),
SEP-2575 (per-request capability override), and SEP-2243
(Mcp-Method/Mcp-Name request headers) - all tagged 'extension' +
DRAFT_PROTOCOL_VERSION per PR #255 conventions.

Branch:
https://github.com/panyam/mcpconformance/tree/feat/tasks-mrtr-extension

Relationship to PR #188 (SEP-2322 MRTR by @CaitieM20)

This PR is complementary to #188, not overlapping. SEP-2663 builds
on SEP-2322's base types, so a few of the tasks scenarios touch the
MRTR shape (inputRequests, requestState, resultType discriminator)
in their tasks-on-the-wire form (status:"input_required" on
tasks/get, tasks/update resume path). The standalone-ephemeral-MRTR
coverage stays in #188.

The branch also contains a src/scenarios/server/mrtr/ folder with
ephemeral-flow scenarios mirroring some of #188's checks. Those exist
because the tasks reference fixture exercises the full MRTR base, and
running them locally caught a real bug. For the upstream merge:

  • If Conformance Tests for SEP-2322 MRTR #188 lands first (expected order - SEP-2322 ships before
    SEP-2663), I'll drop the duplicative mrtr-ephemeral-flow.ts checks
    in favor of Conformance Tests for SEP-2322 MRTR #188's scenarios.
  • The mrtr-tasks-composition check (currently SKIPPED) is the
    genuinely new contribution this PR makes to MRTR coverage - it
    asserts SEP-2663 commit 451f5e1's MRTR→Tasks promotion flow.

Scope

Tasks scenarios (src/scenarios/server/tasks/, 8 ClientScenario
classes, ~33 checks):

  • tasks-lifecycle - sync vs task dispatch, DetailedTask shape, tool
    errors vs protocol errors, cancel ack, cancel-on-terminal -32602
  • tasks-capability-negotiation - extension advertised under
    capabilities.extensions; tasks/* gated behind negotiation;
    SEP-2575 per-request opt-in
  • tasks-wire-fields - ttlSeconds / pollIntervalMilliseconds
    renames, no-early-TTL-expiry, no related-task _meta on inlined result
  • tasks-request-state - optional emission, echo acceptance,
    stale-but-valid tolerance (the tasks-surface form of requestState)
  • tasks-mrtr-input - inputRequests on tasks/get, tasks/update
    resume, partial-fulfillment with multi-input fixture
  • tasks-request-headers - SEP-2243 server tolerates routing headers;
    body authoritative when conflicting
  • tasks-dispatch-and-envelope - removed v1 methods (-32601), legacy
    task param ignored, resultType:"complete" on every non-task
    response, immediate-tasks/get strong consistency, tasks/get unknown
    taskId -32602
  • tasks-status-notifications - optional INFO check (notifications
    are MAY per spec)

Design notes

  • Platform/language-agnostic runner. Fixture configured via
    env vars TASKS_SERVER_URL / TASKS_SERVER_CMD. Spawn is via
    sh -c, readiness via TCP polling. Anyone's server in any language
    works. Suite is describe.skip'd when env vars are unset, so default
    CI runs against everything-server stay green until that fixture
    grows extension support.
  • Raw-fetch escape hatch. The MCP TS SDK's typed schemas strip
    extension fields (resultType, taskId, inputRequests,
    requestState, inlined result/error). Helpers in
    src/scenarios/server/tasks/helpers.ts provide initRawSession +
    rawRequest/rawRequestFull so scenarios read those fields
    directly. When the SDK gains schemas for SEP-2663 wire shapes, the
    call sites switch to client.request(..., AnyResult) and the helper
    shrinks. (Similar in spirit to the raw-MCP additions in Conformance Tests for SEP-2322 MRTR #188 -
    could converge on a shared helper if you'd like.)
  • Registered in pendingClientScenariosList -
    all-scenarios.test.ts skips the suite since everything-server
    doesn't implement the extension yet. CLI lookup
    (getClientScenario(name)) still finds them.
  • One example reference fixture (any-language is fine):
    https://github.com/panyam/mcpkit/tree/main/examples/tasks-v2

Open spec questions

  1. MRTR resultType discriminator value. SEP-2322's draft uses
    "input_required"; SEP-2663's draft uses "incomplete". Centralized
    as MRTR_INCOMPLETE_RESULT_TYPE so it's a one-line flip when SEP
    authors converge.
  2. mrtr-tasks-composition. SEP-2663 commit 451f5e1 made the
    MRTR→Tasks promotion flow normative on the wire: a single
    tools/call MAY exchange one or more IncompleteResult rounds
    and then return CreateTaskResult on a subsequent round.
    Implementing this requires the server middleware to defer task
    creation until the handler signals async-promotion - the natural
    alternative (mint the task up-front the moment a tool advertises
    task support) doesn't fit, because by the time the handler's
    IsIncomplete signal is observable, the CreateTaskResult is
    already on the wire. This is a wire-contract requirement, not an
    SDK-specific implementation choice; existing SDKs across languages
    that took the up-front pattern will need refactoring before this
    check can pass anywhere. Combined with Adjust test and allow running in interactive mode #1 above, that's why the
    check is SKIPPED today.

Testing

  TASKS_SERVER_URL=http://localhost:18092/mcp
  TASKS_SERVER_CMD="/path/to/tasks-fixture --serve --addr :18092"
  MRTR_SERVER_URL=http://localhost:18093/mcp
  MRTR_SERVER_CMD="/path/to/mrtr-fixture --serve --addr :18093"
    npx vitest run src/scenarios/server/

Branch passes:

Against reference Go fixtures. Happy to drop the duplicative MRTR ephemeral checks once #188 lands; the mrtr-tasks-composition skip would rebase onto whatever fixture #188 settles on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions