@adcp/sdk 14.3.0 → 15.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/adcp.js +8 -5
- package/dist/lib/auth/oauth/ClientCredentialsFlow.js +4 -1
- package/dist/lib/auth/oauth/ClientCredentialsFlow.mjs +4 -1
- package/dist/lib/auth/oauth/MCPOAuthProvider.d.mts +25 -8
- package/dist/lib/auth/oauth/MCPOAuthProvider.d.ts +25 -8
- package/dist/lib/auth/oauth/MCPOAuthProvider.js +144 -19
- package/dist/lib/auth/oauth/MCPOAuthProvider.mjs +157 -19
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.d.mts +1 -1
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.d.ts +1 -1
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.js +1 -1
- package/dist/lib/auth/oauth/NonInteractiveFlowHandler.mjs +1 -1
- package/dist/lib/auth/oauth/client-credentials-schema.d.mts +17 -0
- package/dist/lib/auth/oauth/client-credentials-schema.d.ts +17 -0
- package/dist/lib/auth/oauth/client-credentials-schema.js +37 -0
- package/dist/lib/auth/oauth/client-credentials-schema.mjs +13 -0
- package/dist/lib/auth/oauth/diagnose.js +14 -0
- package/dist/lib/auth/oauth/diagnose.mjs +14 -0
- package/dist/lib/auth/oauth/file-storage.d.mts +4 -2
- package/dist/lib/auth/oauth/file-storage.d.ts +4 -2
- package/dist/lib/auth/oauth/file-storage.js +14 -1
- package/dist/lib/auth/oauth/file-storage.mjs +14 -1
- package/dist/lib/auth/oauth/index.d.mts +10 -6
- package/dist/lib/auth/oauth/index.d.ts +10 -6
- package/dist/lib/auth/oauth/index.js +9 -3
- package/dist/lib/auth/oauth/index.mjs +8 -3
- package/dist/lib/auth/oauth/types.d.mts +17 -0
- package/dist/lib/auth/oauth/types.d.ts +17 -0
- package/dist/lib/auth/oauth/types.js +40 -0
- package/dist/lib/auth/oauth/types.mjs +38 -0
- package/dist/lib/auth/oauth/web-flow.d.mts +2 -0
- package/dist/lib/auth/oauth/web-flow.d.ts +2 -0
- package/dist/lib/auth/oauth/web-flow.js +48 -5
- package/dist/lib/auth/oauth/web-flow.mjs +57 -6
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.mjs +3 -1
- package/dist/lib/protocols/mcp.js +2 -0
- package/dist/lib/protocols/mcp.mjs +2 -0
- package/dist/lib/schemas/index.d.mts +2 -0
- package/dist/lib/schemas/index.d.ts +2 -0
- package/dist/lib/schemas/index.js +3 -0
- package/dist/lib/schemas/index.mjs +2 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/client.js +8 -3
- package/dist/lib/testing/client.mjs +8 -3
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/types.d.mts +10 -1
- package/dist/lib/testing/types.d.ts +10 -1
- package/dist/lib/types/adcp.d.mts +6 -0
- package/dist/lib/types/adcp.d.ts +6 -0
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +1 -1
- package/docs/ZOD-SCHEMAS.md +19 -0
- package/docs/guides/OAUTH-ISSUER-BINDING.md +46 -0
- package/docs/guides/WEB-OAUTH.md +58 -163
- package/docs/guides/account-resolution.md +1 -1
- package/docs/llms.txt +1 -1
- package/docs/migration-14.0-to-14.1.md +1 -1
- package/docs/migration-14.x-rc-worksheet.md +8 -8
- package/docs/migration-oauth-issuer-bindings.md +17 -0
- package/package.json +5 -5
|
@@ -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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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,
|
|
@@ -13,6 +13,10 @@ export type { AgentConfig, AgentOAuthTokens, AgentOAuthClient };
|
|
|
13
13
|
* Agent config storage interface
|
|
14
14
|
*
|
|
15
15
|
* Implement this to persist OAuth tokens back to agent configuration.
|
|
16
|
+
* Round-trip pending `oauth_code_verifier` and `oauth_discovery_state` verbatim.
|
|
17
|
+
* For oauth_tokens, oauth_client, oauth_code_verifier and oauth_discovery_state,
|
|
18
|
+
* an own undefined property clears; omission preserves the saved field.
|
|
19
|
+
* Resource overrides and other fields retain the storage backend's semantics.
|
|
16
20
|
* This allows different storage backends (file, database, memory)
|
|
17
21
|
* while keeping tokens in the agent config structure.
|
|
18
22
|
*/
|
|
@@ -74,6 +78,11 @@ export interface OAuthProviderConfig {
|
|
|
74
78
|
storage?: OAuthConfigStorage;
|
|
75
79
|
/** Authorization flow handler */
|
|
76
80
|
flowHandler: OAuthFlowHandler;
|
|
81
|
+
/**
|
|
82
|
+
* Explicitly allow fresh registration, PKCE work, redirects and automatic
|
|
83
|
+
* credential invalidation. Defaults to false; CLI factories opt in.
|
|
84
|
+
*/
|
|
85
|
+
allowInteractiveAuthorization?: boolean;
|
|
77
86
|
/** OAuth client metadata (required - use DEFAULT_CLIENT_METADATA as base) */
|
|
78
87
|
clientMetadata: OAuthClientMetadata;
|
|
79
88
|
/**
|
|
@@ -132,3 +141,11 @@ export declare function toMCPClientInfo(client: AgentOAuthClient): OAuthClientIn
|
|
|
132
141
|
* Convert MCP SDK OAuthClientInformationFull to AgentOAuthClient format
|
|
133
142
|
*/
|
|
134
143
|
export declare function fromMCPClientInfo(info: OAuthClientInformationFull): AgentOAuthClient;
|
|
144
|
+
/** Internal credential-binding guard; old secrets must be migrated from trusted configuration. */
|
|
145
|
+
export declare function assertOAuthCredentialIssuer(credential: {
|
|
146
|
+
issuer?: unknown;
|
|
147
|
+
}, expectedIssuer?: string, requireIssuer?: boolean): void;
|
|
148
|
+
/** Internal metadata guard, matching the modern MCP SDK's asymmetric issuer-echo rule. */
|
|
149
|
+
export declare function assertOAuthServerIssuer(metadata: {
|
|
150
|
+
issuer?: unknown;
|
|
151
|
+
} | undefined, authorizationServerUrl: string): void;
|
|
@@ -13,6 +13,10 @@ export type { AgentConfig, AgentOAuthTokens, AgentOAuthClient };
|
|
|
13
13
|
* Agent config storage interface
|
|
14
14
|
*
|
|
15
15
|
* Implement this to persist OAuth tokens back to agent configuration.
|
|
16
|
+
* Round-trip pending `oauth_code_verifier` and `oauth_discovery_state` verbatim.
|
|
17
|
+
* For oauth_tokens, oauth_client, oauth_code_verifier and oauth_discovery_state,
|
|
18
|
+
* an own undefined property clears; omission preserves the saved field.
|
|
19
|
+
* Resource overrides and other fields retain the storage backend's semantics.
|
|
16
20
|
* This allows different storage backends (file, database, memory)
|
|
17
21
|
* while keeping tokens in the agent config structure.
|
|
18
22
|
*/
|
|
@@ -74,6 +78,11 @@ export interface OAuthProviderConfig {
|
|
|
74
78
|
storage?: OAuthConfigStorage;
|
|
75
79
|
/** Authorization flow handler */
|
|
76
80
|
flowHandler: OAuthFlowHandler;
|
|
81
|
+
/**
|
|
82
|
+
* Explicitly allow fresh registration, PKCE work, redirects and automatic
|
|
83
|
+
* credential invalidation. Defaults to false; CLI factories opt in.
|
|
84
|
+
*/
|
|
85
|
+
allowInteractiveAuthorization?: boolean;
|
|
77
86
|
/** OAuth client metadata (required - use DEFAULT_CLIENT_METADATA as base) */
|
|
78
87
|
clientMetadata: OAuthClientMetadata;
|
|
79
88
|
/**
|
|
@@ -132,3 +141,11 @@ export declare function toMCPClientInfo(client: AgentOAuthClient): OAuthClientIn
|
|
|
132
141
|
* Convert MCP SDK OAuthClientInformationFull to AgentOAuthClient format
|
|
133
142
|
*/
|
|
134
143
|
export declare function fromMCPClientInfo(info: OAuthClientInformationFull): AgentOAuthClient;
|
|
144
|
+
/** Internal credential-binding guard; old secrets must be migrated from trusted configuration. */
|
|
145
|
+
export declare function assertOAuthCredentialIssuer(credential: {
|
|
146
|
+
issuer?: unknown;
|
|
147
|
+
}, expectedIssuer?: string, requireIssuer?: boolean): void;
|
|
148
|
+
/** Internal metadata guard, matching the modern MCP SDK's asymmetric issuer-echo rule. */
|
|
149
|
+
export declare function assertOAuthServerIssuer(metadata: {
|
|
150
|
+
issuer?: unknown;
|
|
151
|
+
} | undefined, authorizationServerUrl: string): void;
|
|
@@ -22,6 +22,8 @@ __export(types_exports, {
|
|
|
22
22
|
OAuthCancelledError: () => OAuthCancelledError,
|
|
23
23
|
OAuthError: () => OAuthError,
|
|
24
24
|
OAuthTimeoutError: () => OAuthTimeoutError,
|
|
25
|
+
assertOAuthCredentialIssuer: () => assertOAuthCredentialIssuer,
|
|
26
|
+
assertOAuthServerIssuer: () => assertOAuthServerIssuer,
|
|
25
27
|
fromMCPClientInfo: () => fromMCPClientInfo,
|
|
26
28
|
fromMCPTokens: () => fromMCPTokens,
|
|
27
29
|
toMCPClientInfo: () => toMCPClientInfo,
|
|
@@ -60,6 +62,7 @@ class OAuthTimeoutError extends OAuthError {
|
|
|
60
62
|
}
|
|
61
63
|
function toMCPTokens(tokens) {
|
|
62
64
|
return {
|
|
65
|
+
...tokens.issuer !== void 0 && tokens.issuer !== null && { issuer: tokens.issuer },
|
|
63
66
|
access_token: tokens.access_token,
|
|
64
67
|
refresh_token: tokens.refresh_token,
|
|
65
68
|
token_type: tokens.token_type || "Bearer",
|
|
@@ -69,6 +72,7 @@ function toMCPTokens(tokens) {
|
|
|
69
72
|
}
|
|
70
73
|
function fromMCPTokens(tokens) {
|
|
71
74
|
const result = {
|
|
75
|
+
...tokens.issuer !== void 0 && tokens.issuer !== null && { issuer: tokens.issuer },
|
|
72
76
|
access_token: tokens.access_token,
|
|
73
77
|
token_type: tokens.token_type,
|
|
74
78
|
scope: tokens.scope
|
|
@@ -84,6 +88,7 @@ function fromMCPTokens(tokens) {
|
|
|
84
88
|
}
|
|
85
89
|
function toMCPClientInfo(client) {
|
|
86
90
|
return {
|
|
91
|
+
...client.issuer !== void 0 && client.issuer !== null && { issuer: client.issuer },
|
|
87
92
|
client_id: client.client_id,
|
|
88
93
|
client_secret: client.client_secret,
|
|
89
94
|
client_secret_expires_at: client.client_secret_expires_at
|
|
@@ -91,17 +96,52 @@ function toMCPClientInfo(client) {
|
|
|
91
96
|
}
|
|
92
97
|
function fromMCPClientInfo(info) {
|
|
93
98
|
return {
|
|
99
|
+
...info.issuer !== void 0 && info.issuer !== null && { issuer: info.issuer },
|
|
94
100
|
client_id: info.client_id,
|
|
95
101
|
client_secret: info.client_secret,
|
|
96
102
|
client_secret_expires_at: info.client_secret_expires_at
|
|
97
103
|
};
|
|
98
104
|
}
|
|
105
|
+
function isOAuthIssuer(value) {
|
|
106
|
+
if (typeof value !== "string" || !value || /[\u0000-\u0020\u007f\\]/.test(value)) return false;
|
|
107
|
+
try {
|
|
108
|
+
const url = new URL(value);
|
|
109
|
+
const rawAuthority = value.match(/^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)/i)?.[1];
|
|
110
|
+
return (url.protocol === "https:" || url.protocol === "http:") && !rawAuthority?.includes("@") && !url.username && !url.password && !url.search && !url.hash;
|
|
111
|
+
} catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function assertOAuthCredentialIssuer(credential, expectedIssuer, requireIssuer = false) {
|
|
116
|
+
const issuer = credential.issuer;
|
|
117
|
+
if ((issuer === void 0 || issuer === null) && !requireIssuer) return;
|
|
118
|
+
if (!isOAuthIssuer(issuer)) {
|
|
119
|
+
throw new OAuthError(
|
|
120
|
+
"Saved OAuth credentials need a valid issuer. Clear them and sign in again, or set their issuer from trusted configuration.",
|
|
121
|
+
"oauth_issuer_required"
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
if (expectedIssuer !== void 0 && issuer !== expectedIssuer && !(issuer.endsWith("/") && issuer.slice(0, -1) === expectedIssuer) && !(expectedIssuer.endsWith("/") && expectedIssuer.slice(0, -1) === issuer)) {
|
|
125
|
+
throw new OAuthError("OAuth credentials belong to a different authorization server.", "oauth_issuer_mismatch");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function assertOAuthServerIssuer(metadata, authorizationServerUrl) {
|
|
129
|
+
const issuer = metadata?.issuer;
|
|
130
|
+
if (!isOAuthIssuer(issuer) || issuer !== authorizationServerUrl && !(authorizationServerUrl.endsWith("/") && issuer === authorizationServerUrl.slice(0, -1))) {
|
|
131
|
+
throw new OAuthError(
|
|
132
|
+
"Authorization-server metadata does not match the discovered issuer.",
|
|
133
|
+
"oauth_issuer_mismatch"
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
99
137
|
// Annotate the CommonJS export names for ESM import in node:
|
|
100
138
|
0 && (module.exports = {
|
|
101
139
|
DEFAULT_CLIENT_METADATA,
|
|
102
140
|
OAuthCancelledError,
|
|
103
141
|
OAuthError,
|
|
104
142
|
OAuthTimeoutError,
|
|
143
|
+
assertOAuthCredentialIssuer,
|
|
144
|
+
assertOAuthServerIssuer,
|
|
105
145
|
fromMCPClientInfo,
|
|
106
146
|
fromMCPTokens,
|
|
107
147
|
toMCPClientInfo,
|
|
@@ -30,6 +30,7 @@ class OAuthTimeoutError extends OAuthError {
|
|
|
30
30
|
}
|
|
31
31
|
function toMCPTokens(tokens) {
|
|
32
32
|
return {
|
|
33
|
+
...tokens.issuer !== void 0 && tokens.issuer !== null && { issuer: tokens.issuer },
|
|
33
34
|
access_token: tokens.access_token,
|
|
34
35
|
refresh_token: tokens.refresh_token,
|
|
35
36
|
token_type: tokens.token_type || "Bearer",
|
|
@@ -39,6 +40,7 @@ function toMCPTokens(tokens) {
|
|
|
39
40
|
}
|
|
40
41
|
function fromMCPTokens(tokens) {
|
|
41
42
|
const result = {
|
|
43
|
+
...tokens.issuer !== void 0 && tokens.issuer !== null && { issuer: tokens.issuer },
|
|
42
44
|
access_token: tokens.access_token,
|
|
43
45
|
token_type: tokens.token_type,
|
|
44
46
|
scope: tokens.scope
|
|
@@ -54,6 +56,7 @@ function fromMCPTokens(tokens) {
|
|
|
54
56
|
}
|
|
55
57
|
function toMCPClientInfo(client) {
|
|
56
58
|
return {
|
|
59
|
+
...client.issuer !== void 0 && client.issuer !== null && { issuer: client.issuer },
|
|
57
60
|
client_id: client.client_id,
|
|
58
61
|
client_secret: client.client_secret,
|
|
59
62
|
client_secret_expires_at: client.client_secret_expires_at
|
|
@@ -61,16 +64,51 @@ function toMCPClientInfo(client) {
|
|
|
61
64
|
}
|
|
62
65
|
function fromMCPClientInfo(info) {
|
|
63
66
|
return {
|
|
67
|
+
...info.issuer !== void 0 && info.issuer !== null && { issuer: info.issuer },
|
|
64
68
|
client_id: info.client_id,
|
|
65
69
|
client_secret: info.client_secret,
|
|
66
70
|
client_secret_expires_at: info.client_secret_expires_at
|
|
67
71
|
};
|
|
68
72
|
}
|
|
73
|
+
function isOAuthIssuer(value) {
|
|
74
|
+
if (typeof value !== "string" || !value || /[\u0000-\u0020\u007f\\]/.test(value)) return false;
|
|
75
|
+
try {
|
|
76
|
+
const url = new URL(value);
|
|
77
|
+
const rawAuthority = value.match(/^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)/i)?.[1];
|
|
78
|
+
return (url.protocol === "https:" || url.protocol === "http:") && !rawAuthority?.includes("@") && !url.username && !url.password && !url.search && !url.hash;
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function assertOAuthCredentialIssuer(credential, expectedIssuer, requireIssuer = false) {
|
|
84
|
+
const issuer = credential.issuer;
|
|
85
|
+
if ((issuer === void 0 || issuer === null) && !requireIssuer) return;
|
|
86
|
+
if (!isOAuthIssuer(issuer)) {
|
|
87
|
+
throw new OAuthError(
|
|
88
|
+
"Saved OAuth credentials need a valid issuer. Clear them and sign in again, or set their issuer from trusted configuration.",
|
|
89
|
+
"oauth_issuer_required"
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
if (expectedIssuer !== void 0 && issuer !== expectedIssuer && !(issuer.endsWith("/") && issuer.slice(0, -1) === expectedIssuer) && !(expectedIssuer.endsWith("/") && expectedIssuer.slice(0, -1) === issuer)) {
|
|
93
|
+
throw new OAuthError("OAuth credentials belong to a different authorization server.", "oauth_issuer_mismatch");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function assertOAuthServerIssuer(metadata, authorizationServerUrl) {
|
|
97
|
+
const issuer = metadata?.issuer;
|
|
98
|
+
if (!isOAuthIssuer(issuer) || issuer !== authorizationServerUrl && !(authorizationServerUrl.endsWith("/") && issuer === authorizationServerUrl.slice(0, -1))) {
|
|
99
|
+
throw new OAuthError(
|
|
100
|
+
"Authorization-server metadata does not match the discovered issuer.",
|
|
101
|
+
"oauth_issuer_mismatch"
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
69
105
|
export {
|
|
70
106
|
DEFAULT_CLIENT_METADATA,
|
|
71
107
|
OAuthCancelledError,
|
|
72
108
|
OAuthError,
|
|
73
109
|
OAuthTimeoutError,
|
|
110
|
+
assertOAuthCredentialIssuer,
|
|
111
|
+
assertOAuthServerIssuer,
|
|
74
112
|
fromMCPClientInfo,
|
|
75
113
|
fromMCPTokens,
|
|
76
114
|
toMCPClientInfo,
|
|
@@ -66,6 +66,8 @@ export interface PendingWebFlow {
|
|
|
66
66
|
resourceOverrideSnapshot?: string | null;
|
|
67
67
|
scope?: string;
|
|
68
68
|
authorizationServerUrl: string;
|
|
69
|
+
/** Validated AS issuer frozen at start. Legacy rows without it cannot spend credentials. */
|
|
70
|
+
authorizationServerIssuer?: string;
|
|
69
71
|
/** Persist as JSON (e.g. Postgres `jsonb`); contents are MCP SDK-typed. */
|
|
70
72
|
clientInformation: OAuthClientInformation;
|
|
71
73
|
createdAt: Date;
|
|
@@ -66,6 +66,8 @@ export interface PendingWebFlow {
|
|
|
66
66
|
resourceOverrideSnapshot?: string | null;
|
|
67
67
|
scope?: string;
|
|
68
68
|
authorizationServerUrl: string;
|
|
69
|
+
/** Validated AS issuer frozen at start. Legacy rows without it cannot spend credentials. */
|
|
70
|
+
authorizationServerIssuer?: string;
|
|
69
71
|
/** Persist as JSON (e.g. Postgres `jsonb`); contents are MCP SDK-typed. */
|
|
70
72
|
clientInformation: OAuthClientInformation;
|
|
71
73
|
createdAt: Date;
|
|
@@ -144,6 +144,9 @@ async function startWebOAuthFlow(opts) {
|
|
|
144
144
|
if (!asMetadata) {
|
|
145
145
|
throw new import_types.OAuthError(`No OAuth metadata at ${asUrl.toString()}`, "no_authorization_server_metadata", agent.id);
|
|
146
146
|
}
|
|
147
|
+
(0, import_types.assertOAuthServerIssuer)(asMetadata, asUrl.toString());
|
|
148
|
+
const authorizationServerIssuer = asUrl.toString();
|
|
149
|
+
assertSavedCredentialIssuers(agent, authorizationServerIssuer);
|
|
147
150
|
const resource = resourceOverride ? new URL(resourceOverride) : prm?.resource ? new URL(prm.resource) : (0, import_auth_utils.resourceUrlFromServerUrl)(new URL(agent.agent_uri));
|
|
148
151
|
const baseClientMetadata = {
|
|
149
152
|
...import_types.DEFAULT_CLIENT_METADATA,
|
|
@@ -158,7 +161,8 @@ async function startWebOAuthFlow(opts) {
|
|
|
158
161
|
asMetadata,
|
|
159
162
|
clientMetadata: baseClientMetadata,
|
|
160
163
|
fetchFn: guardedFetch,
|
|
161
|
-
allowConfidentialClient
|
|
164
|
+
allowConfidentialClient,
|
|
165
|
+
issuer: authorizationServerIssuer
|
|
162
166
|
});
|
|
163
167
|
const state = (generateState ?? defaultGenerateState)();
|
|
164
168
|
const { authorizationUrl, codeVerifier } = await (0, import_auth.startAuthorization)(asUrl.toString(), {
|
|
@@ -186,6 +190,7 @@ async function startWebOAuthFlow(opts) {
|
|
|
186
190
|
resourceOverrideSnapshot: agent.oauth_resource ?? null,
|
|
187
191
|
scope,
|
|
188
192
|
authorizationServerUrl: asUrl.toString(),
|
|
193
|
+
authorizationServerIssuer,
|
|
189
194
|
clientInformation,
|
|
190
195
|
createdAt: now,
|
|
191
196
|
expiresAt,
|
|
@@ -230,6 +235,17 @@ async function completeWebOAuthFlow(opts) {
|
|
|
230
235
|
const asMetadata = await (0, import_auth.discoverAuthorizationServerMetadata)(flow.authorizationServerUrl, {
|
|
231
236
|
fetchFn: guardedFetch
|
|
232
237
|
});
|
|
238
|
+
(0, import_types.assertOAuthServerIssuer)(asMetadata, flow.authorizationServerUrl);
|
|
239
|
+
assertFrozenIssuer(flow);
|
|
240
|
+
(0, import_types.assertOAuthCredentialIssuer)(
|
|
241
|
+
flow.clientInformation,
|
|
242
|
+
flow.authorizationServerIssuer,
|
|
243
|
+
!!flow.clientInformation.client_secret
|
|
244
|
+
);
|
|
245
|
+
if (agentStorage) {
|
|
246
|
+
agentForPersistence = await agentStorage.loadAgent(flow.agentId);
|
|
247
|
+
assertAgentUnchangedForFlow(agentForPersistence, flow);
|
|
248
|
+
}
|
|
233
249
|
let tokens;
|
|
234
250
|
try {
|
|
235
251
|
tokens = await (0, import_auth.exchangeAuthorization)(flow.authorizationServerUrl, {
|
|
@@ -241,6 +257,7 @@ async function completeWebOAuthFlow(opts) {
|
|
|
241
257
|
resource: flow.resource ? new URL(flow.resource) : void 0,
|
|
242
258
|
fetchFn: guardedFetch
|
|
243
259
|
});
|
|
260
|
+
tokens = { ...tokens, issuer: flow.authorizationServerIssuer };
|
|
244
261
|
} catch (err) {
|
|
245
262
|
throw wrapTokenExchangeError(err);
|
|
246
263
|
}
|
|
@@ -254,7 +271,8 @@ async function completeWebOAuthFlow(opts) {
|
|
|
254
271
|
} else if (flow.resourceOverrideAction === "clear") {
|
|
255
272
|
delete agentForPersistence.oauth_resource;
|
|
256
273
|
}
|
|
257
|
-
|
|
274
|
+
agentForPersistence.oauth_code_verifier = void 0;
|
|
275
|
+
agentForPersistence.oauth_discovery_state = void 0;
|
|
258
276
|
await agentStorage.saveAgent(agentForPersistence);
|
|
259
277
|
persisted = true;
|
|
260
278
|
}
|
|
@@ -266,6 +284,20 @@ async function completeWebOAuthFlow(opts) {
|
|
|
266
284
|
persisted
|
|
267
285
|
};
|
|
268
286
|
}
|
|
287
|
+
function assertSavedCredentialIssuers(agent, issuer) {
|
|
288
|
+
if (agent.oauth_tokens) (0, import_types.assertOAuthCredentialIssuer)(agent.oauth_tokens, issuer, !!agent.oauth_tokens.refresh_token);
|
|
289
|
+
if (agent.oauth_client) (0, import_types.assertOAuthCredentialIssuer)(agent.oauth_client, issuer, !!agent.oauth_client.client_secret);
|
|
290
|
+
}
|
|
291
|
+
function assertFrozenIssuer(flow) {
|
|
292
|
+
if (!flow.authorizationServerIssuer) {
|
|
293
|
+
throw new import_types.OAuthError(
|
|
294
|
+
"Pending OAuth flow lacks a validated authorization-server issuer. Start a new owner sign-in.",
|
|
295
|
+
"oauth_issuer_required",
|
|
296
|
+
flow.agentId
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
(0, import_types.assertOAuthServerIssuer)({ issuer: flow.authorizationServerIssuer }, flow.authorizationServerUrl);
|
|
300
|
+
}
|
|
269
301
|
function assertAgentUnchangedForFlow(agent, flow) {
|
|
270
302
|
if (!agent) {
|
|
271
303
|
throw new AgentVanishedDuringFlowError(flow.agentId);
|
|
@@ -273,6 +305,13 @@ function assertAgentUnchangedForFlow(agent, flow) {
|
|
|
273
305
|
if (agent.agent_uri !== flow.agentUrl) {
|
|
274
306
|
throw new AgentChangedDuringFlowError(flow.agentId);
|
|
275
307
|
}
|
|
308
|
+
if (!agent.oauth_client) throw new AgentChangedDuringFlowError(flow.agentId);
|
|
309
|
+
const currentClient = (0, import_types.toMCPClientInfo)(agent.oauth_client);
|
|
310
|
+
for (const key of ["client_id", "client_secret", "client_secret_expires_at", "issuer"]) {
|
|
311
|
+
if (currentClient[key] !== flow.clientInformation[key]) throw new AgentChangedDuringFlowError(flow.agentId);
|
|
312
|
+
}
|
|
313
|
+
assertFrozenIssuer(flow);
|
|
314
|
+
assertSavedCredentialIssuers(agent, flow.authorizationServerIssuer);
|
|
276
315
|
if (Object.prototype.hasOwnProperty.call(flow, "resourceOverrideSnapshot") && (agent.oauth_resource ?? null) !== flow.resourceOverrideSnapshot) {
|
|
277
316
|
throw new AgentChangedDuringFlowError(flow.agentId);
|
|
278
317
|
}
|
|
@@ -408,7 +447,7 @@ function createSsrfSafeOAuthFetch(trustedFetchFn, allowHttp) {
|
|
|
408
447
|
});
|
|
409
448
|
}
|
|
410
449
|
async function resolveClientInformation(args) {
|
|
411
|
-
const { agent, agentStorage, asUrl, asMetadata, clientMetadata, fetchFn, allowConfidentialClient } = args;
|
|
450
|
+
const { agent, agentStorage, asUrl, asMetadata, clientMetadata, fetchFn, allowConfidentialClient, issuer } = args;
|
|
412
451
|
if (agent.oauth_client) {
|
|
413
452
|
return (0, import_types.toMCPClientInfo)(agent.oauth_client);
|
|
414
453
|
}
|
|
@@ -419,16 +458,20 @@ async function resolveClientInformation(args) {
|
|
|
419
458
|
agent.id
|
|
420
459
|
);
|
|
421
460
|
}
|
|
422
|
-
const
|
|
461
|
+
const response = await (0, import_auth.registerClient)(asUrl.toString(), {
|
|
423
462
|
metadata: asMetadata,
|
|
424
463
|
clientMetadata,
|
|
425
464
|
fetchFn
|
|
426
465
|
});
|
|
466
|
+
const registered = { ...response, issuer };
|
|
427
467
|
if (registered.client_secret && !allowConfidentialClient) {
|
|
428
468
|
throw new ConfidentialClientNotAllowedError(agent.id);
|
|
429
469
|
}
|
|
430
470
|
if (agentStorage) {
|
|
431
|
-
const fresh = await agentStorage.loadAgent(agent.id)
|
|
471
|
+
const fresh = await agentStorage.loadAgent(agent.id);
|
|
472
|
+
if (!fresh) throw new AgentVanishedDuringFlowError(agent.id);
|
|
473
|
+
if (fresh.agent_uri !== agent.agent_uri || fresh.oauth_client) throw new AgentChangedDuringFlowError(agent.id);
|
|
474
|
+
assertSavedCredentialIssuers(fresh, issuer);
|
|
432
475
|
fresh.oauth_client = (0, import_types.fromMCPClientInfo)(registered);
|
|
433
476
|
await agentStorage.saveAgent(fresh);
|
|
434
477
|
}
|
|
@@ -7,7 +7,15 @@ import {
|
|
|
7
7
|
startAuthorization
|
|
8
8
|
} from "@modelcontextprotocol/sdk/client/auth.js";
|
|
9
9
|
import { checkResourceAllowed, resourceUrlFromServerUrl } from "@modelcontextprotocol/sdk/shared/auth-utils.js";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
DEFAULT_CLIENT_METADATA,
|
|
12
|
+
fromMCPClientInfo,
|
|
13
|
+
fromMCPTokens,
|
|
14
|
+
OAuthError,
|
|
15
|
+
toMCPClientInfo,
|
|
16
|
+
assertOAuthCredentialIssuer,
|
|
17
|
+
assertOAuthServerIssuer
|
|
18
|
+
} from "./types.mjs";
|
|
11
19
|
import { validateOAuthResourceUrl } from "./resource-url.mjs";
|
|
12
20
|
import { ssrfSafeFetch } from "../../net/ssrf-fetch.mjs";
|
|
13
21
|
const DEFAULT_WEB_FLOW_TTL_MS = 10 * 60 * 1e3;
|
|
@@ -115,6 +123,9 @@ async function startWebOAuthFlow(opts) {
|
|
|
115
123
|
if (!asMetadata) {
|
|
116
124
|
throw new OAuthError(`No OAuth metadata at ${asUrl.toString()}`, "no_authorization_server_metadata", agent.id);
|
|
117
125
|
}
|
|
126
|
+
assertOAuthServerIssuer(asMetadata, asUrl.toString());
|
|
127
|
+
const authorizationServerIssuer = asUrl.toString();
|
|
128
|
+
assertSavedCredentialIssuers(agent, authorizationServerIssuer);
|
|
118
129
|
const resource = resourceOverride ? new URL(resourceOverride) : prm?.resource ? new URL(prm.resource) : resourceUrlFromServerUrl(new URL(agent.agent_uri));
|
|
119
130
|
const baseClientMetadata = {
|
|
120
131
|
...DEFAULT_CLIENT_METADATA,
|
|
@@ -129,7 +140,8 @@ async function startWebOAuthFlow(opts) {
|
|
|
129
140
|
asMetadata,
|
|
130
141
|
clientMetadata: baseClientMetadata,
|
|
131
142
|
fetchFn: guardedFetch,
|
|
132
|
-
allowConfidentialClient
|
|
143
|
+
allowConfidentialClient,
|
|
144
|
+
issuer: authorizationServerIssuer
|
|
133
145
|
});
|
|
134
146
|
const state = (generateState ?? defaultGenerateState)();
|
|
135
147
|
const { authorizationUrl, codeVerifier } = await startAuthorization(asUrl.toString(), {
|
|
@@ -157,6 +169,7 @@ async function startWebOAuthFlow(opts) {
|
|
|
157
169
|
resourceOverrideSnapshot: agent.oauth_resource ?? null,
|
|
158
170
|
scope,
|
|
159
171
|
authorizationServerUrl: asUrl.toString(),
|
|
172
|
+
authorizationServerIssuer,
|
|
160
173
|
clientInformation,
|
|
161
174
|
createdAt: now,
|
|
162
175
|
expiresAt,
|
|
@@ -201,6 +214,17 @@ async function completeWebOAuthFlow(opts) {
|
|
|
201
214
|
const asMetadata = await discoverAuthorizationServerMetadata(flow.authorizationServerUrl, {
|
|
202
215
|
fetchFn: guardedFetch
|
|
203
216
|
});
|
|
217
|
+
assertOAuthServerIssuer(asMetadata, flow.authorizationServerUrl);
|
|
218
|
+
assertFrozenIssuer(flow);
|
|
219
|
+
assertOAuthCredentialIssuer(
|
|
220
|
+
flow.clientInformation,
|
|
221
|
+
flow.authorizationServerIssuer,
|
|
222
|
+
!!flow.clientInformation.client_secret
|
|
223
|
+
);
|
|
224
|
+
if (agentStorage) {
|
|
225
|
+
agentForPersistence = await agentStorage.loadAgent(flow.agentId);
|
|
226
|
+
assertAgentUnchangedForFlow(agentForPersistence, flow);
|
|
227
|
+
}
|
|
204
228
|
let tokens;
|
|
205
229
|
try {
|
|
206
230
|
tokens = await exchangeAuthorization(flow.authorizationServerUrl, {
|
|
@@ -212,6 +236,7 @@ async function completeWebOAuthFlow(opts) {
|
|
|
212
236
|
resource: flow.resource ? new URL(flow.resource) : void 0,
|
|
213
237
|
fetchFn: guardedFetch
|
|
214
238
|
});
|
|
239
|
+
tokens = { ...tokens, issuer: flow.authorizationServerIssuer };
|
|
215
240
|
} catch (err) {
|
|
216
241
|
throw wrapTokenExchangeError(err);
|
|
217
242
|
}
|
|
@@ -225,7 +250,8 @@ async function completeWebOAuthFlow(opts) {
|
|
|
225
250
|
} else if (flow.resourceOverrideAction === "clear") {
|
|
226
251
|
delete agentForPersistence.oauth_resource;
|
|
227
252
|
}
|
|
228
|
-
|
|
253
|
+
agentForPersistence.oauth_code_verifier = void 0;
|
|
254
|
+
agentForPersistence.oauth_discovery_state = void 0;
|
|
229
255
|
await agentStorage.saveAgent(agentForPersistence);
|
|
230
256
|
persisted = true;
|
|
231
257
|
}
|
|
@@ -237,6 +263,20 @@ async function completeWebOAuthFlow(opts) {
|
|
|
237
263
|
persisted
|
|
238
264
|
};
|
|
239
265
|
}
|
|
266
|
+
function assertSavedCredentialIssuers(agent, issuer) {
|
|
267
|
+
if (agent.oauth_tokens) assertOAuthCredentialIssuer(agent.oauth_tokens, issuer, !!agent.oauth_tokens.refresh_token);
|
|
268
|
+
if (agent.oauth_client) assertOAuthCredentialIssuer(agent.oauth_client, issuer, !!agent.oauth_client.client_secret);
|
|
269
|
+
}
|
|
270
|
+
function assertFrozenIssuer(flow) {
|
|
271
|
+
if (!flow.authorizationServerIssuer) {
|
|
272
|
+
throw new OAuthError(
|
|
273
|
+
"Pending OAuth flow lacks a validated authorization-server issuer. Start a new owner sign-in.",
|
|
274
|
+
"oauth_issuer_required",
|
|
275
|
+
flow.agentId
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
assertOAuthServerIssuer({ issuer: flow.authorizationServerIssuer }, flow.authorizationServerUrl);
|
|
279
|
+
}
|
|
240
280
|
function assertAgentUnchangedForFlow(agent, flow) {
|
|
241
281
|
if (!agent) {
|
|
242
282
|
throw new AgentVanishedDuringFlowError(flow.agentId);
|
|
@@ -244,6 +284,13 @@ function assertAgentUnchangedForFlow(agent, flow) {
|
|
|
244
284
|
if (agent.agent_uri !== flow.agentUrl) {
|
|
245
285
|
throw new AgentChangedDuringFlowError(flow.agentId);
|
|
246
286
|
}
|
|
287
|
+
if (!agent.oauth_client) throw new AgentChangedDuringFlowError(flow.agentId);
|
|
288
|
+
const currentClient = toMCPClientInfo(agent.oauth_client);
|
|
289
|
+
for (const key of ["client_id", "client_secret", "client_secret_expires_at", "issuer"]) {
|
|
290
|
+
if (currentClient[key] !== flow.clientInformation[key]) throw new AgentChangedDuringFlowError(flow.agentId);
|
|
291
|
+
}
|
|
292
|
+
assertFrozenIssuer(flow);
|
|
293
|
+
assertSavedCredentialIssuers(agent, flow.authorizationServerIssuer);
|
|
247
294
|
if (Object.prototype.hasOwnProperty.call(flow, "resourceOverrideSnapshot") && (agent.oauth_resource ?? null) !== flow.resourceOverrideSnapshot) {
|
|
248
295
|
throw new AgentChangedDuringFlowError(flow.agentId);
|
|
249
296
|
}
|
|
@@ -379,7 +426,7 @@ function createSsrfSafeOAuthFetch(trustedFetchFn, allowHttp) {
|
|
|
379
426
|
});
|
|
380
427
|
}
|
|
381
428
|
async function resolveClientInformation(args) {
|
|
382
|
-
const { agent, agentStorage, asUrl, asMetadata, clientMetadata, fetchFn, allowConfidentialClient } = args;
|
|
429
|
+
const { agent, agentStorage, asUrl, asMetadata, clientMetadata, fetchFn, allowConfidentialClient, issuer } = args;
|
|
383
430
|
if (agent.oauth_client) {
|
|
384
431
|
return toMCPClientInfo(agent.oauth_client);
|
|
385
432
|
}
|
|
@@ -390,16 +437,20 @@ async function resolveClientInformation(args) {
|
|
|
390
437
|
agent.id
|
|
391
438
|
);
|
|
392
439
|
}
|
|
393
|
-
const
|
|
440
|
+
const response = await registerClient(asUrl.toString(), {
|
|
394
441
|
metadata: asMetadata,
|
|
395
442
|
clientMetadata,
|
|
396
443
|
fetchFn
|
|
397
444
|
});
|
|
445
|
+
const registered = { ...response, issuer };
|
|
398
446
|
if (registered.client_secret && !allowConfidentialClient) {
|
|
399
447
|
throw new ConfidentialClientNotAllowedError(agent.id);
|
|
400
448
|
}
|
|
401
449
|
if (agentStorage) {
|
|
402
|
-
const fresh = await agentStorage.loadAgent(agent.id)
|
|
450
|
+
const fresh = await agentStorage.loadAgent(agent.id);
|
|
451
|
+
if (!fresh) throw new AgentVanishedDuringFlowError(agent.id);
|
|
452
|
+
if (fresh.agent_uri !== agent.agent_uri || fresh.oauth_client) throw new AgentChangedDuringFlowError(agent.id);
|
|
453
|
+
assertSavedCredentialIssuers(fresh, issuer);
|
|
403
454
|
fresh.oauth_client = fromMCPClientInfo(registered);
|
|
404
455
|
await agentStorage.saveAgent(fresh);
|
|
405
456
|
}
|
package/dist/lib/index.d.mts
CHANGED
|
@@ -186,7 +186,7 @@ export { getAuthToken, createAdCPHeaders, createMCPAuthHeaders, createAuthentica
|
|
|
186
186
|
export { parseWWWAuthenticate, decodeAccessTokenClaims, validateTokenAudience, type WWWAuthenticateChallenge, type DecodedJWTHeader, type DecodedJWTClaims, type DecodedAccessToken, type TokenAudienceResult, InvalidTokenError, InsufficientScopeError, } from './auth/oauth/index.mjs';
|
|
187
187
|
export { runAuthDiagnosis, AUTH_DIAGNOSIS_SCHEMA_VERSION, type DiagnoseOptions, type HttpCapture as DiagnosisHttpCapture, type DiagnosisStep, type Hypothesis as DiagnosisHypothesis, type HypothesisVerdict as DiagnosisHypothesisVerdict, type AuthDiagnosisReport, } from './auth/oauth/index.mjs';
|
|
188
188
|
export { NeedsAuthorizationError, discoverAuthorizationRequirements, hasValidatedMcpAuthorizationRequirements, createFileOAuthStorage, bindAgentStorage, getAgentStorage, unbindAgentStorage, type AuthorizationRequirements, type DiscoverAuthorizationOptions, type FileOAuthStorageOptions, } from './auth/oauth/index.mjs';
|
|
189
|
-
export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, MissingEnvSecretError, resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, type AgentOAuthClientCredentials, } from './auth/oauth/index.mjs';
|
|
189
|
+
export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, MissingEnvSecretError, resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, type AgentOAuthClientCredentials, AgentOAuthClientCredentialsSchema, } from './auth/oauth/index.mjs';
|
|
190
190
|
export { validateAgentUrl, validateAdCPResponse, getExpectedSchema, handleAdCPResponse } from './validation/index.mjs';
|
|
191
191
|
export { ProtocolClient, callMCPTool, callA2ATool, createA2AClientFromCardUrl, createMCPClient, createA2AClient, closeMCPConnections, closeOAuthConnections, bundleSupportsAdcpVersionField, BODY_SNIPPET_TIMEOUT_MS, OBSERVER_FLUSH_TIMEOUT_MS, sanitizeTransportHeaders, sanitizeTransportUrl, } from './protocols/index.mjs';
|
|
192
192
|
export { toReleasePrecisionWire, validateAdcpVersionWire } from './validation/schema-loader.mjs';
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -186,7 +186,7 @@ export { getAuthToken, createAdCPHeaders, createMCPAuthHeaders, createAuthentica
|
|
|
186
186
|
export { parseWWWAuthenticate, decodeAccessTokenClaims, validateTokenAudience, type WWWAuthenticateChallenge, type DecodedJWTHeader, type DecodedJWTClaims, type DecodedAccessToken, type TokenAudienceResult, InvalidTokenError, InsufficientScopeError, } from './auth/oauth';
|
|
187
187
|
export { runAuthDiagnosis, AUTH_DIAGNOSIS_SCHEMA_VERSION, type DiagnoseOptions, type HttpCapture as DiagnosisHttpCapture, type DiagnosisStep, type Hypothesis as DiagnosisHypothesis, type HypothesisVerdict as DiagnosisHypothesisVerdict, type AuthDiagnosisReport, } from './auth/oauth';
|
|
188
188
|
export { NeedsAuthorizationError, discoverAuthorizationRequirements, hasValidatedMcpAuthorizationRequirements, createFileOAuthStorage, bindAgentStorage, getAgentStorage, unbindAgentStorage, type AuthorizationRequirements, type DiscoverAuthorizationOptions, type FileOAuthStorageOptions, } from './auth/oauth';
|
|
189
|
-
export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, MissingEnvSecretError, resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, type AgentOAuthClientCredentials, } from './auth/oauth';
|
|
189
|
+
export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, MissingEnvSecretError, resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, type AgentOAuthClientCredentials, AgentOAuthClientCredentialsSchema, } from './auth/oauth';
|
|
190
190
|
export { validateAgentUrl, validateAdCPResponse, getExpectedSchema, handleAdCPResponse } from './validation';
|
|
191
191
|
export { ProtocolClient, callMCPTool, callA2ATool, createA2AClientFromCardUrl, createMCPClient, createA2AClient, closeMCPConnections, closeOAuthConnections, bundleSupportsAdcpVersionField, BODY_SNIPPET_TIMEOUT_MS, OBSERVER_FLUSH_TIMEOUT_MS, sanitizeTransportHeaders, sanitizeTransportUrl, } from './protocols';
|
|
192
192
|
export { toReleasePrecisionWire, validateAdcpVersionWire } from './validation/schema-loader';
|
package/dist/lib/index.js
CHANGED
|
@@ -48,6 +48,7 @@ __export(index_exports, {
|
|
|
48
48
|
AdagentsJsonSchema: () => import_wellknown_schemas.AdagentsJsonSchema,
|
|
49
49
|
AgentClient: () => import_AgentClient.AgentClient,
|
|
50
50
|
AgentNotFoundError: () => import_errors.AgentNotFoundError,
|
|
51
|
+
AgentOAuthClientCredentialsSchema: () => import_oauth4.AgentOAuthClientCredentialsSchema,
|
|
51
52
|
Asset: () => import_asset_builders.Asset,
|
|
52
53
|
AsyncHandler: () => import_AsyncHandler.AsyncHandler,
|
|
53
54
|
AuthenticationCredentialsRejectedError: () => import_errors.AuthenticationCredentialsRejectedError,
|
|
@@ -888,6 +889,7 @@ function createAdCPClientFromEnv() {
|
|
|
888
889
|
AdagentsJsonSchema,
|
|
889
890
|
AgentClient,
|
|
890
891
|
AgentNotFoundError,
|
|
892
|
+
AgentOAuthClientCredentialsSchema,
|
|
891
893
|
Asset,
|
|
892
894
|
AsyncHandler,
|
|
893
895
|
AuthenticationCredentialsRejectedError,
|