@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
@@ -10,6 +10,7 @@ import {
10
10
  toMCPClientInfo,
11
11
  fromMCPClientInfo,
12
12
  assertOAuthCredentialIssuer,
13
+ assertOAuthServerIssuer,
13
14
  OAuthError
14
15
  } from "./types.mjs";
15
16
  import { randomBytes } from "crypto";
@@ -48,6 +49,8 @@ class MCPOAuthProvider {
48
49
  _clientMetadata;
49
50
  allowHttp;
50
51
  configuredResourceOverride;
52
+ allowInteractiveAuthorization;
53
+ pendingDiscoveryState;
51
54
  constructor(config) {
52
55
  this.agent = config.agent;
53
56
  this.storage = config.storage;
@@ -55,6 +58,7 @@ class MCPOAuthProvider {
55
58
  this._clientMetadata = config.clientMetadata;
56
59
  this.allowHttp = config.allowHttp === true;
57
60
  this.configuredResourceOverride = config.resourceOverride;
61
+ this.allowInteractiveAuthorization = config.allowInteractiveAuthorization === true;
58
62
  }
59
63
  /**
60
64
  * Create a provider for CLI usage
@@ -71,7 +75,8 @@ class MCPOAuthProvider {
71
75
  storage,
72
76
  clientMetadata,
73
77
  allowHttp: options?.allowHttp,
74
- resourceOverride: options?.resourceOverride
78
+ resourceOverride: options?.resourceOverride,
79
+ allowInteractiveAuthorization: true
75
80
  });
76
81
  }
77
82
  // ========================================
@@ -112,7 +117,11 @@ class MCPOAuthProvider {
112
117
  /**
113
118
  * Load client information from agent config
114
119
  */
115
- async clientInformation() {
120
+ async clientInformation(ctx) {
121
+ const issuer = this.checkIssuerContext(ctx);
122
+ if (issuer && !this.agent.oauth_client && !this.allowInteractiveAuthorization) {
123
+ throw this.ownerReauthorizationRequired();
124
+ }
116
125
  if (this.agent.oauth_client) {
117
126
  if (this.agent.oauth_client.client_secret) assertLegacyOAuthSdk();
118
127
  assertOAuthCredentialIssuer(this.agent.oauth_client, void 0, !!this.agent.oauth_client.client_secret);
@@ -125,12 +134,13 @@ class MCPOAuthProvider {
125
134
  */
126
135
  async saveClientInformation(clientInfo) {
127
136
  this.agent.oauth_client = fromMCPClientInfo(clientInfo);
128
- await this.persistAgent();
137
+ await this.persistCredentials();
129
138
  }
130
139
  /**
131
140
  * Load existing tokens from agent config
132
141
  */
133
- async tokens() {
142
+ async tokens(ctx) {
143
+ this.checkIssuerContext(ctx);
134
144
  if (this.agent.oauth_tokens) {
135
145
  if (this.agent.oauth_tokens.refresh_token) assertLegacyOAuthSdk();
136
146
  assertOAuthCredentialIssuer(this.agent.oauth_tokens, void 0, !!this.agent.oauth_tokens.refresh_token);
@@ -144,14 +154,18 @@ class MCPOAuthProvider {
144
154
  */
145
155
  async saveTokens(tokens) {
146
156
  this.agent.oauth_tokens = fromMCPTokens(tokens);
147
- delete this.agent.oauth_code_verifier;
148
- delete this.agent.oauth_discovery_state;
149
- await this.persistAgent();
157
+ if (this.allowInteractiveAuthorization) {
158
+ this.agent.oauth_code_verifier = void 0;
159
+ this.agent.oauth_discovery_state = void 0;
160
+ }
161
+ this.pendingDiscoveryState = void 0;
162
+ await this.persistCredentials();
150
163
  }
151
164
  /**
152
165
  * Redirect user to authorization URL
153
166
  */
154
167
  async redirectToAuthorization(authorizationUrl) {
168
+ if (!this.allowInteractiveAuthorization) throw this.ownerReauthorizationRequired("interactive_required");
155
169
  try {
156
170
  await this.flowHandler.redirectToAuthorization(authorizationUrl);
157
171
  } catch (error) {
@@ -161,23 +175,51 @@ class MCPOAuthProvider {
161
175
  }
162
176
  /** Persist the authorization-server identity across the callback leg. */
163
177
  async saveDiscoveryState(state) {
164
- const issuer = String(state.authorizationServerUrl);
165
- if (this.agent.oauth_tokens?.refresh_token) {
166
- assertOAuthCredentialIssuer(this.agent.oauth_tokens, issuer, true);
167
- }
168
- if (this.agent.oauth_client?.client_secret) {
169
- assertOAuthCredentialIssuer(this.agent.oauth_client, issuer, true);
178
+ this.validateDiscoveryState(state);
179
+ if (!this.agent.oauth_client && !this.allowInteractiveAuthorization) throw this.ownerReauthorizationRequired();
180
+ this.pendingDiscoveryState = structuredClone(state);
181
+ if (this.allowInteractiveAuthorization) {
182
+ this.agent.oauth_discovery_state = structuredClone(state);
183
+ await this.persistAgent();
170
184
  }
171
- this.agent.oauth_discovery_state = state;
172
- await this.persistAgent();
173
185
  }
174
186
  async discoveryState() {
175
- return this.agent.oauth_code_verifier ? this.agent.oauth_discovery_state : void 0;
187
+ if (!this.allowInteractiveAuthorization) return void 0;
188
+ if (!this.agent.oauth_code_verifier) return void 0;
189
+ const state = this.pendingDiscoveryState ?? this.agent.oauth_discovery_state;
190
+ if (!state) return void 0;
191
+ this.validateDiscoveryState(state);
192
+ this.pendingDiscoveryState = structuredClone(state);
193
+ return structuredClone(state);
194
+ }
195
+ validateDiscoveryState(state) {
196
+ assertOAuthServerIssuer(state.authorizationServerMetadata, String(state.authorizationServerUrl));
197
+ this.checkIssuerContext({ issuer: String(state.authorizationServerUrl) });
198
+ }
199
+ checkIssuerContext(ctx) {
200
+ const issuer = ctx?.issuer ?? this.pendingDiscoveryState?.authorizationServerUrl;
201
+ if (issuer !== void 0) {
202
+ if (this.agent.oauth_tokens) {
203
+ assertOAuthCredentialIssuer(this.agent.oauth_tokens, issuer, !!this.agent.oauth_tokens.refresh_token);
204
+ }
205
+ if (this.agent.oauth_client) {
206
+ assertOAuthCredentialIssuer(this.agent.oauth_client, issuer, !!this.agent.oauth_client.client_secret);
207
+ }
208
+ }
209
+ return issuer;
210
+ }
211
+ ownerReauthorizationRequired(code = "owner_reauthorization_required") {
212
+ return new OAuthError(
213
+ "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.",
214
+ code,
215
+ this.agent.id
216
+ );
176
217
  }
177
218
  /**
178
219
  * Save PKCE code verifier
179
220
  */
180
221
  async saveCodeVerifier(codeVerifier) {
222
+ if (!this.allowInteractiveAuthorization) throw this.ownerReauthorizationRequired();
181
223
  this.agent.oauth_code_verifier = codeVerifier;
182
224
  await this.persistAgent();
183
225
  }
@@ -187,6 +229,7 @@ class MCPOAuthProvider {
187
229
  * retrieves it here during token exchange.
188
230
  */
189
231
  async codeVerifier() {
232
+ if (!this.allowInteractiveAuthorization) throw this.ownerReauthorizationRequired();
190
233
  if (!this.agent.oauth_code_verifier) {
191
234
  throw new Error(
192
235
  "No PKCE code verifier found. The OAuth flow may have been interrupted or the agent config was modified. Please try authenticating again."
@@ -198,26 +241,40 @@ class MCPOAuthProvider {
198
241
  * Invalidate credentials when server indicates they're invalid
199
242
  */
200
243
  async invalidateCredentials(scope) {
244
+ if (!this.allowInteractiveAuthorization && (scope === "discovery" || scope === "verifier")) {
245
+ this.pendingDiscoveryState = void 0;
246
+ return;
247
+ }
248
+ if (!this.allowInteractiveAuthorization && (scope === "all" || scope === "client" || scope === "tokens")) {
249
+ throw this.ownerReauthorizationRequired();
250
+ }
251
+ await this.clearCredentials(scope);
252
+ }
253
+ async clearCredentials(scope) {
201
254
  switch (scope) {
202
255
  case "all":
203
- delete this.agent.oauth_discovery_state;
204
- delete this.agent.oauth_tokens;
205
- delete this.agent.oauth_client;
206
- delete this.agent.oauth_code_verifier;
256
+ this.pendingDiscoveryState = void 0;
257
+ this.agent.oauth_discovery_state = void 0;
258
+ this.agent.oauth_tokens = void 0;
259
+ this.agent.oauth_client = void 0;
260
+ this.agent.oauth_code_verifier = void 0;
207
261
  break;
208
262
  case "tokens":
209
- delete this.agent.oauth_tokens;
263
+ this.agent.oauth_tokens = void 0;
210
264
  break;
211
265
  case "client":
212
- delete this.agent.oauth_discovery_state;
213
- delete this.agent.oauth_client;
266
+ this.pendingDiscoveryState = void 0;
267
+ this.agent.oauth_discovery_state = void 0;
268
+ this.agent.oauth_client = void 0;
214
269
  break;
215
270
  case "discovery":
216
- delete this.agent.oauth_discovery_state;
271
+ this.pendingDiscoveryState = void 0;
272
+ this.agent.oauth_discovery_state = void 0;
217
273
  break;
218
274
  case "verifier":
219
- delete this.agent.oauth_discovery_state;
220
- delete this.agent.oauth_code_verifier;
275
+ this.pendingDiscoveryState = void 0;
276
+ this.agent.oauth_discovery_state = void 0;
277
+ this.agent.oauth_code_verifier = void 0;
221
278
  break;
222
279
  }
223
280
  await this.persistAgent();
@@ -226,11 +283,20 @@ class MCPOAuthProvider {
226
283
  // Additional methods
227
284
  // ========================================
228
285
  /**
229
- * Persist agent config to storage if configured
286
+ * Persist a credential update without modifying independent browser state.
230
287
  */
231
- async persistAgent() {
288
+ async persistCredentials() {
289
+ let savedAgent = this.agent;
290
+ if (!this.allowInteractiveAuthorization) {
291
+ savedAgent = { ...this.agent };
292
+ delete savedAgent.oauth_code_verifier;
293
+ delete savedAgent.oauth_discovery_state;
294
+ }
295
+ await this.persistAgent(savedAgent);
296
+ }
297
+ async persistAgent(agent = this.agent) {
232
298
  if (this.storage) {
233
- await this.storage.saveAgent(this.agent);
299
+ await this.storage.saveAgent(agent);
234
300
  }
235
301
  }
236
302
  /**
@@ -272,7 +338,7 @@ class MCPOAuthProvider {
272
338
  * Clear all OAuth data for this agent
273
339
  */
274
340
  async clearAuth() {
275
- await this.invalidateCredentials("all");
341
+ await this.clearCredentials("all");
276
342
  }
277
343
  /**
278
344
  * Get the agent config this provider manages
@@ -21,7 +21,7 @@ export interface NonInteractiveFlowHandlerConfig {
21
21
  redirectUrl?: string | URL;
22
22
  /**
23
23
  * Optional hint shown in the error message when a browser flow is
24
- * attempted — e.g., the alias name to pass to `adcp --save-auth`.
24
+ * attempted — e.g., the saved alias for `adcp <alias> --oauth`.
25
25
  */
26
26
  agentHint?: string;
27
27
  }
@@ -21,7 +21,7 @@ export interface NonInteractiveFlowHandlerConfig {
21
21
  redirectUrl?: string | URL;
22
22
  /**
23
23
  * Optional hint shown in the error message when a browser flow is
24
- * attempted — e.g., the alias name to pass to `adcp --save-auth`.
24
+ * attempted — e.g., the saved alias for `adcp <alias> --oauth`.
25
25
  */
26
26
  agentHint?: string;
27
27
  }
@@ -33,7 +33,7 @@ class NonInteractiveFlowHandler {
33
33
  return this._redirectUrl;
34
34
  }
35
35
  async redirectToAuthorization() {
36
- const target = this.agentHint ? `adcp --save-auth ${this.agentHint} --oauth` : "adcp --save-auth <alias> <url> --oauth";
36
+ const target = this.agentHint ? `adcp ${this.agentHint} --oauth` : "adcp --save-auth <alias> <url> --oauth";
37
37
  throw new import_types.OAuthError(
38
38
  `OAuth authorization required but this context is non-interactive. Run \`${target}\` from a terminal with a browser, then retry.`,
39
39
  "interactive_required"
@@ -10,7 +10,7 @@ class NonInteractiveFlowHandler {
10
10
  return this._redirectUrl;
11
11
  }
12
12
  async redirectToAuthorization() {
13
- const target = this.agentHint ? `adcp --save-auth ${this.agentHint} --oauth` : "adcp --save-auth <alias> <url> --oauth";
13
+ const target = this.agentHint ? `adcp ${this.agentHint} --oauth` : "adcp --save-auth <alias> <url> --oauth";
14
14
  throw new OAuthError(
15
15
  `OAuth authorization required but this context is non-interactive. Run \`${target}\` from a terminal with a browser, then retry.`,
16
16
  "interactive_required"
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * OAuth client credentials configuration shape. Secret references remain
4
+ * unresolved; endpoint transport and SSRF checks run during token exchange.
5
+ */
6
+ export declare const AgentOAuthClientCredentialsSchema: z.ZodObject<{
7
+ token_endpoint: z.ZodString;
8
+ client_id: z.ZodString;
9
+ client_secret: z.ZodString;
10
+ scope: z.ZodOptional<z.ZodString>;
11
+ resource: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
12
+ audience: z.ZodOptional<z.ZodString>;
13
+ auth_method: z.ZodOptional<z.ZodEnum<{
14
+ basic: "basic";
15
+ body: "body";
16
+ }>>;
17
+ }, z.core.$strip>;
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * OAuth client credentials configuration shape. Secret references remain
4
+ * unresolved; endpoint transport and SSRF checks run during token exchange.
5
+ */
6
+ export declare const AgentOAuthClientCredentialsSchema: z.ZodObject<{
7
+ token_endpoint: z.ZodString;
8
+ client_id: z.ZodString;
9
+ client_secret: z.ZodString;
10
+ scope: z.ZodOptional<z.ZodString>;
11
+ resource: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
12
+ audience: z.ZodOptional<z.ZodString>;
13
+ auth_method: z.ZodOptional<z.ZodEnum<{
14
+ basic: "basic";
15
+ body: "body";
16
+ }>>;
17
+ }, z.core.$strip>;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var client_credentials_schema_exports = {};
20
+ __export(client_credentials_schema_exports, {
21
+ AgentOAuthClientCredentialsSchema: () => AgentOAuthClientCredentialsSchema
22
+ });
23
+ module.exports = __toCommonJS(client_credentials_schema_exports);
24
+ var import_zod = require("zod");
25
+ const AgentOAuthClientCredentialsSchema = import_zod.z.object({
26
+ token_endpoint: import_zod.z.string().url(),
27
+ client_id: import_zod.z.string().min(1),
28
+ client_secret: import_zod.z.string().min(1),
29
+ scope: import_zod.z.string().optional(),
30
+ resource: import_zod.z.union([import_zod.z.string(), import_zod.z.array(import_zod.z.string())]).optional(),
31
+ audience: import_zod.z.string().optional(),
32
+ auth_method: import_zod.z.enum(["basic", "body"]).optional()
33
+ });
34
+ // Annotate the CommonJS export names for ESM import in node:
35
+ 0 && (module.exports = {
36
+ AgentOAuthClientCredentialsSchema
37
+ });
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+ const AgentOAuthClientCredentialsSchema = z.object({
3
+ token_endpoint: z.string().url(),
4
+ client_id: z.string().min(1),
5
+ client_secret: z.string().min(1),
6
+ scope: z.string().optional(),
7
+ resource: z.union([z.string(), z.array(z.string())]).optional(),
8
+ audience: z.string().optional(),
9
+ auth_method: z.enum(["basic", "body"]).optional()
10
+ });
11
+ export {
12
+ AgentOAuthClientCredentialsSchema
13
+ };
@@ -29,9 +29,9 @@ export interface FileOAuthStorageOptions {
29
29
  * Does NOT touch fields outside the OAuth envelope (`auth_token`, custom
30
30
  * fields) when saving — the MCP provider only mutates `oauth_tokens`,
31
31
  * `oauth_client`, `oauth_resource`, `oauth_code_verifier`, and `oauth_discovery_state`.
32
- * Those fields are authoritative: an absent value deletes the stored value.
33
- * Load the complete agent before constructing a provider; partial snapshots
34
- * cannot preserve omitted OAuth fields. Other fields keep merge semantics.
32
+ * An own property explicitly set to undefined clears tokens, client, verifier
33
+ * or discovery state. Omitted properties preserve stored values for partial
34
+ * callers. Other fields keep their existing merge semantics.
35
35
  *
36
36
  * @example
37
37
  * ```ts
@@ -29,9 +29,9 @@ export interface FileOAuthStorageOptions {
29
29
  * Does NOT touch fields outside the OAuth envelope (`auth_token`, custom
30
30
  * fields) when saving — the MCP provider only mutates `oauth_tokens`,
31
31
  * `oauth_client`, `oauth_resource`, `oauth_code_verifier`, and `oauth_discovery_state`.
32
- * Those fields are authoritative: an absent value deletes the stored value.
33
- * Load the complete agent before constructing a provider; partial snapshots
34
- * cannot preserve omitted OAuth fields. Other fields keep merge semantics.
32
+ * An own property explicitly set to undefined clears tokens, client, verifier
33
+ * or discovery state. Omitted properties preserve stored values for partial
34
+ * callers. Other fields keep their existing merge semantics.
35
35
  *
36
36
  * @example
37
37
  * ```ts
@@ -94,11 +94,18 @@ function createFileOAuthStorage(options) {
94
94
  ...agent.oauth_client_credentials !== void 0 ? { oauth_client_credentials: agent.oauth_client_credentials } : {},
95
95
  ...agent.oauth_code_verifier !== void 0 ? { oauth_code_verifier: agent.oauth_code_verifier } : {}
96
96
  };
97
- if (agent.oauth_tokens === void 0) delete next.oauth_tokens;
98
- if (agent.oauth_client === void 0) delete next.oauth_client;
99
- if (agent.oauth_code_verifier === void 0) delete next.oauth_code_verifier;
100
- if (agent.oauth_discovery_state === void 0) delete next.oauth_discovery_state;
101
- else next.oauth_discovery_state = agent.oauth_discovery_state;
97
+ if (Object.prototype.hasOwnProperty.call(agent, "oauth_tokens") && agent.oauth_tokens === void 0) {
98
+ delete next.oauth_tokens;
99
+ }
100
+ if (Object.prototype.hasOwnProperty.call(agent, "oauth_client") && agent.oauth_client === void 0) {
101
+ delete next.oauth_client;
102
+ }
103
+ if (Object.prototype.hasOwnProperty.call(agent, "oauth_code_verifier") && agent.oauth_code_verifier === void 0) {
104
+ delete next.oauth_code_verifier;
105
+ }
106
+ if (Object.prototype.hasOwnProperty.call(agent, "oauth_discovery_state") && agent.oauth_discovery_state === void 0) {
107
+ delete next.oauth_discovery_state;
108
+ } else if (agent.oauth_discovery_state !== void 0) next.oauth_discovery_state = agent.oauth_discovery_state;
102
109
  if (agent.oauth_resource === void 0) delete next.oauth_resource;
103
110
  config.agents[key] = next;
104
111
  await writeConfig(config);
@@ -61,11 +61,18 @@ function createFileOAuthStorage(options) {
61
61
  ...agent.oauth_client_credentials !== void 0 ? { oauth_client_credentials: agent.oauth_client_credentials } : {},
62
62
  ...agent.oauth_code_verifier !== void 0 ? { oauth_code_verifier: agent.oauth_code_verifier } : {}
63
63
  };
64
- if (agent.oauth_tokens === void 0) delete next.oauth_tokens;
65
- if (agent.oauth_client === void 0) delete next.oauth_client;
66
- if (agent.oauth_code_verifier === void 0) delete next.oauth_code_verifier;
67
- if (agent.oauth_discovery_state === void 0) delete next.oauth_discovery_state;
68
- else next.oauth_discovery_state = agent.oauth_discovery_state;
64
+ if (Object.prototype.hasOwnProperty.call(agent, "oauth_tokens") && agent.oauth_tokens === void 0) {
65
+ delete next.oauth_tokens;
66
+ }
67
+ if (Object.prototype.hasOwnProperty.call(agent, "oauth_client") && agent.oauth_client === void 0) {
68
+ delete next.oauth_client;
69
+ }
70
+ if (Object.prototype.hasOwnProperty.call(agent, "oauth_code_verifier") && agent.oauth_code_verifier === void 0) {
71
+ delete next.oauth_code_verifier;
72
+ }
73
+ if (Object.prototype.hasOwnProperty.call(agent, "oauth_discovery_state") && agent.oauth_discovery_state === void 0) {
74
+ delete next.oauth_discovery_state;
75
+ } else if (agent.oauth_discovery_state !== void 0) next.oauth_discovery_state = agent.oauth_discovery_state;
69
76
  if (agent.oauth_resource === void 0) delete next.oauth_resource;
70
77
  config.agents[key] = next;
71
78
  await writeConfig(config);
@@ -5,7 +5,8 @@
5
5
  *
6
6
  * @example
7
7
  * ```typescript
8
- * import { MCPOAuthProvider, CLIFlowHandler } from '@adcp/sdk';
8
+ * import { MCPOAuthProvider, CLIFlowHandler, DEFAULT_CLIENT_METADATA } from '@adcp/sdk/auth';
9
+ * import type { AgentConfig } from '@adcp/sdk';
9
10
  *
10
11
  * // Agent config - tokens will be stored here
11
12
  * const agent: AgentConfig = {
@@ -13,14 +14,15 @@
13
14
  * name: 'My Agent',
14
15
  * agent_uri: 'https://agent.example.com/mcp',
15
16
  * protocol: 'mcp',
16
- * // After OAuth flow completes:
17
- * // oauth_tokens: { access_token: '...', refresh_token: '...' }
17
+ * // A fresh interactive flow saves issuer-bound tokens here.
18
18
  * };
19
19
  *
20
20
  * // Create provider with CLI flow handler
21
21
  * const provider = new MCPOAuthProvider({
22
+ * allowInteractiveAuthorization: true,
22
23
  * agent,
23
24
  * flowHandler: new CLIFlowHandler(),
25
+ * clientMetadata: DEFAULT_CLIENT_METADATA,
24
26
  * storage: myConfigStorage // Optional: persists tokens to file/db
25
27
  * });
26
28
  *
@@ -99,9 +101,10 @@ export declare function createCLIOAuthProvider(agent: AgentConfig, options?: {
99
101
  * runs, scheduled jobs, and other non-interactive contexts where you've
100
102
  * already saved tokens via `createCLIOAuthProvider`.
101
103
  *
102
- * If refresh fails (e.g., the refresh_token is revoked or expired), the
103
- * MCP SDK will throw `UnauthorizedError` at call time — the caller should
104
- * treat that as a signal to run `adcp --save-auth <alias> --oauth` and retry.
104
+ * A failed grant can throw `OAuthError` with `owner_reauthorization_required`;
105
+ * missing or mismatched issuer bindings throw `oauth_issuer_required` or `oauth_issuer_mismatch`.
106
+ * The owner can run `adcp <alias> --clear-oauth`, then
107
+ * `adcp <alias> --oauth` to start a fresh browser sign-in.
105
108
  */
106
109
  export declare function createNonInteractiveOAuthProvider(agent: AgentConfig, options?: {
107
110
  /** Hint shown in error messages if an interactive flow is attempted. */
@@ -143,5 +146,6 @@ export { createFileOAuthStorage, type FileOAuthStorageOptions } from './file-sto
143
146
  export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, } from './ClientCredentialsFlow.mjs';
144
147
  export { resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, MissingEnvSecretError, } from './secret-resolver.mjs';
145
148
  export type { AgentOAuthClientCredentials } from '../../types/adcp.mjs';
149
+ export { AgentOAuthClientCredentialsSchema } from './client-credentials-schema.mjs';
146
150
  export { bindAgentStorage, getAgentStorage, unbindAgentStorage } from './storage-registry.mjs';
147
151
  export { InvalidTokenError, InsufficientScopeError } from '@modelcontextprotocol/sdk/server/auth/errors.js';
@@ -5,7 +5,8 @@
5
5
  *
6
6
  * @example
7
7
  * ```typescript
8
- * import { MCPOAuthProvider, CLIFlowHandler } from '@adcp/sdk';
8
+ * import { MCPOAuthProvider, CLIFlowHandler, DEFAULT_CLIENT_METADATA } from '@adcp/sdk/auth';
9
+ * import type { AgentConfig } from '@adcp/sdk';
9
10
  *
10
11
  * // Agent config - tokens will be stored here
11
12
  * const agent: AgentConfig = {
@@ -13,14 +14,15 @@
13
14
  * name: 'My Agent',
14
15
  * agent_uri: 'https://agent.example.com/mcp',
15
16
  * protocol: 'mcp',
16
- * // After OAuth flow completes:
17
- * // oauth_tokens: { access_token: '...', refresh_token: '...' }
17
+ * // A fresh interactive flow saves issuer-bound tokens here.
18
18
  * };
19
19
  *
20
20
  * // Create provider with CLI flow handler
21
21
  * const provider = new MCPOAuthProvider({
22
+ * allowInteractiveAuthorization: true,
22
23
  * agent,
23
24
  * flowHandler: new CLIFlowHandler(),
25
+ * clientMetadata: DEFAULT_CLIENT_METADATA,
24
26
  * storage: myConfigStorage // Optional: persists tokens to file/db
25
27
  * });
26
28
  *
@@ -99,9 +101,10 @@ export declare function createCLIOAuthProvider(agent: AgentConfig, options?: {
99
101
  * runs, scheduled jobs, and other non-interactive contexts where you've
100
102
  * already saved tokens via `createCLIOAuthProvider`.
101
103
  *
102
- * If refresh fails (e.g., the refresh_token is revoked or expired), the
103
- * MCP SDK will throw `UnauthorizedError` at call time — the caller should
104
- * treat that as a signal to run `adcp --save-auth <alias> --oauth` and retry.
104
+ * A failed grant can throw `OAuthError` with `owner_reauthorization_required`;
105
+ * missing or mismatched issuer bindings throw `oauth_issuer_required` or `oauth_issuer_mismatch`.
106
+ * The owner can run `adcp <alias> --clear-oauth`, then
107
+ * `adcp <alias> --oauth` to start a fresh browser sign-in.
105
108
  */
106
109
  export declare function createNonInteractiveOAuthProvider(agent: AgentConfig, options?: {
107
110
  /** Hint shown in error messages if an interactive flow is attempted. */
@@ -143,5 +146,6 @@ export { createFileOAuthStorage, type FileOAuthStorageOptions } from './file-sto
143
146
  export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, } from './ClientCredentialsFlow';
144
147
  export { resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, MissingEnvSecretError, } from './secret-resolver';
145
148
  export type { AgentOAuthClientCredentials } from '../../types/adcp';
149
+ export { AgentOAuthClientCredentialsSchema } from './client-credentials-schema';
146
150
  export { bindAgentStorage, getAgentStorage, unbindAgentStorage } from './storage-registry';
147
151
  export { InvalidTokenError, InsufficientScopeError } from '@modelcontextprotocol/sdk/server/auth/errors.js';
@@ -20,6 +20,7 @@ var oauth_exports = {};
20
20
  __export(oauth_exports, {
21
21
  AUTH_DIAGNOSIS_SCHEMA_VERSION: () => import_diagnose.AUTH_DIAGNOSIS_SCHEMA_VERSION,
22
22
  AgentChangedDuringFlowError: () => import_web_flow.AgentChangedDuringFlowError,
23
+ AgentOAuthClientCredentialsSchema: () => import_client_credentials_schema.AgentOAuthClientCredentialsSchema,
23
24
  AgentVanishedDuringFlowError: () => import_web_flow.AgentVanishedDuringFlowError,
24
25
  BrowserBindingRequiredError: () => import_web_flow.BrowserBindingRequiredError,
25
26
  CLIFlowHandler: () => import_CLIFlowHandler.CLIFlowHandler,
@@ -92,6 +93,7 @@ var import_authorization_required = require('./authorization-required.js');
92
93
  var import_file_storage = require('./file-storage.js');
93
94
  var import_ClientCredentialsFlow = require('./ClientCredentialsFlow.js');
94
95
  var import_secret_resolver = require('./secret-resolver.js');
96
+ var import_client_credentials_schema = require('./client-credentials-schema.js');
95
97
  var import_storage_registry = require('./storage-registry.js');
96
98
  var import_errors = require("@modelcontextprotocol/sdk/server/auth/errors.js");
97
99
  function createCLIOAuthProvider(agent, options) {
@@ -107,6 +109,7 @@ function createCLIOAuthProvider(agent, options) {
107
109
  ...options?.clientMetadata
108
110
  };
109
111
  return new import_MCPOAuthProvider2.MCPOAuthProvider({
112
+ allowInteractiveAuthorization: true,
110
113
  agent,
111
114
  flowHandler,
112
115
  storage: options?.storage,
@@ -123,6 +126,7 @@ function createNonInteractiveOAuthProvider(agent, options) {
123
126
  ...options?.clientMetadata
124
127
  };
125
128
  return new import_MCPOAuthProvider2.MCPOAuthProvider({
129
+ allowInteractiveAuthorization: false,
126
130
  agent,
127
131
  flowHandler,
128
132
  storage: options?.storage,
@@ -153,9 +157,10 @@ function hasValidOAuthTokens(agent) {
153
157
  return true;
154
158
  }
155
159
  function clearOAuthTokens(agent) {
156
- delete agent.oauth_tokens;
157
- delete agent.oauth_client;
158
- delete agent.oauth_code_verifier;
160
+ agent.oauth_tokens = void 0;
161
+ agent.oauth_client = void 0;
162
+ agent.oauth_code_verifier = void 0;
163
+ agent.oauth_discovery_state = void 0;
159
164
  }
160
165
  function getEffectiveAuthToken(agent) {
161
166
  if (hasValidOAuthTokens(agent)) {
@@ -167,6 +172,7 @@ function getEffectiveAuthToken(agent) {
167
172
  0 && (module.exports = {
168
173
  AUTH_DIAGNOSIS_SCHEMA_VERSION,
169
174
  AgentChangedDuringFlowError,
175
+ AgentOAuthClientCredentialsSchema,
170
176
  AgentVanishedDuringFlowError,
171
177
  BrowserBindingRequiredError,
172
178
  CLIFlowHandler,
@@ -43,6 +43,7 @@ function createCLIOAuthProvider(agent, options) {
43
43
  ...options?.clientMetadata
44
44
  };
45
45
  return new MCPOAuthProvider2({
46
+ allowInteractiveAuthorization: true,
46
47
  agent,
47
48
  flowHandler,
48
49
  storage: options?.storage,
@@ -59,6 +60,7 @@ function createNonInteractiveOAuthProvider(agent, options) {
59
60
  ...options?.clientMetadata
60
61
  };
61
62
  return new MCPOAuthProvider2({
63
+ allowInteractiveAuthorization: false,
62
64
  agent,
63
65
  flowHandler,
64
66
  storage: options?.storage,
@@ -89,9 +91,10 @@ function hasValidOAuthTokens(agent) {
89
91
  return true;
90
92
  }
91
93
  function clearOAuthTokens(agent) {
92
- delete agent.oauth_tokens;
93
- delete agent.oauth_client;
94
- delete agent.oauth_code_verifier;
94
+ agent.oauth_tokens = void 0;
95
+ agent.oauth_client = void 0;
96
+ agent.oauth_code_verifier = void 0;
97
+ agent.oauth_discovery_state = void 0;
95
98
  }
96
99
  function getEffectiveAuthToken(agent) {
97
100
  if (hasValidOAuthTokens(agent)) {
@@ -132,11 +135,13 @@ import {
132
135
  extractEnvSecretName,
133
136
  MissingEnvSecretError
134
137
  } from "./secret-resolver.mjs";
138
+ import { AgentOAuthClientCredentialsSchema } from "./client-credentials-schema.mjs";
135
139
  import { bindAgentStorage, getAgentStorage, unbindAgentStorage } from "./storage-registry.mjs";
136
140
  import { InvalidTokenError, InsufficientScopeError } from "@modelcontextprotocol/sdk/server/auth/errors.js";
137
141
  export {
138
142
  AUTH_DIAGNOSIS_SCHEMA_VERSION,
139
143
  AgentChangedDuringFlowError,
144
+ AgentOAuthClientCredentialsSchema,
140
145
  AgentVanishedDuringFlowError,
141
146
  BrowserBindingRequiredError,
142
147
  CLIFlowHandler,