Skip to content

feat(webhooks): drop extra='allow' token round-trip once adcp#4339 lands #638

Description

@bokelley

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

  1. 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.

  2. 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.

  3. 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.

  4. 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).

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions