You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
Tasks on 2026-07-28.
subscriptions/listen.
Rewriting the legacy HTTP stack.
Adding stateless-only behavior to the private legacy adapter.
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.
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:
Start src/dev_server.ts through the package script.
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
@modelcontextprotocol/server, pinned exact while in beta (2.0.0-beta.5as of 2026-07-24). The v2 package name differs from v1's@modelcontextprotocol/sdk, so both install side by side.createStatelessServer(actorsMcpServer)from the package root.tools/list,tools/call,resources/*, andprompts/*as a thin protocol adapter overActorsMcpServershared logic.ctx.http?.authInfo?.token, with the existing configured-token fallback where applicable.createMcpHandlerperforms no token verification and never derivesauthInfofrom request headers — it is caller-supplied. The dev server therefore needs a bearer-passthrough shim that lifts theAuthorizationheader intoctx.http.authInfo; hosted auth stays server-derived (see internal repo impact).report-problemvisibility per request.ProtocolErrorandprojectCallToolResult.src/dev_server.tswithisLegacyRequestandcreateMcpHandler; legacy requests continue through the current sessionful route.Out of scope
subscriptions/listen.add-actor; that remains PR 2: delete add-actor implementation #1131.Technical design
Construct one v2
Serverper request, as required bycreateMcpHandler. The adapter converts the v2ServerContextto 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
statelessor the dated revision in our names and docs. The SDK literalmodernmay 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
createStatelessServer(actorsMcpServer): Server.ActorsMcpServerand 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 orpkg.pr.newbuild. Auth stays server-derived and request-scoped.Testing strategy
Unit tests
report-problemgating.Manual gate
After
pnpm run build:src/dev_server.tsthrough the package script.mcpcagainst@stdioto confirm the legacy server remains unchanged.Verification checklist
pnpm run type-checkpnpm run lintpnpm run test:unitpnpm run formatpnpm run check:agentsmcpcsmoke test passes