Summary
The SDK request path rejects AdCP 3.1 beta-four create_media_buy requests that use packages[].optimization_goals[].kind: "vendor_metric" before the request reaches the seller.
In the AdCP training-agent storyboards, this forced the vendor-metric create_media_buy steps to use raw MCP auth instead of the normal SDK client path.
Repro from adcontextprotocol/adcp
Branch/workspace context: bokelley/finish-4591, AdCP 3.1.0-beta.4, SDK @adcp/sdk 7.11.
The storyboard request shape is in:
static/compliance/source/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml
Representative payload fragment:
packages:
- product_id: "$context.product_id"
pricing_option_id: "$context.pricing_option_id"
budget: 5000
optimization_goals:
- kind: "vendor_metric"
vendor:
domain: "attentionvendor.example"
metric_id: "attention_score"
target:
kind: "threshold_rate"
value: 70
priority: 1
committed_metrics:
- scope: "vendor"
vendor:
domain: "attentionvendor.example"
metric_id: "attention_score"
When the storyboard step uses the SDK path, request validation fails before the training agent handler sees the request. The local failure observed from the storyboard runner was:
Request validation failed for create_media_buy: packages.0.optimization_goals.0: Invalid input
After switching the storyboard steps to raw MCP auth, the same training-agent behavior passes:
TENANT_PATH=sales PUBLIC_TEST_AGENT_TOKEN=${PUBLIC_TEST_AGENT_TOKEN:-storyboard-local-token} \
npx tsx server/tests/manual/run-storyboards.ts \
--filter vendor_metric_optimization_flow --verbose
Result:
media_buy_seller/vendor_metric_optimization_flow
✓ 11P / 1S / 0N/A
Expected behavior
The SDK request validator and typed client path should accept the AdCP 3.1 vendor_metric optimization goal shape for create_media_buy, including:
optimization_goals[].kind: "vendor_metric"
optimization_goals[].vendor.domain
optimization_goals[].metric_id
- optional
optimization_goals[].target.kind, such as threshold_rate
- optional numeric
optimization_goals[].target.value
- coherence with vendor-scoped
committed_metrics[] remaining a seller/runtime validation concern, not a SDK schema rejection
Why this matters
Without this, SDK buyers cannot exercise a 3.1 beta-four feature through the normal SDK path and must drop to raw MCP. The compliance runner can work around this, but production SDK users should not need the raw transport escape hatch.
Summary
The SDK request path rejects AdCP 3.1 beta-four
create_media_buyrequests that usepackages[].optimization_goals[].kind: "vendor_metric"before the request reaches the seller.In the AdCP training-agent storyboards, this forced the vendor-metric
create_media_buysteps to use raw MCP auth instead of the normal SDK client path.Repro from adcontextprotocol/adcp
Branch/workspace context:
bokelley/finish-4591, AdCP3.1.0-beta.4, SDK@adcp/sdk7.11.The storyboard request shape is in:
static/compliance/source/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yamlRepresentative payload fragment:
When the storyboard step uses the SDK path, request validation fails before the training agent handler sees the request. The local failure observed from the storyboard runner was:
After switching the storyboard steps to raw MCP auth, the same training-agent behavior passes:
TENANT_PATH=sales PUBLIC_TEST_AGENT_TOKEN=${PUBLIC_TEST_AGENT_TOKEN:-storyboard-local-token} \ npx tsx server/tests/manual/run-storyboards.ts \ --filter vendor_metric_optimization_flow --verboseResult:
Expected behavior
The SDK request validator and typed client path should accept the AdCP 3.1
vendor_metricoptimization goal shape forcreate_media_buy, including:optimization_goals[].kind: "vendor_metric"optimization_goals[].vendor.domainoptimization_goals[].metric_idoptimization_goals[].target.kind, such asthreshold_rateoptimization_goals[].target.valuecommitted_metrics[]remaining a seller/runtime validation concern, not a SDK schema rejectionWhy this matters
Without this, SDK buyers cannot exercise a 3.1 beta-four feature through the normal SDK path and must drop to raw MCP. The compliance runner can work around this, but production SDK users should not need the raw transport escape hatch.