@adcp/sdk 14.0.0-beta.14 → 14.0.0-beta.15

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 (127) hide show
  1. package/dist/lib/auth/oauth/authorization-required.d.mts +25 -11
  2. package/dist/lib/auth/oauth/authorization-required.d.ts +25 -11
  3. package/dist/lib/auth/oauth/authorization-required.js +18 -4
  4. package/dist/lib/auth/oauth/authorization-required.mjs +17 -4
  5. package/dist/lib/auth/oauth/index.d.mts +1 -1
  6. package/dist/lib/auth/oauth/index.d.ts +1 -1
  7. package/dist/lib/auth/oauth/index.js +2 -0
  8. package/dist/lib/auth/oauth/index.mjs +2 -0
  9. package/dist/lib/auth/oauth/resource-url.d.mts +8 -0
  10. package/dist/lib/auth/oauth/resource-url.d.ts +8 -0
  11. package/dist/lib/auth/oauth/resource-url.js +42 -0
  12. package/dist/lib/auth/oauth/resource-url.mjs +40 -0
  13. package/dist/lib/core/ConversationTypes.d.mts +10 -0
  14. package/dist/lib/core/ConversationTypes.d.ts +10 -0
  15. package/dist/lib/core/SingleAgentClient.d.mts +5 -2
  16. package/dist/lib/core/SingleAgentClient.d.ts +5 -2
  17. package/dist/lib/core/SingleAgentClient.js +133 -28
  18. package/dist/lib/core/SingleAgentClient.mjs +138 -29
  19. package/dist/lib/core/TaskExecutor.d.mts +1 -0
  20. package/dist/lib/core/TaskExecutor.d.ts +1 -0
  21. package/dist/lib/core/TaskExecutor.js +7 -1
  22. package/dist/lib/core/TaskExecutor.mjs +7 -1
  23. package/dist/lib/core/webhook-registration.d.mts +8 -1
  24. package/dist/lib/core/webhook-registration.d.ts +8 -1
  25. package/dist/lib/core/webhook-registration.js +65 -5
  26. package/dist/lib/core/webhook-registration.mjs +61 -4
  27. package/dist/lib/errors/index.d.mts +9 -0
  28. package/dist/lib/errors/index.d.ts +9 -0
  29. package/dist/lib/errors/index.js +33 -0
  30. package/dist/lib/errors/index.mjs +32 -0
  31. package/dist/lib/index.d.mts +3 -2
  32. package/dist/lib/index.d.ts +3 -2
  33. package/dist/lib/index.js +4 -0
  34. package/dist/lib/index.mjs +4 -0
  35. package/dist/lib/media-buy/compatibility.js +14 -2
  36. package/dist/lib/media-buy/compatibility.mjs +14 -2
  37. package/dist/lib/protocols/index.js +23 -7
  38. package/dist/lib/protocols/index.mjs +24 -8
  39. package/dist/lib/protocols/mcp.js +8 -6
  40. package/dist/lib/protocols/mcp.mjs +9 -7
  41. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  42. package/dist/lib/server/decisioning/async-outcome.d.mts +11 -0
  43. package/dist/lib/server/decisioning/async-outcome.d.ts +11 -0
  44. package/dist/lib/server/decisioning/context.d.mts +11 -1
  45. package/dist/lib/server/decisioning/context.d.ts +11 -1
  46. package/dist/lib/server/decisioning/index.d.mts +3 -2
  47. package/dist/lib/server/decisioning/index.d.ts +3 -2
  48. package/dist/lib/server/decisioning/index.js +9 -0
  49. package/dist/lib/server/decisioning/index.mjs +10 -0
  50. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -2
  51. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -2
  52. package/dist/lib/server/decisioning/runtime/from-platform.js +40 -8
  53. package/dist/lib/server/decisioning/runtime/from-platform.mjs +40 -8
  54. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.mts +8 -1
  55. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts +8 -1
  56. package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +10 -1
  57. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +9 -1
  58. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.mts +79 -0
  59. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.ts +79 -0
  60. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.js +391 -0
  61. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.mjs +369 -0
  62. package/dist/lib/server/decisioning/runtime/task-registry.d.mts +2 -0
  63. package/dist/lib/server/decisioning/runtime/task-registry.d.ts +2 -0
  64. package/dist/lib/server/decisioning/runtime/task-registry.js +2 -1
  65. package/dist/lib/server/decisioning/runtime/task-registry.mjs +2 -1
  66. package/dist/lib/server/decisioning/runtime/to-context.js +15 -11
  67. package/dist/lib/server/decisioning/runtime/to-context.mjs +15 -11
  68. package/dist/lib/server/index.d.mts +2 -2
  69. package/dist/lib/server/index.d.ts +2 -2
  70. package/dist/lib/server/index.js +4 -0
  71. package/dist/lib/server/index.mjs +4 -0
  72. package/dist/lib/server/webhook-delivery/index.d.mts +2 -2
  73. package/dist/lib/server/webhook-delivery/index.d.ts +2 -2
  74. package/dist/lib/server/webhook-delivery/index.js +4 -0
  75. package/dist/lib/server/webhook-delivery/index.mjs +5 -1
  76. package/dist/lib/server/webhook-delivery/pg.d.mts +3 -1
  77. package/dist/lib/server/webhook-delivery/pg.d.ts +3 -1
  78. package/dist/lib/server/webhook-delivery/pg.js +25 -2
  79. package/dist/lib/server/webhook-delivery/pg.mjs +25 -2
  80. package/dist/lib/server/webhook-delivery/recovery.d.mts +44 -0
  81. package/dist/lib/server/webhook-delivery/recovery.d.ts +44 -0
  82. package/dist/lib/server/webhook-delivery/recovery.js +146 -43
  83. package/dist/lib/server/webhook-delivery/recovery.mjs +144 -43
  84. package/dist/lib/signing/agent-resolver/index.d.mts +1 -1
  85. package/dist/lib/signing/agent-resolver/index.d.ts +1 -1
  86. package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +9 -0
  87. package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +9 -0
  88. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +4 -1
  89. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +4 -1
  90. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +17 -4
  91. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +17 -4
  92. package/dist/lib/signing/jwks.d.mts +7 -0
  93. package/dist/lib/signing/jwks.d.ts +7 -0
  94. package/dist/lib/signing/server.d.mts +2 -2
  95. package/dist/lib/signing/server.d.ts +2 -2
  96. package/dist/lib/signing/webhook-verifier.d.mts +6 -0
  97. package/dist/lib/signing/webhook-verifier.d.ts +6 -0
  98. package/dist/lib/signing/webhook-verifier.js +38 -4
  99. package/dist/lib/signing/webhook-verifier.mjs +38 -4
  100. package/dist/lib/testing/client.d.mts +1 -0
  101. package/dist/lib/testing/client.d.ts +1 -0
  102. package/dist/lib/testing/client.js +6 -2
  103. package/dist/lib/testing/client.mjs +6 -2
  104. package/dist/lib/testing/compliance/comply.d.mts +2 -2
  105. package/dist/lib/testing/compliance/comply.d.ts +2 -2
  106. package/dist/lib/testing/compliance/comply.js +41 -31
  107. package/dist/lib/testing/compliance/comply.mjs +44 -21
  108. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.mts +1 -7
  109. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.ts +1 -7
  110. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.js +6 -42
  111. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.mjs +10 -40
  112. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  113. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  114. package/dist/lib/utils/adcp-version-config.d.mts +2 -0
  115. package/dist/lib/utils/adcp-version-config.d.ts +2 -0
  116. package/dist/lib/utils/adcp-version-config.js +5 -0
  117. package/dist/lib/utils/adcp-version-config.mjs +4 -0
  118. package/dist/lib/version.d.mts +3 -3
  119. package/dist/lib/version.d.ts +3 -3
  120. package/dist/lib/version.js +3 -3
  121. package/dist/lib/version.mjs +3 -3
  122. package/docs/llms.txt +3 -1
  123. package/docs/migration-12-to-14.md +6 -5
  124. package/docs/migration-13-to-14.md +48 -7
  125. package/docs/migration-task-registry-scoping.md +164 -11
  126. package/package.json +1 -1
  127. package/skills/build-decisioning-platform/advanced/REFERENCE.md +1 -1
