Tracking issue for adcontextprotocol/adcp#4339 — promoting the echoed authentication token from an undocumented additionalProperties: true round-trip to a typed property in mcp-webhook-payload.json.
Blocked on
adcontextprotocol/adcp#4339. Nothing to do here until the spec change merges and the schema cache updates.
What changes here when 4339 lands
-
Regenerate types. Once the spec PR merges, scripts/regenerate_* (or the existing schema sync flow) will produce a McpWebhookPayload whose token is a typed field (Annotated[str | None, Field(...)] = None) instead of an extras-bag entry.
-
Drop the extras path in create_mcp_webhook_payload. In src/adcp/webhooks.py, the current builder body has a special-case for token:
# `token` isn't a typed schema field but is accepted via `extra='allow'`;
# it round-trips through `model_dump`. Tracked upstream for promotion to
# a typed field on `mcp-webhook-payload.json`.
extras: dict[str, Any] = {}
if token is not None:
extras["token"] = token
That block goes away. token joins the other typed fields in the model_validate call.
-
Verify wire parity. The serialized output should be byte-identical pre/post — extra='allow' already round-tripped the field. Add a regression test that a payload built via the typed kwarg matches a hand-built dict on the wire.
-
Cross-reference downstream. salesagent and any other adopter that reads payload.get("token") from to_wire_dict(...) keeps working (no change in dict shape). Adopters using payload.token as an attribute now get a typed access path instead of model_extra["token"].
Non-goals
- No behavior change. This is purely typing/ergonomics —
token is still optional, still echoed verbatim, still matches the contract in push-notification-config.json.
- No deprecation needed; the kwarg signature stays the same.
How we'll know it's ready
McpWebhookPayload.model_fields includes token (currently it doesn't — the field surfaces only via model_extra).
Tracking issue for
adcontextprotocol/adcp#4339— promoting the echoed authenticationtokenfrom an undocumentedadditionalProperties: trueround-trip to a typed property inmcp-webhook-payload.json.Blocked on
adcontextprotocol/adcp#4339. Nothing to do here until the spec change merges and the schema cache updates.What changes here when 4339 lands
Regenerate types. Once the spec PR merges,
scripts/regenerate_*(or the existing schema sync flow) will produce aMcpWebhookPayloadwhosetokenis a typed field (Annotated[str | None, Field(...)] = None) instead of an extras-bag entry.Drop the extras path in
create_mcp_webhook_payload. Insrc/adcp/webhooks.py, the current builder body has a special-case fortoken:That block goes away.
tokenjoins the other typed fields in themodel_validatecall.Verify wire parity. The serialized output should be byte-identical pre/post —
extra='allow'already round-tripped the field. Add a regression test that a payload built via the typed kwarg matches a hand-built dict on the wire.Cross-reference downstream.
salesagentand any other adopter that readspayload.get("token")fromto_wire_dict(...)keeps working (no change in dict shape). Adopters usingpayload.tokenas an attribute now get a typed access path instead ofmodel_extra["token"].Non-goals
tokenis still optional, still echoed verbatim, still matches the contract inpush-notification-config.json.How we'll know it's ready
McpWebhookPayload.model_fieldsincludestoken(currently it doesn't — the field surfaces only viamodel_extra).