Skip to content

docs(building): rename @adcp/client → @adcp/sdk, fix API surface, reframe SDK coverage#4045

Merged
bokelley merged 3 commits intomainfrom
bokelley/building-page-fixes
May 4, 2026
Merged

docs(building): rename @adcp/client → @adcp/sdk, fix API surface, reframe SDK coverage#4045
bokelley merged 3 commits intomainfrom
bokelley/building-page-fixes

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

@bokelley bokelley commented May 4, 2026

Summary

Three things prompted this:

  1. The npm package was renamed from @adcp/client to @adcp/sdk. The 5.x line is now security-only support; @adcp/sdk@6.9.0 is the production GA. 244 occurrences across 46 doc files were still on the old name.
  2. The 6.x API surface diverged from what the docs showed: ADCPClient is gone, replaced by createSingleAgentClient / ADCPMultiAgentClient with a new {id, name, agent_uri, protocol} constructor. Python ADCPClient(agent_url=…) was never the real API either.
  3. The "floor / GA" framing on the SDK coverage table conflated "minimum 3.0-conformant" with "current published" — and pinned readers at ^5.13.0 (a security-only line) on get-test-ready.

While doing the rename pass, also lifted the layer diagram from sdk-stack onto 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/sdk everywhere (docs only — GitHub repo path adcontextprotocol/adcp-client unchanged).
  • ADCPClientcreateSingleAgentClient (TS); Python now uses ADCPClient(AgentConfig(...)) with await + GetProductsRequest.
  • Replaced fabricated @adcp/sdk/webhooks with the real createWebhookVerifier from @adcp/sdk/signing/server; refreshed package-exports list to match the actual subpath surface.
  • Fixed CLI invocations to the real positional shape (adcp <protocol> <url> <tool> '<json>').

Coverage reframe

  • choose-your-sdk and sdk-stack tables now have Production GA / Beta-or-dev columns. TS GA 6.9.0, Python GA 3.x with 4.x in beta, Go in dev.
  • get-test-ready no longer pins users at ^5.13.0.

Building landing

  • Replaced "five layers, in one paragraph" prose with the mermaid layer diagram.
  • Added "Talk to Sage" link in Going deeper.
  • Removed stale Remove after 2026-04-25 callout.

Scan punch list

  • version-adaptation: authTokenauth_token.
  • migrate-from-hand-rolled: server supported_versions: ['v2.5', '3.0.5'] was contradicting the version-adaptation rule (release-precision strings on the server) — fixed.
  • Prebid SalesAgent broken link (prebid/prebid-serverprebid/salesagent); unlinked landing mention now linked.

Test plan

  • Mermaid diagram renders on the landing page on the Mintlify preview.
  • No @adcp/client references remain anywhere under docs/.
  • Python from adcp import ADCPClient, AgentConfig, Protocol, GetProductsRequest resolves on adcp@3.9.1 (verified against the wheel).
  • npx @adcp/sdk@latest --help shows the documented positional CLI shape.
  • All anchor links from edited pages resolve (/docs/building/by-layer/L1/security#webhook-error-taxonomy, /docs/building/by-layer/L3/webhooks#signature-verification, /docs/learning/overview).

🤖 Generated with Claude Code

…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>
Copy link
Copy Markdown
Contributor Author

@bokelley bokelley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 example npx @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 against bin/adcp.js in the published 6.9.0 tarball: invoking with mcp first 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 actual argv parsing — 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 mcp if you want to be explicit.
  • docs/quickstart.mdx:279import { AdCPClient } from '@adcp/sdk' works in 6.x only because AdCPClient is exported as a @deprecated alias for ADCPMultiAgentClient. 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 of agent(id).getProducts({...}).

    • Suggested fix: switch to createSingleAgentClient (single seller — matches the rest of the docs) or ADCPMultiAgentClient (kept the array shape) and call client.getProducts({...}) / client.agent('test').getProducts({...}) directly. agent_uri / auth_token field names already match.

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 flip learning/overview.mdx to 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 shows mcp as 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 to adcp storyboard run and registry diagnostics in the same sentence — reader could parse test-mcp as a subcommand. Either drop "the public test agent" half of the sentence, or expand to e.g. "and the built-in test-mcp / test-a2a aliases 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/sdk but URL points at the adcp-client repo. URL is correct (the repo name is still adcp-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 — the tasksGet example uses camelCase but task_id snake_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 — tasksGet vs getTask etc. If the method is actually named getTask or taskGet, fix; if tasksGet, leave.

  • docs/building/by-layer/L4/build-an-agent.mdx:206 — the table claims node_modules/@adcp/sdk/docs/llms.txt and node_modules/@adcp/sdk/docs/guides/BUILD-AN-AGENT.md exist. Verified: both ship in the 6.9.0 tarball at package/docs/. ✓ keep.

  • docs/building/cross-cutting/known-ambiguities.mdx:75-76 — keeps the literal phrase adcp-client#689 after the @adcp/client → @adcp/sdk rename. That's actually correct — the upstream repo name is still adcp-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 example uvx adcp https://sales.example.com/mcp get_products '{"brief":"CTV campaign"}' is correct. But --save-auth storage mention sits with no example — consider adding a one-liner like uvx adcp --save-auth my-agent https://sales.example.com/mcp so it parallels the JS-side wording in validate-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-auth to 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 be by-layer/L4/build-an-agent etc. — 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 &amp; 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>
Copy link
Copy Markdown
Contributor Author

@bokelley bokelley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:46agent_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.mdx plus 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/sdk 6.x = Production GA reads unambiguously.
  • build-an-agent is 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.

Copy link
Copy Markdown
Contributor Author

@bokelley bokelley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@bokelley
Copy link
Copy Markdown
Contributor Author

bokelley commented May 4, 2026

Expert pass summary

Three reviewer passes (code-reviewer, dx-expert, adtech-product-expert), all addressed or deferred.

Fixed in this PR:

  • Code reviewer: fake CLI invocation (adcp mcp <url> doesn't work — first positional is <agent>), fake client.tasksGet({...}) method (doesn't exist on the new SDK), deprecated AdCPClient alias in quickstart.mdx, "Talk to Sage" link landing on a page that introduces the agent as Addie.
  • DX expert: URL-shape inconsistency (https://sales.example.com vs /sales/mcp) — all sales.example.com examples now carry the /mcp suffix.
  • Product expert: added inline links to v2 sunset timeline and versioning & governance under the migration-guide line so procurement / vendor-evaluation readers have the support-window policy one click away.

Deferred to follow-up — wants your input before restructuring:

  • Python wall after install (DX expert): build-a-caller goes single-language past the install tab. A bilingual rewrite is bigger than this PR's scope.
  • build-a-caller is SDK-call-shaped, not buyer-agent-shaped (product expert): walks install → call → webhook → reporting but never maps AdCP tools onto a DSP's existing planning / bidding / reporting stack. Reframing wants product-side direction (which buy-side segments to name, how to thread the "AdCP is additive, not a replacement" framing).
  • build-an-agent skips inventory modeling (product expert): never tells a publisher PM how GAM/FreeWheel/Kevel objects map onto AdCP products/packages/media_buys.
  • "Run a prebuilt agent" card framing (product expert): explicitly out of scope for this PR; worth a separate pass on operating-an-agent.mdx.

Merging on admin since CI is green and the deferred items are restructurings, not blockers.

@bokelley bokelley merged commit eb4108b into main May 4, 2026
18 checks passed
@bokelley bokelley deleted the bokelley/building-page-fixes branch May 4, 2026 02:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant