@adcp/sdk 14.4.0 → 15.2.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 (188) hide show
  1. package/bin/adcp-grade.js +46 -2
  2. package/bin/adcp.js +13 -3
  3. package/dist/lib/auth/oauth/ClientCredentialsFlow.js +4 -1
  4. package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs +4 -1
  5. package/dist/lib/auth/oauth/MCPOAuthProvider.d.mts +19 -6
  6. package/dist/lib/auth/oauth/MCPOAuthProvider.d.ts +19 -6
  7. package/dist/lib/auth/oauth/MCPOAuthProvider.js +95 -30
  8. package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +96 -30
  9. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.d.mts +1 -1
  10. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.d.ts +1 -1
  11. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.js +1 -1
  12. package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs +1 -1
  13. package/dist/lib/auth/oauth/client-credentials-schema.d.mts +17 -0
  14. package/dist/lib/auth/oauth/client-credentials-schema.d.ts +17 -0
  15. package/dist/lib/auth/oauth/client-credentials-schema.js +37 -0
  16. package/dist/lib/auth/oauth/client-credentials-schema.mjs +13 -0
  17. package/dist/lib/auth/oauth/file-storage.d.mts +3 -3
  18. package/dist/lib/auth/oauth/file-storage.d.ts +3 -3
  19. package/dist/lib/auth/oauth/file-storage.js +12 -5
  20. package/dist/lib/auth/oauth/file-storage.mjs +12 -5
  21. package/dist/lib/auth/oauth/index.d.mts +10 -6
  22. package/dist/lib/auth/oauth/index.d.ts +10 -6
  23. package/dist/lib/auth/oauth/index.js +9 -3
  24. package/dist/lib/auth/oauth/index.mjs +8 -3
  25. package/dist/lib/auth/oauth/types.d.mts +9 -2
  26. package/dist/lib/auth/oauth/types.d.ts +9 -2
  27. package/dist/lib/auth/oauth/types.js +3 -2
  28. package/dist/lib/auth/oauth/types.mjs +3 -2
  29. package/dist/lib/auth/oauth/web-flow.d.mts +2 -0
  30. package/dist/lib/auth/oauth/web-flow.d.ts +2 -0
  31. package/dist/lib/auth/oauth/web-flow.js +42 -9
  32. package/dist/lib/auth/oauth/web-flow.mjs +42 -9
  33. package/dist/lib/canonical-references/index.d.mts +19 -1
  34. package/dist/lib/canonical-references/index.d.ts +19 -1
  35. package/dist/lib/canonical-references/index.js +81 -9
  36. package/dist/lib/canonical-references/index.mjs +80 -9
  37. package/dist/lib/client/core.d.mts +1 -0
  38. package/dist/lib/client/core.d.ts +1 -0
  39. package/dist/lib/core/AgentClient.d.mts +9 -1
  40. package/dist/lib/core/AgentClient.d.ts +9 -1
  41. package/dist/lib/core/AgentClient.js +10 -0
  42. package/dist/lib/core/AgentClient.mjs +10 -0
  43. package/dist/lib/core/SingleAgentClient.d.mts +13 -2
  44. package/dist/lib/core/SingleAgentClient.d.ts +13 -2
  45. package/dist/lib/core/SingleAgentClient.js +23 -5
  46. package/dist/lib/core/SingleAgentClient.mjs +23 -5
  47. package/dist/lib/index.d.mts +2 -2
  48. package/dist/lib/index.d.ts +2 -2
  49. package/dist/lib/index.js +2 -0
  50. package/dist/lib/index.mjs +3 -1
  51. package/dist/lib/reporting/gcs/adapter.d.mts +31 -0
  52. package/dist/lib/reporting/gcs/adapter.d.ts +31 -0
  53. package/dist/lib/reporting/gcs/adapter.js +342 -0
  54. package/dist/lib/reporting/gcs/adapter.mjs +325 -0
  55. package/dist/lib/reporting/gcs/bucket-policy.d.mts +3 -0
  56. package/dist/lib/reporting/gcs/bucket-policy.d.ts +3 -0
  57. package/dist/lib/reporting/gcs/bucket-policy.js +31 -0
  58. package/dist/lib/reporting/gcs/bucket-policy.mjs +7 -0
  59. package/dist/lib/reporting/gcs/errors.d.mts +5 -0
  60. package/dist/lib/reporting/gcs/errors.d.ts +5 -0
  61. package/dist/lib/reporting/gcs/errors.js +41 -0
  62. package/dist/lib/reporting/gcs/errors.mjs +16 -0
  63. package/dist/lib/reporting/gcs/fence.d.mts +36 -0
  64. package/dist/lib/reporting/gcs/fence.d.ts +36 -0
  65. package/dist/lib/reporting/gcs/fence.js +250 -0
  66. package/dist/lib/reporting/gcs/fence.mjs +230 -0
  67. package/dist/lib/reporting/gcs/index.d.mts +7 -0
  68. package/dist/lib/reporting/gcs/index.d.ts +7 -0
  69. package/dist/lib/reporting/gcs/index.js +41 -0
  70. package/dist/lib/reporting/gcs/index.mjs +12 -0
  71. package/dist/lib/reporting/gcs/io.d.mts +7 -0
  72. package/dist/lib/reporting/gcs/io.d.ts +7 -0
  73. package/dist/lib/reporting/gcs/io.js +95 -0
  74. package/dist/lib/reporting/gcs/io.mjs +69 -0
  75. package/dist/lib/reporting/gcs/reader.d.mts +43 -0
  76. package/dist/lib/reporting/gcs/reader.d.ts +43 -0
  77. package/dist/lib/reporting/gcs/reader.js +193 -0
  78. package/dist/lib/reporting/gcs/reader.mjs +169 -0
  79. package/dist/lib/reporting/gcs/validation.d.mts +5 -0
  80. package/dist/lib/reporting/gcs/validation.d.ts +5 -0
  81. package/dist/lib/reporting/gcs/validation.js +49 -0
  82. package/dist/lib/reporting/gcs/validation.mjs +25 -0
  83. package/dist/lib/reporting/ledger/handler.d.mts +1 -0
  84. package/dist/lib/reporting/ledger/handler.d.ts +1 -0
  85. package/dist/lib/reporting/ledger/index.d.mts +1 -0
  86. package/dist/lib/reporting/ledger/index.d.ts +1 -0
  87. package/dist/lib/reporting/ledger/index.js +2 -0
  88. package/dist/lib/reporting/ledger/index.mjs +1 -0
  89. package/dist/lib/reporting/ledger/managed-postgres.d.mts +16 -1
  90. package/dist/lib/reporting/ledger/managed-postgres.d.ts +16 -1
  91. package/dist/lib/reporting/ledger/managed-postgres.js +243 -2
  92. package/dist/lib/reporting/ledger/managed-postgres.mjs +248 -2
  93. package/dist/lib/reporting/ledger/object-writes.d.mts +69 -0
  94. package/dist/lib/reporting/ledger/object-writes.d.ts +69 -0
  95. package/dist/lib/reporting/ledger/object-writes.js +147 -0
  96. package/dist/lib/reporting/ledger/object-writes.mjs +114 -0
  97. package/dist/lib/schemas/index.d.mts +2 -0
  98. package/dist/lib/schemas/index.d.ts +2 -0
  99. package/dist/lib/schemas/index.js +3 -0
  100. package/dist/lib/schemas/index.mjs +2 -0
  101. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  102. package/dist/lib/server/a2a-adapter.d.mts +50 -1
  103. package/dist/lib/server/a2a-adapter.d.ts +50 -1
  104. package/dist/lib/server/a2a-adapter.js +230 -7
  105. package/dist/lib/server/a2a-adapter.mjs +237 -7
  106. package/dist/lib/server/auth-signature.d.mts +84 -46
  107. package/dist/lib/server/auth-signature.d.ts +84 -46
  108. package/dist/lib/server/auth-signature.js +48 -14
  109. package/dist/lib/server/auth-signature.mjs +58 -15
  110. package/dist/lib/server/create-adcp-server.js +5 -16
  111. package/dist/lib/server/create-adcp-server.mjs +5 -16
  112. package/dist/lib/server/index.d.mts +1 -1
  113. package/dist/lib/server/index.d.ts +1 -1
  114. package/dist/lib/server/index.js +2 -0
  115. package/dist/lib/server/index.mjs +3 -1
  116. package/dist/lib/signing/agent-fetch.js +3 -33
  117. package/dist/lib/signing/agent-fetch.mjs +3 -33
  118. package/dist/lib/signing/middleware.d.mts +9 -1
  119. package/dist/lib/signing/middleware.d.ts +9 -1
  120. package/dist/lib/signing/operation-resolution.d.mts +37 -0
  121. package/dist/lib/signing/operation-resolution.d.ts +37 -0
  122. package/dist/lib/signing/operation-resolution.js +154 -0
  123. package/dist/lib/signing/operation-resolution.mjs +125 -0
  124. package/dist/lib/signing/postgres-replay-store.d.mts +1 -1
  125. package/dist/lib/signing/postgres-replay-store.d.ts +1 -1
  126. package/dist/lib/signing/redis-replay-store.d.mts +1 -1
  127. package/dist/lib/signing/redis-replay-store.d.ts +1 -1
  128. package/dist/lib/signing/server.d.mts +1 -0
  129. package/dist/lib/signing/server.d.ts +1 -0
  130. package/dist/lib/signing/server.js +7 -0
  131. package/dist/lib/signing/server.mjs +8 -0
  132. package/dist/lib/signing/verifier.d.mts +36 -1
  133. package/dist/lib/signing/verifier.d.ts +36 -1
  134. package/dist/lib/signing/verifier.js +66 -34
  135. package/dist/lib/signing/verifier.mjs +61 -34
  136. package/dist/lib/testing/client.js +8 -3
  137. package/dist/lib/testing/client.mjs +8 -3
  138. package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.mts +12 -0
  139. package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.ts +12 -0
  140. package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.js +29 -2
  141. package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.mjs +27 -1
  142. package/dist/lib/testing/storyboard/request-signing/a2a-operation-resolution.d.mts +61 -0
  143. package/dist/lib/testing/storyboard/request-signing/a2a-operation-resolution.d.ts +61 -0
  144. package/dist/lib/testing/storyboard/request-signing/a2a-operation-resolution.js +298 -0
  145. package/dist/lib/testing/storyboard/request-signing/a2a-operation-resolution.mjs +276 -0
  146. package/dist/lib/testing/storyboard/request-signing/grader.d.mts +31 -1
  147. package/dist/lib/testing/storyboard/request-signing/grader.d.ts +31 -1
  148. package/dist/lib/testing/storyboard/request-signing/grader.js +11 -0
  149. package/dist/lib/testing/storyboard/request-signing/grader.mjs +11 -0
  150. package/dist/lib/testing/storyboard/request-signing/index.d.mts +5 -4
  151. package/dist/lib/testing/storyboard/request-signing/index.d.ts +5 -4
  152. package/dist/lib/testing/storyboard/request-signing/index.js +13 -0
  153. package/dist/lib/testing/storyboard/request-signing/index.mjs +18 -2
  154. package/dist/lib/testing/storyboard/request-signing/types.d.mts +43 -0
  155. package/dist/lib/testing/storyboard/request-signing/types.d.ts +43 -0
  156. package/dist/lib/testing/storyboard/request-signing/types.js +3 -0
  157. package/dist/lib/testing/storyboard/request-signing/types.mjs +2 -0
  158. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +42 -1
  159. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +42 -1
  160. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +100 -1
  161. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +104 -3
  162. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  163. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  164. package/dist/lib/testing/types.d.mts +10 -1
  165. package/dist/lib/testing/types.d.ts +10 -1
  166. package/dist/lib/version.d.mts +3 -3
  167. package/dist/lib/version.d.ts +3 -3
  168. package/dist/lib/version.js +3 -3
  169. package/dist/lib/version.mjs +3 -3
  170. package/docs/TYPE-SUMMARY.md +2 -2
  171. package/docs/ZOD-SCHEMAS.md +19 -0
  172. package/docs/guides/BUILD-AN-AGENT.md +9 -4
  173. package/docs/guides/CREATIVE-DELIVERY.md +34 -0
  174. package/docs/guides/OAUTH-ISSUER-BINDING.md +46 -0
  175. package/docs/guides/REPORTING-GCS-FENCE.md +52 -0
  176. package/docs/guides/REPORTING-GCS-MANAGED.md +56 -0
  177. package/docs/guides/REPORTING-OPERATIONS.md +4 -0
  178. package/docs/guides/SIGNING-GUIDE.md +20 -6
  179. package/docs/guides/VALIDATE-YOUR-AGENT.md +4 -0
  180. package/docs/guides/WEB-OAUTH.md +58 -163
  181. package/docs/guides/account-resolution.md +1 -1
  182. package/docs/llms.txt +2 -2
  183. package/docs/migration-14.0-to-14.1.md +1 -1
  184. package/docs/migration-14.x-rc-worksheet.md +8 -7
  185. package/docs/migration-buyer-agent-registry.md +1 -1
  186. package/docs/migration-oauth-issuer-bindings.md +14 -79
  187. package/package.json +19 -1
  188. package/skills/build-seller-agent/specialisms/signed-requests.md +2 -0
package/bin/adcp-grade.js CHANGED
@@ -45,7 +45,25 @@ Options:
45
45
  JSON-RPC tools/call envelope and posts to the
46
46
  agent's MCP mount (see #612); \`raw\` posts to
47
47
  per-operation AdCP endpoints (REST-binding agents);
48
- \`a2a\` signs the official A2A client's request.
48
+ \`a2a\` signs the official A2A client's request
49
+ and also grades the A2A operation-resolution
50
+ vectors (adcp#7945): required_for must be
51
+ enforced against the operation named by the
52
+ invocation DataPart's \`skill\`, not the JSON-RPC
53
+ method. Vector ids are prefixed a2a/. Tiers:
54
+ contradiction-resolution (MUST in 3.2) and
55
+ hardening (SHOULD in 3.2.x, MUST from 3.3). The
56
+ signed create_media_buy vectors need
57
+ --allow-live-side-effects (or a sandbox
58
+ contract). If the compliance bundle carries no
59
+ A2A vectors the run reports them unavailable.
60
+ --required-for <op[,op...]>
61
+ Agent's request_signing.required_for. Skips
62
+ vectors that assert an operation the agent does
63
+ not require (capability_profile_mismatch).
64
+ --protocol-methods-required-for <m[,m...]>
65
+ Agent's request_signing.protocol_methods_required_for
66
+ (e.g. SendMessage). Gates A2A negative/007.
49
67
  --timeout <ms> Per-probe timeout (default 10000)
50
68
  --json Emit the full GradeReport as JSON
51
69
  -h, --help Show this help
@@ -54,6 +72,9 @@ Environment:
54
72
  ADCP_GRADE_INITIALIZE_AUTHORIZATION
55
73
  Authorization header used only for the MCP
56
74
  initialize lifecycle (kept out of process argv).
75
+ ADCP_A2A_VECTORS_DIR Directory with the A2A operation-resolution
76
+ vectors (positive/ and negative/), overriding the
77
+ compliance bundle. For bundles that predate them.
57
78
 
58
79
  Exit code:
59
80
  0 all graded vectors passed (skipped vectors don't count as failures)
@@ -202,6 +223,12 @@ async function runRequestSigningGrader(args) {
202
223
  options.signingProfileVersion = profile;
203
224
  break;
204
225
  }
226
+ case '--required-for':
227
+ options.agentRequiredFor = parseVectorList(args[++i], '--required-for');
228
+ break;
229
+ case '--protocol-methods-required-for':
230
+ options.agentProtocolMethodsRequiredFor = parseVectorList(args[++i], '--protocol-methods-required-for');
231
+ break;
205
232
  case '--allow-live-side-effects':
206
233
  options.allowLiveSideEffects = true;
207
234
  break;
@@ -470,6 +497,7 @@ function printHumanReport(report, options = {}) {
470
497
  `${report.passed_count} passed, ${report.failed_count} failed, ${report.skipped_count} skipped — total ${report.total_duration_ms}ms`
471
498
  );
472
499
  console.log(`Overall: ${report.passed ? 'PASS' : 'FAIL'}`);
500
+ printA2aOperationResolutionSummary(report.a2a_operation_resolution);
473
501
  // Only hint on an EXPLICIT --transport raw run — mcp is the default now,
474
502
  // so an unset transport already grades over MCP and the raw→mcp retry
475
503
  // hint would misdirect (if mcp mode fails everywhere, it's a different
@@ -484,6 +512,22 @@ function printHumanReport(report, options = {}) {
484
512
  console.log();
485
513
  }
486
514
 
515
+ function printA2aOperationResolutionSummary(summary) {
516
+ if (!summary) return;
517
+ console.log();
518
+ if (!summary.vectors_available) {
519
+ console.log(`⚠ A2A operation-resolution: ${summary.message}. required_for over A2A was NOT graded.`);
520
+ return;
521
+ }
522
+ const t = summary.tiers;
523
+ const line = (label, tier) =>
524
+ ` ${label}: ${tier.passed} passed, ${tier.failed} failed, ${tier.skipped} skipped` +
525
+ (tier.failed_vectors.length ? ` (failed: ${tier.failed_vectors.join(', ')})` : '');
526
+ console.log(`A2A operation-resolution vectors (source: ${summary.source}):`);
527
+ console.log(line('contradiction-resolution (MUST in 3.2)', t['contradiction-resolution']));
528
+ console.log(line('hardening (SHOULD in 3.2.x, MUST from 3.3)', t.hardening));
529
+ }
530
+
487
531
  /**
488
532
  * Heuristic: if the grader ran in `raw` mode (explicit --transport raw —
489
533
  * mcp is the default) and every non-skipped vector
@@ -516,7 +560,7 @@ function formatRow(r) {
516
560
  : r.passed
517
561
  ? `${r.http_status}${r.actual_error_code ? ` ${r.actual_error_code}` : ''}`
518
562
  : (r.diagnostic ?? 'see report');
519
- return { id, status, detail };
563
+ return { id, status, detail: r.tier && !r.skipped ? `[${r.tier}] ${detail}` : detail };
520
564
  }
521
565
 
522
566
  module.exports = { handleGradeCommand };
package/bin/adcp.js CHANGED
@@ -1966,7 +1966,9 @@ COMMANDS:
1966
1966
  doctor [options] Check project secrets, SDK drift, and migrations
1967
1967
  storyboard <subcommand> Test agent flows (run, list, show, step)
1968
1968
  specialism <subcommand> Inspect a compliance specialism (list, show)
1969
- grade <subject> <url> Conformance graders (e.g. request-signing)
1969
+ grade <subject> <url> Conformance graders (e.g. request-signing; with
1970
+ --transport a2a it also grades the A2A
1971
+ operation-resolution vectors)
1970
1972
  fuzz <url> Property-based conformance fuzzing against schemas
1971
1973
  resolve <agent-url> Walk the brand_json_url discovery chain
1972
1974
  (capabilities -> brand.json -> JWKS) and print
@@ -2191,7 +2193,10 @@ REQUEST-SIGNING VECTOR OPTIONS (signed_requests storyboard):
2191
2193
  discovery. Pass raw for agents that
2192
2194
  expose AdCP tools as per-operation HTTP
2193
2195
  endpoints. Mirrors
2194
- \`adcp grade request-signing --transport\`.
2196
+ \`adcp grade request-signing --transport\`,
2197
+ which with a2a additionally grades the A2A
2198
+ operation-resolution vectors (required_for
2199
+ keyed on the DataPart skill, adcp#7945).
2195
2200
  --signing-skip-vectors IDS Comma-separated vector ids to skip (graded
2196
2201
  operator_skip), e.g.
2197
2202
  025-jwk-alg-crv-mismatch. Unknown ids are
@@ -6659,7 +6664,12 @@ credential material — never sync or commit.
6659
6664
  }
6660
6665
 
6661
6666
  const agentConfig = getAgent(alias);
6662
- if (!agentConfig.oauth_tokens) {
6667
+ if (
6668
+ !agentConfig.oauth_tokens &&
6669
+ !agentConfig.oauth_client &&
6670
+ !agentConfig.oauth_code_verifier &&
6671
+ !agentConfig.oauth_discovery_state
6672
+ ) {
6663
6673
  console.log(`\nAgent '${alias}' has no OAuth tokens to clear.\n`);
6664
6674
  process.exit(0);
6665
6675
  }
@@ -247,7 +247,10 @@ async function ensureClientCredentialsTokens(agent, options = {}) {
247
247
  });
248
248
  agent.oauth_tokens = tokens;
249
249
  if (options.storage) {
250
- await options.storage.saveAgent(agent);
250
+ const refreshedAgent = { ...agent };
251
+ delete refreshedAgent.oauth_code_verifier;
252
+ delete refreshedAgent.oauth_discovery_state;
253
+ await options.storage.saveAgent(refreshedAgent);
251
254
  }
252
255
  return tokens;
253
256
  } finally {
@@ -222,7 +222,10 @@ async function ensureClientCredentialsTokens(agent, options = {}) {
222
222
  });
223
223
  agent.oauth_tokens = tokens;
224
224
  if (options.storage) {
225
- await options.storage.saveAgent(agent);
225
+ const refreshedAgent = { ...agent };
226
+ delete refreshedAgent.oauth_code_verifier;
227
+ delete refreshedAgent.oauth_discovery_state;
228
+ await options.storage.saveAgent(refreshedAgent);
226
229
  }
227
230
  return tokens;
228
231
  } finally {
@@ -20,13 +20,15 @@ export declare function assertLegacyOAuthSdk(): void;
20
20
  * name: 'My Agent',
21
21
  * agent_uri: 'https://agent.example.com/mcp',
22
22
  * protocol: 'mcp',
23
- * // OAuth tokens stored here after auth flow
24
- * oauth_tokens: { access_token: '...', refresh_token: '...' }
23
+ * // A fresh interactive flow saves issuer-bound credentials afterward.
25
24
  * };
26
25
  *
26
+ * const flowHandler = new CLIFlowHandler();
27
27
  * const provider = new MCPOAuthProvider({
28
28
  * agent,
29
- * flowHandler: new CLIFlowHandler(),
29
+ * flowHandler,
30
+ * clientMetadata: { ...DEFAULT_CLIENT_METADATA, redirect_uris: [flowHandler.getRedirectUrl().toString()] },
31
+ * allowInteractiveAuthorization: true,
30
32
  * storage: myConfigStorage // Optional: persists tokens
31
33
  * });
32
34
  *
@@ -42,6 +44,8 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
42
44
  private readonly _clientMetadata;
43
45
  private readonly allowHttp;
44
46
  private readonly configuredResourceOverride?;
47
+ private readonly allowInteractiveAuthorization;
48
+ private pendingDiscoveryState?;
45
49
  constructor(config: OAuthProviderConfig);
46
50
  /**
47
51
  * Create a provider for CLI usage
@@ -73,7 +77,9 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
73
77
  /**
74
78
  * Load client information from agent config
75
79
  */
76
- clientInformation(): Promise<OAuthClientInformation | undefined>;
80
+ clientInformation(ctx?: {
81
+ issuer: string;
82
+ }): Promise<OAuthClientInformation | undefined>;
77
83
  /**
78
84
  * Save client information after dynamic registration
79
85
  */
@@ -81,7 +87,9 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
81
87
  /**
82
88
  * Load existing tokens from agent config
83
89
  */
84
- tokens(): Promise<OAuthTokens | undefined>;
90
+ tokens(ctx?: {
91
+ issuer: string;
92
+ }): Promise<OAuthTokens | undefined>;
85
93
  /**
86
94
  * Save tokens after authorization
87
95
  * Also cleans up the temporary code verifier
@@ -94,6 +102,9 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
94
102
  /** Persist the authorization-server identity across the callback leg. */
95
103
  saveDiscoveryState(state: OAuthDiscoveryState): Promise<void>;
96
104
  discoveryState(): Promise<OAuthDiscoveryState | undefined>;
105
+ private validateDiscoveryState;
106
+ private checkIssuerContext;
107
+ private ownerReauthorizationRequired;
97
108
  /**
98
109
  * Save PKCE code verifier
99
110
  */
@@ -108,9 +119,11 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
108
119
  * Invalidate credentials when server indicates they're invalid
109
120
  */
110
121
  invalidateCredentials(scope: Parameters<NonNullable<OAuthClientProvider['invalidateCredentials']>>[0]): Promise<void>;
122
+ private clearCredentials;
111
123
  /**
112
- * Persist agent config to storage if configured
124
+ * Persist a credential update without modifying independent browser state.
113
125
  */
126
+ private persistCredentials;
114
127
  private persistAgent;
115
128
  /**
116
129
  * Wait for the OAuth callback
@@ -20,13 +20,15 @@ export declare function assertLegacyOAuthSdk(): void;
20
20
  * name: 'My Agent',
21
21
  * agent_uri: 'https://agent.example.com/mcp',
22
22
  * protocol: 'mcp',
23
- * // OAuth tokens stored here after auth flow
24
- * oauth_tokens: { access_token: '...', refresh_token: '...' }
23
+ * // A fresh interactive flow saves issuer-bound credentials afterward.
25
24
  * };
26
25
  *
26
+ * const flowHandler = new CLIFlowHandler();
27
27
  * const provider = new MCPOAuthProvider({
28
28
  * agent,
29
- * flowHandler: new CLIFlowHandler(),
29
+ * flowHandler,
30
+ * clientMetadata: { ...DEFAULT_CLIENT_METADATA, redirect_uris: [flowHandler.getRedirectUrl().toString()] },
31
+ * allowInteractiveAuthorization: true,
30
32
  * storage: myConfigStorage // Optional: persists tokens
31
33
  * });
32
34
  *
@@ -42,6 +44,8 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
42
44
  private readonly _clientMetadata;
43
45
  private readonly allowHttp;
44
46
  private readonly configuredResourceOverride?;
47
+ private readonly allowInteractiveAuthorization;
48
+ private pendingDiscoveryState?;
45
49
  constructor(config: OAuthProviderConfig);
46
50
  /**
47
51
  * Create a provider for CLI usage
@@ -73,7 +77,9 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
73
77
  /**
74
78
  * Load client information from agent config
75
79
  */
76
- clientInformation(): Promise<OAuthClientInformation | undefined>;
80
+ clientInformation(ctx?: {
81
+ issuer: string;
82
+ }): Promise<OAuthClientInformation | undefined>;
77
83
  /**
78
84
  * Save client information after dynamic registration
79
85
  */
@@ -81,7 +87,9 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
81
87
  /**
82
88
  * Load existing tokens from agent config
83
89
  */
84
- tokens(): Promise<OAuthTokens | undefined>;
90
+ tokens(ctx?: {
91
+ issuer: string;
92
+ }): Promise<OAuthTokens | undefined>;
85
93
  /**
86
94
  * Save tokens after authorization
87
95
  * Also cleans up the temporary code verifier
@@ -94,6 +102,9 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
94
102
  /** Persist the authorization-server identity across the callback leg. */
95
103
  saveDiscoveryState(state: OAuthDiscoveryState): Promise<void>;
96
104
  discoveryState(): Promise<OAuthDiscoveryState | undefined>;
105
+ private validateDiscoveryState;
106
+ private checkIssuerContext;
107
+ private ownerReauthorizationRequired;
97
108
  /**
98
109
  * Save PKCE code verifier
99
110
  */
@@ -108,9 +119,11 @@ export declare class MCPOAuthProvider implements OAuthClientProvider {
108
119
  * Invalidate credentials when server indicates they're invalid
109
120
  */
110
121
  invalidateCredentials(scope: Parameters<NonNullable<OAuthClientProvider['invalidateCredentials']>>[0]): Promise<void>;
122
+ private clearCredentials;
111
123
  /**
112
- * Persist agent config to storage if configured
124
+ * Persist a credential update without modifying independent browser state.
113
125
  */
126
+ private persistCredentials;
114
127
  private persistAgent;
115
128
  /**
116
129
  * Wait for the OAuth callback
@@ -59,6 +59,8 @@ class MCPOAuthProvider {
59
59
  _clientMetadata;
60
60
  allowHttp;
61
61
  configuredResourceOverride;
62
+ allowInteractiveAuthorization;
63
+ pendingDiscoveryState;
62
64
  constructor(config) {
63
65
  this.agent = config.agent;
64
66
  this.storage = config.storage;
@@ -66,6 +68,7 @@ class MCPOAuthProvider {
66
68
  this._clientMetadata = config.clientMetadata;
67
69
  this.allowHttp = config.allowHttp === true;
68
70
  this.configuredResourceOverride = config.resourceOverride;
71
+ this.allowInteractiveAuthorization = config.allowInteractiveAuthorization === true;
69
72
  }
70
73
  /**
71
74
  * Create a provider for CLI usage
@@ -82,7 +85,8 @@ class MCPOAuthProvider {
82
85
  storage,
83
86
  clientMetadata,
84
87
  allowHttp: options?.allowHttp,
85
- resourceOverride: options?.resourceOverride
88
+ resourceOverride: options?.resourceOverride,
89
+ allowInteractiveAuthorization: true
86
90
  });
87
91
  }
88
92
  // ========================================
@@ -123,7 +127,11 @@ class MCPOAuthProvider {
123
127
  /**
124
128
  * Load client information from agent config
125
129
  */
126
- async clientInformation() {
130
+ async clientInformation(ctx) {
131
+ const issuer = this.checkIssuerContext(ctx);
132
+ if (issuer && !this.agent.oauth_client && !this.allowInteractiveAuthorization) {
133
+ throw this.ownerReauthorizationRequired();
134
+ }
127
135
  if (this.agent.oauth_client) {
128
136
  if (this.agent.oauth_client.client_secret) assertLegacyOAuthSdk();
129
137
  (0, import_types.assertOAuthCredentialIssuer)(this.agent.oauth_client, void 0, !!this.agent.oauth_client.client_secret);
@@ -136,12 +144,13 @@ class MCPOAuthProvider {
136
144
  */
137
145
  async saveClientInformation(clientInfo) {
138
146
  this.agent.oauth_client = (0, import_types.fromMCPClientInfo)(clientInfo);
139
- await this.persistAgent();
147
+ await this.persistCredentials();
140
148
  }
141
149
  /**
142
150
  * Load existing tokens from agent config
143
151
  */
144
- async tokens() {
152
+ async tokens(ctx) {
153
+ this.checkIssuerContext(ctx);
145
154
  if (this.agent.oauth_tokens) {
146
155
  if (this.agent.oauth_tokens.refresh_token) assertLegacyOAuthSdk();
147
156
  (0, import_types.assertOAuthCredentialIssuer)(this.agent.oauth_tokens, void 0, !!this.agent.oauth_tokens.refresh_token);
@@ -155,14 +164,18 @@ class MCPOAuthProvider {
155
164
  */
156
165
  async saveTokens(tokens) {
157
166
  this.agent.oauth_tokens = (0, import_types.fromMCPTokens)(tokens);
158
- delete this.agent.oauth_code_verifier;
159
- delete this.agent.oauth_discovery_state;
160
- await this.persistAgent();
167
+ if (this.allowInteractiveAuthorization) {
168
+ this.agent.oauth_code_verifier = void 0;
169
+ this.agent.oauth_discovery_state = void 0;
170
+ }
171
+ this.pendingDiscoveryState = void 0;
172
+ await this.persistCredentials();
161
173
  }
162
174
  /**
163
175
  * Redirect user to authorization URL
164
176
  */
165
177
  async redirectToAuthorization(authorizationUrl) {
178
+ if (!this.allowInteractiveAuthorization) throw this.ownerReauthorizationRequired("interactive_required");
166
179
  try {
167
180
  await this.flowHandler.redirectToAuthorization(authorizationUrl);
168
181
  } catch (error) {
@@ -172,23 +185,51 @@ class MCPOAuthProvider {
172
185
  }
173
186
  /** Persist the authorization-server identity across the callback leg. */
174
187
  async saveDiscoveryState(state) {
175
- const issuer = String(state.authorizationServerUrl);
176
- if (this.agent.oauth_tokens?.refresh_token) {
177
- (0, import_types.assertOAuthCredentialIssuer)(this.agent.oauth_tokens, issuer, true);
178
- }
179
- if (this.agent.oauth_client?.client_secret) {
180
- (0, import_types.assertOAuthCredentialIssuer)(this.agent.oauth_client, issuer, true);
188
+ this.validateDiscoveryState(state);
189
+ if (!this.agent.oauth_client && !this.allowInteractiveAuthorization) throw this.ownerReauthorizationRequired();
190
+ this.pendingDiscoveryState = structuredClone(state);
191
+ if (this.allowInteractiveAuthorization) {
192
+ this.agent.oauth_discovery_state = structuredClone(state);
193
+ await this.persistAgent();
181
194
  }
182
- this.agent.oauth_discovery_state = state;
183
- await this.persistAgent();
184
195
  }
185
196
  async discoveryState() {
186
- return this.agent.oauth_code_verifier ? this.agent.oauth_discovery_state : void 0;
197
+ if (!this.allowInteractiveAuthorization) return void 0;
198
+ if (!this.agent.oauth_code_verifier) return void 0;
199
+ const state = this.pendingDiscoveryState ?? this.agent.oauth_discovery_state;
200
+ if (!state) return void 0;
201
+ this.validateDiscoveryState(state);
202
+ this.pendingDiscoveryState = structuredClone(state);
203
+ return structuredClone(state);
204
+ }
205
+ validateDiscoveryState(state) {
206
+ (0, import_types.assertOAuthServerIssuer)(state.authorizationServerMetadata, String(state.authorizationServerUrl));
207
+ this.checkIssuerContext({ issuer: String(state.authorizationServerUrl) });
208
+ }
209
+ checkIssuerContext(ctx) {
210
+ const issuer = ctx?.issuer ?? this.pendingDiscoveryState?.authorizationServerUrl;
211
+ if (issuer !== void 0) {
212
+ if (this.agent.oauth_tokens) {
213
+ (0, import_types.assertOAuthCredentialIssuer)(this.agent.oauth_tokens, issuer, !!this.agent.oauth_tokens.refresh_token);
214
+ }
215
+ if (this.agent.oauth_client) {
216
+ (0, import_types.assertOAuthCredentialIssuer)(this.agent.oauth_client, issuer, !!this.agent.oauth_client.client_secret);
217
+ }
218
+ }
219
+ return issuer;
220
+ }
221
+ ownerReauthorizationRequired(code = "owner_reauthorization_required") {
222
+ return new import_types.OAuthError(
223
+ "OAuth owner reauthorization is required; this provider will not automatically clear credentials or register a new client. CLI: adcp <alias> --clear-oauth, then adcp <alias> --oauth.",
224
+ code,
225
+ this.agent.id
226
+ );
187
227
  }
188
228
  /**
189
229
  * Save PKCE code verifier
190
230
  */
191
231
  async saveCodeVerifier(codeVerifier) {
232
+ if (!this.allowInteractiveAuthorization) throw this.ownerReauthorizationRequired();
192
233
  this.agent.oauth_code_verifier = codeVerifier;
193
234
  await this.persistAgent();
194
235
  }
@@ -198,6 +239,7 @@ class MCPOAuthProvider {
198
239
  * retrieves it here during token exchange.
199
240
  */
200
241
  async codeVerifier() {
242
+ if (!this.allowInteractiveAuthorization) throw this.ownerReauthorizationRequired();
201
243
  if (!this.agent.oauth_code_verifier) {
202
244
  throw new Error(
203
245
  "No PKCE code verifier found. The OAuth flow may have been interrupted or the agent config was modified. Please try authenticating again."
@@ -209,26 +251,40 @@ class MCPOAuthProvider {
209
251
  * Invalidate credentials when server indicates they're invalid
210
252
  */
211
253
  async invalidateCredentials(scope) {
254
+ if (!this.allowInteractiveAuthorization && (scope === "discovery" || scope === "verifier")) {
255
+ this.pendingDiscoveryState = void 0;
256
+ return;
257
+ }
258
+ if (!this.allowInteractiveAuthorization && (scope === "all" || scope === "client" || scope === "tokens")) {
259
+ throw this.ownerReauthorizationRequired();
260
+ }
261
+ await this.clearCredentials(scope);
262
+ }
263
+ async clearCredentials(scope) {
212
264
  switch (scope) {
213
265
  case "all":
214
- delete this.agent.oauth_discovery_state;
215
- delete this.agent.oauth_tokens;
216
- delete this.agent.oauth_client;
217
- delete this.agent.oauth_code_verifier;
266
+ this.pendingDiscoveryState = void 0;
267
+ this.agent.oauth_discovery_state = void 0;
268
+ this.agent.oauth_tokens = void 0;
269
+ this.agent.oauth_client = void 0;
270
+ this.agent.oauth_code_verifier = void 0;
218
271
  break;
219
272
  case "tokens":
220
- delete this.agent.oauth_tokens;
273
+ this.agent.oauth_tokens = void 0;
221
274
  break;
222
275
  case "client":
223
- delete this.agent.oauth_discovery_state;
224
- delete this.agent.oauth_client;
276
+ this.pendingDiscoveryState = void 0;
277
+ this.agent.oauth_discovery_state = void 0;
278
+ this.agent.oauth_client = void 0;
225
279
  break;
226
280
  case "discovery":
227
- delete this.agent.oauth_discovery_state;
281
+ this.pendingDiscoveryState = void 0;
282
+ this.agent.oauth_discovery_state = void 0;
228
283
  break;
229
284
  case "verifier":
230
- delete this.agent.oauth_discovery_state;
231
- delete this.agent.oauth_code_verifier;
285
+ this.pendingDiscoveryState = void 0;
286
+ this.agent.oauth_discovery_state = void 0;
287
+ this.agent.oauth_code_verifier = void 0;
232
288
  break;
233
289
  }
234
290
  await this.persistAgent();
@@ -237,11 +293,20 @@ class MCPOAuthProvider {
237
293
  // Additional methods
238
294
  // ========================================
239
295
  /**
240
- * Persist agent config to storage if configured
296
+ * Persist a credential update without modifying independent browser state.
241
297
  */
242
- async persistAgent() {
298
+ async persistCredentials() {
299
+ let savedAgent = this.agent;
300
+ if (!this.allowInteractiveAuthorization) {
301
+ savedAgent = { ...this.agent };
302
+ delete savedAgent.oauth_code_verifier;
303
+ delete savedAgent.oauth_discovery_state;
304
+ }
305
+ await this.persistAgent(savedAgent);
306
+ }
307
+ async persistAgent(agent = this.agent) {
243
308
  if (this.storage) {
244
- await this.storage.saveAgent(this.agent);
309
+ await this.storage.saveAgent(agent);
245
310
  }
246
311
  }
247
312
  /**
@@ -283,7 +348,7 @@ class MCPOAuthProvider {
283
348
  * Clear all OAuth data for this agent
284
349
  */
285
350
  async clearAuth() {
286
- await this.invalidateCredentials("all");
351
+ await this.clearCredentials("all");
287
352
  }
288
353
  /**
289
354
  * Get the agent config this provider manages