docs(building): rename @adcp/client → @adcp/sdk, fix API surface, reframe SDK coverage#4045
docs(building): rename @adcp/client → @adcp/sdk, fix API surface, reframe SDK coverage#4045
Conversation
…rame SDK coverage
- Bulk rename @adcp/client → @adcp/sdk (244 occurrences across 46 files);
5.x is security-only support, 6.9.0 is the production GA.
- Rewrite caller code samples to match 6.x: ADCPClient is gone, replaced by
createSingleAgentClient / ADCPMultiAgentClient with the new
{id, name, agent_uri, protocol, auth_token} constructor shape.
- Fix Python samples: ADCPClient(agent_url=…) was never the real API; now
uses ADCPClient(AgentConfig(...)) with await + GetProductsRequest.
- Replace fabricated @adcp/sdk/webhooks import with createWebhookVerifier
from @adcp/sdk/signing/server, and refresh package-exports to match the
actual subpath surface.
- Fix CLI invocations: positional shape adcp <protocol> <url> <tool> '<json>',
not --agent flags.
- Reframe coverage tables on choose-your-sdk and sdk-stack from
"5.13.0 floor / 6.9.0 GA" to "Production GA / Beta-or-dev" columns.
TS GA 6.9.0, Python GA 3.x with 4.x in beta, Go in dev.
- Lift the layer diagram onto /docs/building/ landing in place of the
"five layers, in one paragraph" prose; add "Talk to Sage" link.
- Drop stale Remove-after-2026-04-25 callout.
- Fix get-test-ready pinning users at ^5.13.0 (security-only line).
- Fix migrate-from-hand-rolled supported_versions example contradicting the
version-adaptation rule (release-precision strings on the server).
- Fix Prebid SalesAgent repo link (prebid/prebid-server → prebid/salesagent).
- authToken → auth_token on version-adaptation; link the unlinked Prebid
SalesAgent mention on the landing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley
left a comment
There was a problem hiding this comment.
Code-review pass — focused list of issues, file:line refs, suggested fixes. Verified against the published @adcp/sdk@6.9.0 tarball and adcp==3.9.1 wheel.
Blockers
-
docs/building/by-layer/L4/choose-your-sdk.mdx:127— The JS CLI examplenpx @adcp/sdk@latest mcp https://sales.example.com/mcp get_products '...'does not actually work. The CLI's first positional is<agent>(alias / built-in / URL), not<protocol>. I confirmed this againstbin/adcp.jsin the published 6.9.0 tarball: invoking withmcpfirst errors with'mcp' is not a valid agent alias or URL. Protocol selection is a flag (--protocol) and is auto-detected from the URL otherwise. The bin/adcp.js docstring header (adcp <protocol> <agent-url> <tool-name>) is stale and contradicts the actualargvparsing — don't trust it.- Suggested fix:
npx @adcp/sdk@latest https://sales.example.com/mcp get_products '{"brief":"CTV campaign"}'(auto-detect), or add--protocol mcpif you want to be explicit.
- Suggested fix:
-
docs/quickstart.mdx:279—import { AdCPClient } from '@adcp/sdk'works in 6.x only becauseAdCPClientis exported as a@deprecatedalias forADCPMultiAgentClient. Using a deprecated symbol in the canonical quickstart is a long-term footgun: when 7.x drops the alias, the quickstart silently breaks.executeTask('get_products', {...})is also the older indirection path on top ofagent(id).getProducts({...}).- Suggested fix: switch to
createSingleAgentClient(single seller — matches the rest of the docs) orADCPMultiAgentClient(kept the array shape) and callclient.getProducts({...})/client.agent('test').getProducts({...})directly.agent_uri/auth_tokenfield names already match.
- Suggested fix: switch to
Issues
-
docs/building/index.mdx:92— "Talk to Sage" lands on a page that introduces the teaching agent as "Addie" (docs/learning/overview.mdx:4, the Card on line 18 says "Talk to Addie",href="…/chat"). User clicks "Sage", reads "Addie", sees a button labeled "Open Addie." Either rename the link to "Talk to Addie" for now, or fliplearning/overview.mdxto introduce Sage as the protocol-training persona before this link goes live. Per the Sage = Addie-teal split, the building-page side is the right framing — the destination page is what's stale. -
docs/building/by-layer/L4/choose-your-sdk.mdx:139— "Same positional shape as the JS CLI" is technically correct on the alias path (adcp my-agent get_products) but contradictory next to the JS example three lines earlier that showsmcpas a leading positional. After fixing the JS example above, this sentence reads cleanly. Worth a re-read. -
docs/building/by-layer/L4/choose-your-sdk.mdx:130— "the public test agent (adcp test-mcp)" is correct (built-in alias, lists tools) but ambiguous next toadcp storyboard runandregistry diagnosticsin the same sentence — reader could parsetest-mcpas a subcommand. Either drop "the public test agent" half of the sentence, or expand to e.g. "and the built-intest-mcp/test-a2aaliases that point at AAO's public test agent." -
docs/building/by-layer/L4/build-a-caller.mdx:194— the[@adcp/sdk README](https://github.com/adcontextprotocol/adcp-client#readme)link text says@adcp/sdkbut URL points at theadcp-clientrepo. URL is correct (the repo name is stilladcp-client); the friction is purely visual. Either accept the inconsistency or change the link text to "[adcp-client README]". -
docs/building/by-layer/L4/build-a-caller.mdx:155— thetasksGetexample uses camelCase buttask_idsnake_case. That's actually the pattern the SDK uses (typed methods camelCase, JSON payload fields snake_case), but worth confirming against the 6.9.0 SingleAgentClient surface —tasksGetvsgetTasketc. If the method is actually namedgetTaskortaskGet, fix; iftasksGet, leave. -
docs/building/by-layer/L4/build-an-agent.mdx:206— the table claimsnode_modules/@adcp/sdk/docs/llms.txtandnode_modules/@adcp/sdk/docs/guides/BUILD-AN-AGENT.mdexist. Verified: both ship in the 6.9.0 tarball atpackage/docs/. ✓ keep. -
docs/building/cross-cutting/known-ambiguities.mdx:75-76— keeps the literal phraseadcp-client#689after the@adcp/client → @adcp/sdkrename. That's actually correct — the upstream repo name is stilladcp-client, only the npm package moved — but a reviewer may flag it as "missed rename." Add a parenthetical: "(repo name unchanged; only the npm package moved to@adcp/sdk)" if you want to head that off.
Nits
-
docs/building/by-layer/L4/choose-your-sdk.mdx:139— Python CLI exampleuvx adcp https://sales.example.com/mcp get_products '{"brief":"CTV campaign"}'is correct. But--save-authstorage mention sits with no example — consider adding a one-liner likeuvx adcp --save-auth my-agent https://sales.example.com/mcpso it parallels the JS-side wording invalidate-your-agent.mdx. -
docs/building/index.mdx:14— "L4 is the part you write either way" — slightly tautological (since L4 is defined as "what you write"). Consider "L4 is the part the SDK can't write for you" or just "L4 is yours." -
docs/building/by-layer/L4/choose-your-sdk.mdx:140("Save aliases with--save-authto avoid retyping URLs.") — true for both CLIs, but only documented under the Python heading. Either move up to the JS section as well or pull into a shared note above both. -
docs/quickstart.mdx:299-303— the "What's next" links use the pre-IA-reorg paths (/docs/building/build-an-agent,/docs/building/validate-your-agent, etc.). Outside this PR's scope, but they should beby-layer/L4/build-an-agentetc. — those redirects might be canonicalized by Addie's middleware (#4034) so click-through works, but the source link text is stale. Worth a follow-up PR.
Tables on choose-your-sdk.mdx:18-22 and sdk-stack.mdx:205-209 match exactly. ✓
Mermaid syntax on index.mdx:16-35 mirrors the working pattern from sdk-stack.mdx — same init block, same & escapes, same subgraph IDs. Should render cleanly.
The deleted Remove after 2026-04-25 Info callout is correctly removed (today is 2026-05-03) and nothing else in docs/building/ linked to it.
All @adcp/sdk/<subpath> imports introduced in the diff (/conformance, /schemas, /server/legacy/v5, /server, /signing/client, /signing/server, /signing, /testing, /types/v2-5, /types) match real exports in the 6.9.0 package.json. ✓ No --agent flag, no hyphenated tool names (get-products, create-media-buy), no @adcp/client@latest npx invocations introduced.
This is advisory — not requesting changes.
…e tasksGet, deprecated AdCPClient alias, stale quickstart paths
- Fix JS CLI examples: first positional is `<agent>` (alias / built-in / URL),
not `<protocol>`. Auto-detect from URL or use `--protocol mcp`. The bin
docstring header was stale; canonical shape comes from `printUsage()`.
- Drop the fake `client.tasksGet({...})` polling sample in build-a-caller —
the SDK doesn't expose `tasks/get` at the high-level client. Steer to
webhooks (the SDK's actual async path) and link L3/async-operations for
the wire contract if direct polling is needed.
- Quickstart: switch from the deprecated `AdCPClient` alias (which is just
`ADCPMultiAgentClient` under the hood) to `ADCPMultiAgentClient` directly,
and use the typed `getProducts()` method instead of the older
`executeTask('get_products', ...)` indirection.
- Quickstart "What's next" links updated to post-IA-reorg paths
(matches PR #4034's Addie-side canonicalization).
- "Talk to Sage" → "Talk to Addie" on the building landing — the destination
page introduces the agent as Addie; the Sage rebrand on the learning side
hasn't shipped yet.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley
left a comment
There was a problem hiding this comment.
DX review — onboarding flow against the renamed/reframed surface
Walked the docs cold as a TS-first buyer-side dev, then again as a Python dev. The rename and the GA/Beta reframe land cleanly. Three onboarding-shaped issues are worth fixing before merge; one optional polish.
1. The L4 caller path is TypeScript-only past "Install"
docs/building/by-layer/L4/build-a-caller.mdx: the install section has Python and Go tabs, but every section after that — Authenticate, First call, Make a call, Handle responses, Recover from errors, Receive webhooks, Ingest reporting — is single-language TypeScript. A Python dev who picks the Python tab on line 44 sees ADCPClient(AgentConfig(...)) once, then loses their language for the rest of the page.
This is the highest-impact friction on the page because Python is a first-class language per the coverage matrix and the page bills itself as the L4 caller landing.
Smallest fix: keep the page TS-primary (acknowledge it is), but at the top of "Authenticate" add a short callout: "Code samples below are TypeScript; the Python equivalents map 1:1 — see Python SDK reference. Field names are snake_case in both." That at least tells Python devs to keep reading instead of bouncing to choose-your-sdk.
2. The "try it against a live agent" tip and the install snippet use mismatched URL shapes
docs/building/by-layer/L4/build-a-caller.mdx:15 says: point your client at https://test-agent.adcontextprotocol.org/sales/mcp (full path with /mcp). The very next snippet at line 31–36 uses agent_uri: 'https://sales.example.com' (no path). A dev copy-pasting the install snippet and substituting the test-agent URL has to figure out whether /mcp belongs in agent_uri, in a separate field, or is implied by protocol: 'mcp'.
Same ambiguity on choose-your-sdk.mdx:46 — agent_uri: 'https://sales.example.com' with no /mcp, but validate-your-agent.mdx:29 saves an alias for http://localhost:3001/mcp with the path. Across three pages, three URL shapes.
Smallest fix: make the install snippet use a URL with the explicit /mcp suffix (or whatever agent_uri actually expects), and have one comment line under it: // agent_uri includes the transport path; protocol just tells the SDK how to frame envelopes. Removes the question entirely.
3. CLI samples on validate-your-agent need a one-line "alias resolution" hint
docs/building/verification/validate-your-agent.mdx:30 saves an alias to ~/.adcp/config.json. Subsequent samples then call npx @adcp/sdk@latest storyboard run my-agent — works only if the alias was saved. That ordering is fine if you read the page top-to-bottom. Devs landing from a Google search on "adcp storyboard run" hit the snippet and get a "no alias found" error first time.
choose-your-sdk.mdx:128–135 already does this well — the JS CLI block shows --save-auth then my-agent then the test-mcp built-in, all in one block, so there's no implicit ordering. validate-your-agent could mirror that pattern.
Smallest fix: in the "Run a storyboard" intro, one line: "All examples assume you ran --save-auth my-agent <url> from the Setup section, or replace my-agent with test-mcp to use the public test agent."
4. (Optional) Python CLI tooling assumption
choose-your-sdk.mdx:140 and validate-your-agent.mdx both lead the Python CLI with uvx adcp …. uvx is increasingly common but not yet ubiquitous outside Astral-flavored workflows. Adding # or: pip install adcp && adcp … underneath would unblock pip-only environments without bloating the page.
What's working
- The five-layer mermaid on
docs/building/index.mdxplus the Two-checks block plus the Recommended-path cards is a tight 90-second decision flow. No friction there. - The Production-GA / Beta-or-dev reframe of the coverage matrix is much cleaner than the old floor/GA dual line.
@adcp/sdk6.x = Production GA reads unambiguously. build-an-agentis internally consistent and the storyboard CLI samples there (npx @adcp/sdk@latest storyboard run http://localhost:3001/mcp media_buy_seller --json) are paste-runnable.- choose-your-sdk vs sdk-stack split is coherent: choose-your-sdk is the decision page, sdk-stack is the layered reasoning. They cross-link and don't overlap meaningfully.
- The Talk-to-Addie link in Going deeper reads as a natural off-ramp, not a marketing hook — it's framed around "stuck on a concept" with clear scope (teaching agent, certification path).
Verdict: ship after fixing #1 and #2; #3 and #4 are nice-to-have.
bokelley
left a comment
There was a problem hiding this comment.
Product-side review (buy/sell-side PM lens)
The PR cleans up real friction (package rename, working samples, the layer diagram on the landing) and the Production GA / Beta column shape is the right move for a first-time builder. Five product-level concerns from the adopter side, none of them blockers for this PR but all worth filing as follow-ups:
1. build-a-caller is shaped like an SDK how-to, not a buyer-agent build guide
docs/building/by-layer/L4/build-a-caller.mdx walks install → auth → discover → call → handle responses → webhooks → ingest. That's "how to make an HTTP call." A DSP / agency-platform / planning-tool PM scoping a build is asking a different question: where does AdCP plug into my existing planning, bidding, and reporting stack? The mapping getProducts → planning/forecasting, createMediaBuy → order management / IO ledger, getMediaBuyDelivery → reporting warehouse + pacing + attribution joins — that's the build. Today the doc compresses it to one line: "Caller L4 — optimization, pacing alerts, attribution joins, dashboards — is your application code on top of the typed delivery object." (line 202).
Reframe: add a "What L4 looks like on the buy side" section between Ingest reporting and What you didn't have to write, with three paragraphs — planning integration, order/IO integration, reporting integration — each naming the AdCP tools it consumes and the existing systems it typically lands in (DSP forecast cache, agency IO ledger, MMM/MTA inputs). Keep it short; the point is to show a DSP PM that AdCP additive, not a rip-and-replace.
2. The caller doc doesn't name its audience the way the buy side actually segments
Lede on build-a-caller.mdx:8 says "DSP, planning tool, agentic client, or any application." That elides the actual buy-side personas: DSP, agency holdco platform, in-house brand stack, measurement/analytics consumer. It also silently drops the framing Brian has been consistent on — DSP = buyer-agent equivalent (not an add-on), measurement vendors don't change, agency relationships are additive. Without that framing a TTD or DV360 PM reading this thinks AdCP is asking them to replace something.
Reframe: one paragraph after the lede that names the segments and explicitly says: "AdCP is the protocol your buying stack speaks to seller agents. It's additive — your planning, bidding, attribution, and agency relationships don't move."
3. build-an-agent skips the "what does this agent model from my existing inventory system?" question
The skill list in docs/building/by-layer/L4/build-an-agent.mdx:84-94 names skills by agent type but never tells a publisher PM how their existing GAM line items / FreeWheel orders / Kevel campaigns / Magnite deals map onto AdCP products, packages, media_buys. The whole "what am I integrating into?" question is offloaded to Operating an Agent via a Note, but that's the question a PM scoping the build actually needs answered first — it determines whether this is a wrapper project or a modeling project.
Reframe: add a small section before Choose a skill — "What your agent wraps" — that says: AdCP products map to your existing inventory representation (GAM line item, FreeWheel package, Kevel ad set, etc.); AdCP media buys map to your existing order/booking object; AdCP packages map to your existing flight/placement. Two-sentence version is fine. The point is to make the wrapper-shape obvious so a publisher PM doesn't think they're rebuilding order management.
4. Coverage matrix is clearer for builders, weaker for vendor evaluators
docs/building/by-layer/L4/choose-your-sdk.mdx:18-26. The new Production GA / Beta-or-dev columns are right for a new builder. For a procurement / roadmap-evaluation reader, "5.x is on security-only support and not recommended for new builds" is a sentence in prose (line 26) when it should be a link to a support policy. Brian has both a v2 sunset policy decision and a release-cadence rationale that vendor-evaluation readers will want to see — neither is linked from this page.
Reframe: below the matrix, one line: "See SDK support policy for the support window, deprecation cadence, and security-only timelines." Link to whichever single page consolidates the v2-sunset and cadence decisions. If that page doesn't exist yet, that's the gap to file.
5. "Run a prebuilt agent" card under-serves the small-publisher audience
docs/building/index.mdx:50-52. A publisher without engineering capacity isn't choosing between self-host Prebid SalesAgent and managed platform in the abstract — they're asking "does my existing SSP / ad server / Magnite / PubMatic / Kevel / GAM partner ship AdCP yet, and if not who do I call?" Framing managed platforms as a distinct category when they're really existing ad-tech vendors with AdCP support obscures the actual decision.
Reframe: in the linked Operating an agent page (out of scope for this PR but worth filing), lead with a short "is your existing SSP/ad-server already an AdCP agent?" check before the self-host vs. managed-platform fork. Today both options read as new vendor selections, which isn't how a non-engineering publisher experiences this.
None of these block the PR — the rename, the diagram, the working samples, and the GA/beta column are all clear improvements for a new builder. The concerns above are about the next layer of polish for the buy/sell-side PMs Brian is trying to convert into adopters.
…icy links - DX expert flagged URL-shape mismatch: bare `https://sales.example.com` on some samples vs `/mcp` suffix on others. Made all `sales.example.com` examples carry the `/mcp` suffix consistently so paste-execute works. - Product expert flagged the coverage matrix lacks procurement-grade context. Added inline links to the v2 sunset timeline and the versioning & governance reference under the migration-guide line. Two larger product-shaped findings (Python dev wall after install, and build-a-caller being SDK-call-shaped rather than buyer-agent-shaped) deferred to follow-up — both want Brian's input on framing before restructuring the page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expert pass summaryThree reviewer passes (code-reviewer, dx-expert, adtech-product-expert), all addressed or deferred. Fixed in this PR:
Deferred to follow-up — wants your input before restructuring:
Merging on admin since CI is green and the deferred items are restructurings, not blockers. |
Summary
Three things prompted this:
@adcp/clientto@adcp/sdk. The 5.x line is now security-only support;@adcp/sdk@6.9.0is the production GA. 244 occurrences across 46 doc files were still on the old name.ADCPClientis gone, replaced bycreateSingleAgentClient/ADCPMultiAgentClientwith a new{id, name, agent_uri, protocol}constructor. PythonADCPClient(agent_url=…)was never the real API either.^5.13.0(a security-only line) onget-test-ready.While doing the rename pass, also lifted the layer diagram from
sdk-stackonto the/docs/building/landing in place of the prose paragraph, added a "Talk to Sage" entry-point link, and ran a scan across all building pages for readability fallout.What changed
SDK rename + API rewrite
@adcp/client→@adcp/sdkeverywhere (docs only — GitHub repo pathadcontextprotocol/adcp-clientunchanged).ADCPClient→createSingleAgentClient(TS); Python now usesADCPClient(AgentConfig(...))withawait+GetProductsRequest.@adcp/sdk/webhookswith the realcreateWebhookVerifierfrom@adcp/sdk/signing/server; refreshed package-exports list to match the actual subpath surface.adcp <protocol> <url> <tool> '<json>').Coverage reframe
choose-your-sdkandsdk-stacktables now have Production GA / Beta-or-dev columns. TS GA6.9.0, Python GA3.xwith4.xin beta, Go in dev.get-test-readyno longer pins users at^5.13.0.Building landing
Remove after 2026-04-25callout.Scan punch list
version-adaptation:authToken→auth_token.migrate-from-hand-rolled: serversupported_versions: ['v2.5', '3.0.5']was contradicting the version-adaptation rule (release-precision strings on the server) — fixed.prebid/prebid-server→prebid/salesagent); unlinked landing mention now linked.Test plan
@adcp/clientreferences remain anywhere underdocs/.from adcp import ADCPClient, AgentConfig, Protocol, GetProductsRequestresolves onadcp@3.9.1(verified against the wheel).npx @adcp/sdk@latest --helpshows the documented positional CLI shape./docs/building/by-layer/L1/security#webhook-error-taxonomy,/docs/building/by-layer/L3/webhooks#signature-verification,/docs/learning/overview).🤖 Generated with Claude Code