@adcp/sdk 14.2.0 → 14.4.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 (68) hide show
  1. package/bin/adcp.js +2 -4
  2. package/dist/lib/auth/oauth/MCPOAuthProvider.d.mts +6 -2
  3. package/dist/lib/auth/oauth/MCPOAuthProvider.d.ts +6 -2
  4. package/dist/lib/auth/oauth/MCPOAuthProvider.js +63 -3
  5. package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +75 -3
  6. package/dist/lib/auth/oauth/diagnose.js +14 -0
  7. package/dist/lib/auth/oauth/diagnose.mjs +14 -0
  8. package/dist/lib/auth/oauth/file-storage.d.mts +4 -2
  9. package/dist/lib/auth/oauth/file-storage.d.ts +4 -2
  10. package/dist/lib/auth/oauth/file-storage.js +7 -1
  11. package/dist/lib/auth/oauth/file-storage.mjs +7 -1
  12. package/dist/lib/auth/oauth/types.d.mts +10 -0
  13. package/dist/lib/auth/oauth/types.d.ts +10 -0
  14. package/dist/lib/auth/oauth/types.js +39 -0
  15. package/dist/lib/auth/oauth/types.mjs +37 -0
  16. package/dist/lib/auth/oauth/web-flow.js +11 -1
  17. package/dist/lib/auth/oauth/web-flow.mjs +20 -2
  18. package/dist/lib/protocols/mcp.js +2 -0
  19. package/dist/lib/protocols/mcp.mjs +2 -0
  20. package/dist/lib/reporting/inspection.d.mts +3 -3
  21. package/dist/lib/reporting/inspection.d.ts +3 -3
  22. package/dist/lib/reporting/inspection.js +229 -84
  23. package/dist/lib/reporting/inspection.mjs +229 -84
  24. package/dist/lib/reporting/ledger/status-ingest.js +3 -19
  25. package/dist/lib/reporting/ledger/status-ingest.mjs +2 -18
  26. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  27. package/dist/lib/server/create-adcp-server.js +5 -2
  28. package/dist/lib/server/create-adcp-server.mjs +5 -2
  29. package/dist/lib/signing/canonicalize.d.mts +2 -0
  30. package/dist/lib/signing/canonicalize.d.ts +2 -0
  31. package/dist/lib/signing/canonicalize.js +1 -1
  32. package/dist/lib/signing/canonicalize.mjs +1 -1
  33. package/dist/lib/signing/verifier.js +1 -1
  34. package/dist/lib/signing/verifier.mjs +1 -1
  35. package/dist/lib/testing/storyboard/request-signing/builder.js +13 -1
  36. package/dist/lib/testing/storyboard/request-signing/builder.mjs +13 -1
  37. package/dist/lib/testing/storyboard/request-signing/grader.js +1 -0
  38. package/dist/lib/testing/storyboard/request-signing/grader.mjs +1 -0
  39. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +1 -1
  40. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +1 -1
  41. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  42. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  43. package/dist/lib/types/adcp.d.mts +6 -0
  44. package/dist/lib/types/adcp.d.ts +6 -0
  45. package/dist/lib/utils/pointer-utils.d.mts +2 -0
  46. package/dist/lib/utils/pointer-utils.d.ts +2 -0
  47. package/dist/lib/utils/pointer-utils.js +43 -0
  48. package/dist/lib/utils/pointer-utils.mjs +19 -0
  49. package/dist/lib/validation/diagnostic-limits.d.mts +4 -0
  50. package/dist/lib/validation/diagnostic-limits.d.ts +4 -0
  51. package/dist/lib/validation/diagnostic-limits.js +57 -0
  52. package/dist/lib/validation/diagnostic-limits.mjs +32 -0
  53. package/dist/lib/validation/schema-errors.d.mts +3 -1
  54. package/dist/lib/validation/schema-errors.d.ts +3 -1
  55. package/dist/lib/validation/schema-errors.js +18 -3
  56. package/dist/lib/validation/schema-errors.mjs +18 -3
  57. package/dist/lib/validation/schema-validator.js +56 -4
  58. package/dist/lib/validation/schema-validator.mjs +56 -4
  59. package/dist/lib/version.d.mts +3 -3
  60. package/dist/lib/version.d.ts +3 -3
  61. package/dist/lib/version.js +3 -3
  62. package/dist/lib/version.mjs +3 -3
  63. package/docs/TYPE-SUMMARY.md +2 -2
  64. package/docs/llms.txt +2 -2
  65. package/docs/migration-14.x-rc-worksheet.md +5 -5
  66. package/docs/migration-oauth-issuer-bindings.md +82 -0
  67. package/package.json +6 -6
  68. package/skills/call-adcp-agent/SKILL.md +4 -1
