Skip to content

feat: Add MCP 2026-07-28 stateless server #1140

Description

@jirispilka

Part of #1128. Depends on #1139, #1145, #1146, and #1147. The shared tool-call engine from #1139 is already merged.

Context and motivation

Add a 2026-07-28 stateless registration surface without changing the existing sessionful 2025-era server. PR #1143 is a spike and reference only; this issue defines its replacement after the behavior-preserving refactors land.

Scope

In scope

  • Add the v2 SDK dependencies alongside v1: @modelcontextprotocol/server, pinned exact while in beta (2.0.0-beta.5 as of 2026-07-24). The v2 package name differs from v1's @modelcontextprotocol/sdk, so both install side by side.
  • Export createStatelessServer(actorsMcpServer) from the package root.
  • Register tools/list, tools/call, resources/*, and prompts/* as a thin protocol adapter over ActorsMcpServer shared logic.
  • Normalize v2 per-request client context at the adapter boundary.
  • Read the Apify token from ctx.http?.authInfo?.token, with the existing configured-token fallback where applicable.
  • createMcpHandler performs no token verification and never derives authInfo from request headers — it is caller-supplied. The dev server therefore needs a bearer-passthrough shim that lifts the Authorization header into ctx.http.authInfo; hosted auth stays server-derived (see internal repo impact).
  • Build a fresh request-scoped tool snapshot and resolve mode and report-problem visibility per request.
  • Map neutral service and tool-call outcomes to v2 ProtocolError and projectCallToolResult.
  • Wire src/dev_server.ts with isLegacyRequest and createMcpHandler; legacy requests continue through the current sessionful route.
  • Add development-server routing tests for both protocol eras.

Out of scope

Technical design

Construct one v2 Server per request, as required by createMcpHandler. The adapter converts the v2 ServerContext to the neutral client and call contexts, asks the facade for a request-scoped tool snapshot, and delegates to shared tool, prompt, resource, and telemetry logic. It owns only v2 registration and error/result projection.

Use stateless or the dated revision in our names and docs. The SDK literal modern may appear only where its external API requires it.

The development server is mandatory. It must expose both the existing sessionful route and the new stateless route through the same endpoint so local tests match hosted routing.

Public API

  • Add createStatelessServer(actorsMcpServer): Server.
  • Keep ActorsMcpServer and all existing exports source-compatible.

Internal repo impact

Internal issue apify/apify-mcp-server-internal#676 consumes this export through createMcpHandler. It must wait for a public package release or pkg.pr.new build. Auth stays server-derived and request-scoped.

Testing strategy

Unit tests

  • Handler registration and advertised capabilities.
  • Per-request client identity, capabilities, protocol version, mode, and report-problem gating.
  • Auth token precedence and request-origin attribution.
  • Tool list and call parity for INTERNAL, ACTOR, and ACTOR_MCP tools.
  • Prompt and resource delegation and v2 error projection.
  • Tasks return method-not-found through the SDK.
  • Development-server legacy/stateless routing.

Manual gate

After pnpm run build:

  1. Start src/dev_server.ts through the package script.
  2. Run the v2 client against the stateless route.
  3. Run the official conformance command from test: Add MCP 2026-07-28 integration and conformance coverage #1132 against the same endpoint.
  4. Run mcpc against @stdio to confirm the legacy server remains unchanged.

Verification checklist

  • pnpm run type-check
  • pnpm run lint
  • pnpm run test:unit
  • pnpm run format
  • pnpm run check:agents
  • Development server serves both protocol eras
  • Applicable 2026-07-28 conformance scenarios pass
  • Legacy mcpc smoke test passes
  • Internal contract impact coordinated

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    t-aiIssues owned by the AI team.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions