Build signals agent
Skill adcontextprotocol/adcp-client/skills/build-signals-agent
Use when building an AdCP signals agent — a marketplace data provider, identity provider, CDP, or any system that serves audience or contextual signals to buyers.From its SKILL.md
npx -y skills add adcontextprotocol/adcp-client --skill build-signals-agentAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.5 KB, as published. Nobody here has run it
Build a Signals Agent
A signals agent serves audience and contextual targeting segments to buyer agents. The fastest path to a passing agent is to fork the worked adapter and replace its // SWAP: markers with calls to your backend.
Pick your fork target
| Specialism | Archetype | Fork this | Mock upstream | Storyboard |
|---|---|---|---|---|
signal-marketplace | Multi-provider data marketplace (Oracle Data Cloud, LiveRamp, third-party data) | hello_signals_adapter_marketplace.ts | npx adcp mock-server signal-marketplace | signal_marketplace |
signal-owned | First-party / single-provider data (CDP, identity provider, contextual) | Same — fork the marketplace adapter and apply the single-provider deltas below | Same | signal_owned |
Both specialisms share the same tool surface (get_signals, activate_signal, list_accounts); the difference is whether you serve segments from multiple data_provider_domain values or one.
For exact response shapes, error codes, and optional fields, docs/llms.txt is the canonical reference. The fork target stays in sync with the spec because PR #1394's three-gate contract fails CI when it drifts. See SHAPE-GOTCHAS.md — particularly §1 (flat activation_key.key/value), §2 (signal_ids is SignalID[], not string[]), and §7 (marketplace / owned / custom decision).
When to use this skill
- User wants to serve audience segments, identity data, or contextual targeting to buyers
- User mentions
get_signals,activate_signal, or the AdCP signals protocol - User describes themselves as a CDP, DMP, identity provider, or data marketplace
Not this skill:
- Selling ad inventory →
skills/build-seller-agent/ - Audience push (sync to a walled garden) → that's the
audience-synctrack inskills/build-seller-agent/
Cross-cutting rules
Every signals agent hits the cross-cutting rules in ../cross-cutting.md. The high-traffic ones for signals (deep-linked to the rule):
idempotency_keyonactivate_signal- Authentication —
serve({ authenticate })baseline - Resolve-then-authorize — byte-equivalent errors on
signal_agent_segment_idlookups across tenants - Webhooks — for async platform-activation completions, use
signal_activation.${signal_agent_segment_id}.${platform}as the stableoperation_id
Two signals-specific notes on top of those:
Async platform activation
Platform activations (type: 'platform') take minutes-to-hours to propagate to the DSP. Return is_live: false with estimated_activation_duration_minutes on first call; the buyer polls activate_signal again until is_live: true. Commit activation_key up front so the buyer can trust it across the poll window. Agent activations (type: 'agent') are instant — return is_live: true immediately.
forceDeploymentStatus in your TestControllerStore flips pending deployments to live for deterministic compliance tests.
Provenance — data_provider_domain must resolve
Buyers fetch https://{domain}/adagents.json out-of-band to verify the provider. Use real domains even in demos, not example.com. For marketplace adopters, seed ≥2 different data_provider_domain values so the multi-provider nature is visible to the storyboard.
Specialism deltas
signal-marketplace (the baseline fork target)
Multi-provider directory: signals[].data_provider_domain varies across cohorts. Platform-activation polling pattern is fully exercised. The marketplace governance sub-scenario in the storyboard exercises consent flows across providers; if you can't model multi-provider consent yet, surface INVALID_REQUEST rather than silently fall through. Use signal_type: 'marketplace' only when data_provider_domain resolves to a real adagents.json.
signal-owned (single-provider)
Forking the marketplace adapter for a signal-owned agent? Apply these deltas — leaning on stable symbol names rather than line numbers (the adapter evolves; greppable identifiers don't):
- Replace the multi-provider seed. The adapter ships an
UpstreamCohortarray seeded with multipledata_provider_domain/data_provider_id/data_provider_nametriples. Replace with your single-provider catalog: every cohort gets the samedata_provider_domain(your domain) anddata_provider_name(your brand). - Strip marketplace-discovery filters in
getSignalsthat filtersignals[]by(data_provider_domain, data_provider_id)pairs — single-provider adopters either return everything or filter on signal id alone. - Set
signal_type: 'owned'(not'marketplace') in thetoAdcpSignalprojection. See SHAPE-GOTCHAS §7 for the decision table —ownedis the default for first-party data agents. - Drop the marketplace governance sub-scenario from your storyboard run if you don't model multi-provider consent flows. The
signal_ownedstoryboard is simpler. value_typedrives targeting semantics for owned segments:binary(in/out),categorical(withallowed_values: [...]),numeric(withmin,max, optionalunits).
Keep: the accounts / createTenantStore block (single-tenant adapters pass one tenant entry), agentRegistry, the signals SignalsPlatform block (getSignals, activateSignal, listAccounts), platform-vs-agent activation polling logic, forceDeploymentStatus for compliance-test determinism.
Validate locally
# Run the fork-matrix gate
npm run compliance:fork-matrix -- --test-name-pattern="hello-signals-adapter-marketplace"
# Or validate your forked agent directly against its storyboard
adcp storyboard run http://127.0.0.1:3001/mcp signal_marketplace \
--bearer "$ADCP_AUTH_TOKEN" --include-bundles --json
The fork-matrix gate is the three-gate contract from docs/guides/EXAMPLE-TEST-CONTRACT.md: tsc strict / storyboard zero-failures / upstream façade.
For deeper validation: docs/guides/VALIDATE-YOUR-AGENT.md.
Migration notes
- 6.6 → 6.7:
docs/migration-6.6-to-6.7.md - 4.x → 5.x:
docs/migration-4.x-to-5.x.md