Skip to content

feat(server): add stateless discovery over HTTP - #1

Draft
bglusman wants to merge 4 commits into
faisalnazir7:feature/protocol-2026-07-28-dialectfrom
bglusman:feature/stateless-server-discovery
Draft

bglusman wants to merge 4 commits into
faisalnazir7:feature/protocol-2026-07-28-dialectfrom
bglusman:feature/stateless-server-discovery

Conversation

@bglusman

@bglusman bglusman commented Aug 5, 2026

Copy link
Copy Markdown

Problem

MCP 2026-07-28
removes protocol sessions and the initialization handshake, so servers need a
stateless way to advertise identity, capabilities, and supported versions before
clients send operational requests through
server/discover.

This is a draft stacked PR targeting your
feature/protocol-2026-07-28-dialect
branch directly. It contributes one child commit to
upstream PR #269, which adds
the stateless protocol dialect, era-aware registry, request metadata schema, and
reserved errors but intentionally exposes no modern behavior on the wire. This
PR advances, but does not close,
upstream issue #263.

Please review the focused child delta against zoedsoupe#269 here:
stateless discovery child diff.

Solution

  • Add Anubis.Server.Discovery to construct the transport-independent
    server/discover result from server metadata and protocol-filtered
    capabilities.
  • Route explicitly configured stateless versions from the existing Streamable
    HTTP Plug into a POST-only adapter while preserving the legacy GET/POST/DELETE
    path.
  • Validate Origin, exact Content-Type/Accept media types, per-request MCP
    metadata, and the standard MCP-Protocol-Version, Mcp-Method, and Mcp-Name
    headers. Base64 sentinel values are decoded before comparison.
  • Return the modern reserved errors and HTTP statuses for header mismatch,
    unsupported versions, and unknown methods.
  • Do not create or echo protocol sessions; ignore legacy Mcp-Session-Id and
    Last-Event-ID request headers.
  • Document the opt-in configuration and the intentionally incomplete scope.

This slice implements discovery only. Stateless tool/resource/prompt dispatch,
request-scoped SSE, subscriptions, MRTR, result caching, Mcp-Param-* headers,
and stateless client support remain follow-up work under
upstream issue #263.

Rationale

Discovery response shaping belongs to the server layer rather than the HTTP
adapter so future transports and clients can reuse the same contract. The HTTP
module remains responsible only for transport security, header/body consistency,
decoding, and status codes.

The modern path is explicit opt-in through protocol_versions: ["2026-07-28"].
Servers that advertise only legacy versions continue through the existing
session-oriented handlers and retain their previous unsupported-version response.

Validation

  • TDD red/green coverage for server discovery and stateless transport behavior.
  • mix test test/anubis/server/discovery_test.exs test/anubis/server/transport/streamable_http/stateless_test.exs test/anubis/server/transport/streamable_http/plug_test.exs — 45 passed.
  • mix test — 1,127 passed, 12 excluded.
  • mix lint — formatting, strict Credo, and Dialyzer passed.
  • git diff --check — passed.

Impact & Risk

Risk: medium. The feature is opt-in and has focused plus full-suite coverage,
but it changes the shared Streamable HTTP entrypoint and externally observable
protocol negotiation/error behavior. Cicada traces the in-repository path to
Plug.call/2 → Stateless.handle/3 → Discovery.result/2; consumers of the public
Plug are primarily external or dynamically mounted and cannot be enumerated here.

The child delta contains six files with 692 additions and 20 deletions. It has no
persistence, migration, authorization-policy, or destructive data behavior.

Skills Used

  • developing-with-tdd
  • writing-elixir-code
  • analyzing-change-impact
  • committing-changes-interactively
  • opening-pull-requests

faisalnazir7 and others added 4 commits July 31, 2026 21:45
Route explicitly configured 2026-07-28 requests through a POST-only stateless adapter, while keeping discovery response shaping in the server layer and preserving legacy transport behavior.

Add strict Origin, content negotiation, request metadata, and standard-header validation without creating protocol sessions. This is a dependent server slice for zoedsoupe#263, stacked on zoedsoupe#269.

Co-authored-by: Codex (GPT-5)
@faisalnazir7
faisalnazir7 force-pushed the feature/protocol-2026-07-28-dialect branch from 85fe48b to 40c3685 Compare August 6, 2026 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants