From c1c1f2a84e48f154c7da0354fc5a573dbde83c29 Mon Sep 17 00:00:00 2001 From: tom Date: Sat, 1 Aug 2026 10:00:39 +0200 Subject: [PATCH] Restructure specs/ as ADRs with a roadmap Legacy documents renumbered ADR_0001-0004 (Historical, preserved as-written); new ADRs 0005-0013 capture the open protocol-gap analysis (derived output schemas, definition metadata, progress, cancellation, MRTR, OAuth resource metadata, pagination/extensions, tasks extension, corpus extraction). ROADMAP.md orders them into batches; README points at both. Co-Authored-By: Claude Fable 5 --- README.md | 5 ++ specs/{SPEC.md => ADR_0001_original_spec.md} | 2 + ...md => ADR_0002_support_parameter_types.md} | 2 + ...MENTS.md => ADR_0003_test_improvements.md} | 2 + ...8.md => ADR_0004_upgrade_to_2025-06-18.md} | 2 + specs/ADR_0005_derived_output_schemas.md | 48 +++++++++++++ specs/ADR_0006_definition_metadata.md | 47 +++++++++++++ specs/ADR_0007_progress_notifications.md | 49 ++++++++++++++ specs/ADR_0008_request_cancellation.md | 46 +++++++++++++ specs/ADR_0009_mrtr_input_required.md | 50 ++++++++++++++ specs/ADR_0010_oauth_resource_metadata.md | 46 +++++++++++++ specs/ADR_0011_protocol_completeness.md | 42 ++++++++++++ specs/ADR_0012_tasks_extension.md | 36 ++++++++++ .../ADR_0013_conformance_corpus_extraction.md | 44 ++++++++++++ specs/README.md | 52 ++++++++++++++ specs/ROADMAP.md | 67 +++++++++++++++++++ 16 files changed, 540 insertions(+) rename specs/{SPEC.md => ADR_0001_original_spec.md} (97%) rename specs/{SUPPORT_PARAMETER_TYPES.md => ADR_0002_support_parameter_types.md} (94%) rename specs/{TEST_IMPROVEMENTS.md => ADR_0003_test_improvements.md} (97%) rename specs/{UPGRADE_TO_2025-06-18.md => ADR_0004_upgrade_to_2025-06-18.md} (90%) create mode 100644 specs/ADR_0005_derived_output_schemas.md create mode 100644 specs/ADR_0006_definition_metadata.md create mode 100644 specs/ADR_0007_progress_notifications.md create mode 100644 specs/ADR_0008_request_cancellation.md create mode 100644 specs/ADR_0009_mrtr_input_required.md create mode 100644 specs/ADR_0010_oauth_resource_metadata.md create mode 100644 specs/ADR_0011_protocol_completeness.md create mode 100644 specs/ADR_0012_tasks_extension.md create mode 100644 specs/ADR_0013_conformance_corpus_extraction.md create mode 100644 specs/README.md create mode 100644 specs/ROADMAP.md diff --git a/README.md b/README.md index 8527721..fbb1a2d 100644 --- a/README.md +++ b/README.md @@ -381,6 +381,11 @@ Haskell-specific — any MCP server implementation that reproduces the small reference server described in the corpus README can replay the requests and diff the responses. Contributions of new cases are welcome. +## Roadmap + +Design decisions and planned work live as ADRs under +[`specs/`](specs/README.md), ordered by [`specs/ROADMAP.md`](specs/ROADMAP.md). + ## Examples The library includes several examples: diff --git a/specs/SPEC.md b/specs/ADR_0001_original_spec.md similarity index 97% rename from specs/SPEC.md rename to specs/ADR_0001_original_spec.md index eebdc4a..f1cbf7b 100644 --- a/specs/SPEC.md +++ b/specs/ADR_0001_original_spec.md @@ -1,3 +1,5 @@ +> **ADR_0001 — Historical.** This document predates the ADR convention: it is preserved as-written (a working note from the time), renumbered for the index. New ADRs follow the format described in [README.md](README.md). + # NOTICE diff --git a/specs/SUPPORT_PARAMETER_TYPES.md b/specs/ADR_0002_support_parameter_types.md similarity index 94% rename from specs/SUPPORT_PARAMETER_TYPES.md rename to specs/ADR_0002_support_parameter_types.md index eed8401..6efd72f 100644 --- a/specs/SUPPORT_PARAMETER_TYPES.md +++ b/specs/ADR_0002_support_parameter_types.md @@ -1,3 +1,5 @@ +> **ADR_0002 — Historical.** This document predates the ADR convention: it is preserved as-written (a working note from the time), renumbered for the index. New ADRs follow the format described in [README.md](README.md). + # Support for better parameter types Currently, the mcp-server library supports defining Tools, Prompts and Resources like the following: diff --git a/specs/TEST_IMPROVEMENTS.md b/specs/ADR_0003_test_improvements.md similarity index 97% rename from specs/TEST_IMPROVEMENTS.md rename to specs/ADR_0003_test_improvements.md index f14c509..3e2d755 100644 --- a/specs/TEST_IMPROVEMENTS.md +++ b/specs/ADR_0003_test_improvements.md @@ -1,3 +1,5 @@ +> **ADR_0003 — Historical.** This document predates the ADR convention: it is preserved as-written (a working note from the time), renumbered for the index. New ADRs follow the format described in [README.md](README.md). + # Test Suite Improvement Recommendations ## Current State Analysis diff --git a/specs/UPGRADE_TO_2025-06-18.md b/specs/ADR_0004_upgrade_to_2025-06-18.md similarity index 90% rename from specs/UPGRADE_TO_2025-06-18.md rename to specs/ADR_0004_upgrade_to_2025-06-18.md index 0cf37e3..5532aff 100644 --- a/specs/UPGRADE_TO_2025-06-18.md +++ b/specs/ADR_0004_upgrade_to_2025-06-18.md @@ -1,3 +1,5 @@ +> **ADR_0004 — Historical.** This document predates the ADR convention: it is preserved as-written (a working note from the time), renumbered for the index. New ADRs follow the format described in [README.md](README.md). + Update the MCP Protocol version from: 2025-03-26 to 2025-06-18. **BREAKING CHANGE**: Remove backward compatibility. Server will ONLY support 2025-06-18. diff --git a/specs/ADR_0005_derived_output_schemas.md b/specs/ADR_0005_derived_output_schemas.md new file mode 100644 index 0000000..fafe55d --- /dev/null +++ b/specs/ADR_0005_derived_output_schemas.md @@ -0,0 +1,48 @@ +# ADR 0005: Derived output schemas and structured content + +- **Status**: Proposed +- **Date**: 2026-08-01 +- **Depends on**: — + +## Context + +Since 0.2.0 the protocol layer carries `outputSchema` on `ToolDefinition` +and `structuredContent` on tool results, but only manual handlers can +populate them — the Template Haskell derivation always emits +`toolDefinitionOutputSchema = Nothing`. Meanwhile the library's entire +thesis is that schemas fall out of ADTs: `inputSchema` is already derived +from the tool constructor's fields. + +The spec (2025-06-18+) also recommends that when a result carries +`structuredContent`, the serialized JSON is additionally included as a text +content block for clients that predate structured output. + +## Decision + +Extend the derive layer so a tool handler can return a typed result and get +the full structured-output story for free: + +- A new derivation (working name `deriveToolHandlerWithOutput`, or an + output-type annotation on the existing one) maps the handler's result + record to a generated `outputSchema` using the same `Schema` machinery as + input derivation (primitives, `Maybe`, lists, all-nullary enums, nested + records). +- At call time the typed result is serialized into `structuredContent`, and + the library also appends the spec-recommended text block containing the + same JSON, unless the handler supplied its own content. +- Plain `ToToolResult` handlers are untouched — this is opt-in per tool. + +## Consequences + +- Completes the typed core end-to-end (typed in, typed out); no other MCP + library derives both sides declaratively. +- New exports → PVP minor bump; can join the pending 0.2.1.x line. +- The schema generator is shared with input derivation, so schema-feature + work (e.g. richer JSON Schema keywords) benefits both directions. +- Golden corpus gains structured-output cases in both eras. + +## References + +- MCP 2025-06-18 changelog (structured tool output, `outputSchema`) +- 2026-07-28 loosened `outputSchema` to any JSON Schema 2020-12 keywords + (SEP-2106) diff --git a/specs/ADR_0006_definition_metadata.md b/specs/ADR_0006_definition_metadata.md new file mode 100644 index 0000000..cbdf323 --- /dev/null +++ b/specs/ADR_0006_definition_metadata.md @@ -0,0 +1,47 @@ +# ADR 0006: Tool annotations, icons, content annotations + +- **Status**: Proposed +- **Date**: 2026-08-01 +- **Depends on**: — + +## Context + +Three metadata features from recent protocol revisions are missing from our +definition and content types: + +- **Tool annotations** (2025-03-26): `readOnlyHint`, `destructiveHint`, + `idempotentHint`, `openWorldHint` on tool definitions. Clients use these + for permission UX (e.g. auto-approving read-only tools), so their absence + degrades how our servers are treated. +- **Icons** (2025-11-25): optional icon lists on tool/prompt/resource + definitions. +- **Content annotations** (2025-03-26): `audience`, `priority`, + `lastModified` on content blocks. The 0.2.0 plan named these ("Content + grows audio/resource-link/annotations") but the annotations part did not + land. + +## Decision + +- Add an `Annotations` record to `Content` variants (optional field, + omitted from JSON when absent) and `ToolAnnotations`/icon fields to the + definition types, serialized per spec. +- Extend the derive customization API: alongside the existing + `[("Constructor", "Description")]` mechanism, accept per-constructor + options (a small record — working name `ToolOptions` — carrying + annotations, icon, title) via a `WithOptions` variant. The plain + string-pair API stays as-is. + +## Consequences + +- Cheap, additive, PVP minor; a natural companion to ADR_0005 in the same + release batch. +- The `WithOptions` design decides the shape of all future per-constructor + customization — worth a moment of API design so we don't accrete N + `WithX` variants. +- Legacy golden fixtures are unaffected (new fields are omitted when + unset). + +## References + +- MCP 2025-03-26 changelog (ToolAnnotations, content annotations) +- MCP 2025-11-25 changelog (icons) diff --git a/specs/ADR_0007_progress_notifications.md b/specs/ADR_0007_progress_notifications.md new file mode 100644 index 0000000..ebd3289 --- /dev/null +++ b/specs/ADR_0007_progress_notifications.md @@ -0,0 +1,49 @@ +# ADR 0007: Progress notifications and per-request SSE + +- **Status**: Proposed +- **Date**: 2026-08-01 +- **Depends on**: — + +## Context + +A client may attach a `progressToken` to any request's `_meta`; the server +may then emit `notifications/progress` (progress, optional total, optional +message) while the request runs. We support none of this: handlers have no +way to report progress, and on HTTP every request is answered with a single +JSON object — whereas the Streamable HTTP spec expects request-scoped +notifications to flow on an SSE response stream for that request, which +clients MUST support. (Per-request `notifications/message` logging via the +`io.modelcontextprotocol/logLevel` `_meta` key rides the same mechanism and +can come along nearly for free.) + +## Decision + +- `ClientContext` gains a `reportProgress` action (progress → maybe total → + maybe message → IO ()). It is a no-op when the request carried no + `progressToken`, so handlers can call it unconditionally. +- **stdio**: progress notifications are written to the shared stdout + channel (under the existing write lock), interleaved before the response + — the spec's normal shape for stdio. +- **HTTP**: when a request carries a `progressToken`, the transport answers + with `Content-Type: text/event-stream` and streams progress notifications + followed by the final response, reusing the SSE plumbing built for + `subscriptions/listen` (`X-Accel-Buffering: no`, keep-alive comments). + Requests without a token keep the single-JSON-object response. +- Optionally in the same change: honor `io.modelcontextprotocol/logLevel` + by giving `ClientContext` a client-log action with the same delivery + rules (never emitted when the key is absent, per spec MUST NOT). + +## Consequences + +- Handler execution on HTTP moves inside a streaming response body; this is + the structural change that ADR_0008 (cancellation) builds on — do this + first. +- `ClientContext` grows; `anonymousContext` keeps construction stable. +- Golden corpus stays single-message per case; progress ordering gets its + own streaming tests (like the live subscription driver). + +## References + +- MCP 2026-07-28 Streamable HTTP: per-request SSE response streams +- Progress pattern: /specification/2026-07-28/basic/patterns/progress +- Logging via `_meta` logLevel: 2026-07-28 changelog (SEP-2575) diff --git a/specs/ADR_0008_request_cancellation.md b/specs/ADR_0008_request_cancellation.md new file mode 100644 index 0000000..2bf9395 --- /dev/null +++ b/specs/ADR_0008_request_cancellation.md @@ -0,0 +1,46 @@ +# ADR 0008: Cancellation of in-flight requests + +- **Status**: Proposed +- **Date**: 2026-08-01 +- **Depends on**: ADR_0007 + +## Context + +Handlers currently run synchronously to completion. `notifications/cancelled` +on stdio is honored only for subscription streams; a cancelled long-running +tool call still burns to the end, and on HTTP a client closing the response +stream (the modern cancellation signal — servers SHOULD stop work and MUST +NOT send further messages for the request) goes unnoticed. + +Alone this is plumbing without payoff: until ADR_0007 moves handler +execution into an async/streaming model, there is nothing to interrupt. It +only makes sense on top of that structure — which is why it is a separate +ADR sequenced after it. + +## Decision + +- Run request handlers in `async` tasks (new dependency or plain + `forkIO`+`MVar`). +- **stdio**: track in-flight requests by id; `notifications/cancelled` + cancels the async, and nothing further is written for that id. +- **HTTP**: detect response-stream closure (WAI write failure / Warp + connection teardown) and cancel the handler's async. +- Handlers opt into cooperative interruption simply by being interruptible + Haskell code (blocking calls, `IO`); we document that `killThread`-style + async exceptions are the mechanism, and that handlers needing cleanup + should use `bracket`. + +## Consequences + +- Concurrency surface grows: responses may now interleave differently on + stdio; the write lock and per-request bookkeeping need the same care as + the subscription registry. +- Async-exception safety becomes part of the handler contract and must be + documented prominently. +- Spec compliance: "SHOULD stop work as soon as practical, MUST NOT send + any further messages for it" becomes true instead of aspirational. + +## References + +- Cancellation pattern: /specification/2026-07-28/basic/patterns/cancellation +- Streamable HTTP: stream closure as cancellation (2026-07-28) diff --git a/specs/ADR_0009_mrtr_input_required.md b/specs/ADR_0009_mrtr_input_required.md new file mode 100644 index 0000000..2c30064 --- /dev/null +++ b/specs/ADR_0009_mrtr_input_required.md @@ -0,0 +1,50 @@ +# ADR 0009: MRTR — input_required results (elicitation) + +- **Status**: Proposed +- **Date**: 2026-08-01 +- **Depends on**: — + +## Context + +Revision 2026-07-28 replaced server-initiated requests (elicitation, +sampling, roots) with the Multi Round-Trip Request pattern: a server that +needs client input returns an `InputRequiredResult` +(`resultType: "input_required"`) whose `inputRequests` carry what it needs +(e.g. an `elicitation/create` payload); the client gathers the input and +**retries the original request** with `inputResponses` attached, plus any +opaque `requestState` the server included for correlation. + +We implement none of this — a tool handler cannot ask the user anything +mid-call. This is the largest missing capability class that is +spec-current. (Legacy `elicitation/create` as a server-initiated request is +deliberately out of scope: our transports do not send server-initiated +requests, and the feature is superseded.) + +## Decision + +- `ToolResult` (or a wrapping result type) gains an `input_required` + variant carrying typed `inputRequests` and an opaque `requestState`. +- The handler API lets a tool either complete or request input; on retry, + the handler receives the `inputResponses` and its own `requestState` + back. Because the server is stateless, all correlation state rides in + `requestState` — the library treats it as an opaque JSON value. +- Dispatch stamps `resultType: "input_required"` and the MRTR fields on the + modern envelope; legacy clients never see the variant (a handler + returning it to a legacy request gets a defined error, since legacy has + no retry semantics). +- A TH nicety can follow later: derive the elicitation input schema from a + record type, same machinery as ADR_0005. + +## Consequences + +- The headline feature of a future minor/major release; touches the result + types, so design it before (or with) any other result-shape change. +- Interacts with the era model: input_required is modern-only, another + place the dual-era split must stay honest. +- Golden corpus gains retry-cycle cases (initial → input_required → retry → + complete). + +## References + +- MRTR pattern: /specification/2026-07-28/basic/patterns/mrtr (SEP-2322) +- 2026-07-28 changelog items 7–8 (InputRequiredResult, resultType) diff --git a/specs/ADR_0010_oauth_resource_metadata.md b/specs/ADR_0010_oauth_resource_metadata.md new file mode 100644 index 0000000..32d54de --- /dev/null +++ b/specs/ADR_0010_oauth_resource_metadata.md @@ -0,0 +1,46 @@ +# ADR 0010: OAuth protected-resource metadata + +- **Status**: Proposed +- **Date**: 2026-08-01 +- **Depends on**: — + +## Context + +Our HTTP auth story is a deliberately minimal callback (`httpAuthorize` +receives the bearer token, returns a principal or rejects). The MCP +authorization spec expects a compliant HTTP server to also act as an OAuth +2.0 *protected resource*: serve RFC 9728 metadata at +`/.well-known/oauth-protected-resource` naming its authorization servers, +and return `401` with a `WWW-Authenticate` header pointing at that metadata +so clients can discover how to obtain a token. This discovery layer is what +lets MCP clients (Claude, inspector tooling) drive an OAuth flow +automatically — and it is the main functional advantage dpella/mcp +currently has (servant-auth JWT support). + +## Decision + +- Keep `httpAuthorize` as the validation primitive (the library still never + validates tokens itself). +- Add an optional `httpResourceMetadata` config: when set (authorization + server URLs, resource id, scopes), the transport serves the RFC 9728 + document at the well-known path and enriches `401` responses with the + spec-shaped `WWW-Authenticate` header. +- Token validation guidance (JWT verification against the AS's JWKS) goes + in documentation/examples rather than the library, avoiding a heavy + crypto dependency footprint; a separate optional package could offer a + ready-made JWT `httpAuthorize` later. + +## Consequences + +- Compliant discovery without hardcoding any particular token format; the + library stays dependency-light. +- Closes the practical gap with dpella/mcp for browser/agent-driven auth. +- Needs care with `httpEndpoint` vs the well-known path when users embed + `mcpApplication` in a larger router (document that the well-known path is + served at the root, or expose it as a second WAI app). + +## References + +- MCP authorization spec (2025-06-18+), RFC 9728, RFC 8414 +- 2026-07-28 auth changes: RFC 9207 `iss` validation, Client ID Metadata + Documents (client-side; server impact is documentation only) diff --git a/specs/ADR_0011_protocol_completeness.md b/specs/ADR_0011_protocol_completeness.md new file mode 100644 index 0000000..481f015 --- /dev/null +++ b/specs/ADR_0011_protocol_completeness.md @@ -0,0 +1,42 @@ +# ADR 0011: Pagination and the extensions capability + +- **Status**: Proposed +- **Date**: 2026-08-01 +- **Depends on**: — + +## Context + +Two small spec features round out protocol completeness: + +- **Pagination**: list operations accept a `cursor` param and may return + `nextCursor`. Clients MUST support pagination; servers MAY paginate. We + never paginate — fine for typical derived servers (a handful of tools), + a real limitation for the manual-handler user with hundreds of resources. +- **Extensions capability** (2026-07-28): `ServerCapabilities` gained an + `extensions` map (identifier → settings object) for negotiating optional + extensions. We have no way to populate it, which blocks advertising any + extension (including tasks, ADR_0012). + +## Decision + +- Add an opt-in page size to the list handlers' dispatch: when configured, + the library slices the handler-returned list and mints opaque cursors + (offset-based, encoded, treated as opaque by clients per spec). Handlers + keep returning full lists — pagination is a dispatch concern, keeping the + derive API untouched. (A streaming/chunked handler API is deliberately + out of scope until someone needs it.) +- Add `serverExtensions :: Map Text Value` to server configuration, + advertised in capabilities in both eras' capability objects. + +## Consequences + +- Additive, PVP minor; low urgency — schedule opportunistically or when a + user asks. +- Cursor stability across list changes is documented as best-effort (the + spec allows invalid-cursor errors: `-32602`). +- The `extensions` map is a prerequisite for ADR_0012. + +## References + +- Pagination: /specification/2026-07-28/server/utilities/pagination +- Extensions: 2026-07-28 changelog (minor change 1), versioning page diff --git a/specs/ADR_0012_tasks_extension.md b/specs/ADR_0012_tasks_extension.md new file mode 100644 index 0000000..6e005a5 --- /dev/null +++ b/specs/ADR_0012_tasks_extension.md @@ -0,0 +1,36 @@ +# ADR 0012: Tasks extension + +- **Status**: Hold — until the extension spec stabilizes and ADR_0007/0008 + have landed +- **Date**: 2026-08-01 +- **Depends on**: ADR_0007, ADR_0008, ADR_0011 (extensions capability) + +## Context + +Revision 2026-07-28 moved experimental tasks out of the core protocol into +an official extension (`io.modelcontextprotocol/tasks`), redesigning it in +the process: blocking `tasks/result` replaced by polling `tasks/get`, a new +`tasks/update` for client→server input, `tasks/list` removed, and servers +may return task handles unsolicited. It is the spec's answer to +long-running tool calls that outlive a request/response cycle — a natural +fit alongside our notifier machinery. + +## Decision (when taken up) + +Implement the extension behind the `extensions` capability map +(ADR_0011): a task-aware tool handler returns a task handle; the library +stores task state (pluggable store, default in-memory) and serves +`tasks/get`/`tasks/update`. Not before: the extension was redesigned in +this very revision and may move again, and the async execution model from +ADR_0007/0008 is a prerequisite for actually running anything in the +background. + +## Consequences + +- Parked deliberately; revisit when the extension has survived a revision + unchanged or a user asks for it. + +## References + +- 2026-07-28 changelog major change 6 (SEP-2663) +- Extension: /extensions/tasks/overview diff --git a/specs/ADR_0013_conformance_corpus_extraction.md b/specs/ADR_0013_conformance_corpus_extraction.md new file mode 100644 index 0000000..4ebbbc3 --- /dev/null +++ b/specs/ADR_0013_conformance_corpus_extraction.md @@ -0,0 +1,44 @@ +# ADR 0013: Extracting the conformance corpus + +- **Status**: Hold — until there is a second consumer (see issue #9) +- **Date**: 2026-08-01 +- **Depends on**: — + +## Context + +Since 0.2.1.0 the golden fixtures under `test/golden/` are a +self-describing, API-agnostic conformance corpus: on-disk +request/response pairs per protocol era, enumerated by a manifest, with +the reference server documented in prose. Nothing in it is +Haskell-specific — any MCP server implementation that reproduces the +reference server can replay the requests and diff the responses. + +Issue #9 (merge with dpella/mcp?) surfaced the appetite for shared +infrastructure between competing implementations ("at least sharing +mcp-types… agreeing on something like wai"). A neutral conformance corpus +is the cheapest such shared ground: it standardizes observable wire +behavior without forcing anyone's API or types on anyone else. + +## Decision (when taken up) + +Extract the corpus to its own repository with per-revision directories, +this library's CI consuming it as a pinned submodule/tarball, and an +invitation to dpella/mcp (and others) to run it in their CI. Grow cases as +features land here (structured output, MRTR retry cycles, progress +ordering). + +Not before there is a second consumer: extraction has real coordination +cost (versioning the corpus against spec revisions, governance of the +reference-server definition), and inside this repo the corpus already +delivers full value to us. The trigger is interest from another +implementation — at which point this is the concrete collaboration offer. + +## Consequences + +- Until extraction, keep the corpus scrupulously implementation-neutral + (no Haskell-isms in fixtures, manifest, or README) so extraction stays a + file move. + +## References + +- Issue #9; `test/golden/README.md` diff --git a/specs/README.md b/specs/README.md new file mode 100644 index 0000000..23b803f --- /dev/null +++ b/specs/README.md @@ -0,0 +1,52 @@ +# Architecture Decision Records + +Design decisions for mcp-server live here as numbered ADRs. Each records +the context, the decision, and its consequences — so future readers (and +future maintainers) can see not just what the library does but why. + +[ROADMAP.md](ROADMAP.md) orders the open ADRs into an intended sequence. + +## Statuses + +- **Proposed** — analysed and written up; not yet committed to. +- **Accepted** — we intend to build this; design is settled enough to start. +- **Landed** — implemented and merged (the ADR notes the version/PR). +- **Hold** — deliberately parked, with the unblocking condition stated. +- **Historical** — ADR_0001–0004 predate this convention: working notes + from earlier development, preserved as-written and renumbered. They are + not templates for new ADRs. + +## Format for new ADRs + +Filename `ADR_XXXX_short_slug.md`, numbered sequentially. Body: + +```markdown +# ADR XXXX: Title + +- **Status**: Proposed | Accepted | Landed (vX.Y.Z) | Hold +- **Date**: YYYY-MM-DD +- **Depends on**: ADR_XXXX (or —) + +## Context +## Decision +## Consequences +## References +``` + +## Index + +| ADR | Title | Status | +|---|---|---| +| [0001](ADR_0001_original_spec.md) | Original library specification | Historical | +| [0002](ADR_0002_support_parameter_types.md) | Support for better parameter types | Historical | +| [0003](ADR_0003_test_improvements.md) | Test suite improvements | Historical | +| [0004](ADR_0004_upgrade_to_2025-06-18.md) | Upgrade to protocol 2025-06-18 | Historical | +| [0005](ADR_0005_derived_output_schemas.md) | Derived output schemas and structured content | Proposed | +| [0006](ADR_0006_definition_metadata.md) | Tool annotations, icons, content annotations | Proposed | +| [0007](ADR_0007_progress_notifications.md) | Progress notifications and per-request SSE | Proposed | +| [0008](ADR_0008_request_cancellation.md) | Cancellation of in-flight requests | Proposed | +| [0009](ADR_0009_mrtr_input_required.md) | MRTR: input_required results (elicitation) | Proposed | +| [0010](ADR_0010_oauth_resource_metadata.md) | OAuth protected-resource metadata | Proposed | +| [0011](ADR_0011_protocol_completeness.md) | Pagination and the extensions capability | Proposed | +| [0012](ADR_0012_tasks_extension.md) | Tasks extension | Hold | +| [0013](ADR_0013_conformance_corpus_extraction.md) | Extracting the conformance corpus | Hold | diff --git a/specs/ROADMAP.md b/specs/ROADMAP.md new file mode 100644 index 0000000..1f03478 --- /dev/null +++ b/specs/ROADMAP.md @@ -0,0 +1,67 @@ +# Roadmap + +Where mcp-server is headed, as an ordering over the open +[ADRs](README.md#index). Dates are deliberately absent — releases are +batched (no release per feature), and the order reflects dependency and +value, not commitment. + +**Current state**: 0.2.0.0 is on Hackage (typed core, dual-era protocol +support for 2024-11-05…2025-11-25 via `initialize` and stateless +2026-07-28, resource templates, completions, change notifications with +`subscriptions/listen`). 0.2.1.0 sits merged-but-unreleased (WAI +application export, conformance corpus), soaking until enough accumulates. + +## Batch 1 — complete the typed core *(candidates to join the pending release)* + +Both are additive (PVP minor) and could ship with 0.2.1.x. + +1. [ADR_0005 — Derived output schemas and structured content](ADR_0005_derived_output_schemas.md). + The highest-leverage item: finishes the library's thesis (typed in, + typed out) and is a genuine differentiator. +2. [ADR_0006 — Tool annotations, icons, content annotations](ADR_0006_definition_metadata.md). + Cheap metadata that materially improves how clients treat our servers + (read-only/destructive hints drive permission UX). + +## Batch 2 — long-running tools + +3. [ADR_0007 — Progress notifications and per-request SSE](ADR_0007_progress_notifications.md). + The biggest behavioral gap vs the spec; also the structural change + (async, streaming HTTP responses) everything after it builds on. +4. [ADR_0008 — Cancellation of in-flight requests](ADR_0008_request_cancellation.md). + Only meaningful on top of ADR_0007's execution model — sequenced + immediately after, possibly the same release. + +## Batch 3 — interactivity + +5. [ADR_0009 — MRTR: input_required results](ADR_0009_mrtr_input_required.md). + The largest missing capability class (tools that ask the user for + input mid-call, the 2026-07-28 replacement for elicitation). Headline + of its own release; touches result types, so any result-shape changes + should co-design with it. + +## Opportunistic — order by demand + +- [ADR_0010 — OAuth protected-resource metadata](ADR_0010_oauth_resource_metadata.md): + do when an HTTP-deployment user needs discoverable auth; closes the + practical gap with dpella/mcp. +- [ADR_0011 — Pagination and the extensions capability](ADR_0011_protocol_completeness.md): + do when someone has enough tools/resources to care, or as the + prerequisite step for the tasks extension. + +## On hold, with stated triggers + +- [ADR_0012 — Tasks extension](ADR_0012_tasks_extension.md): wait for the + extension spec to stop moving and for Batch 2 to land. +- [ADR_0013 — Extracting the conformance corpus](ADR_0013_conformance_corpus_extraction.md): + wait for a second consumer (issue #9 is the likely origin). + +## Deliberate non-goals + +- **Roots, sampling, client-directed logging** — formally deprecated in + 2026-07-28; stderr (stdio) is the blessed logging channel and we already + use it. +- **Legacy `resources/subscribe`** — superseded by `subscriptions/listen`; + we advertise `subscribe` only to modern clients. +- **JSON-RPC batching and SSE resumability** — removed from the spec. +- **A per-feature release cadence** — releases are batched; CHANGELOG + entries carry `???` dates until the Hackage upload stamps them.