From adcp-client
Use when building an AdCP governance agent — campaign governance (spending authority, approval/denial), property/collection lists for brand safety, or content standards for creative compliance.
npx claudepluginhub adcontextprotocol/adcp-client --plugin adcp-clientThis skill uses the workspace's default tool permissions.
A governance agent enforces policy on the buy side. It evaluates spending authority, maintains property and collection lists, and defines content standards. There is no dedicated `hello_governance_adapter_*.ts` yet — this skill collapses against the seller adapter pattern and the documented tool surface.
Execute AdCP Governance Protocol operations with governance agents - manage property lists, collection lists, content standards, and campaign governance (plans, checks, outcomes, audit trail). Use when users want to create include/exclude lists, set up brand safety rules, validate content delivery, register campaign plans, validate actions against policy, or produce internal/shareable audit trails.
Implements governance patterns for AI agents: policy-based tool controls, intent classification, trust scoring, audit trails, rate limits. For LangChain, CrewAI, OpenAI Agents.
Governs AI agent MCP tool calls with Cedar policy authoring, shadow-to-enforce rollout, and Ed25519 receipt verification for tamper-evident audits.
Share bugs, ideas, or general feedback.
A governance agent enforces policy on the buy side. It evaluates spending authority, maintains property and collection lists, and defines content standards. There is no dedicated hello_governance_adapter_*.ts yet — this skill collapses against the seller adapter pattern and the documented tool surface.
| Specialism | Status | Fork this | Storyboard |
|---|---|---|---|
governance-spend-authority | stable | hello_seller_adapter_multi_tenant.ts — campaignGovernance block | governance_spend_authority |
governance-delivery-monitor | stable | Same; add phase: 'delivery' branch on checkGovernance | governance_delivery_monitor |
property-lists | stable | hello_seller_adapter_multi_tenant.ts — propertyLists block | property_lists |
collection-lists | stable | Same shape as property-lists; add IMDb/Gracenote/EIDR resolution | placeholder |
content-standards | stable | Add contentStandards domain group via defineContentStandardsPlatform | placeholder |
measurement-verification | preview | v3.1 placeholder. Baseline only. | placeholder |
The multi-tenant adapter is the canonical fork target — it implements campaignGovernance (sync_plans, check_governance, report_plan_outcome, get_plan_audit_logs), propertyLists (CRUD + validate_property_delivery), and brandRights against a per-tenant in-memory store with full tenant isolation via createTenantStore.
Forking the multi-tenant adapter for a single specialism? Delete these blocks first — leaning on stable symbol names rather than line numbers (the adapter evolves; greppable identifiers don't):
A single-specialism governance-spend-authority adopter (an in-house policy engine, IAS, DoubleVerify) deletes:
brandRights = defineBrandRightsPlatform({ ... }) block (the entire brand-rights surface)propertyLists = definePropertyListsPlatform({ ... }) block if you don't claim property-listsprivate async enforceGovernance(...) helper and the interface GovernanceBinding — these belong to brandRights cross-specialism dispatch, not to standalone governancebrands / rights Maps on TenantState (no brand-rights catalog to seed)A single-specialism property-lists adopter mirrors this: keep the propertyLists block; delete campaignGovernance, brandRights, enforceGovernance, the brand/rights Maps, and the governanceBindings map.
Keep: the accounts / createTenantStore block (translates to single-tenant by passing one tenant entry — needed for tenant isolation), agentRegistry, the specialism block(s) you claim, getTenant(ctx) resolution. Don't keep enforceGovernance if you also delete brandRights — the helper has no caller and wires a non-existent governance binding.
For content-standards and collection-lists, no worked fork target ships yet — wire defineContentStandardsPlatform / defineCollectionListsPlatform from @adcp/sdk/server against the multi-tenant scaffolding.
For exact response shapes, error codes, and optional fields, docs/llms.txt is the canonical reference.
check_governance, validate_property_delivery, validate_content_deliveryNot this skill:
skills/build-seller-agent/ (governance-aware seller track)skills/build-brand-rights-agent/skills/build-seller-agent/ (audience-sync track)Every governance agent hits the cross-cutting rules in ../cross-cutting.md. The high-traffic ones for governance (deep-linked to the rule):
idempotency_key on sync_plans, sync_governance, report_plan_outcome, create_property_list / update_property_list / delete_property_list, create_collection_list / update_collection_list / delete_collection_list, create_content_standards / update_content_standards / calibrate_contentproperty_list_id / collection_list_id / plan_id cross-tenant lookupscreateTenantStore for multi-tenant policy hubsOne governance-specific rule on top:
comply_test_controller is requiredBoth governance_spend_authority and property_lists storyboards seed fixtures via comply_test_controller.seed_plan / seed_property_list before running the business-logic phases. Register via createComplyController({ seed: { plan, property_list, collection_list, content_standards } }) and call controller.register(server) — same pattern as the seller adapter wires for media-buy seeding.
Without the test controller, every business-logic step skips with missing_test_controller and the track "passes" vacuously — the grader treats vacuous green as fail. Wire it on day one.
governance-spend-authority — check_governance evaluates the request's binding against the Plan's budget.total, human_review_required, and custom_policies. Returns one of approved / conditions / denied. The Plan model is the source of truth: read sync_plans / get_plan to materialize the spending authority, then check the inbound binding against it.
governance-delivery-monitor — check_governance with phase: 'delivery' + delivery_metrics. Compute drift vs Plan's budget.reallocation_threshold; return BUDGET_DRIFT_EXCEEDED findings when delivery exceeds the threshold.
property-lists — tool family property_list_* (create, read, update, delete, list). validate_property_delivery returns full violations[] (publisher property not in the inclusion list, or hit the exclusion list). Property identity is {agent_url, id} — buyers fetch lists by reference, not by inline copy.
collection-lists — program-level brand safety (shows, series, podcasts) identified by platform-independent IDs: IMDb (movies/TV), Gracenote (TV/audio metadata), EIDR (entertainment industry standard). Mirrors property-lists CRUD plus collection resolution.
content-standards — policies[] is an array of { policy_id, enforcement, policy, policy_categories?, channels? }. validate_content_delivery uses records[].artifact (not creative_id). Re-read policies per call so standards_version_change events don't serve stale policy.
measurement-verification — v3.1 placeholder (empty phases). Pass universal + governance baseline only. Advertise the capability for discoverability.
# Run the fork-matrix gate (tsc strict)
npm run compliance:fork-matrix -- --test-name-pattern="hello-seller-adapter-multi-tenant"
# Run your forked agent against the matching storyboard
adcp storyboard run http://127.0.0.1:3003/mcp governance_spend_authority \
--bearer "$ADCP_AUTH_TOKEN" --include-bundles --json
# Property-lists track
adcp storyboard run http://127.0.0.1:3003/mcp property_lists \
--bearer "$ADCP_AUTH_TOKEN" --include-bundles --json
The fork-matrix gate is the three-gate contract from docs/guides/EXAMPLE-TEST-CONTRACT.md. The multi-tenant adapter currently runs the strict-tsc gate only (no governance / brand-rights mock-server today); storyboard-grader gates land alongside the next mock-server family.
For deeper validation: docs/guides/VALIDATE-YOUR-AGENT.md.
policies[] is { policy_id, enforcement, policy, ... } — a wrapped policy, not a bare string. validate_content_delivery keys on records[].artifact, not creative_id. Property identity is {agent_url, id} (a PropertyId), not a bare string. check_governance response uses decision: 'approved' | 'conditions' | 'denied' — not boolean. See ../SHAPE-GOTCHAS.md.
docs/migration-6.6-to-6.7.md. Note: inventory-lists was renamed to property-lists in AdCP 3.0 GA (5.x → 5.2 migration).docs/migration-4.x-to-5.x.md