@adcp/sdk 14.3.0 → 15.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/bin/adcp.js +8 -5
  2. package/dist/lib/auth/oauth/ClientCredentialsFlow.js +4 -1
  3. package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs +4 -1
  4. package/dist/lib/auth/oauth/MCPOAuthProvider.d.mts +25 -8
  5. package/dist/lib/auth/oauth/MCPOAuthProvider.d.ts +25 -8
  6. package/dist/lib/auth/oauth/MCPOAuthProvider.js +144 -19
  7. package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +157 -19
  8. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.d.mts +1 -1
  9. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.d.ts +1 -1
  10. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.js +1 -1
  11. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs +1 -1
  12. package/dist/lib/auth/oauth/client-credentials-schema.d.mts +17 -0
  13. package/dist/lib/auth/oauth/client-credentials-schema.d.ts +17 -0
  14. package/dist/lib/auth/oauth/client-credentials-schema.js +37 -0
  15. package/dist/lib/auth/oauth/client-credentials-schema.mjs +13 -0
  16. package/dist/lib/auth/oauth/diagnose.js +14 -0
  17. package/dist/lib/auth/oauth/diagnose.mjs +14 -0
  18. package/dist/lib/auth/oauth/file-storage.d.mts +4 -2
  19. package/dist/lib/auth/oauth/file-storage.d.ts +4 -2
  20. package/dist/lib/auth/oauth/file-storage.js +14 -1
  21. package/dist/lib/auth/oauth/file-storage.mjs +14 -1
  22. package/dist/lib/auth/oauth/index.d.mts +10 -6
  23. package/dist/lib/auth/oauth/index.d.ts +10 -6
  24. package/dist/lib/auth/oauth/index.js +9 -3
  25. package/dist/lib/auth/oauth/index.mjs +8 -3
  26. package/dist/lib/auth/oauth/types.d.mts +17 -0
  27. package/dist/lib/auth/oauth/types.d.ts +17 -0
  28. package/dist/lib/auth/oauth/types.js +40 -0
  29. package/dist/lib/auth/oauth/types.mjs +38 -0
  30. package/dist/lib/auth/oauth/web-flow.d.mts +2 -0
  31. package/dist/lib/auth/oauth/web-flow.d.ts +2 -0
  32. package/dist/lib/auth/oauth/web-flow.js +48 -5
  33. package/dist/lib/auth/oauth/web-flow.mjs +57 -6
  34. package/dist/lib/index.d.mts +1 -1
  35. package/dist/lib/index.d.ts +1 -1
  36. package/dist/lib/index.js +2 -0
  37. package/dist/lib/index.mjs +3 -1
  38. package/dist/lib/protocols/mcp.js +2 -0
  39. package/dist/lib/protocols/mcp.mjs +2 -0
  40. package/dist/lib/schemas/index.d.mts +2 -0
  41. package/dist/lib/schemas/index.d.ts +2 -0
  42. package/dist/lib/schemas/index.js +3 -0
  43. package/dist/lib/schemas/index.mjs +2 -0
  44. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  45. package/dist/lib/testing/client.js +8 -3
  46. package/dist/lib/testing/client.mjs +8 -3
  47. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  48. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  49. package/dist/lib/testing/types.d.mts +10 -1
  50. package/dist/lib/testing/types.d.ts +10 -1
  51. package/dist/lib/types/adcp.d.mts +6 -0
  52. package/dist/lib/types/adcp.d.ts +6 -0
  53. package/dist/lib/version.d.mts +3 -3
  54. package/dist/lib/version.d.ts +3 -3
  55. package/dist/lib/version.js +3 -3
  56. package/dist/lib/version.mjs +3 -3
  57. package/docs/TYPE-SUMMARY.md +1 -1
  58. package/docs/ZOD-SCHEMAS.md +19 -0
  59. package/docs/guides/OAUTH-ISSUER-BINDING.md +46 -0
  60. package/docs/guides/WEB-OAUTH.md +58 -163
  61. package/docs/guides/account-resolution.md +1 -1
  62. package/docs/llms.txt +1 -1
  63. package/docs/migration-14.0-to-14.1.md +1 -1
  64. package/docs/migration-14.x-rc-worksheet.md +8 -8
  65. package/docs/migration-oauth-issuer-bindings.md +17 -0
  66. package/package.json +5 -5
@@ -445,7 +445,8 @@ import {
445
445
  resolveSecret,
446
446
  isEnvSecretReference,
447
447
  toEnvSecretReference,
448
- extractEnvSecretName
448
+ extractEnvSecretName,
449
+ AgentOAuthClientCredentialsSchema
449
450
  } from "./auth/oauth/index.mjs";
450
451
  import { validateAgentUrl, validateAdCPResponse, getExpectedSchema, handleAdCPResponse } from "./validation/index.mjs";
