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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions