@intentface/latch-mcp 0.9.1

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.
@@ -0,0 +1,106 @@
1
+ /** Well-known suffixes for the two discovery document kinds we touch. */
2
+ const PROTECTED_RESOURCE = "oauth-protected-resource";
3
+ const AUTH_SERVER = "oauth-authorization-server";
4
+ const OPENID = "openid-configuration";
5
+ /** Apply `forceScheme` to a URL string, returning it unchanged on parse failure. */
6
+ function withScheme(value, scheme) {
7
+ if (!scheme || typeof value !== "string")
8
+ return value;
9
+ try {
10
+ const u = new URL(value);
11
+ if (u.protocol === `${scheme}:`)
12
+ return value;
13
+ u.protocol = `${scheme}:`;
14
+ return u.toString();
15
+ }
16
+ catch {
17
+ return value;
18
+ }
19
+ }
20
+ /** Strip a single trailing slash so an issuer matches the SDK's bare-origin form. */
21
+ function stripTrailingSlash(value) {
22
+ return typeof value === "string" && value.endsWith("/")
23
+ ? value.slice(0, -1)
24
+ : value;
25
+ }
26
+ function normalizeProtectedResource(doc, scheme) {
27
+ const out = { ...doc };
28
+ if (typeof out.resource === "string") {
29
+ out.resource = withScheme(out.resource, scheme);
30
+ }
31
+ if (Array.isArray(out.authorization_servers)) {
32
+ out.authorization_servers = out.authorization_servers.map((s) => typeof s === "string" ? withScheme(s, scheme) : s);
33
+ }
34
+ return out;
35
+ }
36
+ function normalizeAuthorizationServer(doc, scheme) {
37
+ const out = { ...doc };
38
+ // The SDK's expected issuer is always trailing-slash-free; canonicalize both
39
+ // scheme and the slash so `assertMetadataIssuerMatches` succeeds.
40
+ if (typeof out.issuer === "string") {
41
+ out.issuer = stripTrailingSlash(withScheme(out.issuer, scheme));
42
+ }
43
+ for (const key of [
44
+ "authorization_endpoint",
45
+ "token_endpoint",
46
+ "registration_endpoint",
47
+ "revocation_endpoint",
48
+ "introspection_endpoint",
49
+ "userinfo_endpoint",
50
+ "jwks_uri",
51
+ ]) {
52
+ if (typeof out[key] === "string") {
53
+ out[key] = withScheme(out[key], scheme);
54
+ }
55
+ }
56
+ return out;
57
+ }
58
+ export function createOAuthDiscoveryFetch(options = {}) {
59
+ const base = options.baseFetch ?? globalThis.fetch;
60
+ const hosts = options.hosts?.map((h) => h.toLowerCase());
61
+ return async (input, init) => {
62
+ const response = await base(input, init);
63
+ let url;
64
+ try {
65
+ url = new URL(typeof input === "string"
66
+ ? input
67
+ : input instanceof URL
68
+ ? input.href
69
+ : input.url);
70
+ }
71
+ catch {
72
+ return response;
73
+ }
74
+ // Only touch successful discovery documents on permitted hosts.
75
+ if (!response.ok)
76
+ return response;
77
+ if (hosts && !hosts.includes(url.hostname.toLowerCase()))
78
+ return response;
79
+ const path = url.pathname;
80
+ const isProtectedResource = path.includes(PROTECTED_RESOURCE);
81
+ const isAuthServer = path.includes(AUTH_SERVER) || path.includes(OPENID);
82
+ if (!isProtectedResource && !isAuthServer)
83
+ return response;
84
+ let doc;
85
+ try {
86
+ doc = await response.clone().json();
87
+ }
88
+ catch {
89
+ return response; // not JSON — leave as-is
90
+ }
91
+ if (typeof doc !== "object" || doc === null)
92
+ return response;
93
+ const normalized = isProtectedResource
94
+ ? normalizeProtectedResource(doc, options.forceScheme)
95
+ : normalizeAuthorizationServer(doc, options.forceScheme);
96
+ // Preserve status/headers; replace only the body.
97
+ const headers = new Headers(response.headers);
98
+ headers.delete("content-length");
99
+ return new Response(JSON.stringify(normalized), {
100
+ status: response.status,
101
+ statusText: response.statusText,
102
+ headers,
103
+ });
104
+ };
105
+ }
106
+ //# sourceMappingURL=oauth-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-fetch.js","sourceRoot":"","sources":["../src/oauth-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ import { type OAuthClientProvider, type OAuthClientMetadata, type OAuthClientInformation } from "@ai-sdk/mcp";
2
+ import type { Vault } from "@intentface/latch-core";
3
+ import type { FetchFunction } from "./oauth-fetch.js";
4
+ /**
5
+ * MCP OAuth (Authorization Code + PKCE), Vault-backed and per-tenant.
6
+ *
7
+ * The consent step is a browser redirect, so this is *chat-initiated,
8
+ * browser-completed, callback-finalized*: `start()` returns the IdP URL to send
9
+ * the user to; the host app's callback route calls `finish()` to exchange the
10
+ * code for tokens. All flow state (tokens, PKCE verifier, CSRF state, DCR client
11
+ * info) is stored in the Vault under the tenant's scope — never logged, never
12
+ * sent to the model. An authorization-server allowlist stops a malicious MCP
13
+ * server from pointing us at an attacker's IdP.
14
+ */
15
+ export interface McpOAuthConfig<P = unknown> {
16
+ /** Connection name — namespaces the Vault keys for this server. */
17
+ name: string;
18
+ /**
19
+ * MCP server URL (the protected resource). A function defers the lookup to
20
+ * flow time, per caller — used by UI-added connections whose URL lives in the
21
+ * caller's Vault and isn't known when the OAuth client is constructed.
22
+ */
23
+ serverUrl: string | ((principal: P) => string | Promise<string>);
24
+ /** Our callback URL, registered with the IdP. Must be exact. */
25
+ redirectUrl: string;
26
+ /** OAuth client metadata (DCR or pre-registered client). */
27
+ clientMetadata: OAuthClientMetadata;
28
+ /**
29
+ * A pre-registered OAuth client. When this resolves to a value,
30
+ * `clientInformation()` returns it and the SDK SKIPS Dynamic Client
31
+ * Registration — required for auth servers without DCR (Google, etc.). A
32
+ * function defers the lookup per caller (e.g. UI connections whose creds live
33
+ * in the caller's Vault).
34
+ */
35
+ clientInformation?: OAuthClientInformation | ((principal: P) => OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>);
36
+ /** Allowed OAuth authorization-server origins. Empty/undefined = allow any. */
37
+ allowedAuthorizationServers?: string[];
38
+ /**
39
+ * Requested scope string, if the server expects one.
40
+ *
41
+ * A function defers the lookup to flow time, per caller — necessary, not
42
+ * merely symmetric with `serverUrl`: a single `McpOAuth` instance is shared
43
+ * across callers (UI connections are cached by connection NAME while the
44
+ * connection record itself is per-caller), so a static string would request
45
+ * one caller's scope on another caller's behalf. Resolve per principal and
46
+ * that cannot happen.
47
+ */
48
+ scope?: string | ((principal: P) => string | undefined | Promise<string | undefined>);
49
+ /**
50
+ * Optionally validate/normalize the RFC 8707 resource URL discovered from the
51
+ * server's metadata. Default (when omitted) requires an exact origin match;
52
+ * override to tolerate e.g. a proxied http/https scheme difference. Return the
53
+ * resource URL to use, or undefined to omit the resource parameter.
54
+ */
55
+ validateResourceURL?: (serverUrl: string | URL, resource?: string) => URL | undefined | Promise<URL | undefined>;
56
+ /**
57
+ * Custom fetch for the OAuth flow (discovery, token exchange, refresh). Use
58
+ * `createOAuthDiscoveryFetch` to normalize a provider's non-conformant
59
+ * discovery documents. Pass the SAME fetch to the host connection so the
60
+ * transport's on-401 re-auth uses it too.
61
+ */
62
+ fetch?: FetchFunction;
63
+ /**
64
+ * Extra query params appended to the authorization redirect URL — provider
65
+ * extensions the SDK doesn't model, e.g. Google's
66
+ * `{ access_type: "offline", prompt: "consent" }` to be issued a refresh
67
+ * token. Applied on top of the SDK-built URL, so they can also override a
68
+ * standard param if a provider needs that.
69
+ */
70
+ authorizationParams?: Record<string, string>;
71
+ }
72
+ /** Decode the app payload baked into an OAuth `state` by `start({ state })`. */
73
+ export declare function decodeOAuthState(state: string | null | undefined): Record<string, unknown> | undefined;
74
+ /**
75
+ * A Vault-backed `OAuthClientProvider` for one tenant + connection. Returned
76
+ * alongside `takeAuthorizationUrl()`, which yields the URL captured during a
77
+ * `REDIRECT` so the route can 302 the browser to it.
78
+ */
79
+ export declare function createVaultOAuthProvider<P>(opts: {
80
+ vault: Vault<P>;
81
+ principal: P;
82
+ config: McpOAuthConfig<P>;
83
+ /** App context to bake into the OAuth `state` (recovered on callback). */
84
+ stateData?: Record<string, unknown>;
85
+ }): {
86
+ provider: OAuthClientProvider;
87
+ takeAuthorizationUrl: () => URL | undefined;
88
+ };
89
+ export type StartResult = {
90
+ status: "redirect";
91
+ authorizationUrl: string;
92
+ } | {
93
+ status: "authorized";
94
+ };
95
+ export interface McpOAuth<P> {
96
+ /** Whether this caller already holds tokens for the connection. */
97
+ isAuthorized(principal: P): Promise<boolean>;
98
+ /**
99
+ * Begin the flow: returns the IdP URL to redirect to, or 'authorized' if
100
+ * tokens already exist. `state` is app context (e.g. `{ chatId, approvalId }`)
101
+ * baked into the OAuth state and recoverable on callback via `decodeOAuthState`.
102
+ */
103
+ start(principal: P, opts?: {
104
+ state?: Record<string, unknown>;
105
+ }): Promise<StartResult>;
106
+ /** Finalize on the callback: exchange the code for tokens (stored in the Vault). */
107
+ finish(principal: P, params: {
108
+ code: string;
109
+ state?: string;
110
+ }): Promise<{
111
+ status: "authorized";
112
+ }>;
113
+ /** The Vault-backed provider for the *use* phase (auto-refreshes tokens). */
114
+ provider(principal: P): OAuthClientProvider;
115
+ }
116
+ export declare function createMcpOAuth<P>(opts: {
117
+ vault: Vault<P>;
118
+ config: McpOAuthConfig<P>;
119
+ }): McpOAuth<P>;
120
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
package/dist/oauth.js ADDED
@@ -0,0 +1,202 @@
1
+ import { auth, } from "@ai-sdk/mcp";
2
+ const vaultKey = (name, part) => `mcp_oauth:${name}:${part}`;
3
+ function randomState() {
4
+ const bytes = crypto.getRandomValues(new Uint8Array(16));
5
+ let s = "";
6
+ for (const b of bytes)
7
+ s += b.toString(16).padStart(2, "0");
8
+ return s;
9
+ }
10
+ // --- state encoding ---------------------------------------------------------
11
+ // The OAuth `state` is `<csrf>.<payload>`: a random CSRF nonce, then optional
12
+ // base64url JSON carrying app context (which chat/approval to resume after the
13
+ // callback). The SDK round-trips the whole string and checks it against the
14
+ // stored value, so the payload is CSRF-protected too; we decode it on callback.
15
+ function b64urlEncode(json) {
16
+ const s = JSON.stringify(json);
17
+ let bin = "";
18
+ for (const ch of new TextEncoder().encode(s))
19
+ bin += String.fromCharCode(ch);
20
+ return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
21
+ }
22
+ function b64urlDecode(part) {
23
+ const b64 = part.replace(/-/g, "+").replace(/_/g, "/");
24
+ const bin = atob(b64);
25
+ const bytes = new Uint8Array(bin.length);
26
+ for (let i = 0; i < bin.length; i++)
27
+ bytes[i] = bin.charCodeAt(i);
28
+ return JSON.parse(new TextDecoder().decode(bytes));
29
+ }
30
+ /** Decode the app payload baked into an OAuth `state` by `start({ state })`. */
31
+ export function decodeOAuthState(state) {
32
+ if (!state)
33
+ return undefined;
34
+ const dot = state.indexOf(".");
35
+ if (dot === -1)
36
+ return undefined;
37
+ try {
38
+ const decoded = b64urlDecode(state.slice(dot + 1));
39
+ return typeof decoded === "object" && decoded
40
+ ? decoded
41
+ : undefined;
42
+ }
43
+ catch {
44
+ return undefined;
45
+ }
46
+ }
47
+ /**
48
+ * A Vault-backed `OAuthClientProvider` for one tenant + connection. Returned
49
+ * alongside `takeAuthorizationUrl()`, which yields the URL captured during a
50
+ * `REDIRECT` so the route can 302 the browser to it.
51
+ */
52
+ export function createVaultOAuthProvider(opts) {
53
+ const { vault, principal, config, stateData } = opts;
54
+ const k = (part) => vaultKey(config.name, part);
55
+ let captured;
56
+ const provider = {
57
+ get redirectUrl() {
58
+ return config.redirectUrl;
59
+ },
60
+ get clientMetadata() {
61
+ return config.clientMetadata;
62
+ },
63
+ async tokens() {
64
+ const raw = await vault.get(principal, k("tokens"));
65
+ return raw ? JSON.parse(raw) : undefined;
66
+ },
67
+ async saveTokens(tokens) {
68
+ await vault.set(principal, k("tokens"), JSON.stringify(tokens));
69
+ },
70
+ async saveCodeVerifier(verifier) {
71
+ await vault.set(principal, k("verifier"), verifier);
72
+ },
73
+ async codeVerifier() {
74
+ const v = await vault.get(principal, k("verifier"));
75
+ if (!v)
76
+ throw new Error(`MCP OAuth "${config.name}": missing PKCE code verifier`);
77
+ return v;
78
+ },
79
+ async clientInformation() {
80
+ // A pre-registered client (config) wins and skips DCR; else use the
81
+ // DCR-registered client stored in the Vault.
82
+ if (config.clientInformation) {
83
+ const ci = typeof config.clientInformation === "function"
84
+ ? await config.clientInformation(principal)
85
+ : config.clientInformation;
86
+ if (ci)
87
+ return ci;
88
+ }
89
+ const raw = await vault.get(principal, k("client"));
90
+ return raw ? JSON.parse(raw) : undefined;
91
+ },
92
+ async saveClientInformation(info) {
93
+ await vault.set(principal, k("client"), JSON.stringify(info));
94
+ },
95
+ // Persist the authorization-server metadata discovered during `start` so the
96
+ // callback's code exchange can read it back. Required for pre-registered
97
+ // clients (DCR skipped): without these, the SDK would otherwise stash the AS
98
+ // info onto the client record, which our config-provided `clientInformation`
99
+ // shadows — leaving the exchange with no stored AS metadata.
100
+ async authorizationServerInformation() {
101
+ const raw = await vault.get(principal, k("as_info"));
102
+ return raw ? JSON.parse(raw) : undefined;
103
+ },
104
+ async saveAuthorizationServerInformation(info) {
105
+ await vault.set(principal, k("as_info"), JSON.stringify(info));
106
+ },
107
+ state() {
108
+ const csrf = randomState();
109
+ return stateData && Object.keys(stateData).length > 0
110
+ ? `${csrf}.${b64urlEncode(stateData)}`
111
+ : csrf;
112
+ },
113
+ async saveState(state) {
114
+ await vault.set(principal, k("state"), state);
115
+ },
116
+ async storedState() {
117
+ return (await vault.get(principal, k("state"))) ?? undefined;
118
+ },
119
+ redirectToAuthorization(url) {
120
+ captured = url; // the route reads this and issues the 302
121
+ },
122
+ // Passthrough: omitted → SDK default (exact origin match).
123
+ validateResourceURL: config.validateResourceURL
124
+ ? async (serverUrl, resource) => config.validateResourceURL(serverUrl, resource)
125
+ : undefined,
126
+ validateAuthorizationServerURL(serverUrl, authorizationServerUrl) {
127
+ const allow = config.allowedAuthorizationServers;
128
+ if (!allow || allow.length === 0)
129
+ return; // not configured → allow
130
+ const origin = new URL(authorizationServerUrl).origin;
131
+ if (!allow.includes(origin)) {
132
+ throw new Error(`MCP OAuth "${config.name}": authorization server ${origin} is not allowed`);
133
+ }
134
+ },
135
+ async invalidateCredentials(which) {
136
+ const parts = which === "all"
137
+ ? ["tokens", "verifier", "state", "client", "as_info"]
138
+ : which === "tokens"
139
+ ? ["tokens"]
140
+ : which === "verifier"
141
+ ? ["verifier"]
142
+ : ["client"];
143
+ await Promise.all(parts.map((p) => vault.delete(principal, k(p))));
144
+ },
145
+ };
146
+ return { provider, takeAuthorizationUrl: () => captured };
147
+ }
148
+ export function createMcpOAuth(opts) {
149
+ const { vault, config } = opts;
150
+ const resolveServerUrl = (principal) => typeof config.serverUrl === "function" ? config.serverUrl(principal) : config.serverUrl;
151
+ const resolveScope = (principal) => typeof config.scope === "function" ? config.scope(principal) : config.scope;
152
+ return {
153
+ async isAuthorized(principal) {
154
+ return vault.has(principal, vaultKey(config.name, "tokens"));
155
+ },
156
+ async start(principal, opts) {
157
+ const { provider, takeAuthorizationUrl } = createVaultOAuthProvider({
158
+ vault,
159
+ principal,
160
+ config,
161
+ stateData: opts?.state,
162
+ });
163
+ const result = await auth(provider, {
164
+ serverUrl: await resolveServerUrl(principal),
165
+ scope: await resolveScope(principal),
166
+ fetchFn: config.fetch,
167
+ });
168
+ if (result === "AUTHORIZED")
169
+ return { status: "authorized" };
170
+ const url = takeAuthorizationUrl();
171
+ if (!url) {
172
+ throw new Error(`MCP OAuth "${config.name}": authorization required but no redirect URL was produced`);
173
+ }
174
+ for (const [key, value] of Object.entries(config.authorizationParams ?? {})) {
175
+ url.searchParams.set(key, value);
176
+ }
177
+ return { status: "redirect", authorizationUrl: url.toString() };
178
+ },
179
+ async finish(principal, params) {
180
+ const { provider } = createVaultOAuthProvider({ vault, principal, config });
181
+ await auth(provider, {
182
+ serverUrl: await resolveServerUrl(principal),
183
+ authorizationCode: params.code,
184
+ callbackState: params.state,
185
+ fetchFn: config.fetch,
186
+ });
187
+ // Single-use flow state: the CSRF state and PKCE verifier are spent the
188
+ // moment the exchange succeeds — delete them so a replayed callback URL
189
+ // finds no stored flow material to validate against. (The platform's
190
+ // oauth2 path already does this; tokens/client/as_info must survive.)
191
+ await Promise.all([
192
+ vault.delete(principal, vaultKey(config.name, "state")),
193
+ vault.delete(principal, vaultKey(config.name, "verifier")),
194
+ ]);
195
+ return { status: "authorized" };
196
+ },
197
+ provider(principal) {
198
+ return createVaultOAuthProvider({ vault, principal, config }).provider;
199
+ },
200
+ };
201
+ }
202
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=oauth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.test.d.ts","sourceRoot":"","sources":["../src/oauth.test.ts"],"names":[],"mappings":""}