451
452
  import {
@@ -847,6 +848,7 @@ export {
847
848
  AdagentsJsonSchema,
848
849
  AgentClient,
849
850
  AgentNotFoundError,
851
+ AgentOAuthClientCredentialsSchema,
850
852
  Asset,
851
853
  AsyncHandler,
852
854
  AuthenticationCredentialsRejectedError,
@@ -34,6 +34,7 @@ var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamable
34
34
  var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
35
35
  var import_auth = require("@modelcontextprotocol/sdk/client/auth.js");
36
36
  var import_node_crypto = require("node:crypto");
37
+ var import_MCPOAuthProvider = require('../auth/oauth/MCPOAuthProvider.js');
37
38
  var import_auth2 = require('../auth/index.js');
38
39
  var import_errors = require('../errors/index.js');
39
40
  var import_tracing = require('../observability/tracing.js');
@@ -713,6 +714,7 @@ async function connectMCP(options) {
713
714
  fetchFn,
714
715
  allowPrivateIp
715
716
  } = options;
717
+ if (authProvider) (0, import_MCPOAuthProvider.assertLegacyOAuthSdk)();
716
718
  const baseUrl = new URL(agentUrl);
717
719
  debugLogs.push({
718
720
  type: "info",
@@ -11,6 +11,7 @@ import {
11
11
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
12
12
  import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
13
13
  import { hkdfSync, randomBytes } from "node:crypto";
14
+ import { assertLegacyOAuthSdk } from "../auth/oauth/MCPOAuthProvider.mjs";
14
15
  import { createMCPRequestHeaders } from "../auth/index.mjs";
15
16
  import { is401Error } from "../errors/index.mjs";
16
17
  import { withSpan, injectTraceHeaders } from "../observability/tracing.mjs";
@@ -700,6 +701,7 @@ async function connectMCP(options) {
700
701
  fetchFn,
701
702
  allowPrivateIp
702
703
  } = options;
704
+ if (authProvider) assertLegacyOAuthSdk();
703
705
  const baseUrl = new URL(agentUrl);
704
706
  debugLogs.push({
705
707
  type: "info",
@@ -46,6 +46,8 @@ import type { KnownToolRequestSchemas } from '../utils/tool-request-schemas.mjs'
46
46
  import { getSchemaDocumentByRef, type Direction, type ResolvedToolSchemaDocument, type ResponseVariant } from '../validation/schema-loader.mjs';
47
47
  import type { ValidateFunction } from 'ajv';
48
48
  export * from '../types/schemas.generated.mjs';
49
+ export { AgentOAuthClientCredentialsSchema } from '../auth/oauth/client-credentials-schema.mjs';
50
+ export type { AgentOAuthClientCredentials } from '../types/adcp.mjs';
49
51
  export type { PlacementPresentationDocument, PlacementPresentationReference } from '../types/core.generated.mjs';
50
52
  type LooseObjectShapeFor<T extends object> = {
51
53
  [K in keyof T]-?: undefined extends T[K] ? z.ZodOptional<z.ZodType<Exclude<T[K], undefined>, Exclude<T[K], undefined>>> : z.ZodType<T[K], T[K]>;
@@ -46,6 +46,8 @@ import type { KnownToolRequestSchemas } from '../utils/tool-request-schemas';
46
46
  import { getSchemaDocumentByRef, type Direction, type ResolvedToolSchemaDocument, type ResponseVariant } from '../validation/schema-loader';
47
47
  import type { ValidateFunction } from 'ajv';
48
48
  export * from '../types/schemas.generated';
49
+ export { AgentOAuthClientCredentialsSchema } from '../auth/oauth/client-credentials-schema';
50
+ export type { AgentOAuthClientCredentials } from '../types/adcp';
49
51
  export type { PlacementPresentationDocument, PlacementPresentationReference } from '../types/core.generated';
50
52
  type LooseObjectShapeFor<T extends object> = {
51
53
  [K in keyof T]-?: undefined extends T[K] ? z.ZodOptional<z.ZodType<Exclude<T[K], undefined>, Exclude<T[K], undefined>>> : z.ZodType<T[K], T[K]>;
@@ -29,6 +29,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
30
  var schemas_exports = {};
31
31
  __export(schemas_exports, {
32
+ AgentOAuthClientCredentialsSchema: () => import_client_credentials_schema.AgentOAuthClientCredentialsSchema,
32
33
  BiddingPolicySchema: () => import_bidding_policy.BiddingPolicySchema,
33
34
  CanonicalBudgetAllocationSchema: () => import_budget_allocation.CanonicalBudgetAllocationSchema,
34
35
  GetProductsRequestSchema: () => GetProductsRequestSchema,
@@ -56,6 +57,7 @@ var import_tool_request_schemas = require('../utils/tool-request-schemas.js');
56
57
  var import_schema_loader = require('../validation/schema-loader.js');
57
58
  var import_adcp_version_config = require('../utils/adcp-version-config.js');
58
59
  __reExport(schemas_exports, require('../types/schemas.generated.js'), module.exports);
60
+ var import_client_credentials_schema = require('../auth/oauth/client-credentials-schema.js');
59
61
  var import_bidding_policy = require('../validation/bidding-policy.js');
60
62
  var import_budget_allocation = require('../validation/budget-allocation.js');
61
63
  var import_tool_request_schemas2 = require('../utils/tool-request-schemas.js');
@@ -114,6 +116,7 @@ function customToolForSchema(name, description, inputSchema, handler) {
114
116
  }
115
117
  // Annotate the CommonJS export names for ESM import in node:
116
118
  0 && (module.exports = {
119
+ AgentOAuthClientCredentialsSchema,
117
120
  BiddingPolicySchema,
118
121
  CanonicalBudgetAllocationSchema,
119
122
  GetProductsRequestSchema,
@@ -9,6 +9,7 @@ import {
9
9
  } from "../validation/schema-loader.mjs";
10
10
  import { resolveAdcpVersion } from "../utils/adcp-version-config.mjs";
11
11
  export * from "../types/schemas.generated.mjs";
12
+ import { AgentOAuthClientCredentialsSchema } from "../auth/oauth/client-credentials-schema.mjs";
12
13
  const LegacyGetProductsRequestSchema = schemas.GetProductsRequestSchema;
13
14
  const canonicalGetProductsFields = GetProductsRequest_FieldsValues.filter(
14
15
  (field) => field !== "format_ids"
@@ -71,6 +72,7 @@ function customToolForSchema(name, description, inputSchema, handler) {
71
72
  return { description, inputSchema, handler };
72
73
  }
73
74
  export {
75
+ AgentOAuthClientCredentialsSchema,
74
76
  BiddingPolicySchema,
75
77
  CanonicalBudgetAllocationSchema,
76
78
  GetProductsRequestSchema,
@@ -4,5 +4,5 @@
4
4
  "source_sha": "4e553ad955f83b49c7d221ab5c3ff78237ad02e3",
5
5
  "source_tarball_sha256": "580656d6466ef9f0d1119985e6726c2efea718dc671e2ad30957fcb2fd54af0f",
6
6
  "upstream_adcp_version": "2.5.3",
7
- "synced_at": "2026-10-06T17:21:37.513Z"
7
+ "synced_at": "2026-10-07T00:14:46.446Z"
8
8
  }
@@ -52,6 +52,7 @@ var import_node_crypto = require("node:crypto");
52
52
  var import_client_hooks = require('../validation/client-hooks.js');
53
53
  var import_error_extraction = require('../utils/error-extraction.js');
54
54
  var import_client = require('../signing/client.js');
55
+ var import_storage_registry = require('../auth/oauth/storage-registry.js');
55
56
  const TEST_CLIENT_VERSION_OPTIONS = /* @__PURE__ */ Symbol("adcp.testClientVersionOptions");
56
57
  const TEST_CLIENT_SCOPE_SALT = (0, import_node_crypto.randomBytes)(32);
57
58
  function resolveAuthPrincipal(options) {
@@ -123,6 +124,7 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
123
124
  } else if (options.auth.type === "oauth") {
124
125
  agentConfig.oauth_tokens = options.auth.tokens;
125
126
  if (options.auth.client) agentConfig.oauth_client = options.auth.client;
127
+ if (options.auth.storage) (0, import_storage_registry.bindAgentStorage)(agentConfig, options.auth.storage);
126
128
  } else if (options.auth.type === "oauth_client_credentials") {
127
129
  agentConfig.oauth_client_credentials = options.auth.credentials;
128
130
  if (options.auth.tokens) agentConfig.oauth_tokens = options.auth.tokens;
@@ -160,6 +162,7 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
160
162
  ...authMode !== void 0 && { authMode },
161
163
  ...requestScopeMode !== void 0 && { requestScopeMode },
162
164
  ...requestSigningMode !== void 0 && { requestSigningMode },
165
+ ...options.auth?.type === "oauth" && options.auth.storage && { oauthStorage: options.auth.storage },
163
166
  ...options.transport?.trustedFetchFn && { fetchFn: options.transport.trustedFetchFn },
164
167
  ...options.transport?.allowPrivateIp !== void 0 && { allowPrivateIp: options.transport.allowPrivateIp },
165
168
  ...options.transport?.maxResponseBytes !== void 0 && {
@@ -198,13 +201,14 @@ function testClientMatchesVersionOptions(client, agentUrl, options) {
198
201
  const expectedAuthMode = authReuseMode(effectiveOptions);
199
202
  const expectedRequestScopeMode = requestScopeReuseMode(effectiveOptions);
200
203
  const expectedRequestSigningMode = requestSigningReuseMode(effectiveOptions.functional_request_signing);
204
+ const expectedOAuthStorage = effectiveOptions.auth?.type === "oauth" ? effectiveOptions.auth.storage : void 0;
201
205
  if (!meta) {
202
- return expectedRequestSigningMode === void 0 && effectiveOptions.adcpVersion === void 0 && effectiveOptions.versionEnvelope === void 0 && effectiveOptions.transport === void 0;
206
+ return expectedOAuthStorage === void 0 && expectedRequestSigningMode === void 0 && effectiveOptions.adcpVersion === void 0 && effectiveOptions.versionEnvelope === void 0 && effectiveOptions.transport === void 0;
203
207
  }
204
208
  const expectedAdcpVersion = effectiveOptions.adcpVersion ?? import_version.ADCP_VERSION;
205
209
  const expectedWireAdcpVersion = effectiveOptions.wireAdcpVersion;
206
210
  const expectedVersionEnvelope = effectiveOptions.versionEnvelope ?? "auto";
207
- return meta.agentUrl === agentUrl && meta.protocol === (effectiveOptions.protocol ?? "mcp") && meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.requestScopeMode === expectedRequestScopeMode && meta.requestSigningMode === expectedRequestSigningMode && meta.fetchFn === effectiveOptions.transport?.trustedFetchFn && meta.allowPrivateIp === effectiveOptions.transport?.allowPrivateIp && meta.maxResponseBytes === effectiveOptions.transport?.maxResponseBytes && meta.requestTimeoutMs === effectiveOptions.transport?.requestTimeoutMs && meta.legacyCompatEnabled === effectiveOptions.transport?.legacyCompat?.enabled;
211
+ return meta.agentUrl === agentUrl && meta.protocol === (effectiveOptions.protocol ?? "mcp") && meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.requestScopeMode === expectedRequestScopeMode && meta.requestSigningMode === expectedRequestSigningMode && meta.oauthStorage === expectedOAuthStorage && meta.fetchFn === effectiveOptions.transport?.trustedFetchFn && meta.allowPrivateIp === effectiveOptions.transport?.allowPrivateIp && meta.maxResponseBytes === effectiveOptions.transport?.maxResponseBytes && meta.requestTimeoutMs === effectiveOptions.transport?.requestTimeoutMs && meta.legacyCompatEnabled === effectiveOptions.transport?.legacyCompat?.enabled;
208
212
  }
209
213
  function withTestKitAuthDefaults(options) {
210
214
  if (options.auth) return options;
@@ -240,9 +244,10 @@ function requestScopeReuseMode(options) {
240
244
  Object.entries(options.headers).map(([name, value]) => [name.toLowerCase(), value]).sort(([a], [b]) => a.localeCompare(b))
241
245
  ) : void 0;
242
246
  if (!options.auth && !headers && !options.test_session_id && !options.userAgent) return void 0;
247
+ const auth = options.auth?.type === "oauth" ? { ...options.auth, storage: void 0 } : options.auth;
243
248
  return testClientScopeDisambiguator(
244
249
  JSON.stringify({
245
- auth: options.auth,
250
+ auth,
246
251
  headers,
247
252
  testSessionId: options.test_session_id,
248
253
  userAgent: options.userAgent
@@ -12,6 +12,7 @@ import { createHmac, hkdfSync, randomBytes } from "node:crypto";
12
12
  import { validateIncomingResponse } from "../validation/client-hooks.mjs";
13
13
  import { extractVersionUnsupportedDetails } from "../utils/error-extraction.mjs";
14
14
  import { buildAgentSigningContext } from "../signing/client.mjs";
15
+ import { bindAgentStorage } from "../auth/oauth/storage-registry.mjs";
15
16
  const TEST_CLIENT_VERSION_OPTIONS = /* @__PURE__ */ Symbol("adcp.testClientVersionOptions");
16
17
  const TEST_CLIENT_SCOPE_SALT = randomBytes(32);
17
18
  function resolveAuthPrincipal(options) {
@@ -83,6 +84,7 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
83
84
  } else if (options.auth.type === "oauth") {
84
85
  agentConfig.oauth_tokens = options.auth.tokens;
85
86
  if (options.auth.client) agentConfig.oauth_client = options.auth.client;
87
+ if (options.auth.storage) bindAgentStorage(agentConfig, options.auth.storage);
86
88
  } else if (options.auth.type === "oauth_client_credentials") {
87
89
  agentConfig.oauth_client_credentials = options.auth.credentials;
88
90
  if (options.auth.tokens) agentConfig.oauth_tokens = options.auth.tokens;
@@ -120,6 +122,7 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
120
122
  ...authMode !== void 0 && { authMode },
121
123
  ...requestScopeMode !== void 0 && { requestScopeMode },
122
124
  ...requestSigningMode !== void 0 && { requestSigningMode },
125
+ ...options.auth?.type === "oauth" && options.auth.storage && { oauthStorage: options.auth.storage },
123
126
  ...options.transport?.trustedFetchFn && { fetchFn: options.transport.trustedFetchFn },
124
127
  ...options.transport?.allowPrivateIp !== void 0 && { allowPrivateIp: options.transport.allowPrivateIp },
125
128
  ...options.transport?.maxResponseBytes !== void 0 && {
@@ -158,13 +161,14 @@ function testClientMatchesVersionOptions(client, agentUrl, options) {
158
161
  const expectedAuthMode = authReuseMode(effectiveOptions);
159
162
  const expectedRequestScopeMode = requestScopeReuseMode(effectiveOptions);
160
163
  const expectedRequestSigningMode = requestSigningReuseMode(effectiveOptions.functional_request_signing);
164
+ const expectedOAuthStorage = effectiveOptions.auth?.type === "oauth" ? effectiveOptions.auth.storage : void 0;
161
165
  if (!meta) {
162
- return expectedRequestSigningMode === void 0 && effectiveOptions.adcpVersion === void 0 && effectiveOptions.versionEnvelope === void 0 && effectiveOptions.transport === void 0;
166
+ return expectedOAuthStorage === void 0 && expectedRequestSigningMode === void 0 && effectiveOptions.adcpVersion === void 0 && effectiveOptions.versionEnvelope === void 0 && effectiveOptions.transport === void 0;
163
167
  }
164
168
  const expectedAdcpVersion = effectiveOptions.adcpVersion ?? ADCP_VERSION;
165
169
  const expectedWireAdcpVersion = effectiveOptions.wireAdcpVersion;
166
170
  const expectedVersionEnvelope = effectiveOptions.versionEnvelope ?? "auto";
167
- return meta.agentUrl === agentUrl && meta.protocol === (effectiveOptions.protocol ?? "mcp") && meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.requestScopeMode === expectedRequestScopeMode && meta.requestSigningMode === expectedRequestSigningMode && meta.fetchFn === effectiveOptions.transport?.trustedFetchFn && meta.allowPrivateIp === effectiveOptions.transport?.allowPrivateIp && meta.maxResponseBytes === effectiveOptions.transport?.maxResponseBytes && meta.requestTimeoutMs === effectiveOptions.transport?.requestTimeoutMs && meta.legacyCompatEnabled === effectiveOptions.transport?.legacyCompat?.enabled;
171
+ return meta.agentUrl === agentUrl && meta.protocol === (effectiveOptions.protocol ?? "mcp") && meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.requestScopeMode === expectedRequestScopeMode && meta.requestSigningMode === expectedRequestSigningMode && meta.oauthStorage === expectedOAuthStorage && meta.fetchFn === effectiveOptions.transport?.trustedFetchFn && meta.allowPrivateIp === effectiveOptions.transport?.allowPrivateIp && meta.maxResponseBytes === effectiveOptions.transport?.maxResponseBytes && meta.requestTimeoutMs === effectiveOptions.transport?.requestTimeoutMs && meta.legacyCompatEnabled === effectiveOptions.transport?.legacyCompat?.enabled;
168
172
  }
169
173
  function withTestKitAuthDefaults(options) {
170
174
  if (options.auth) return options;
@@ -200,9 +204,10 @@ function requestScopeReuseMode(options) {
200
204
  Object.entries(options.headers).map(([name, value]) => [name.toLowerCase(), value]).sort(([a], [b]) => a.localeCompare(b))
201
205
  ) : void 0;
202
206
  if (!options.auth && !headers && !options.test_session_id && !options.userAgent) return void 0;
207
+ const auth = options.auth?.type === "oauth" ? { ...options.auth, storage: void 0 } : options.auth;
203
208
  return testClientScopeDisambiguator(
204
209
  JSON.stringify({
205
- auth: options.auth,
210
+ auth,
206
211
  headers,
207
212
  testSessionId: options.test_session_id,
208
213
  userAgent: options.userAgent
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
197
197
  */
198
198
  export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
199
199
  /** Capability semver emitted in run summaries and used for advisory expiry. */
200
- export declare const RUNNER_CAPABILITY_VERSION = "14.3.0";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "15.0.0";
201
201
  /** True when a failed validation contributes to the owning step's grade. */
202
202
  export declare function validationFailsStep(result: ValidationResult): boolean;
203
203
  /**
@@ -197,7 +197,7 @@ export interface UpstreamTrafficQueryResult {
197
197
  */
198
198
  export declare function runValidations(validations: StoryboardValidation[], context: ValidationContext): ValidationResult[];
199
199
  /** Capability semver emitted in run summaries and used for advisory expiry. */
200
- export declare const RUNNER_CAPABILITY_VERSION = "14.3.0";
200
+ export declare const RUNNER_CAPABILITY_VERSION = "15.0.0";
201
201
  /** True when a failed validation contributes to the owning step's grade. */
202
202
  export declare function validationFailsStep(result: ValidationResult): boolean;
203
203
  /**
@@ -88,7 +88,7 @@ export interface TestOptions {
88
88
  * - `basic`: cleartext `username` and `password`, encoded internally.
89
89
  * - `oauth`: saved OAuth tokens (access_token + refresh_token). MCP only.
90
90
  * The library auto-refreshes on 401. Obtain tokens interactively via
91
- * `adcp --save-auth <alias> --oauth`, then pass the saved blob here for
91
+ * `adcp --save-auth <alias> <url> --oauth`, then pass the saved blob here for
92
92
  * non-interactive reuse.
93
93
  * - `oauth_client_credentials`: RFC 6749 §4.4 machine-to-machine flow.
94
94
  * The library exchanges the secret for a fresh access token before each
@@ -106,6 +106,15 @@ export interface TestOptions {
106
106
  type: 'oauth';
107
107
  tokens: import('../types/adcp.mjs').AgentOAuthTokens;
108
108
  client?: import('../types/adcp.mjs').AgentOAuthClient;
109
+ /**
110
+ * Trusted runtime storage for refreshed OAuth configuration. Bound before
111
+ * client normalization; never sent to the agent. The adapter receives
112
+ * the testing client's ID (`test`), so capture any database context or
113
+ * tenant identity in the adapter itself. Shared clients require the
114
+ * same adapter object. Persistence alone does not coordinate concurrent
115
+ * refreshes of a rotating grant.
116
+ */
117
+ storage?: import('../auth/oauth/types.mjs').OAuthConfigStorage;
109
118
  } | {
110
119
  type: 'oauth_client_credentials';
111
120
  credentials: import('../types/adcp.mjs').AgentOAuthClientCredentials;
@@ -88,7 +88,7 @@ export interface TestOptions {
88
88
  * - `basic`: cleartext `username` and `password`, encoded internally.
89
89
  * - `oauth`: saved OAuth tokens (access_token + refresh_token). MCP only.
90
90
  * The library auto-refreshes on 401. Obtain tokens interactively via
91
- * `adcp --save-auth <alias> --oauth`, then pass the saved blob here for
91
+ * `adcp --save-auth <alias> <url> --oauth`, then pass the saved blob here for
92
92
  * non-interactive reuse.
93
93
  * - `oauth_client_credentials`: RFC 6749 §4.4 machine-to-machine flow.
94
94
  * The library exchanges the secret for a fresh access token before each
@@ -106,6 +106,15 @@ export interface TestOptions {
106
106
  type: 'oauth';
107
107
  tokens: import('../types/adcp').AgentOAuthTokens;
108
108
  client?: import('../types/adcp').AgentOAuthClient;
109
+ /**
110
+ * Trusted runtime storage for refreshed OAuth configuration. Bound before
111
+ * client normalization; never sent to the agent. The adapter receives
112
+ * the testing client's ID (`test`), so capture any database context or
113
+ * tenant identity in the adapter itself. Shared clients require the
114
+ * same adapter object. Persistence alone does not coordinate concurrent
115
+ * refreshes of a rotating grant.
116
+ */
117
+ storage?: import('../auth/oauth/types').OAuthConfigStorage;
109
118
  } | {
110
119
  type: 'oauth_client_credentials';
111
120
  credentials: import('../types/adcp').AgentOAuthClientCredentials;
@@ -145,6 +145,8 @@ export interface DayParting {
145
145
  * OAuth tokens for agent authentication
146
146
  */
147
147
  export interface AgentOAuthTokens {
148
+ /** Authorization server that issued these tokens. Required when reusing a refresh token. */
149
+ issuer?: string;
148
150
  /** OAuth access token */
149
151
  access_token: string;
150
152
  /** OAuth refresh token (for token renewal) */
@@ -162,6 +164,8 @@ export interface AgentOAuthTokens {
162
164
  * OAuth client information (from dynamic registration)
163
165
  */
164
166
  export interface AgentOAuthClient {
167
+ /** Authorization server where this client was registered. Required when reusing a client secret. */
168
+ issuer?: string;
165
169
  /** OAuth client ID */
166
170
  client_id: string;
167
171
  /** OAuth client secret (for confidential clients) */
@@ -401,6 +405,8 @@ export interface AgentConfig {
401
405
  * authorization flow.
402
406
  */
403
407
  oauth_client_credentials?: AgentOAuthClientCredentials;
408
+ /** Opaque discovery state paired with the pending PKCE verifier; persist and return verbatim. */
409
+ oauth_discovery_state?: import('@modelcontextprotocol/sdk/client/auth.js').OAuthDiscoveryState;
404
410
  /**
405
411
  * Additional HTTP headers to include in every request to this agent.
406
412
  * Useful for sending API keys, org IDs, or other vendor-specific headers
@@ -145,6 +145,8 @@ export interface DayParting {
145
145
  * OAuth tokens for agent authentication
146
146
  */
147
147
  export interface AgentOAuthTokens {
148
+ /** Authorization server that issued these tokens. Required when reusing a refresh token. */
149
+ issuer?: string;
148
150
  /** OAuth access token */
149
151
  access_token: string;
150
152
  /** OAuth refresh token (for token renewal) */
@@ -162,6 +164,8 @@ export interface AgentOAuthTokens {
162
164
  * OAuth client information (from dynamic registration)
163
165
  */
164
166
  export interface AgentOAuthClient {
167
+ /** Authorization server where this client was registered. Required when reusing a client secret. */
168
+ issuer?: string;
165
169
  /** OAuth client ID */
166
170
  client_id: string;
167
171
  /** OAuth client secret (for confidential clients) */
@@ -401,6 +405,8 @@ export interface AgentConfig {
401
405
  * authorization flow.
402
406
  */
403
407
  oauth_client_credentials?: AgentOAuthClientCredentials;
408
+ /** Opaque discovery state paired with the pending PKCE verifier; persist and return verbatim. */
409
+ oauth_discovery_state?: import('@modelcontextprotocol/sdk/client/auth.js').OAuthDiscoveryState;
404
410
  /**
405
411
  * Additional HTTP headers to include in every request to this agent.
406
412
  * Useful for sending API keys, org IDs, or other vendor-specific headers
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "14.3.0";
4
+ export declare const LIBRARY_VERSION = "15.0.0";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
33
33
  * Full version information
34
34
  */
35
35
  export declare const VERSION_INFO: {
36
- readonly library: "14.3.0";
36
+ readonly library: "15.0.0";
37
37
  readonly adcp: "3.2.1";
38
38
  readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.2.1", "3.2"];
39
- readonly generatedAt: "2026-10-06T16:34:47.947Z";
39
+ readonly generatedAt: "2026-10-06T23:38:05.170Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "14.3.0";
4
+ export declare const LIBRARY_VERSION = "15.0.0";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
33
33
  * Full version information
34
34
  */
35
35
  export declare const VERSION_INFO: {
36
- readonly library: "14.3.0";
36
+ readonly library: "15.0.0";
37
37
  readonly adcp: "3.2.1";
38
38
  readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.2.1", "3.2"];
39
- readonly generatedAt: "2026-10-06T16:34:47.947Z";
39
+ readonly generatedAt: "2026-10-06T23:38:05.170Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for
@@ -31,7 +31,7 @@ __export(version_exports, {
31
31
  toReleasePrecisionVersion: () => toReleasePrecisionVersion
32
32
  });
33
33
  module.exports = __toCommonJS(version_exports);
34
- const LIBRARY_VERSION = "14.3.0";
34
+ const LIBRARY_VERSION = "15.0.0";
35
35
  const ADCP_VERSION = "3.2.1";
36
36
  const ADCP_MAJOR_VERSION = 3;
37
37
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -95,10 +95,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
95
95
  "3.2"
96
96
  ];
97
97
  const VERSION_INFO = {
98
- library: "14.3.0",
98
+ library: "15.0.0",
99
99
  adcp: "3.2.1",
100
100
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
101
- generatedAt: "2026-10-06T16:34:47.947Z"
101
+ generatedAt: "2026-10-06T23:38:05.170Z"
102
102
  };
103
103
  function getAdcpVersion() {
104
104
  return ADCP_VERSION;
@@ -1,4 +1,4 @@
1
- const LIBRARY_VERSION = "14.3.0";
1
+ const LIBRARY_VERSION = "15.0.0";
2
2
  const ADCP_VERSION = "3.2.1";
3
3
  const ADCP_MAJOR_VERSION = 3;
4
4
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -62,10 +62,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
62
62
  "3.2"
63
63
  ];
64
64
  const VERSION_INFO = {
65
- library: "14.3.0",
65
+ library: "15.0.0",
66
66
  adcp: "3.2.1",
67
67
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
68
- generatedAt: "2026-10-06T16:34:47.947Z"
68
+ generatedAt: "2026-10-06T23:38:05.170Z"
69
69
  };
70
70
  function getAdcpVersion() {
71
71
  return ADCP_VERSION;
@@ -1,7 +1,7 @@
1
1
  # AdCP Type Summary
2
2
 
3
3
  > Generated at: 2026-10-06
4
- > @adcp/sdk v14.3.0
4
+ > @adcp/sdk v15.0.0
5
5
 
6
6
  Curated reference of the types that matter for using the AdCP client. For full generated types see `src/lib/types/tools.generated.ts` and `src/lib/types/core.generated.ts`.
7
7
 
@@ -41,6 +41,25 @@ if (result.success) {
41
41
 
42
42
  ## Common Use Cases
43
43
 
44
+ ### OAuth Client Credentials Configuration
45
+
46
+ `AgentOAuthClientCredentialsSchema` validates SDK configuration accepted by an API. It is available from `@adcp/sdk`, `@adcp/sdk/auth`, and `@adcp/sdk/schemas`.
47
+
48
+ ```typescript
49
+ import { AgentOAuthClientCredentialsSchema } from '@adcp/sdk/schemas';
50
+
51
+ const credentials = AgentOAuthClientCredentialsSchema.parse({
52
+ token_endpoint: 'https://auth.example.com/oauth/token',
53
+ client_id: 'client-id',
54
+ client_secret: '$ENV:ADCP_CLIENT_SECRET',
55
+ scope: 'adcp',
56
+ resource: ['https://agent.example.com'],
57
+ auth_method: 'basic',
58
+ });
59
+ ```
60
+
61
+ The schema requires a valid `token_endpoint` URL and non-empty `client_id` and `client_secret` strings. Optional fields are `scope`, `resource` (a string or string array), `audience`, and `auth_method` (`'basic'` or `'body'`). Parsing preserves `$ENV:VAR_NAME` references and leaves omitted fields unset. Token exchange resolves secrets and enforces HTTPS, URL userinfo, and private-address restrictions; this schema validates the configuration shape.
62
+
44
63
  ### API Request Validation
45
64
 
46
65
  ```typescript
@@ -0,0 +1,46 @@
1
+ # OAuth authorization-server binding
2
+
3
+ Major migration: background defaults and partial storage.
4
+
5
+ Refresh tokens/confidential clients need independently trusted `issuer` in
6
+ `AgentOAuthTokens` / `AgentOAuthClient`. Missing/mismatched bindings refuse before
7
+ secret refresh, DCR or replacement (`oauth_issuer_required` / `oauth_issuer_mismatch`).
8
+ Access-only tokens/public clients permit missing/null issuer; refresh requires it
9
+ even with valid access. Comparison tolerates one trailing slash, never different
10
+ tenant paths. Metadata follows the official asymmetric issuer-echo rule.
11
+
12
+ Recover: `adcp <alias> --clear-oauth`, then `adcp <alias> --oauth`.
13
+ Clear tokens/client/verifier/discovery, keeping URL/other auth. Each issuer may come
14
+ from trusted registration records, never PRM, unverified JWT, token-endpoint hostname
15
+ or successful requests. Upgrades cannot restore historical trust. Trust the resource
16
+ before fresh credentialless sign-in uses AS metadata; missing/mismatched returned
17
+ metadata issuer refuses.
18
+
19
+ Direct `MCPOAuthProvider` defaults to background; interactive opt-in:
20
+ `allowInteractiveAuthorization: true` (CLI factories do). Background PKCE/DCR and
21
+ token/client/all invalidation refuse (`owner_reauthorization_required`); direct
22
+ redirects retain `interactive_required`. Discovery/verifier invalidation is private
23
+ in background. Callers must authorize explicit `clearAuth`.
24
+
25
+ Adapters must retain token/client issuer and interactive PKCE/discovery. The SDK
26
+ revalidates restored discovery. File/custom adapters must BOTH preserve omitted
27
+ `oauth_tokens`, `oauth_client`, `oauth_code_verifier`, `oauth_discovery_state` AND
28
+ clear own `undefined` fields. Other fields retain backend semantics: omitted
29
+ `oauth_resource` clears in file storage. Background token/client/configured
30
+ client-credentials saves omit pending fields, preserving browser state created
31
+ during HTTP. Interactive completion clears its state; background never borrows owner PKCE.
32
+
33
+ Web stores must retain `PendingWebFlow.authorizationServerIssuer` and
34
+ `clientInformation.issuer`; restart unbound flows. Check frozen AS/current client
35
+ after metadata, before POST and before save; use the same client-bearing view at
36
+ start/callback. Explicit fresh owner flows may present a credentialless view,
37
+ stage DCR privately and reconstruct for callback. Applications provide ownership
38
+ and atomic generation replacement. No distributed refresh coordination,
39
+ grant/client CAS or spent-grant cancellation: quiesce background callers for recovery.
40
+
41
+ Custom providers must preserve issuer in getters/saves. Upstream
42
+ `ClientCredentialsProvider`, `PrivateKeyJwtProvider`, `StaticPrivateKeyJwtProvider`,
43
+ `CrossAppAccessProvider` need independent `expectedIssuer`. Direct exchange/refresh
44
+ helpers require caller binding checks (SDK web/diagnosis do them). Configured client
45
+ credentials retain the exact operator token endpoint, without PRM replacement or
46
+ credential-bearing redirects.