@@ -1,9 +1,10 @@
1
1
  import { AuthenticationRequiredError } from '../../errors/index.mjs';
2
2
  import { type WWWAuthenticateChallenge } from './diagnostics.mjs';
3
3
  /**
4
- * Structured description of what an agent's authorization server requires
5
- * before it will accept a `tools/call`. Produced by
6
- * {@link discoverAuthorizationRequirements}.
4
+ * Structured result from a Bearer challenge and its available discovery
5
+ * metadata. Records may be partial; use
6
+ * {@link hasValidatedMcpAuthorizationRequirements} before treating one as
7
+ * proof that an MCP endpoint requires OAuth.
7
8
  */
8
9
  export interface AuthorizationRequirements {
9
10
  /** The agent URL we probed. */
@@ -62,12 +63,12 @@ export interface AuthorizationRequirements {
62
63
  * `instanceof NeedsAuthorizationError` for type-narrowing and use `subCode`
63
64
  * only for structured-log keying.
64
65
  *
65
- * Note on `hasOAuth`:
66
+ * Note on validation and `hasOAuth`:
66
67
  * The inherited getter returns `true` only when both `authorization_endpoint`
67
68
  * and `token_endpoint` were walked successfully. A partially-walked
68
- * requirements record (PRM reachable but AS metadata missing) still yields
69
- * `hasOAuth === false` even though `requirements.authorizationServer` is set.
70
- * Treat it as "we have enough to start a flow," not "server wants OAuth."
69
+ * requirements record still yields `hasOAuth === false`. Callers should
70
+ * construct this error only after
71
+ * {@link hasValidatedMcpAuthorizationRequirements} succeeds.
71
72
  */
72
73
  export declare class NeedsAuthorizationError extends AuthenticationRequiredError {
73
74
  /** Narrow discriminator for consumers that already know about this class. */
@@ -95,14 +96,17 @@ export interface DiscoverAuthorizationOptions {
95
96
  wwwAuthenticate?: string;
96
97
  }
97
98
  /**
98
- * Walk the OAuth discovery chain starting from an agent URL. Returns
99
- * `AuthorizationRequirements` when the agent demands OAuth, or `null` when a
100
- * `tools/list` call succeeds without credentials.
99
+ * Walk the OAuth discovery chain starting from an agent URL. Returns an
100
+ * `AuthorizationRequirements` diagnostic record for a Bearer challenge (even
101
+ * when later metadata is absent), or `null` when the probe is not a Bearer
102
+ * 401. Use {@link hasValidatedMcpAuthorizationRequirements} before promoting
103
+ * the record to an interactive OAuth requirement.
101
104
  *
102
105
  * Strategy:
103
106
  * 1. POST `tools/list` to the agent with no `Authorization` header.
104
107
  * 2. If 401 + `WWW-Authenticate: Bearer`: parse the challenge.
105
- * 3. If the challenge carries `resource_metadata=…`: GET it and read
108
+ * 3. Resolve `resource_metadata=…`, or the RFC 9728 well-known fallback,
109
+ * then GET it and read
106
110
  * `resource` + `authorization_servers`.
107
111
  * 4. For the first `authorization_servers[0]`: GET `/.well-known/oauth-authorization-server`
108
112
  * and read `authorization_endpoint`, `token_endpoint`, `registration_endpoint`,
@@ -113,6 +117,16 @@ export interface DiscoverAuthorizationOptions {
113
117
  * callers can still present a partial picture without re-probing.
114
118
  */
115
119
  export declare function discoverAuthorizationRequirements(agentUrl: string, options?: DiscoverAuthorizationOptions): Promise<AuthorizationRequirements | null>;
120
+ /**
121
+ * Whether a discovery record proves the MCP endpoint is OAuth protected.
122
+ *
123
+ * `discoverAuthorizationRequirements` intentionally returns partial records
124
+ * for diagnostics. Those records are not sufficient evidence for an
125
+ * interactive OAuth prompt: the MCP authorization profile requires protected
126
+ * resource metadata whose `resource` exactly identifies the endpoint and
127
+ * which names at least one authorization server.
128
+ */
129
+ export declare function hasValidatedMcpAuthorizationRequirements(requirements: AuthorizationRequirements, agentUrl: string): boolean;
116
130
  /**
117
131
  * Probe the agent for the parsed `WWW-Authenticate` challenge on a 401.
118
132
  *
@@ -1,9 +1,10 @@
1
1
  import { AuthenticationRequiredError } from '../../errors';
2
2
  import { type WWWAuthenticateChallenge } from './diagnostics';
3
3
  /**
4
- * Structured description of what an agent's authorization server requires
5
- * before it will accept a `tools/call`. Produced by
6
- * {@link discoverAuthorizationRequirements}.
4
+ * Structured result from a Bearer challenge and its available discovery
5
+ * metadata. Records may be partial; use
6
+ * {@link hasValidatedMcpAuthorizationRequirements} before treating one as
7
+ * proof that an MCP endpoint requires OAuth.
7
8
  */
8
9
  export interface AuthorizationRequirements {
9
10
  /** The agent URL we probed. */
@@ -62,12 +63,12 @@ export interface AuthorizationRequirements {
62
63
  * `instanceof NeedsAuthorizationError` for type-narrowing and use `subCode`
63
64
  * only for structured-log keying.
64
65
  *
65
- * Note on `hasOAuth`:
66
+ * Note on validation and `hasOAuth`:
66
67
  * The inherited getter returns `true` only when both `authorization_endpoint`
67
68
  * and `token_endpoint` were walked successfully. A partially-walked
68
- * requirements record (PRM reachable but AS metadata missing) still yields
69
- * `hasOAuth === false` even though `requirements.authorizationServer` is set.
70
- * Treat it as "we have enough to start a flow," not "server wants OAuth."
69
+ * requirements record still yields `hasOAuth === false`. Callers should
70
+ * construct this error only after
71
+ * {@link hasValidatedMcpAuthorizationRequirements} succeeds.
71
72
  */
72
73
  export declare class NeedsAuthorizationError extends AuthenticationRequiredError {
73
74
  /** Narrow discriminator for consumers that already know about this class. */
@@ -95,14 +96,17 @@ export interface DiscoverAuthorizationOptions {
95
96
  wwwAuthenticate?: string;
96
97
  }
97
98
  /**
98
- * Walk the OAuth discovery chain starting from an agent URL. Returns
99
- * `AuthorizationRequirements` when the agent demands OAuth, or `null` when a
100
- * `tools/list` call succeeds without credentials.
99
+ * Walk the OAuth discovery chain starting from an agent URL. Returns an
100
+ * `AuthorizationRequirements` diagnostic record for a Bearer challenge (even
101
+ * when later metadata is absent), or `null` when the probe is not a Bearer
102
+ * 401. Use {@link hasValidatedMcpAuthorizationRequirements} before promoting
103
+ * the record to an interactive OAuth requirement.
101
104
  *
102
105
  * Strategy:
103
106
  * 1. POST `tools/list` to the agent with no `Authorization` header.
104
107
  * 2. If 401 + `WWW-Authenticate: Bearer`: parse the challenge.
105
- * 3. If the challenge carries `resource_metadata=…`: GET it and read
108
+ * 3. Resolve `resource_metadata=…`, or the RFC 9728 well-known fallback,
109
+ * then GET it and read
106
110
  * `resource` + `authorization_servers`.
107
111
  * 4. For the first `authorization_servers[0]`: GET `/.well-known/oauth-authorization-server`
108
112
  * and read `authorization_endpoint`, `token_endpoint`, `registration_endpoint`,
@@ -113,6 +117,16 @@ export interface DiscoverAuthorizationOptions {
113
117
  * callers can still present a partial picture without re-probing.
114
118
  */
115
119
  export declare function discoverAuthorizationRequirements(agentUrl: string, options?: DiscoverAuthorizationOptions): Promise<AuthorizationRequirements | null>;
120
+ /**
121
+ * Whether a discovery record proves the MCP endpoint is OAuth protected.
122
+ *
123
+ * `discoverAuthorizationRequirements` intentionally returns partial records
124
+ * for diagnostics. Those records are not sufficient evidence for an
125
+ * interactive OAuth prompt: the MCP authorization profile requires protected
126
+ * resource metadata whose `resource` exactly identifies the endpoint and
127
+ * which names at least one authorization server.
128
+ */
129
+ export declare function hasValidatedMcpAuthorizationRequirements(requirements: AuthorizationRequirements, agentUrl: string): boolean;
116
130
  /**
117
131
  * Probe the agent for the parsed `WWW-Authenticate` challenge on a 401.
118
132
  *
@@ -20,6 +20,7 @@ var authorization_required_exports = {};
20
20
  __export(authorization_required_exports, {
21
21
  NeedsAuthorizationError: () => NeedsAuthorizationError,
22
22
  discoverAuthorizationRequirements: () => discoverAuthorizationRequirements,
23
+ hasValidatedMcpAuthorizationRequirements: () => hasValidatedMcpAuthorizationRequirements,
23
24
  probeAuthChallenge: () => probeAuthChallenge
24
25
  });
25
26
  module.exports = __toCommonJS(authorization_required_exports);
@@ -27,6 +28,7 @@ var import_net = require('../../net/index.js');
27
28
  var import_errors = require('../../errors/index.js');
28
29
  var import_abort = require('../../protocols/abort.js');
29
30
  var import_diagnostics = require('./diagnostics.js');
31
+ var import_resource_url = require('./resource-url.js');
30
32
  const MAX_DISPLAY_STRING = 256;
31
33
  const MAX_SCOPES = 64;
32
34
  const MAX_CHALLENGE_PARAMS = 32;
@@ -106,14 +108,22 @@ async function discoverAuthorizationRequirements(agentUrl, options = {}) {
106
108
  }
107
109
  const requirements = {
108
110
  agentUrl,
109
- resourceMetadataUrl: challenge.resource_metadata ? sanitizeDisplay(challenge.resource_metadata) : void 0,
110
111
  challengeScope: challenge.scope ? sanitizeDisplay(challenge.scope) : void 0,
111
112
  challenge: sanitizeChallenge(challenge)
112
113
  };
113
- if (challenge.resource_metadata && isSafeHttpUrl(challenge.resource_metadata)) {
114
+ let resourceMetadataUrl = challenge.resource_metadata;
115
+ if (!resourceMetadataUrl) {
116
+ try {
117
+ resourceMetadataUrl = (0, import_resource_url.buildProtectedResourceMetadataUrl)(agentUrl);
118
+ } catch {
119
+ resourceMetadataUrl = void 0;
120
+ }
121
+ }
122
+ if (resourceMetadataUrl) requirements.resourceMetadataUrl = sanitizeDisplay(resourceMetadataUrl);
123
+ if (resourceMetadataUrl && isSafeHttpUrl(resourceMetadataUrl)) {
114
124
  const prm = await fetchJson(
115
- challenge.resource_metadata,
116
- allowPrivateIpForHop(challenge.resource_metadata),
125
+ resourceMetadataUrl,
126
+ allowPrivateIpForHop(resourceMetadataUrl),
117
127
  options.timeoutMs,
118
128
  options.fetchFn,
119
129
  options.signal
@@ -187,6 +197,9 @@ async function discoverAuthorizationRequirements(agentUrl, options = {}) {
187
197
  }
188
198
  return requirements;
189
199
  }
200
+ function hasValidatedMcpAuthorizationRequirements(requirements, agentUrl) {
201
+ return (0, import_resource_url.normalizeOAuthResourceForComparison)(requirements.resource ?? "") === (0, import_resource_url.normalizeOAuthResourceForComparison)(agentUrl) && Array.isArray(requirements.authorizationServers) && requirements.authorizationServers.length > 0;
202
+ }
190
203
  async function probeAuthChallenge(agentUrl, options = {}) {
191
204
  const probe = await probeAgent401(
192
205
  agentUrl,
@@ -267,5 +280,6 @@ async function fetchJson(url, allowPrivateIp, timeoutMs, fetchFn, signal) {
267
280
  0 && (module.exports = {
268
281
  NeedsAuthorizationError,
269
282
  discoverAuthorizationRequirements,
283
+ hasValidatedMcpAuthorizationRequirements,
270
284
  probeAuthChallenge
271
285
  });
@@ -2,6 +2,7 @@ import { ssrfSafeFetch, decodeBodyAsJsonOrText } from "../../net/index.mjs";
2
2
  import { AuthenticationRequiredError } from "../../errors/index.mjs";
3
3
  import { throwIfAborted } from "../../protocols/abort.mjs";
4
4
  import { parseWWWAuthenticate } from "./diagnostics.mjs";
5
+ import { buildProtectedResourceMetadataUrl, normalizeOAuthResourceForComparison } from "./resource-url.mjs";
5
6
  const MAX_DISPLAY_STRING = 256;
6
7
  const MAX_SCOPES = 64;
7
8
  const MAX_CHALLENGE_PARAMS = 32;
@@ -81,14 +82,22 @@ async function discoverAuthorizationRequirements(agentUrl, options = {}) {
81
82
  }
82
83
  const requirements = {
83
84
  agentUrl,
84
- resourceMetadataUrl: challenge.resource_metadata ? sanitizeDisplay(challenge.resource_metadata) : void 0,
85
85
  challengeScope: challenge.scope ? sanitizeDisplay(challenge.scope) : void 0,
86
86
  challenge: sanitizeChallenge(challenge)
87
87
  };
88
- if (challenge.resource_metadata && isSafeHttpUrl(challenge.resource_metadata)) {
88
+ let resourceMetadataUrl = challenge.resource_metadata;
89
+ if (!resourceMetadataUrl) {
90
+ try {
91
+ resourceMetadataUrl = buildProtectedResourceMetadataUrl(agentUrl);
92
+ } catch {
93
+ resourceMetadataUrl = void 0;
94
+ }
95
+ }
96
+ if (resourceMetadataUrl) requirements.resourceMetadataUrl = sanitizeDisplay(resourceMetadataUrl);
97
+ if (resourceMetadataUrl && isSafeHttpUrl(resourceMetadataUrl)) {
89
98
  const prm = await fetchJson(
90
- challenge.resource_metadata,
91
- allowPrivateIpForHop(challenge.resource_metadata),
99
+ resourceMetadataUrl,
100
+ allowPrivateIpForHop(resourceMetadataUrl),
92
101
  options.timeoutMs,
93
102
  options.fetchFn,
94
103
  options.signal
@@ -162,6 +171,9 @@ async function discoverAuthorizationRequirements(agentUrl, options = {}) {
162
171
  }
163
172
  return requirements;
164
173
  }
174
+ function hasValidatedMcpAuthorizationRequirements(requirements, agentUrl) {
175
+ return normalizeOAuthResourceForComparison(requirements.resource ?? "") === normalizeOAuthResourceForComparison(agentUrl) && Array.isArray(requirements.authorizationServers) && requirements.authorizationServers.length > 0;
176
+ }
165
177
  async function probeAuthChallenge(agentUrl, options = {}) {
166
178
  const probe = await probeAgent401(
167
179
  agentUrl,
@@ -241,5 +253,6 @@ async function fetchJson(url, allowPrivateIp, timeoutMs, fetchFn, signal) {
241
253
  export {
242
254
  NeedsAuthorizationError,
243
255
  discoverAuthorizationRequirements,
256
+ hasValidatedMcpAuthorizationRequirements,
244
257
  probeAuthChallenge
245
258
  };
@@ -138,7 +138,7 @@ export declare function getEffectiveAuthToken(agent: AgentConfig): string | unde
138
138
  export { discoverOAuthMetadata, supportsOAuth, supportsDynamicRegistration, type OAuthMetadata, type DiscoveryOptions, } from './discovery.mjs';
139
139
  export { parseWWWAuthenticate, decodeAccessTokenClaims, validateTokenAudience, type WWWAuthenticateChallenge, type DecodedJWTHeader, type DecodedJWTClaims, type DecodedAccessToken, type TokenAudienceResult, } from './diagnostics.mjs';
140
140
  export { runAuthDiagnosis, AUTH_DIAGNOSIS_SCHEMA_VERSION, type DiagnoseOptions, type HttpCapture, type DiagnosisStep, type Hypothesis, type HypothesisVerdict, type AuthDiagnosisReport, } from './diagnose.mjs';
141
- export { NeedsAuthorizationError, discoverAuthorizationRequirements, probeAuthChallenge, type AuthorizationRequirements, type DiscoverAuthorizationOptions, } from './authorization-required.mjs';
141
+ export { NeedsAuthorizationError, discoverAuthorizationRequirements, hasValidatedMcpAuthorizationRequirements, probeAuthChallenge, type AuthorizationRequirements, type DiscoverAuthorizationOptions, } from './authorization-required.mjs';
142
142
  export { createFileOAuthStorage, type FileOAuthStorageOptions } from './file-storage.mjs';
143
143
  export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, } from './ClientCredentialsFlow.mjs';
144
144
  export { resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, MissingEnvSecretError, } from './secret-resolver.mjs';
@@ -138,7 +138,7 @@ export declare function getEffectiveAuthToken(agent: AgentConfig): string | unde
138
138
  export { discoverOAuthMetadata, supportsOAuth, supportsDynamicRegistration, type OAuthMetadata, type DiscoveryOptions, } from './discovery';
139
139
  export { parseWWWAuthenticate, decodeAccessTokenClaims, validateTokenAudience, type WWWAuthenticateChallenge, type DecodedJWTHeader, type DecodedJWTClaims, type DecodedAccessToken, type TokenAudienceResult, } from './diagnostics';
140
140
  export { runAuthDiagnosis, AUTH_DIAGNOSIS_SCHEMA_VERSION, type DiagnoseOptions, type HttpCapture, type DiagnosisStep, type Hypothesis, type HypothesisVerdict, type AuthDiagnosisReport, } from './diagnose';
141
- export { NeedsAuthorizationError, discoverAuthorizationRequirements, probeAuthChallenge, type AuthorizationRequirements, type DiscoverAuthorizationOptions, } from './authorization-required';
141
+ export { NeedsAuthorizationError, discoverAuthorizationRequirements, hasValidatedMcpAuthorizationRequirements, probeAuthChallenge, type AuthorizationRequirements, type DiscoverAuthorizationOptions, } from './authorization-required';
142
142
  export { createFileOAuthStorage, type FileOAuthStorageOptions } from './file-storage';
143
143
  export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, } from './ClientCredentialsFlow';
144
144
  export { resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, MissingEnvSecretError, } from './secret-resolver';
@@ -58,6 +58,7 @@ __export(oauth_exports, {
58
58
  getAgentStorage: () => import_storage_registry.getAgentStorage,
59
59
  getEffectiveAuthToken: () => getEffectiveAuthToken,
60
60
  hasValidOAuthTokens: () => hasValidOAuthTokens,
61
+ hasValidatedMcpAuthorizationRequirements: () => import_authorization_required.hasValidatedMcpAuthorizationRequirements,
61
62
  isEnvSecretReference: () => import_secret_resolver.isEnvSecretReference,
62
63
  isOAuthRequired: () => isOAuthRequired,
63
64
  parseWWWAuthenticate: () => import_diagnostics.parseWWWAuthenticate,
@@ -204,6 +205,7 @@ function getEffectiveAuthToken(agent) {
204
205
  getAgentStorage,
205
206
  getEffectiveAuthToken,
206
207
  hasValidOAuthTokens,
208
+ hasValidatedMcpAuthorizationRequirements,
207
209
  isEnvSecretReference,
208
210
  isOAuthRequired,
209
211
  parseWWWAuthenticate,
@@ -116,6 +116,7 @@ import {
116
116
  import {
117
117
  NeedsAuthorizationError,
118
118
  discoverAuthorizationRequirements,
119
+ hasValidatedMcpAuthorizationRequirements,
119
120
  probeAuthChallenge
120
121
  } from "./authorization-required.mjs";
121
122
  import { createFileOAuthStorage } from "./file-storage.mjs";
@@ -174,6 +175,7 @@ export {
174
175
  getAgentStorage,
175
176
  getEffectiveAuthToken,
176
177
  hasValidOAuthTokens,
178
+ hasValidatedMcpAuthorizationRequirements,
177
179
  isEnvSecretReference,
178
180
  isOAuthRequired,
179
181
  parseWWWAuthenticate,
@@ -1,3 +1,11 @@
1
+ /**
2
+ * RFC 9728 resource comparison semantics used by OAuth discovery and
3
+ * compliance grading. Scheme and host are case-insensitive and default ports
4
+ * are equivalent; the remainder stays byte-for-byte significant.
5
+ */
6
+ export declare function normalizeOAuthResourceForComparison(value: string): string;
7
+ /** Build the RFC 9728 well-known metadata URL for a protected resource. */
8
+ export declare function buildProtectedResourceMetadataUrl(agentUrl: string): string;
1
9
  /** Validate and canonicalize an operator-configured RFC 8707 resource URI. */
2
10
  export declare function validateOAuthResourceUrl(value: string, options?: {
3
11
  allowHttp?: boolean;
@@ -1,3 +1,11 @@
1
+ /**
2
+ * RFC 9728 resource comparison semantics used by OAuth discovery and
3
+ * compliance grading. Scheme and host are case-insensitive and default ports
4
+ * are equivalent; the remainder stays byte-for-byte significant.
5
+ */
6
+ export declare function normalizeOAuthResourceForComparison(value: string): string;
7
+ /** Build the RFC 9728 well-known metadata URL for a protected resource. */
8
+ export declare function buildProtectedResourceMetadataUrl(agentUrl: string): string;
1
9
  /** Validate and canonicalize an operator-configured RFC 8707 resource URI. */
2
10
  export declare function validateOAuthResourceUrl(value: string, options?: {
3
11
  allowHttp?: boolean;
@@ -18,11 +18,51 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var resource_url_exports = {};
20
20
  __export(resource_url_exports, {
21
+ buildProtectedResourceMetadataUrl: () => buildProtectedResourceMetadataUrl,
22
+ normalizeOAuthResourceForComparison: () => normalizeOAuthResourceForComparison,
21
23
  validateOAuthResourceUrl: () => validateOAuthResourceUrl
22
24
  });
23
25
  module.exports = __toCommonJS(resource_url_exports);
24
26
  var import_types = require('./types.js');
25
27
  const MAX_RESOURCE_URL_LENGTH = 2048;
28
+ function normalizeOAuthResourceForComparison(value) {
29
+ const match = /^([A-Za-z][A-Za-z\d+.-]*):\/\/([^/?#]*)([\s\S]*)$/.exec(value);
30
+ if (!match) return value;
31
+ const scheme = match[1].toLowerCase();
32
+ const authority = match[2];
33
+ const remainder = match[3];
34
+ const at = authority.lastIndexOf("@");
35
+ const userinfo = at >= 0 ? authority.slice(0, at + 1) : "";
36
+ const hostAndPort = at >= 0 ? authority.slice(at + 1) : authority;
37
+ let host;
38
+ let port = "";
39
+ if (hostAndPort.startsWith("[")) {
40
+ const bracket = hostAndPort.indexOf("]");
41
+ if (bracket < 0) return value;
42
+ host = hostAndPort.slice(0, bracket + 1).toLowerCase();
43
+ const suffix = hostAndPort.slice(bracket + 1);
44
+ if (suffix && !/^:\d+$/.test(suffix)) return value;
45
+ port = suffix.slice(1);
46
+ } else {
47
+ const colon = hostAndPort.lastIndexOf(":");
48
+ if (colon >= 0) {
49
+ const suffix = hostAndPort.slice(colon + 1);
50
+ if (!/^\d+$/.test(suffix)) return value;
51
+ host = hostAndPort.slice(0, colon).toLowerCase();
52
+ port = suffix;
53
+ } else {
54
+ host = hostAndPort.toLowerCase();
55
+ }
56
+ }
57
+ if (!host) return value;
58
+ const defaultPort = scheme === "https" ? "443" : scheme === "http" ? "80" : void 0;
59
+ const renderedPort = port && port !== defaultPort ? `:${port}` : "";
60
+ return `${scheme}://${userinfo}${host}${renderedPort}${remainder}`;
61
+ }
62
+ function buildProtectedResourceMetadataUrl(agentUrl) {
63
+ const url = new URL(agentUrl);
64
+ return `${url.origin}/.well-known/oauth-protected-resource${url.pathname}`;
65
+ }
26
66
  function validateOAuthResourceUrl(value, options = {}) {
27
67
  if (value.length === 0 || value.length > MAX_RESOURCE_URL_LENGTH) {
28
68
  throw new import_types.OAuthError("OAuth resource override must be between 1 and 2048 characters", "invalid_resource_override");
@@ -46,5 +86,7 @@ function validateOAuthResourceUrl(value, options = {}) {
46
86
  }
47
87
  // Annotate the CommonJS export names for ESM import in node:
48
88
  0 && (module.exports = {
89
+ buildProtectedResourceMetadataUrl,
90
+ normalizeOAuthResourceForComparison,
49
91
  validateOAuthResourceUrl
50
92
  });
@@ -1,5 +1,43 @@
1
1
  import { OAuthError } from "./types.mjs";
2
2
  const MAX_RESOURCE_URL_LENGTH = 2048;
3
+ function normalizeOAuthResourceForComparison(value) {
4
+ const match = /^([A-Za-z][A-Za-z\d+.-]*):\/\/([^/?#]*)([\s\S]*)$/.exec(value);
5
+ if (!match) return value;
6
+ const scheme = match[1].toLowerCase();
7
+ const authority = match[2];
8
+ const remainder = match[3];
9
+ const at = authority.lastIndexOf("@");
10
+ const userinfo = at >= 0 ? authority.slice(0, at + 1) : "";
11
+ const hostAndPort = at >= 0 ? authority.slice(at + 1) : authority;
12
+ let host;
13
+ let port = "";
14
+ if (hostAndPort.startsWith("[")) {
15
+ const bracket = hostAndPort.indexOf("]");
16
+ if (bracket < 0) return value;
17
+ host = hostAndPort.slice(0, bracket + 1).toLowerCase();
18
+ const suffix = hostAndPort.slice(bracket + 1);
19
+ if (suffix && !/^:\d+$/.test(suffix)) return value;
20
+ port = suffix.slice(1);
21
+ } else {
22
+ const colon = hostAndPort.lastIndexOf(":");
23
+ if (colon >= 0) {
24
+ const suffix = hostAndPort.slice(colon + 1);
25
+ if (!/^\d+$/.test(suffix)) return value;
26
+ host = hostAndPort.slice(0, colon).toLowerCase();
27
+ port = suffix;
28
+ } else {
29
+ host = hostAndPort.toLowerCase();
30
+ }
31
+ }
32
+ if (!host) return value;
33
+ const defaultPort = scheme === "https" ? "443" : scheme === "http" ? "80" : void 0;
34
+ const renderedPort = port && port !== defaultPort ? `:${port}` : "";
35
+ return `${scheme}://${userinfo}${host}${renderedPort}${remainder}`;
36
+ }
37
+ function buildProtectedResourceMetadataUrl(agentUrl) {
38
+ const url = new URL(agentUrl);
39
+ return `${url.origin}/.well-known/oauth-protected-resource${url.pathname}`;
40
+ }
3
41
  function validateOAuthResourceUrl(value, options = {}) {
4
42
  if (value.length === 0 || value.length > MAX_RESOURCE_URL_LENGTH) {
5
43
  throw new OAuthError("OAuth resource override must be between 1 and 2048 characters", "invalid_resource_override");
@@ -22,5 +60,7 @@ function validateOAuthResourceUrl(value, options = {}) {
22
60
  return url;
23
61
  }
24
62
  export {
63
+ buildProtectedResourceMetadataUrl,
64
+ normalizeOAuthResourceForComparison,
25
65
  validateOAuthResourceUrl
26
66
  };
@@ -1,4 +1,5 @@
1
1
  import type { ProductPropertyPolicyDiagnostic, ProductPropertyPolicyMode } from '../media-buy/property-policy.mjs';
2
+ import type { DelegatedOperatorAuthorizationContext } from '../signing/agent-resolver/resolve-agent.mjs';
2
3
  /**
3
4
  * Represents a single message in a conversation with an agent
4
5
  */
@@ -152,6 +153,15 @@ export interface TaskOptions {
152
153
  debug?: boolean;
153
154
  /** Suppress automatic webhook URL generation for this call. */
154
155
  disableWebhook?: boolean;
156
+ /**
157
+ * Trusted local authorization tuple for a delegated, cross-origin seller.
158
+ * The SDK snapshots this before dispatch and persists it with any generated
159
+ * webhook registration. It is never inferred from or sent in task arguments.
160
+ *
161
+ * When present, this whole object takes precedence over the client-wide
162
+ * `webhookVerification.resolverOptions.requiredOperator*` fallback.
163
+ */
164
+ delegatedOperatorAuthorization?: DelegatedOperatorAuthorizationContext;
155
165
  /** Additional metadata to include */
156
166
  metadata?: Record<string, any>;
157
167
  /**
@@ -1,4 +1,5 @@
1
1
  import type { ProductPropertyPolicyDiagnostic, ProductPropertyPolicyMode } from '../media-buy/property-policy';
2
+ import type { DelegatedOperatorAuthorizationContext } from '../signing/agent-resolver/resolve-agent';
2
3
  /**
3
4
  * Represents a single message in a conversation with an agent
4
5
  */
@@ -152,6 +153,15 @@ export interface TaskOptions {
152
153
  debug?: boolean;
153
154
  /** Suppress automatic webhook URL generation for this call. */
154
155
  disableWebhook?: boolean;
156
+ /**
157
+ * Trusted local authorization tuple for a delegated, cross-origin seller.
158
+ * The SDK snapshots this before dispatch and persists it with any generated
159
+ * webhook registration. It is never inferred from or sent in task arguments.
160
+ *
161
+ * When present, this whole object takes precedence over the client-wide
162
+ * `webhookVerification.resolverOptions.requiredOperator*` fallback.
163
+ */
164
+ delegatedOperatorAuthorization?: DelegatedOperatorAuthorizationContext;
155
165
  /** Additional metadata to include */
156
166
  metadata?: Record<string, any>;
157
167
  /**
@@ -457,6 +457,9 @@ export declare class SingleAgentClient {
457
457
  private readonly durableDeferredResumeTokenReplacers;
458
458
  constructor(agent: AgentConfig, config?: SingleAgentClientConfig);
459
459
  private persistWebhookRegistration;
460
+ private configuredDelegatedOperatorAuthorization;
461
+ private effectiveDelegatedOperatorAuthorization;
462
+ private delegatedOperatorAuthorizationForRegistration;
460
463
  private markWebhookDurableSettlementRequired;
461
464
  private webhookJwksFor;
462
465
  private resolveLegacyFormatConverter;
@@ -536,8 +539,8 @@ export declare class SingleAgentClient {
536
539
  *
537
540
  * Special handling for authentication errors (401):
538
541
  * - If any endpoint returns 401, we know the server exists but requires auth
539
- * - We fetch OAuth metadata and throw AuthenticationRequiredError
540
- * - This gives consumers clear guidance on how to authenticate
542
+ * - A validated MCP protected-resource metadata chain yields NeedsAuthorizationError
543
+ * - Otherwise AuthenticationRequiredError carries the advertised challenge
541
544
  *
542
545
  * Note: This is async and called lazily on first agent interaction
543
546
  */
@@ -457,6 +457,9 @@ export declare class SingleAgentClient {
457
457
  private readonly durableDeferredResumeTokenReplacers;
458
458
  constructor(agent: AgentConfig, config?: SingleAgentClientConfig);
459
459
  private persistWebhookRegistration;
460
+ private configuredDelegatedOperatorAuthorization;
461
+ private effectiveDelegatedOperatorAuthorization;
462
+ private delegatedOperatorAuthorizationForRegistration;
460
463
  private markWebhookDurableSettlementRequired;
461
464
  private webhookJwksFor;
462
465
  private resolveLegacyFormatConverter;
@@ -536,8 +539,8 @@ export declare class SingleAgentClient {
536
539
  *
537
540
  * Special handling for authentication errors (401):
538
541
  * - If any endpoint returns 401, we know the server exists but requires auth
539
- * - We fetch OAuth metadata and throw AuthenticationRequiredError
540
- * - This gives consumers clear guidance on how to authenticate
542
+ * - A validated MCP protected-resource metadata chain yields NeedsAuthorizationError
543
+ * - Otherwise AuthenticationRequiredError carries the advertised challenge
541
544
  *
542
545
  * Note: This is async and called lazily on first agent interaction
543
546
  */