Description
Observed (adcp 10.0.0b0)
A server pinned to AdCP 3.2 still hands its handlers requests upgraded to the packaged 3.3-beta.0:
import asyncio
from typing import Any
from adcp.server import ADCPHandler
from adcp.server.mcp_tools import create_tool_caller
class Seller(ADCPHandler[Any]):
_adcp_version = "3.2"
async def get_products(self, params, context=None):
print("handler sees adcp_version:", params.get("adcp_version") if isinstance(params, dict) else getattr(params, "adcp_version", None))
return {"products": []}
call = create_tool_caller(Seller(), "get_products", supported_versions=["3.2"])
asyncio.run(call({"adcp_version": "3.2", "buying_mode": "brief", "brief": "shoes"}))handler sees adcp_version: 3.3-beta.0
Cause: adcp/server/mcp_tools.py computes application_version = resolve_adcp_version(None), the packaged default, and converts every request from the wire version up to it. The handler's adcp_version pin and the server's supported_versions aren't consulted.
Why this is a bug, not just behaviour
MIGRATION_v9_to_v10.md says both things:
- "Pin
adcp_version="3.2"on a client or server that must keep a 3.2 contract." - "A
PlatformHandlerorcreate_adcp_server_from_platform(...)withsupported_versions=["3.2"]and noadcp_versionserves 3.2."
and also:
- "Handlers receive requests upgraded to
3.3-beta.0."
A seller that must keep a 3.2 contract can't, through any setting: its handler code and models see 3.3 payloads, and responses are converted down afterwards. A seller can't stay on a stable contract while the SDK's default is a pre-release.
Expected
The server's pinned (or newest supported) release is the application version requests are converted to, and responses are converted from. A 3.2-pinned seller's handlers then see 3.2. If that's not intended, the migration guide should say that a server pin governs only the wire, and that handler code always runs on the SDK's packaged release.
Impact
Found while exploring the Embedded Sales Agent on adcp 10 (draft scope3data/embedded-sales-agent#1042). ESA serves AdCP 3.2 natively. Its request hook had to treat an incoming adcp_version: "3.3-beta.0" (written by the SDK's upgrade) as its native 3.2. Its handlers now run on 3.3-beta models, so a pre-release protocol can change behaviour in a production seller.
Activity
fix(server)!: let a server's version pin set the release its handlers…
fix(server)!: let a server's version pin set the release its handlers…
bokelley commentedon Oct 29, 2026
Fixed on
nextby #1689: a server's pin (or the newest of itssupported_versions) sets the release its handlers run on, on every transport. It ships in SDK 10.0.0b1.