Problem
Server-side tool calls can currently pass through permissive SDK/FastMCP request models before adopter-specific strict models see the raw arguments. That can allow unknown top-level tool fields to be accepted or silently dropped, especially on MCP.
In salesagent this caused a regression where dev/CI no longer failed loudly for payloads such as:
{
"brief": "test ads",
"nonsense_field": "bar"
}
The local workaround in salesagent PR #603 adds pre-validation hooks that:
- normalize legacy fields first
- reject unknown top-level fields in non-production/dev mode
- strip unsupported unknown fields in production/forward-compatible mode
- cover advertised write tools such as
create_media_buy, not only read tools
Why this belongs in the SDK
This is a generic transport-boundary concern, not a seller-specific business rule. The SDK already owns:
- MCP/A2A dispatch
- request validation hooks
- generated tool schemas
- canonical error envelopes
If the SDK handles this centrally, every adopter gets consistent behavior before permissive Pydantic models can swallow extras.
Suggested API
One possible shape:
from adcp.validation import UnknownFieldPolicy, ValidationHookConfig
serve(
handler,
validation=ValidationHookConfig(
unknown_fields=UnknownFieldPolicy.REJECT, # or STRIP / IGNORE
),
)
or a simpler top-level option:
serve(handler, unknown_fields="reject") # "strip" / "ignore"
The key is that this should run before tool argument validation/coercion on both MCP and A2A.
Expected behavior
reject: fail loudly with canonical INVALID_REQUEST, including the unknown field path/name.
strip: remove unsupported unknown top-level fields before validation, for forward-compatible production deployments.
ignore: preserve current permissive behavior when adopters explicitly want it.
- Behavior should be transport-consistent for MCP and A2A.
- Regression tests should include mutating tools such as
create_media_buy, because accepting unknown fields on write operations is the highest-risk path.
Reference
Salesagent fixed this locally in PR #603: bokelley/salesagent#603
Problem
Server-side tool calls can currently pass through permissive SDK/FastMCP request models before adopter-specific strict models see the raw arguments. That can allow unknown top-level tool fields to be accepted or silently dropped, especially on MCP.
In salesagent this caused a regression where dev/CI no longer failed loudly for payloads such as:
{ "brief": "test ads", "nonsense_field": "bar" }The local workaround in salesagent PR #603 adds pre-validation hooks that:
create_media_buy, not only read toolsWhy this belongs in the SDK
This is a generic transport-boundary concern, not a seller-specific business rule. The SDK already owns:
If the SDK handles this centrally, every adopter gets consistent behavior before permissive Pydantic models can swallow extras.
Suggested API
One possible shape:
or a simpler top-level option:
The key is that this should run before tool argument validation/coercion on both MCP and A2A.
Expected behavior
reject: fail loudly with canonicalINVALID_REQUEST, including the unknown field path/name.strip: remove unsupported unknown top-level fields before validation, for forward-compatible production deployments.ignore: preserve current permissive behavior when adopters explicitly want it.create_media_buy, because accepting unknown fields on write operations is the highest-risk path.Reference
Salesagent fixed this locally in PR #603: bokelley/salesagent#603