@@ -29,6 +29,7 @@ var import_schema_loader = require('./schema-loader.js');
29
29
  var import_version = require('../version.js');
30
30
  var import_hints = require('./hints.js');
31
31
  var import_envelope_status_compat = require('../utils/envelope-status-compat.js');
32
+ var import_diagnostic_limits = require('./diagnostic-limits.js');
32
33
  const OK = Object.freeze({ valid: true, issues: [], variant: "skipped" });
33
34
  function extractSchemaId(schemaPath, rootSchema, registeredIds) {
34
35
  if (schemaPath.startsWith("#") || schemaPath === "") {
@@ -80,6 +81,59 @@ function resolveSchemaPath(rootSchema, schemaPath) {
80
81
  }
81
82
  return cursor;
82
83
  }
84
+ function* expandNotErrors(errors, rootSchema, payload) {
85
+ for (const error of errors) {
86
+ const rule = error.keyword === "not" ? resolveSchemaPath(rootSchema, error.schemaPath) : void 0;
87
+ const branches = rule && typeof rule === "object" ? rule.anyOf : void 0;
88
+ if (!Array.isArray(branches) || branches.length === 0 || Object.keys(rule).length !== 1) {
89
+ yield error;
90
+ continue;
91
+ }
92
+ let instance = payload;
93
+ if (error.instancePath) {
94
+ for (const encoded of error.instancePath.slice(1).split("/")) {
95
+ const key = encoded.replace(/~1/g, "/").replace(/~0/g, "~");
96
+ if (instance == null || typeof instance !== "object" || !Object.hasOwn(instance, key)) {
97
+ instance = void 0;
98
+ break;
99
+ }
100
+ instance = instance[key];
101
+ }
102
+ }
103
+ const keys = /* @__PURE__ */ new Set();
104
+ let opaqueBranch = false;
105
+ if (instance != null && typeof instance === "object" && !Array.isArray(instance)) {
106
+ for (const branch of branches) {
107
+ if (branch == null || typeof branch !== "object" || Object.keys(branch).length !== 1 || !Array.isArray(branch.required) || branch.required.length !== 1 || typeof branch.required[0] !== "string") {
108
+ opaqueBranch = true;
109
+ continue;
110
+ }
111
+ const key = branch.required[0];
112
+ if (Object.hasOwn(instance, key) && instance[key] !== void 0) keys.add(key);
113
+ }
114
+ }
115
+ if (keys.size === 0) {
116
+ yield error;
117
+ continue;
118
+ }
119
+ for (const key of keys) {
120
+ yield {
121
+ ...error,
122
+ instancePath: `${error.instancePath}/${key.replace(/~/g, "~0").replace(/\//g, "~1")}`,
123
+ message: `${key} cannot be set here`
124
+ };
125
+ }
126
+ if (opaqueBranch) yield error;
127
+ }
128
+ }
129
+ function formatValidationIssues(errors, ctx, payload) {
130
+ function* formatted() {
131
+ for (const error of expandNotErrors(compactUnionErrors(errors, ctx.rootSchema), ctx.rootSchema, payload)) {
132
+ yield enrichWithVariants(formatIssue(error, ctx), ctx.rootSchema);
133
+ }
134
+ }
135
+ return ctx.toolName === "sync_accounts" ? [...formatted()] : (0, import_diagnostic_limits.boundValidationIssues)(formatted());
136
+ }
83
137
  function compactUnionErrors(errors, rootSchema) {
84
138
  if (errors.length === 0) return [...errors];
85
139
  const errorsByOneOfPath = /* @__PURE__ */ new Map();
@@ -249,10 +303,9 @@ function validateRequest(toolName, payload, version) {
249
303
  if (valid) return { valid: true, issues: [], variant: "request", ...rootSchemaId && { schemaId: rootSchemaId } };
250
304
  const registeredIds = (0, import_schema_loader.getRegisteredSchemaIds)(version);
251
305
  const ctx = { rootSchema, registeredIds, toolName };
252
- const compacted = compactUnionErrors(validator.errors ?? [], rootSchema);
253
306
  return {
254
307
  valid: false,
255
- issues: compacted.map((e) => formatIssue(e, ctx)).map((i) => enrichWithVariants(i, rootSchema)),
308
+ issues: formatValidationIssues(validator.errors ?? [], ctx, payload),
256
309
  variant: "request",
257
310
  ...rootSchemaId && { schemaId: rootSchemaId }
258
311
  };
@@ -314,10 +367,9 @@ function validateResponse(toolName, payload, version) {
314
367
  }
315
368
  const registeredIds = (0, import_schema_loader.getRegisteredSchemaIds)(version);
316
369
  const ctx = { rootSchema, registeredIds, toolName };
317
- const compacted = compactUnionErrors(effective.errors ?? [], rootSchema);
318
370
  return {
319
371
  valid: false,
320
- issues: compacted.map((e) => formatIssue(e, ctx)).map((i) => enrichWithVariants(i, rootSchema)),
372
+ issues: formatValidationIssues(effective.errors ?? [], ctx, normalizedPayload),
321
373
  variant: usedVariant,
322
374
  ...rootSchemaId && { schemaId: rootSchemaId },
323
375
  ...fallbackFields
@@ -2,6 +2,7 @@ import { getValidator, getRegisteredSchemaIds } from "./schema-loader.mjs";
2
2
  import { parseAdcpMajorVersion } from "../version.mjs";
3
3
  import { findHint } from "./hints.mjs";
4
4
  import { injectLegacyEnvelopeStatus } from "../utils/envelope-status-compat.mjs";
5
+ import { boundValidationIssues } from "./diagnostic-limits.mjs";
5
6
  const OK = Object.freeze({ valid: true, issues: [], variant: "skipped" });
6
7
  function extractSchemaId(schemaPath, rootSchema, registeredIds) {
7
8
  if (schemaPath.startsWith("#") || schemaPath === "") {
@@ -53,6 +54,59 @@ function resolveSchemaPath(rootSchema, schemaPath) {
53
54
  }
54
55
  return cursor;
55
56
  }
57
+ function* expandNotErrors(errors, rootSchema, payload) {
58
+ for (const error of errors) {
59
+ const rule = error.keyword === "not" ? resolveSchemaPath(rootSchema, error.schemaPath) : void 0;
60
+ const branches = rule && typeof rule === "object" ? rule.anyOf : void 0;
61
+ if (!Array.isArray(branches) || branches.length === 0 || Object.keys(rule).length !== 1) {
62
+ yield error;
63
+ continue;
64
+ }
65
+ let instance = payload;
66
+ if (error.instancePath) {
67
+ for (const encoded of error.instancePath.slice(1).split("/")) {
68
+ const key = encoded.replace(/~1/g, "/").replace(/~0/g, "~");
69
+ if (instance == null || typeof instance !== "object" || !Object.hasOwn(instance, key)) {
70
+ instance = void 0;
71
+ break;
72
+ }
73
+ instance = instance[key];
74
+ }
75
+ }
76
+ const keys = /* @__PURE__ */ new Set();
77
+ let opaqueBranch = false;
78
+ if (instance != null && typeof instance === "object" && !Array.isArray(instance)) {
79
+ for (const branch of branches) {
80
+ if (branch == null || typeof branch !== "object" || Object.keys(branch).length !== 1 || !Array.isArray(branch.required) || branch.required.length !== 1 || typeof branch.required[0] !== "string") {
81
+ opaqueBranch = true;
82
+ continue;
83
+ }
84
+ const key = branch.required[0];
85
+ if (Object.hasOwn(instance, key) && instance[key] !== void 0) keys.add(key);
86
+ }
87
+ }
88
+ if (keys.size === 0) {
89
+ yield error;
90
+ continue;
91
+ }
92
+ for (const key of keys) {
93
+ yield {
94
+ ...error,
95
+ instancePath: `${error.instancePath}/${key.replace(/~/g, "~0").replace(/\//g, "~1")}`,
96
+ message: `${key} cannot be set here`
97
+ };
98
+ }
99
+ if (opaqueBranch) yield error;
100
+ }
101
+ }
102
+ function formatValidationIssues(errors, ctx, payload) {
103
+ function* formatted() {
104
+ for (const error of expandNotErrors(compactUnionErrors(errors, ctx.rootSchema), ctx.rootSchema, payload)) {
105
+ yield enrichWithVariants(formatIssue(error, ctx), ctx.rootSchema);
106
+ }
107
+ }
108
+ return ctx.toolName === "sync_accounts" ? [...formatted()] : boundValidationIssues(formatted());
109
+ }
56
110
  function compactUnionErrors(errors, rootSchema) {
57
111
  if (errors.length === 0) return [...errors];
58
112
  const errorsByOneOfPath = /* @__PURE__ */ new Map();
@@ -222,10 +276,9 @@ function validateRequest(toolName, payload, version) {
222
276
  if (valid) return { valid: true, issues: [], variant: "request", ...rootSchemaId && { schemaId: rootSchemaId } };
223
277
  const registeredIds = getRegisteredSchemaIds(version);
224
278
  const ctx = { rootSchema, registeredIds, toolName };
225
- const compacted = compactUnionErrors(validator.errors ?? [], rootSchema);
226
279
  return {
227
280
  valid: false,
228
- issues: compacted.map((e) => formatIssue(e, ctx)).map((i) => enrichWithVariants(i, rootSchema)),
281
+ issues: formatValidationIssues(validator.errors ?? [], ctx, payload),
229
282
  variant: "request",
230
283
  ...rootSchemaId && { schemaId: rootSchemaId }
231
284
  };
@@ -287,10 +340,9 @@ function validateResponse(toolName, payload, version) {
287
340
  }
288
341
  const registeredIds = getRegisteredSchemaIds(version);
289
342
  const ctx = { rootSchema, registeredIds, toolName };
290
- const compacted = compactUnionErrors(effective.errors ?? [], rootSchema);
291
343
  return {
292
344
  valid: false,
293
- issues: compacted.map((e) => formatIssue(e, ctx)).map((i) => enrichWithVariants(i, rootSchema)),
345
+ issues: formatValidationIssues(effective.errors ?? [], ctx, normalizedPayload),
294
346
  variant: usedVariant,
295
347
  ...rootSchemaId && { schemaId: rootSchemaId },
296
348
  ...fallbackFields
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "14.2.0";
4
+ export declare const LIBRARY_VERSION = "14.4.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.2.0";
36
+ readonly library: "14.4.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-05T12:32:54.072Z";
39
+ readonly generatedAt: "2026-10-06T19:00:01.077Z";
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.2.0";
4
+ export declare const LIBRARY_VERSION = "14.4.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.2.0";
36
+ readonly library: "14.4.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-05T12:32:54.072Z";
39
+ readonly generatedAt: "2026-10-06T19:00:01.077Z";
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.2.0";
34
+ const LIBRARY_VERSION = "14.4.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.2.0",
98
+ library: "14.4.0",
99
99
  adcp: "3.2.1",
100
100
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
101
- generatedAt: "2026-10-05T12:32:54.072Z"
101
+ generatedAt: "2026-10-06T19:00:01.077Z"
102
102
  };
103
103
  function getAdcpVersion() {
104
104
  return ADCP_VERSION;
@@ -1,4 +1,4 @@
1
- const LIBRARY_VERSION = "14.2.0";
1
+ const LIBRARY_VERSION = "14.4.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.2.0",
65
+ library: "14.4.0",
66
66
  adcp: "3.2.1",
67
67
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
68
- generatedAt: "2026-10-05T12:32:54.072Z"
68
+ generatedAt: "2026-10-06T19:00:01.077Z"
69
69
  };
70
70
  function getAdcpVersion() {
71
71
  return ADCP_VERSION;
@@ -1,7 +1,7 @@
1
1
  # AdCP Type Summary
2
2
 
3
- > Generated at: 2026-10-05
4
- > @adcp/sdk v14.2.0
3
+ > Generated at: 2026-10-06
4
+ > @adcp/sdk v14.4.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
 
package/docs/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ad Context Protocol (AdCP)
2
2
 
3
- > Generated at: 2026-10-05
4
- > Library: @adcp/sdk v14.2.0
3
+ > Generated at: 2026-10-06
4
+ > Library: @adcp/sdk v14.4.0
5
5
  > AdCP major version: 3
6
6
  > Canonical URL: https://adcontextprotocol.github.io/adcp-client/llms.txt
7
7
  > Note: the `Library` stamp reflects the package.json version at doc-generation time. The narrative below describes the surface that lands on the next-published minor — including any 6.7 helpers documented here ahead of the release tag.
@@ -11,8 +11,8 @@ below as the publication/deployment gate.
11
11
 
12
12
  | Fact | Value |
13
13
  | --- | --- |
14
- | Exact npm package | `@adcp/sdk@14.2.0` |
15
- | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@14.2.0 dist.integrity` |
14
+ | Exact npm package | `@adcp/sdk@14.4.0` |
15
+ | npm integrity | registry-derived after publication; run `npm view @adcp/sdk@14.4.0 dist.integrity` |
16
16
  | Node.js runtime | `^20.19.0 || >=22.12.0` |
17
17
  | Default AdCP wire release | `3.2.1` |
18
18
  | Maintained wire releases | `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` |
@@ -21,8 +21,8 @@ below as the publication/deployment gate.
21
21
  Install exact production inputs rather than a moving range or dist-tag:
22
22
 
23
23
  ```bash
24
- npm install --save-exact '@adcp/sdk@14.2.0'
25
- npm view '@adcp/sdk@14.2.0' dist.integrity
24
+ npm install --save-exact '@adcp/sdk@14.4.0'
25
+ npm view '@adcp/sdk@14.4.0' dist.integrity
26
26
  ```
27
27
 
28
28
  ### Required and optional peers
@@ -32,7 +32,7 @@ Install the peer packages used by your application at versions satisfying these
32
32
  | Peer | Supported range | Installation |
33
33
  | --- | --- | --- |
34
34
  | `@a2a-js/sdk` | `^1.0.1` | Required |
35
- | `@modelcontextprotocol/sdk` | `^1.24.0` | Required |
35
+ | `@modelcontextprotocol/sdk` | `^1.31.0` | Required |
36
36
  | `@opentelemetry/api` | `^1.0.0` | Optional |
37
37
  | `redis` | `^4.6.0 || ^5.0.0 || ^6.0.0` | Optional |
38
38
  | `zod` | `^4.1.5` | Required |
@@ -0,0 +1,82 @@
1
+ # OAuth issuer bindings
2
+
3
+ The corrective release after SDK 14.3.0 upgrades the official MCP client and
4
+ server to 2.2.0 and requires the legacy `@modelcontextprotocol/sdk` peer at
5
+ `^1.31.0`. These versions address
6
+ [GHSA-6qxp-vccf-f47h](https://github.com/advisories/GHSA-6qxp-vccf-f47h).
7
+ Installations pinned to legacy SDK 1.24–1.30 must upgrade that peer dependency.
8
+ The legacy OAuth transport rejects vulnerable versions even if package-manager
9
+ peer checks were bypassed. The Node.js requirement remains `^20.19.0 || >=22.12.0`.
10
+
11
+ OAuth refresh tokens and client secrets belong to an authorization server.
12
+ `AgentOAuthTokens` and `AgentOAuthClient` now preserve an optional `issuer`
13
+ field through the SDK's conversions, providers, and file storage. Newly saved
14
+ credentials receive their binding from the authorization flow. The provider
15
+ persists discovery alongside the pending PKCE verifier and clears that temporary
16
+ state after exchange; a callback uses the original authorization server even if
17
+ resource discovery changes while the browser is away. Custom `OAuthConfigStorage`
18
+ implementations must preserve `oauth_discovery_state` alongside `oauth_code_verifier`. Web flows
19
+ validate the discovered server's metadata issuer before registration and
20
+ token exchange; diagnostic refreshes validate it before sending credentials.
21
+ The provider refuses a changed authorization server before replacing a trusted
22
+ confidential registration or reusing a refresh token. Clear credentials explicitly
23
+ if an independently verified server migration requires a fresh registration.
24
+
25
+ File storage saves the OAuth fields as an authoritative snapshot: omitted tokens,
26
+ client, verifier, or discovery state are deleted. Load the complete agent from
27
+ storage before creating a provider; keep unrelated persisted fields as before.
28
+
29
+ ## Existing saved credentials
30
+
31
+ `MCPOAuthProvider` refuses to reuse a saved refresh token or client secret
32
+ without a valid issuer, with `oauth_issuer_required`. The web flow and
33
+ diagnostic runner also refuse mismatched bindings. Access-token-only and
34
+ public-client configurations do not require a new field. A saved unbound refresh
35
+ token blocks every call through the provider, even while its access token is
36
+ still valid; clear the saved credentials before reconnecting.
37
+
38
+ For a saved CLI alias, run `adcp <alias> --clear-oauth`, then
39
+ `adcp <alias> --oauth` to sign in again.
40
+
41
+ For legacy saved credentials, clear `oauth_tokens` and any confidential
42
+ `oauth_client` registration, then sign in again. Alternatively, an operator
43
+ may add the authorization-server issuer established independently from
44
+ trusted registration records. **Do not infer it from the current MCP server's
45
+ discovery metadata**, an access token's unverified claims, or its resource URL.
46
+ If the issuer is unknown, sign in again. Raw `issuer: null` is treated as absent for access-token-only and public-client
47
+ configurations; secrets still require a valid string issuer.
48
+
49
+ ```ts
50
+ agent.oauth_tokens = {
51
+ ...agent.oauth_tokens!,
52
+ issuer: 'https://auth.example.com', // independently verified token issuer
53
+ };
54
+ agent.oauth_client = {
55
+ ...agent.oauth_client!,
56
+ issuer: 'https://auth.example.com', // where this client was registered
57
+ };
58
+ ```
59
+
60
+ An issuer is an authorization-server URL, including its tenant path when one
61
+ exists. A single trailing slash difference is tolerated for credential
62
+ comparison; distinct tenant paths remain distinct. Stored pending web flows
63
+ containing an unbound confidential client must be restarted.
64
+
65
+ ## Custom providers
66
+
67
+ Preserve the complete `issuer` field passed to `saveTokens()` and
68
+ `saveClientInformation()`, and return it from the corresponding getters. Add
69
+ an independently verified issuer to pre-registered client information. The
70
+ upstream bundled `ClientCredentialsProvider`, `PrivateKeyJwtProvider`,
71
+ `StaticPrivateKeyJwtProvider`, and `CrossAppAccessProvider` also need
72
+ `expectedIssuer` configured. These are adopter-owned provider settings; a
73
+ dependency upgrade cannot reconstruct the ownership of older credentials.
74
+
75
+ Calls made directly to the upstream `exchangeAuthorization()` and
76
+ `refreshAuthorization()` helpers need their own credential-issuer checks.
77
+ The SDK's web-flow and diagnosis helpers perform those checks. The SDK's
78
+ client-credentials flow uses an explicitly configured token endpoint rather
79
+ than selecting one from MCP server discovery.
80
+
81
+ If affected credentials were sent to an untrusted authorization server,
82
+ follow the upstream advisory's credential-rotation guidance.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adcp/sdk",
3
- "version": "14.2.0",
3
+ "version": "14.4.0",
4
4
  "description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
5
5
  "workspaces": [
6
6
  ".",
@@ -713,10 +713,10 @@
713
713
  "email": "bugs@adcontextprotocol.org"
714
714
  },
715
715
  "dependencies": {
716
- "@modelcontextprotocol/client": "2.0.0",
716
+ "@modelcontextprotocol/client": "2.2.0",
717
717
  "@modelcontextprotocol/ext-apps": "2.0.0",
718
718
  "@modelcontextprotocol/node": "2.0.0",
719
- "@modelcontextprotocol/server": "2.0.0",
719
+ "@modelcontextprotocol/server": "2.2.0",
720
720
  "@types/ws": "^8.18.1",
721
721
  "ajv": "^8.20.0",
722
722
  "ajv-formats": "^3.0.1",
@@ -733,7 +733,7 @@
733
733
  },
734
734
  "peerDependencies": {
735
735
  "@a2a-js/sdk": "^1.0.1",
736
- "@modelcontextprotocol/sdk": "^1.24.0",
736
+ "@modelcontextprotocol/sdk": "^1.31.0",
737
737
  "@opentelemetry/api": "^1.0.0",
738
738
  "redis": "^4.6.0 || ^5.0.0 || ^6.0.0",
739
739
  "zod": "^4.1.5"
@@ -753,7 +753,7 @@
753
753
  "@changesets/cli": "^3.0.3",
754
754
  "@commitlint/cli": "^20.5.3",
755
755
  "@commitlint/config-conventional": "^20.5.3",
756
- "@modelcontextprotocol/sdk": "^1.30.0",
756
+ "@modelcontextprotocol/sdk": "^1.31.0",
757
757
  "@opentelemetry/api": "^1.9.1",
758
758
  "@types/express": "4.17.25",
759
759
  "@types/node": "^20.19.43",
@@ -790,7 +790,7 @@
790
790
  "js-yaml": "^4.1.1",
791
791
  "@apidevtools/json-schema-ref-parser@^15.0.0": {
792
792
  ".": "$@apidevtools/json-schema-ref-parser",
793
- "js-yaml": "^5.2.2"
793
+ "js-yaml": "^5.4.3"
794
794
  },
795
795
  "@changesets/parse": {
796
796
  "js-yaml": "^3.15.2"
@@ -112,7 +112,7 @@ Every validation failure produces:
112
112
  "adcp_error": {
113
113
  "code": "VALIDATION_ERROR",
114
114
  "recovery": "correctable",
115
- "field": "/first/offending/pointer",
115
+ "field": "account",
116
116
  "issues": [
117
117
  {
118
118
  "pointer": "/account",
@@ -130,7 +130,10 @@ Every validation failure produces:
130
130
  ```
131
131
 
132
132
  - `issues[].pointer` — RFC 6901 JSON Pointer to the field.
133
+ - `field` — the first issue's pointer translated to JSONPath-lite (for example, `packages[0].targeting`). Parse `issues[].pointer` when you need JSON Pointer notation.
133
134
  - `issues[].keyword` — AJV keyword (`required`, `type`, `oneOf`, `anyOf`, `additionalProperties`, `format`, `enum`).
135
+ - `not` presence guards name individually forbidden fields (for example, `product_id cannot be set here`). Compound guards retain their original diagnostic.
136
+ - `adcp_error.details.issues_truncated` — when true, the diagnostic list reached its count or byte limit. Fix the displayed failures and retry to see any remaining failures.
134
137
  - `issues[].variants` — when the keyword is `oneOf` or `anyOf`, each entry lists one variant's `required` + declared `properties`. **Pick ONE variant**, send only its `required` fields. This is the fastest recovery path when you didn't know the field was a union.
135
138
  - `issues[].discriminator` — when an SDK ≥6.7 picks a "best surviving variant" of a const-discriminated union, this is the `[{field, value}, …]` pairs that variant requires. Reads as the validator's verdict on which branch you were inferred to be targeting. Example: `discriminator: [{field: 'type', value: 'key_value'}]` plus `pointer: '/deployments/0/activation_key/key'` and `keyword: 'required'` means "you picked the `key_value` activation_key variant and it requires top-level `key` and `value`." Compound discriminators like `audience-selector`'s `(type, value_type)` produce two-entry arrays.
136
139
  - `issues[].schemaId` — `$id` of the rejecting schema. For tools served from the bundled tree this is usually the response root; for flat-tree tools it can land on the deeper sub-schema. Diagnostic only; the actionable lever is `discriminator` + `variants` + `pointer`.