Skip to content

Server: add configurable unknown-field policy before tool argument coercion #858

@bokelley

Description

@bokelley

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions