@agent-native/core 0.26.7 → 0.26.9
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/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +108 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/mcp/build-server.d.ts +1 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +4 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/oauth-route.d.ts.map +1 -1
- package/dist/mcp/oauth-route.js +1 -0
- package/dist/mcp/oauth-route.js.map +1 -1
- package/dist/mcp/oauth-token.d.ts +3 -0
- package/dist/mcp/oauth-token.d.ts.map +1 -1
- package/dist/mcp/oauth-token.js +2 -0
- package/dist/mcp/oauth-token.js.map +1 -1
- package/docs/content/skills-guide.md +7 -4
- package/docs/content/template-design.md +11 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-route.js","sourceRoot":"","sources":["../../src/mcp/oauth-route.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Standard remote MCP OAuth 2.1 endpoints.\n *\n * These routes let MCP hosts such as Claude Code and ChatGPT authenticate\n * through their native remote-MCP OAuth flow instead of pasting bearer tokens.\n * The issued access tokens are audience-bound to `/_agent-native/mcp`, carry\n * the same user/org identity as the existing connect flow, and are mediated by\n * `verifyAuth` before any MCP tool/resource request runs.\n */\n\nimport type { H3Event } from \"h3\";\nimport { getHeader, getMethod, getQuery, setResponseStatus } from \"h3\";\nimport { createHash, createHmac, timingSafeEqual } from \"node:crypto\";\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getConfiguredLoginHtml, getSession } from \"../server/auth.js\";\nimport { getAuthSecret } from \"../server/better-auth-instance.js\";\nimport { getOrgDomain } from \"../org/context.js\";\nimport {\n createOAuthCode,\n createOAuthRefreshToken,\n consumeOAuthCode,\n generateOpaqueToken,\n getOAuthClient,\n getOAuthCode,\n getOAuthRefreshToken,\n registerOAuthClient,\n rotateOAuthRefreshToken,\n} from \"./oauth-store.js\";\nimport {\n MCP_OAUTH_DEFAULT_SCOPE,\n MCP_OAUTH_SCOPES,\n normalizeOAuthScope,\n signMcpOAuthAccessToken,\n} from \"./oauth-token.js\";\n\nexport interface McpOAuthRouteOptions {\n appId?: string;\n appName?: string;\n}\n\nfunction json(body: unknown, status = 200): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": \"no-store\",\n Pragma: \"no-cache\",\n },\n });\n}\n\nfunction html(body: string, status = 200): Response {\n return new Response(body, {\n status,\n headers: {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n },\n });\n}\n\nfunction redirect(location: string): Response {\n return new Response(null, {\n status: 302,\n headers: { Location: location, \"Cache-Control\": \"no-store\" },\n });\n}\n\nfunction isSameOriginPost(event: H3Event): boolean {\n const origin = getHeader(event, \"origin\");\n if (!origin) return true;\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return false;\n try {\n return new URL(origin).origin === new URL(issuer).origin;\n } catch {\n return false;\n }\n}\n\nfunction oauthError(\n error: string,\n description: string,\n status = 400,\n): Response {\n return json({ error, error_description: description }, status);\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\nfunction normalizeBasePath(raw: string | undefined): string {\n const trimmed = (raw ?? \"\").trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n const withSlash = trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n return withSlash.replace(/\\/+$/, \"\");\n}\n\nfunction configuredBasePath(): string {\n return normalizeBasePath(\n process.env.APP_BASE_PATH || process.env.VITE_APP_BASE_PATH,\n );\n}\n\nfunction deriveOrigin(event: H3Event): string {\n const forwardedProto = getHeader(event, \"x-forwarded-proto\");\n const host = getHeader(event, \"x-forwarded-host\") || getHeader(event, \"host\");\n const proto =\n forwardedProto?.split(\",\")[0]?.trim() ||\n (host && /^(localhost|127\\.0\\.0\\.1|\\[::1\\])(:|$)/.test(host)\n ? \"http\"\n : \"https\");\n return host ? `${proto}://${host}` : \"\";\n}\n\nexport function getMcpOAuthIssuer(event: H3Event): string | undefined {\n const origin = deriveOrigin(event);\n if (!origin) return undefined;\n return `${origin}${configuredBasePath()}`;\n}\n\nexport function getMcpOAuthResource(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return undefined;\n return `${issuer}/_agent-native/mcp`;\n}\n\nexport function getMcpOAuthProtectedResourceMetadataUrl(\n event: H3Event,\n): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return undefined;\n return `${issuer}/.well-known/oauth-protected-resource`;\n}\n\nexport function buildMcpOAuthChallenge(event: H3Event): string {\n const metadata = getMcpOAuthProtectedResourceMetadataUrl(event);\n const scope = MCP_OAUTH_DEFAULT_SCOPE;\n return metadata\n ? `Bearer resource_metadata=\"${metadata}\", scope=\"${scope}\"`\n : `Bearer scope=\"${scope}\"`;\n}\n\nfunction authorizationEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/authorize` : undefined;\n}\n\nfunction tokenEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/token` : undefined;\n}\n\nfunction registrationEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/register` : undefined;\n}\n\nexport function handleMcpOAuthProtectedResourceMetadata(\n event: H3Event,\n): Response {\n if (getMethod(event) !== \"GET\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const resource = getMcpOAuthResource(event);\n const issuer = getMcpOAuthIssuer(event);\n if (!resource || !issuer) {\n return oauthError(\"server_error\", \"Unable to derive MCP resource\", 500);\n }\n return json({\n resource,\n authorization_servers: [issuer],\n scopes_supported: MCP_OAUTH_SCOPES,\n resource_documentation: issuer,\n });\n}\n\nexport function handleMcpOAuthAuthorizationServerMetadata(\n event: H3Event,\n): Response {\n if (getMethod(event) !== \"GET\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const issuer = getMcpOAuthIssuer(event);\n const authorize = authorizationEndpoint(event);\n const token = tokenEndpoint(event);\n const register = registrationEndpoint(event);\n if (!issuer || !authorize || !token || !register) {\n return oauthError(\"server_error\", \"Unable to derive OAuth endpoints\", 500);\n }\n return json({\n issuer,\n authorization_endpoint: authorize,\n token_endpoint: token,\n registration_endpoint: register,\n response_types_supported: [\"code\"],\n grant_types_supported: [\"authorization_code\", \"refresh_token\"],\n code_challenge_methods_supported: [\"S256\"],\n token_endpoint_auth_methods_supported: [\"none\"],\n scopes_supported: MCP_OAUTH_SCOPES,\n });\n}\n\nfunction isAllowedRedirectUri(value: unknown): value is string {\n if (typeof value !== \"string\" || value.length > 2048) return false;\n try {\n const url = new URL(value);\n if (url.hash) return false;\n if (url.username || url.password) return false;\n if (url.protocol === \"https:\") return true;\n if (url.protocol !== \"http:\") return false;\n return (\n url.hostname === \"localhost\" ||\n url.hostname === \"127.0.0.1\" ||\n url.hostname === \"::1\" ||\n url.hostname === \"[::1]\"\n );\n } catch {\n return false;\n }\n}\n\nfunction parseStringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : [];\n}\n\nasync function handleRegister(event: H3Event): Promise<Response> {\n if (getMethod(event) !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const body = ((await readBody(event).catch(() => ({}))) ?? {}) as Record<\n string,\n unknown\n >;\n const redirectUris = parseStringArray(body.redirect_uris);\n if (\n redirectUris.length === 0 ||\n redirectUris.length > 20 ||\n !redirectUris.every(isAllowedRedirectUri)\n ) {\n return oauthError(\n \"invalid_client_metadata\",\n \"redirect_uris must contain valid HTTPS or localhost callback URLs\",\n );\n }\n\n const grantTypes = parseStringArray(body.grant_types);\n if (\n grantTypes.length &&\n !grantTypes.every(\n (g) => g === \"authorization_code\" || g === \"refresh_token\",\n )\n ) {\n return oauthError(\"invalid_client_metadata\", \"Unsupported grant_type\");\n }\n const responseTypes = parseStringArray(body.response_types);\n if (responseTypes.length && !responseTypes.every((r) => r === \"code\")) {\n return oauthError(\"invalid_client_metadata\", \"Unsupported response_type\");\n }\n const method =\n typeof body.token_endpoint_auth_method === \"string\"\n ? body.token_endpoint_auth_method\n : \"none\";\n if (method !== \"none\") {\n return oauthError(\n \"invalid_client_metadata\",\n \"Only public OAuth clients are supported\",\n );\n }\n\n const clientName =\n typeof body.client_name === \"string\"\n ? body.client_name.trim().slice(0, 120)\n : null;\n let client;\n try {\n client = await registerOAuthClient({\n clientName,\n redirectUris: [...new Set(redirectUris)],\n grantTypes: grantTypes.length ? grantTypes : undefined,\n responseTypes: responseTypes.length ? responseTypes : undefined,\n tokenEndpointAuthMethod: method,\n });\n } catch (err: any) {\n if (err?.message === \"RATE_LIMITED\") {\n return oauthError(\"slow_down\", \"Too many client registrations\", 429);\n }\n throw err;\n }\n return json(\n {\n client_id: client.clientId,\n client_id_issued_at: Math.floor((client.createdAt ?? Date.now()) / 1000),\n client_name: client.clientName ?? undefined,\n redirect_uris: client.redirectUris,\n grant_types: client.grantTypes,\n response_types: client.responseTypes,\n token_endpoint_auth_method: client.tokenEndpointAuthMethod,\n },\n 201,\n );\n}\n\nfunction redirectWithOAuthError(params: {\n redirectUri: string;\n state?: string;\n error: string;\n description?: string;\n}): Response {\n const url = new URL(params.redirectUri);\n url.searchParams.set(\"error\", params.error);\n if (params.description) {\n url.searchParams.set(\"error_description\", params.description);\n }\n if (params.state) url.searchParams.set(\"state\", params.state);\n return redirect(url.toString());\n}\n\nfunction redirectWithCode(params: {\n redirectUri: string;\n code: string;\n state?: string;\n}): Response {\n const url = new URL(params.redirectUri);\n url.searchParams.set(\"code\", params.code);\n if (params.state) url.searchParams.set(\"state\", params.state);\n return redirect(url.toString());\n}\n\nfunction codeChallengeForVerifier(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n return aa.length === bb.length && timingSafeEqual(aa, bb);\n}\n\nfunction base64UrlEncode(value: Buffer | string): string {\n const buf = typeof value === \"string\" ? Buffer.from(value, \"utf8\") : value;\n return buf.toString(\"base64url\");\n}\n\nfunction base64UrlDecode(value: string): Buffer {\n return Buffer.from(value, \"base64url\");\n}\n\nfunction consentSigningKey(): string {\n return process.env.A2A_SECRET || getAuthSecret();\n}\n\nfunction consentPayload(params: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n}): string {\n return JSON.stringify({\n ...params,\n exp: Math.floor(Date.now() / 1000) + 10 * 60,\n });\n}\n\nfunction signConsentToken(params: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n}): string {\n const payload = base64UrlEncode(consentPayload(params));\n const sig = base64UrlEncode(\n createHmac(\"sha256\", consentSigningKey()).update(payload).digest(),\n );\n return `${payload}.${sig}`;\n}\n\nfunction verifyConsentToken(\n token: string | undefined,\n expected: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n },\n): boolean {\n if (!token || !token.includes(\".\")) return false;\n const [payload, sig] = token.split(\".\", 2);\n if (!payload || !sig) return false;\n const expectedSig = base64UrlEncode(\n createHmac(\"sha256\", consentSigningKey()).update(payload).digest(),\n );\n if (!safeEqual(sig, expectedSig)) return false;\n try {\n const parsed = JSON.parse(base64UrlDecode(payload).toString(\"utf8\"));\n return (\n parsed.email === expected.email &&\n parsed.clientId === expected.clientId &&\n parsed.redirectUri === expected.redirectUri &&\n parsed.resource === expected.resource &&\n parsed.scope === expected.scope &&\n parsed.codeChallenge === expected.codeChallenge &&\n typeof parsed.exp === \"number\" &&\n parsed.exp * 1000 >= Date.now()\n );\n } catch {\n return false;\n }\n}\n\nfunction isValidCodeVerifier(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length >= 43 &&\n value.length <= 128 &&\n /^[A-Za-z0-9._~-]+$/.test(value)\n );\n}\n\nfunction renderConsentPage(params: {\n appName: string;\n email: string;\n clientName: string;\n scopes: string[];\n fields: Record<string, string>;\n}): string {\n const hidden = Object.entries(params.fields)\n .map(\n ([key, value]) =>\n `<input type=\"hidden\" name=\"${escapeHtml(key)}\" value=\"${escapeHtml(value)}\">`,\n )\n .join(\"\\n\");\n const scopes = params.scopes\n .map((scope) => `<li><code>${escapeHtml(scope)}</code></li>`)\n .join(\"\");\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Authorize ${escapeHtml(params.appName)}</title>\n<style>\n :root { color-scheme: dark; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; background: #09090b; color: #f4f4f5; }\n body { min-height: 100vh; display: grid; place-items: center; margin: 0; padding: 24px; }\n main { width: min(520px, 100%); border: 1px solid #27272a; border-radius: 8px; background: #111113; padding: 24px; box-shadow: 0 24px 80px rgba(0,0,0,.35); }\n h1 { font-size: 22px; line-height: 1.2; margin: 0 0 10px; }\n p { color: #a1a1aa; line-height: 1.5; margin: 0 0 18px; }\n ul { margin: 0 0 22px; padding-left: 22px; color: #d4d4d8; }\n code { color: #67e8f9; }\n .actions { display: flex; gap: 10px; justify-content: flex-end; }\n button { border: 0; border-radius: 6px; padding: 10px 14px; font-weight: 650; cursor: pointer; }\n .primary { background: #f4f4f5; color: #09090b; }\n .secondary { background: #27272a; color: #f4f4f5; }\n</style>\n</head>\n<body>\n<main>\n <h1>Authorize ${escapeHtml(params.clientName)}</h1>\n <p>${escapeHtml(params.appName)} will let this MCP client act as ${escapeHtml(params.email)} for these scopes:</p>\n <ul>${scopes}</ul>\n <form method=\"post\">\n ${hidden}\n <div class=\"actions\">\n <button class=\"secondary\" type=\"submit\" name=\"decision\" value=\"deny\">Deny</button>\n <button class=\"primary\" type=\"submit\" name=\"decision\" value=\"approve\">Authorize</button>\n </div>\n </form>\n</main>\n</body>\n</html>`;\n}\n\nasync function resolveOrgDomain(\n orgId: string | undefined,\n): Promise<string | undefined> {\n if (!orgId) return undefined;\n try {\n return (await getOrgDomain(orgId)) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function readOAuthParams(\n event: H3Event,\n): Promise<Record<string, string>> {\n if (getMethod(event) === \"GET\") {\n const query = getQuery(event);\n return Object.fromEntries(\n Object.entries(query).flatMap(([key, value]) =>\n typeof value === \"string\" ? [[key, value]] : [],\n ),\n );\n }\n const body = await readBody(event).catch(() => ({}));\n if (typeof body === \"string\") {\n return Object.fromEntries(new URLSearchParams(body));\n }\n if (body && typeof body === \"object\") {\n return Object.fromEntries(\n Object.entries(body as Record<string, unknown>).flatMap(([key, value]) =>\n typeof value === \"string\" ? [[key, value]] : [],\n ),\n );\n }\n return {};\n}\n\nasync function handleAuthorize(\n event: H3Event,\n options: McpOAuthRouteOptions,\n): Promise<Response> {\n const method = getMethod(event);\n if (method !== \"GET\" && method !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n if (method === \"POST\" && !isSameOriginPost(event)) {\n return oauthError(\n \"invalid_request\",\n \"Cross-origin authorize POST rejected\",\n 403,\n );\n }\n const params = await readOAuthParams(event);\n const state = params.state;\n const clientId = params.client_id;\n const redirectUri = params.redirect_uri;\n const resource = params.resource || getMcpOAuthResource(event);\n const expectedResource = getMcpOAuthResource(event);\n\n if (params.response_type !== \"code\") {\n return oauthError(\n \"unsupported_response_type\",\n \"response_type must be code\",\n );\n }\n if (!clientId || !redirectUri || !resource || resource !== expectedResource) {\n return oauthError(\"invalid_request\", \"Invalid OAuth authorization request\");\n }\n if (params.code_challenge_method !== \"S256\" || !params.code_challenge) {\n return oauthError(\"invalid_request\", \"PKCE S256 is required\");\n }\n\n const client = await getOAuthClient(clientId);\n if (!client || !client.redirectUris.includes(redirectUri)) {\n return oauthError(\"invalid_client\", \"Unknown client or redirect_uri\");\n }\n\n const session = await getSession(event);\n if (!session?.email) {\n if (params.prompt === \"none\") {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"login_required\",\n });\n }\n const loginHtml = getConfiguredLoginHtml(event);\n return loginHtml\n ? html(loginHtml, 200)\n : oauthError(\"login_required\", \"Sign in required\", 401);\n }\n\n const scope = normalizeOAuthScope(params.scope);\n if (!scope) {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"invalid_scope\",\n });\n }\n if (method === \"GET\") {\n return html(\n renderConsentPage({\n appName: options.appName || options.appId || \"Agent Native\",\n email: session.email,\n clientName: client.clientName || client.clientId,\n scopes: scope.split(/\\s+/),\n fields: {\n response_type: \"code\",\n client_id: clientId,\n redirect_uri: redirectUri,\n resource,\n scope,\n state: state ?? \"\",\n code_challenge: params.code_challenge,\n code_challenge_method: \"S256\",\n consent_token: signConsentToken({\n email: session.email,\n clientId,\n redirectUri,\n resource,\n scope,\n codeChallenge: params.code_challenge,\n }),\n },\n }),\n );\n }\n\n if (\n !verifyConsentToken(params.consent_token, {\n email: session.email,\n clientId,\n redirectUri,\n resource,\n scope,\n codeChallenge: params.code_challenge,\n })\n ) {\n return oauthError(\"invalid_request\", \"Invalid authorization consent token\");\n }\n\n if (params.decision !== \"approve\") {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"access_denied\",\n });\n }\n\n const orgDomain = await resolveOrgDomain(session.orgId);\n const code = await createOAuthCode({\n clientId,\n redirectUri,\n codeChallenge: params.code_challenge,\n codeChallengeMethod: \"S256\",\n ownerEmail: session.email,\n orgId: session.orgId ?? null,\n orgDomain: orgDomain ?? null,\n scope,\n resource,\n });\n return redirectWithCode({ redirectUri, state, code: code.code });\n}\n\nasync function issueTokenSet(params: {\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n clientId: string;\n scope: string;\n resource: string;\n issuer: string;\n}): Promise<Record<string, unknown>> {\n const refreshToken = generateOpaqueToken();\n await createOAuthRefreshToken({\n refreshToken,\n clientId: params.clientId,\n ownerEmail: params.ownerEmail,\n orgId: params.orgId ?? null,\n orgDomain: params.orgDomain ?? null,\n scope: params.scope,\n resource: params.resource,\n });\n const accessToken = await signMcpOAuthAccessToken(params);\n return {\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: 3600,\n refresh_token: refreshToken,\n scope: params.scope,\n };\n}\n\nasync function handleAuthorizationCodeGrant(\n event: H3Event,\n body: Record<string, string>,\n): Promise<Response> {\n const code = body.code;\n const clientId = body.client_id;\n const redirectUri = body.redirect_uri;\n const verifier = body.code_verifier;\n if (!code || !clientId || !redirectUri || !isValidCodeVerifier(verifier)) {\n return oauthError(\"invalid_request\", \"Missing authorization-code fields\");\n }\n const row = await getOAuthCode(code);\n if (!row) return oauthError(\"invalid_grant\", \"Invalid or expired code\");\n if (row.clientId !== clientId || row.redirectUri !== redirectUri) {\n return oauthError(\"invalid_grant\", \"Code was issued to another client\");\n }\n const expectedChallenge = codeChallengeForVerifier(verifier);\n if (!safeEqual(expectedChallenge, row.codeChallenge)) {\n return oauthError(\"invalid_grant\", \"PKCE verification failed\");\n }\n const consumed = await consumeOAuthCode(code);\n if (!consumed) return oauthError(\"invalid_grant\", \"Invalid or expired code\");\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer)\n return oauthError(\"server_error\", \"Unable to derive issuer\", 500);\n return json(\n await issueTokenSet({\n ownerEmail: row.ownerEmail,\n orgId: row.orgId,\n orgDomain: row.orgDomain,\n clientId,\n scope: row.scope,\n resource: row.resource,\n issuer,\n }),\n );\n}\n\nasync function handleRefreshTokenGrant(\n event: H3Event,\n body: Record<string, string>,\n): Promise<Response> {\n const refreshToken = body.refresh_token;\n const clientId = body.client_id;\n if (!refreshToken) {\n return oauthError(\"invalid_request\", \"refresh_token is required\");\n }\n if (!clientId) {\n return oauthError(\"invalid_request\", \"client_id is required\");\n }\n const existing = await getOAuthRefreshToken(refreshToken);\n if (!existing) return oauthError(\"invalid_grant\", \"Invalid refresh token\");\n if (existing.clientId !== clientId) {\n return oauthError(\n \"invalid_grant\",\n \"Refresh token belongs to another client\",\n );\n }\n const nextRefreshToken = generateOpaqueToken();\n const row = await rotateOAuthRefreshToken({\n oldRefreshToken: refreshToken,\n newRefreshToken: nextRefreshToken,\n });\n if (!row) return oauthError(\"invalid_grant\", \"Invalid refresh token\");\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer)\n return oauthError(\"server_error\", \"Unable to derive issuer\", 500);\n const accessToken = await signMcpOAuthAccessToken({\n ownerEmail: row.ownerEmail,\n orgDomain: row.orgDomain,\n clientId: row.clientId,\n scope: row.scope,\n resource: row.resource,\n issuer,\n });\n return json({\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: 3600,\n refresh_token: nextRefreshToken,\n scope: row.scope,\n });\n}\n\nasync function handleToken(event: H3Event): Promise<Response> {\n if (getMethod(event) !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const body = await readOAuthParams(event);\n switch (body.grant_type) {\n case \"authorization_code\":\n return handleAuthorizationCodeGrant(event, body);\n case \"refresh_token\":\n return handleRefreshTokenGrant(event, body);\n default:\n return oauthError(\"unsupported_grant_type\", \"Unsupported grant_type\");\n }\n}\n\nexport async function handleMcpOAuth(\n event: H3Event,\n subpath: string,\n options: McpOAuthRouteOptions = {},\n): Promise<Response> {\n const path = subpath.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n try {\n if (path === \"authorize\") return await handleAuthorize(event, options);\n if (path === \"token\") return await handleToken(event);\n if (path === \"register\") return await handleRegister(event);\n setResponseStatus(event, 404);\n return json({ error: \"Not found\" }, 404);\n } catch (err: any) {\n return oauthError(\n \"server_error\",\n err?.message || \"OAuth request failed\",\n 500,\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"oauth-route.js","sourceRoot":"","sources":["../../src/mcp/oauth-route.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Standard remote MCP OAuth 2.1 endpoints.\n *\n * These routes let MCP hosts such as Claude Code and ChatGPT authenticate\n * through their native remote-MCP OAuth flow instead of pasting bearer tokens.\n * The issued access tokens are audience-bound to `/_agent-native/mcp`, carry\n * the same user/org identity as the existing connect flow, and are mediated by\n * `verifyAuth` before any MCP tool/resource request runs.\n */\n\nimport type { H3Event } from \"h3\";\nimport { getHeader, getMethod, getQuery, setResponseStatus } from \"h3\";\nimport { createHash, createHmac, timingSafeEqual } from \"node:crypto\";\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getConfiguredLoginHtml, getSession } from \"../server/auth.js\";\nimport { getAuthSecret } from \"../server/better-auth-instance.js\";\nimport { getOrgDomain } from \"../org/context.js\";\nimport {\n createOAuthCode,\n createOAuthRefreshToken,\n consumeOAuthCode,\n generateOpaqueToken,\n getOAuthClient,\n getOAuthCode,\n getOAuthRefreshToken,\n registerOAuthClient,\n rotateOAuthRefreshToken,\n} from \"./oauth-store.js\";\nimport {\n MCP_OAUTH_DEFAULT_SCOPE,\n MCP_OAUTH_SCOPES,\n normalizeOAuthScope,\n signMcpOAuthAccessToken,\n} from \"./oauth-token.js\";\n\nexport interface McpOAuthRouteOptions {\n appId?: string;\n appName?: string;\n}\n\nfunction json(body: unknown, status = 200): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": \"no-store\",\n Pragma: \"no-cache\",\n },\n });\n}\n\nfunction html(body: string, status = 200): Response {\n return new Response(body, {\n status,\n headers: {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n },\n });\n}\n\nfunction redirect(location: string): Response {\n return new Response(null, {\n status: 302,\n headers: { Location: location, \"Cache-Control\": \"no-store\" },\n });\n}\n\nfunction isSameOriginPost(event: H3Event): boolean {\n const origin = getHeader(event, \"origin\");\n if (!origin) return true;\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return false;\n try {\n return new URL(origin).origin === new URL(issuer).origin;\n } catch {\n return false;\n }\n}\n\nfunction oauthError(\n error: string,\n description: string,\n status = 400,\n): Response {\n return json({ error, error_description: description }, status);\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\nfunction normalizeBasePath(raw: string | undefined): string {\n const trimmed = (raw ?? \"\").trim();\n if (!trimmed || trimmed === \"/\") return \"\";\n const withSlash = trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n return withSlash.replace(/\\/+$/, \"\");\n}\n\nfunction configuredBasePath(): string {\n return normalizeBasePath(\n process.env.APP_BASE_PATH || process.env.VITE_APP_BASE_PATH,\n );\n}\n\nfunction deriveOrigin(event: H3Event): string {\n const forwardedProto = getHeader(event, \"x-forwarded-proto\");\n const host = getHeader(event, \"x-forwarded-host\") || getHeader(event, \"host\");\n const proto =\n forwardedProto?.split(\",\")[0]?.trim() ||\n (host && /^(localhost|127\\.0\\.0\\.1|\\[::1\\])(:|$)/.test(host)\n ? \"http\"\n : \"https\");\n return host ? `${proto}://${host}` : \"\";\n}\n\nexport function getMcpOAuthIssuer(event: H3Event): string | undefined {\n const origin = deriveOrigin(event);\n if (!origin) return undefined;\n return `${origin}${configuredBasePath()}`;\n}\n\nexport function getMcpOAuthResource(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return undefined;\n return `${issuer}/_agent-native/mcp`;\n}\n\nexport function getMcpOAuthProtectedResourceMetadataUrl(\n event: H3Event,\n): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer) return undefined;\n return `${issuer}/.well-known/oauth-protected-resource`;\n}\n\nexport function buildMcpOAuthChallenge(event: H3Event): string {\n const metadata = getMcpOAuthProtectedResourceMetadataUrl(event);\n const scope = MCP_OAUTH_DEFAULT_SCOPE;\n return metadata\n ? `Bearer resource_metadata=\"${metadata}\", scope=\"${scope}\"`\n : `Bearer scope=\"${scope}\"`;\n}\n\nfunction authorizationEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/authorize` : undefined;\n}\n\nfunction tokenEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/token` : undefined;\n}\n\nfunction registrationEndpoint(event: H3Event): string | undefined {\n const issuer = getMcpOAuthIssuer(event);\n return issuer ? `${issuer}/_agent-native/mcp/oauth/register` : undefined;\n}\n\nexport function handleMcpOAuthProtectedResourceMetadata(\n event: H3Event,\n): Response {\n if (getMethod(event) !== \"GET\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const resource = getMcpOAuthResource(event);\n const issuer = getMcpOAuthIssuer(event);\n if (!resource || !issuer) {\n return oauthError(\"server_error\", \"Unable to derive MCP resource\", 500);\n }\n return json({\n resource,\n authorization_servers: [issuer],\n scopes_supported: MCP_OAUTH_SCOPES,\n resource_documentation: issuer,\n });\n}\n\nexport function handleMcpOAuthAuthorizationServerMetadata(\n event: H3Event,\n): Response {\n if (getMethod(event) !== \"GET\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const issuer = getMcpOAuthIssuer(event);\n const authorize = authorizationEndpoint(event);\n const token = tokenEndpoint(event);\n const register = registrationEndpoint(event);\n if (!issuer || !authorize || !token || !register) {\n return oauthError(\"server_error\", \"Unable to derive OAuth endpoints\", 500);\n }\n return json({\n issuer,\n authorization_endpoint: authorize,\n token_endpoint: token,\n registration_endpoint: register,\n response_types_supported: [\"code\"],\n grant_types_supported: [\"authorization_code\", \"refresh_token\"],\n code_challenge_methods_supported: [\"S256\"],\n token_endpoint_auth_methods_supported: [\"none\"],\n scopes_supported: MCP_OAUTH_SCOPES,\n });\n}\n\nfunction isAllowedRedirectUri(value: unknown): value is string {\n if (typeof value !== \"string\" || value.length > 2048) return false;\n try {\n const url = new URL(value);\n if (url.hash) return false;\n if (url.username || url.password) return false;\n if (url.protocol === \"https:\") return true;\n if (url.protocol !== \"http:\") return false;\n return (\n url.hostname === \"localhost\" ||\n url.hostname === \"127.0.0.1\" ||\n url.hostname === \"::1\" ||\n url.hostname === \"[::1]\"\n );\n } catch {\n return false;\n }\n}\n\nfunction parseStringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === \"string\")\n : [];\n}\n\nasync function handleRegister(event: H3Event): Promise<Response> {\n if (getMethod(event) !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const body = ((await readBody(event).catch(() => ({}))) ?? {}) as Record<\n string,\n unknown\n >;\n const redirectUris = parseStringArray(body.redirect_uris);\n if (\n redirectUris.length === 0 ||\n redirectUris.length > 20 ||\n !redirectUris.every(isAllowedRedirectUri)\n ) {\n return oauthError(\n \"invalid_client_metadata\",\n \"redirect_uris must contain valid HTTPS or localhost callback URLs\",\n );\n }\n\n const grantTypes = parseStringArray(body.grant_types);\n if (\n grantTypes.length &&\n !grantTypes.every(\n (g) => g === \"authorization_code\" || g === \"refresh_token\",\n )\n ) {\n return oauthError(\"invalid_client_metadata\", \"Unsupported grant_type\");\n }\n const responseTypes = parseStringArray(body.response_types);\n if (responseTypes.length && !responseTypes.every((r) => r === \"code\")) {\n return oauthError(\"invalid_client_metadata\", \"Unsupported response_type\");\n }\n const method =\n typeof body.token_endpoint_auth_method === \"string\"\n ? body.token_endpoint_auth_method\n : \"none\";\n if (method !== \"none\") {\n return oauthError(\n \"invalid_client_metadata\",\n \"Only public OAuth clients are supported\",\n );\n }\n\n const clientName =\n typeof body.client_name === \"string\"\n ? body.client_name.trim().slice(0, 120)\n : null;\n let client;\n try {\n client = await registerOAuthClient({\n clientName,\n redirectUris: [...new Set(redirectUris)],\n grantTypes: grantTypes.length ? grantTypes : undefined,\n responseTypes: responseTypes.length ? responseTypes : undefined,\n tokenEndpointAuthMethod: method,\n });\n } catch (err: any) {\n if (err?.message === \"RATE_LIMITED\") {\n return oauthError(\"slow_down\", \"Too many client registrations\", 429);\n }\n throw err;\n }\n return json(\n {\n client_id: client.clientId,\n client_id_issued_at: Math.floor((client.createdAt ?? Date.now()) / 1000),\n client_name: client.clientName ?? undefined,\n redirect_uris: client.redirectUris,\n grant_types: client.grantTypes,\n response_types: client.responseTypes,\n token_endpoint_auth_method: client.tokenEndpointAuthMethod,\n },\n 201,\n );\n}\n\nfunction redirectWithOAuthError(params: {\n redirectUri: string;\n state?: string;\n error: string;\n description?: string;\n}): Response {\n const url = new URL(params.redirectUri);\n url.searchParams.set(\"error\", params.error);\n if (params.description) {\n url.searchParams.set(\"error_description\", params.description);\n }\n if (params.state) url.searchParams.set(\"state\", params.state);\n return redirect(url.toString());\n}\n\nfunction redirectWithCode(params: {\n redirectUri: string;\n code: string;\n state?: string;\n}): Response {\n const url = new URL(params.redirectUri);\n url.searchParams.set(\"code\", params.code);\n if (params.state) url.searchParams.set(\"state\", params.state);\n return redirect(url.toString());\n}\n\nfunction codeChallengeForVerifier(verifier: string): string {\n return createHash(\"sha256\").update(verifier).digest(\"base64url\");\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n return aa.length === bb.length && timingSafeEqual(aa, bb);\n}\n\nfunction base64UrlEncode(value: Buffer | string): string {\n const buf = typeof value === \"string\" ? Buffer.from(value, \"utf8\") : value;\n return buf.toString(\"base64url\");\n}\n\nfunction base64UrlDecode(value: string): Buffer {\n return Buffer.from(value, \"base64url\");\n}\n\nfunction consentSigningKey(): string {\n return process.env.A2A_SECRET || getAuthSecret();\n}\n\nfunction consentPayload(params: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n}): string {\n return JSON.stringify({\n ...params,\n exp: Math.floor(Date.now() / 1000) + 10 * 60,\n });\n}\n\nfunction signConsentToken(params: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n}): string {\n const payload = base64UrlEncode(consentPayload(params));\n const sig = base64UrlEncode(\n createHmac(\"sha256\", consentSigningKey()).update(payload).digest(),\n );\n return `${payload}.${sig}`;\n}\n\nfunction verifyConsentToken(\n token: string | undefined,\n expected: {\n email: string;\n clientId: string;\n redirectUri: string;\n resource: string;\n scope: string;\n codeChallenge: string;\n },\n): boolean {\n if (!token || !token.includes(\".\")) return false;\n const [payload, sig] = token.split(\".\", 2);\n if (!payload || !sig) return false;\n const expectedSig = base64UrlEncode(\n createHmac(\"sha256\", consentSigningKey()).update(payload).digest(),\n );\n if (!safeEqual(sig, expectedSig)) return false;\n try {\n const parsed = JSON.parse(base64UrlDecode(payload).toString(\"utf8\"));\n return (\n parsed.email === expected.email &&\n parsed.clientId === expected.clientId &&\n parsed.redirectUri === expected.redirectUri &&\n parsed.resource === expected.resource &&\n parsed.scope === expected.scope &&\n parsed.codeChallenge === expected.codeChallenge &&\n typeof parsed.exp === \"number\" &&\n parsed.exp * 1000 >= Date.now()\n );\n } catch {\n return false;\n }\n}\n\nfunction isValidCodeVerifier(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length >= 43 &&\n value.length <= 128 &&\n /^[A-Za-z0-9._~-]+$/.test(value)\n );\n}\n\nfunction renderConsentPage(params: {\n appName: string;\n email: string;\n clientName: string;\n scopes: string[];\n fields: Record<string, string>;\n}): string {\n const hidden = Object.entries(params.fields)\n .map(\n ([key, value]) =>\n `<input type=\"hidden\" name=\"${escapeHtml(key)}\" value=\"${escapeHtml(value)}\">`,\n )\n .join(\"\\n\");\n const scopes = params.scopes\n .map((scope) => `<li><code>${escapeHtml(scope)}</code></li>`)\n .join(\"\");\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Authorize ${escapeHtml(params.appName)}</title>\n<style>\n :root { color-scheme: dark; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; background: #09090b; color: #f4f4f5; }\n body { min-height: 100vh; display: grid; place-items: center; margin: 0; padding: 24px; }\n main { width: min(520px, 100%); border: 1px solid #27272a; border-radius: 8px; background: #111113; padding: 24px; box-shadow: 0 24px 80px rgba(0,0,0,.35); }\n h1 { font-size: 22px; line-height: 1.2; margin: 0 0 10px; }\n p { color: #a1a1aa; line-height: 1.5; margin: 0 0 18px; }\n ul { margin: 0 0 22px; padding-left: 22px; color: #d4d4d8; }\n code { color: #67e8f9; }\n .actions { display: flex; gap: 10px; justify-content: flex-end; }\n button { border: 0; border-radius: 6px; padding: 10px 14px; font-weight: 650; cursor: pointer; }\n .primary { background: #f4f4f5; color: #09090b; }\n .secondary { background: #27272a; color: #f4f4f5; }\n</style>\n</head>\n<body>\n<main>\n <h1>Authorize ${escapeHtml(params.clientName)}</h1>\n <p>${escapeHtml(params.appName)} will let this MCP client act as ${escapeHtml(params.email)} for these scopes:</p>\n <ul>${scopes}</ul>\n <form method=\"post\">\n ${hidden}\n <div class=\"actions\">\n <button class=\"secondary\" type=\"submit\" name=\"decision\" value=\"deny\">Deny</button>\n <button class=\"primary\" type=\"submit\" name=\"decision\" value=\"approve\">Authorize</button>\n </div>\n </form>\n</main>\n</body>\n</html>`;\n}\n\nasync function resolveOrgDomain(\n orgId: string | undefined,\n): Promise<string | undefined> {\n if (!orgId) return undefined;\n try {\n return (await getOrgDomain(orgId)) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function readOAuthParams(\n event: H3Event,\n): Promise<Record<string, string>> {\n if (getMethod(event) === \"GET\") {\n const query = getQuery(event);\n return Object.fromEntries(\n Object.entries(query).flatMap(([key, value]) =>\n typeof value === \"string\" ? [[key, value]] : [],\n ),\n );\n }\n const body = await readBody(event).catch(() => ({}));\n if (typeof body === \"string\") {\n return Object.fromEntries(new URLSearchParams(body));\n }\n if (body && typeof body === \"object\") {\n return Object.fromEntries(\n Object.entries(body as Record<string, unknown>).flatMap(([key, value]) =>\n typeof value === \"string\" ? [[key, value]] : [],\n ),\n );\n }\n return {};\n}\n\nasync function handleAuthorize(\n event: H3Event,\n options: McpOAuthRouteOptions,\n): Promise<Response> {\n const method = getMethod(event);\n if (method !== \"GET\" && method !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n if (method === \"POST\" && !isSameOriginPost(event)) {\n return oauthError(\n \"invalid_request\",\n \"Cross-origin authorize POST rejected\",\n 403,\n );\n }\n const params = await readOAuthParams(event);\n const state = params.state;\n const clientId = params.client_id;\n const redirectUri = params.redirect_uri;\n const resource = params.resource || getMcpOAuthResource(event);\n const expectedResource = getMcpOAuthResource(event);\n\n if (params.response_type !== \"code\") {\n return oauthError(\n \"unsupported_response_type\",\n \"response_type must be code\",\n );\n }\n if (!clientId || !redirectUri || !resource || resource !== expectedResource) {\n return oauthError(\"invalid_request\", \"Invalid OAuth authorization request\");\n }\n if (params.code_challenge_method !== \"S256\" || !params.code_challenge) {\n return oauthError(\"invalid_request\", \"PKCE S256 is required\");\n }\n\n const client = await getOAuthClient(clientId);\n if (!client || !client.redirectUris.includes(redirectUri)) {\n return oauthError(\"invalid_client\", \"Unknown client or redirect_uri\");\n }\n\n const session = await getSession(event);\n if (!session?.email) {\n if (params.prompt === \"none\") {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"login_required\",\n });\n }\n const loginHtml = getConfiguredLoginHtml(event);\n return loginHtml\n ? html(loginHtml, 200)\n : oauthError(\"login_required\", \"Sign in required\", 401);\n }\n\n const scope = normalizeOAuthScope(params.scope);\n if (!scope) {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"invalid_scope\",\n });\n }\n if (method === \"GET\") {\n return html(\n renderConsentPage({\n appName: options.appName || options.appId || \"Agent Native\",\n email: session.email,\n clientName: client.clientName || client.clientId,\n scopes: scope.split(/\\s+/),\n fields: {\n response_type: \"code\",\n client_id: clientId,\n redirect_uri: redirectUri,\n resource,\n scope,\n state: state ?? \"\",\n code_challenge: params.code_challenge,\n code_challenge_method: \"S256\",\n consent_token: signConsentToken({\n email: session.email,\n clientId,\n redirectUri,\n resource,\n scope,\n codeChallenge: params.code_challenge,\n }),\n },\n }),\n );\n }\n\n if (\n !verifyConsentToken(params.consent_token, {\n email: session.email,\n clientId,\n redirectUri,\n resource,\n scope,\n codeChallenge: params.code_challenge,\n })\n ) {\n return oauthError(\"invalid_request\", \"Invalid authorization consent token\");\n }\n\n if (params.decision !== \"approve\") {\n return redirectWithOAuthError({\n redirectUri,\n state,\n error: \"access_denied\",\n });\n }\n\n const orgDomain = await resolveOrgDomain(session.orgId);\n const code = await createOAuthCode({\n clientId,\n redirectUri,\n codeChallenge: params.code_challenge,\n codeChallengeMethod: \"S256\",\n ownerEmail: session.email,\n orgId: session.orgId ?? null,\n orgDomain: orgDomain ?? null,\n scope,\n resource,\n });\n return redirectWithCode({ redirectUri, state, code: code.code });\n}\n\nasync function issueTokenSet(params: {\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n clientId: string;\n scope: string;\n resource: string;\n issuer: string;\n}): Promise<Record<string, unknown>> {\n const refreshToken = generateOpaqueToken();\n await createOAuthRefreshToken({\n refreshToken,\n clientId: params.clientId,\n ownerEmail: params.ownerEmail,\n orgId: params.orgId ?? null,\n orgDomain: params.orgDomain ?? null,\n scope: params.scope,\n resource: params.resource,\n });\n const accessToken = await signMcpOAuthAccessToken(params);\n return {\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: 3600,\n refresh_token: refreshToken,\n scope: params.scope,\n };\n}\n\nasync function handleAuthorizationCodeGrant(\n event: H3Event,\n body: Record<string, string>,\n): Promise<Response> {\n const code = body.code;\n const clientId = body.client_id;\n const redirectUri = body.redirect_uri;\n const verifier = body.code_verifier;\n if (!code || !clientId || !redirectUri || !isValidCodeVerifier(verifier)) {\n return oauthError(\"invalid_request\", \"Missing authorization-code fields\");\n }\n const row = await getOAuthCode(code);\n if (!row) return oauthError(\"invalid_grant\", \"Invalid or expired code\");\n if (row.clientId !== clientId || row.redirectUri !== redirectUri) {\n return oauthError(\"invalid_grant\", \"Code was issued to another client\");\n }\n const expectedChallenge = codeChallengeForVerifier(verifier);\n if (!safeEqual(expectedChallenge, row.codeChallenge)) {\n return oauthError(\"invalid_grant\", \"PKCE verification failed\");\n }\n const consumed = await consumeOAuthCode(code);\n if (!consumed) return oauthError(\"invalid_grant\", \"Invalid or expired code\");\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer)\n return oauthError(\"server_error\", \"Unable to derive issuer\", 500);\n return json(\n await issueTokenSet({\n ownerEmail: row.ownerEmail,\n orgId: row.orgId,\n orgDomain: row.orgDomain,\n clientId,\n scope: row.scope,\n resource: row.resource,\n issuer,\n }),\n );\n}\n\nasync function handleRefreshTokenGrant(\n event: H3Event,\n body: Record<string, string>,\n): Promise<Response> {\n const refreshToken = body.refresh_token;\n const clientId = body.client_id;\n if (!refreshToken) {\n return oauthError(\"invalid_request\", \"refresh_token is required\");\n }\n if (!clientId) {\n return oauthError(\"invalid_request\", \"client_id is required\");\n }\n const existing = await getOAuthRefreshToken(refreshToken);\n if (!existing) return oauthError(\"invalid_grant\", \"Invalid refresh token\");\n if (existing.clientId !== clientId) {\n return oauthError(\n \"invalid_grant\",\n \"Refresh token belongs to another client\",\n );\n }\n const nextRefreshToken = generateOpaqueToken();\n const row = await rotateOAuthRefreshToken({\n oldRefreshToken: refreshToken,\n newRefreshToken: nextRefreshToken,\n });\n if (!row) return oauthError(\"invalid_grant\", \"Invalid refresh token\");\n const issuer = getMcpOAuthIssuer(event);\n if (!issuer)\n return oauthError(\"server_error\", \"Unable to derive issuer\", 500);\n const accessToken = await signMcpOAuthAccessToken({\n ownerEmail: row.ownerEmail,\n orgId: row.orgId,\n orgDomain: row.orgDomain,\n clientId: row.clientId,\n scope: row.scope,\n resource: row.resource,\n issuer,\n });\n return json({\n access_token: accessToken,\n token_type: \"Bearer\",\n expires_in: 3600,\n refresh_token: nextRefreshToken,\n scope: row.scope,\n });\n}\n\nasync function handleToken(event: H3Event): Promise<Response> {\n if (getMethod(event) !== \"POST\") {\n return oauthError(\"invalid_request\", \"Method not allowed\", 405);\n }\n const body = await readOAuthParams(event);\n switch (body.grant_type) {\n case \"authorization_code\":\n return handleAuthorizationCodeGrant(event, body);\n case \"refresh_token\":\n return handleRefreshTokenGrant(event, body);\n default:\n return oauthError(\"unsupported_grant_type\", \"Unsupported grant_type\");\n }\n}\n\nexport async function handleMcpOAuth(\n event: H3Event,\n subpath: string,\n options: McpOAuthRouteOptions = {},\n): Promise<Response> {\n const path = subpath.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n try {\n if (path === \"authorize\") return await handleAuthorize(event, options);\n if (path === \"token\") return await handleToken(event);\n if (path === \"register\") return await handleRegister(event);\n setResponseStatus(event, 404);\n return json({ error: \"Not found\" }, 404);\n } catch (err: any) {\n return oauthError(\n \"server_error\",\n err?.message || \"OAuth request failed\",\n 500,\n );\n }\n}\n"]}
|
|
@@ -2,6 +2,7 @@ export declare const MCP_OAUTH_SCOPES: readonly ["mcp:read", "mcp:write", "mcp:a
|
|
|
2
2
|
export declare const MCP_OAUTH_DEFAULT_SCOPE: string;
|
|
3
3
|
export interface McpOAuthAccessTokenClaims {
|
|
4
4
|
sub: string;
|
|
5
|
+
org_id?: string;
|
|
5
6
|
org_domain?: string;
|
|
6
7
|
scope: string;
|
|
7
8
|
client_id: string;
|
|
@@ -13,6 +14,7 @@ export declare function scopeList(scope: string | undefined): string[];
|
|
|
13
14
|
export declare function hasMcpOAuthScope(scopes: string[] | undefined, scope: (typeof MCP_OAUTH_SCOPES)[number]): boolean;
|
|
14
15
|
export declare function signMcpOAuthAccessToken(params: {
|
|
15
16
|
ownerEmail: string;
|
|
17
|
+
orgId?: string | null;
|
|
16
18
|
orgDomain?: string | null;
|
|
17
19
|
clientId: string;
|
|
18
20
|
scope: string;
|
|
@@ -21,6 +23,7 @@ export declare function signMcpOAuthAccessToken(params: {
|
|
|
21
23
|
}): Promise<string>;
|
|
22
24
|
export declare function verifyMcpOAuthAccessToken(token: string, resource: string | undefined): Promise<{
|
|
23
25
|
userEmail: string;
|
|
26
|
+
orgId?: string;
|
|
24
27
|
orgDomain?: string;
|
|
25
28
|
scopes: string[];
|
|
26
29
|
clientId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-token.d.ts","sourceRoot":"","sources":["../../src/mcp/oauth-token.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,gBAAgB,gDAAiD,CAAC;AAE/E,eAAO,MAAM,uBAAuB,QAA6B,CAAC;AAElE,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,wBAAwB,CAAC;CAC/B;AAMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAYjE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAK7D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAC5B,KAAK,EAAE,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,GACvC,OAAO,CAGT;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"oauth-token.d.ts","sourceRoot":"","sources":["../../src/mcp/oauth-token.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,gBAAgB,gDAAiD,CAAC;AAE/E,eAAO,MAAM,uBAAuB,QAA6B,CAAC;AAElE,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,wBAAwB,CAAC;CAC/B;AAMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAYjE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAK7D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAC5B,KAAK,EAAE,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,GACvC,OAAO,CAGT;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBlB;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,OAAO,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAAC,CA4BR"}
|
package/dist/mcp/oauth-token.js
CHANGED
|
@@ -35,6 +35,7 @@ export async function signMcpOAuthAccessToken(params) {
|
|
|
35
35
|
return new jose.SignJWT({
|
|
36
36
|
typ: "agent-native-mcp-oauth",
|
|
37
37
|
sub: params.ownerEmail,
|
|
38
|
+
...(params.orgId ? { org_id: params.orgId } : {}),
|
|
38
39
|
...(params.orgDomain ? { org_domain: params.orgDomain } : {}),
|
|
39
40
|
scope: params.scope,
|
|
40
41
|
client_id: params.clientId,
|
|
@@ -71,6 +72,7 @@ export async function verifyMcpOAuthAccessToken(token, resource) {
|
|
|
71
72
|
}
|
|
72
73
|
return {
|
|
73
74
|
userEmail: payload.sub,
|
|
75
|
+
orgId: typeof payload.org_id === "string" ? payload.org_id : undefined,
|
|
74
76
|
orgDomain: typeof payload.org_domain === "string" ? payload.org_domain : undefined,
|
|
75
77
|
scopes,
|
|
76
78
|
clientId: payload.client_id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-token.js","sourceRoot":"","sources":["../../src/mcp/oauth-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAE9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,CAAU,CAAC;AAE/E,MAAM,CAAC,MAAM,uBAAuB,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"oauth-token.js","sourceRoot":"","sources":["../../src/mcp/oauth-token.ts"],"names":[],"mappings":"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","sourcesContent":["import * as jose from \"jose\";\nimport { randomUUID } from \"node:crypto\";\nimport { getAuthSecret } from \"../server/better-auth-instance.js\";\nimport { MCP_OAUTH_ACCESS_TOKEN_TTL } from \"./oauth-store.js\";\n\nexport const MCP_OAUTH_SCOPES = [\"mcp:read\", \"mcp:write\", \"mcp:apps\"] as const;\n\nexport const MCP_OAUTH_DEFAULT_SCOPE = MCP_OAUTH_SCOPES.join(\" \");\n\nexport interface McpOAuthAccessTokenClaims {\n sub: string;\n org_id?: string;\n org_domain?: string;\n scope: string;\n client_id: string;\n resource: string;\n typ: \"agent-native-mcp-oauth\";\n}\n\nfunction signingSecret(): Uint8Array {\n return new TextEncoder().encode(process.env.A2A_SECRET || getAuthSecret());\n}\n\nexport function normalizeOAuthScope(input: unknown): string | null {\n const requested =\n typeof input === \"string\"\n ? input\n .split(/\\s+/)\n .map((s) => s.trim())\n .filter(Boolean)\n : [];\n const allowed = new Set<string>(MCP_OAUTH_SCOPES);\n if (requested.length === 0) return MCP_OAUTH_DEFAULT_SCOPE;\n const selected = requested.filter((scope) => allowed.has(scope));\n return selected.length ? [...new Set(selected)].join(\" \") : null;\n}\n\nexport function scopeList(scope: string | undefined): string[] {\n return (scope ?? \"\")\n .split(/\\s+/)\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nexport function hasMcpOAuthScope(\n scopes: string[] | undefined,\n scope: (typeof MCP_OAUTH_SCOPES)[number],\n): boolean {\n if (!scopes) return true;\n return scopes.includes(scope);\n}\n\nexport async function signMcpOAuthAccessToken(params: {\n ownerEmail: string;\n orgId?: string | null;\n orgDomain?: string | null;\n clientId: string;\n scope: string;\n resource: string;\n issuer: string;\n}): Promise<string> {\n return new jose.SignJWT({\n typ: \"agent-native-mcp-oauth\",\n sub: params.ownerEmail,\n ...(params.orgId ? { org_id: params.orgId } : {}),\n ...(params.orgDomain ? { org_domain: params.orgDomain } : {}),\n scope: params.scope,\n client_id: params.clientId,\n resource: params.resource,\n })\n .setProtectedHeader({ alg: \"HS256\" })\n .setIssuer(params.issuer)\n .setAudience(params.resource)\n .setJti(randomUUID())\n .setIssuedAt()\n .setExpirationTime(MCP_OAUTH_ACCESS_TOKEN_TTL)\n .sign(signingSecret());\n}\n\nexport async function verifyMcpOAuthAccessToken(\n token: string,\n resource: string | undefined,\n): Promise<{\n userEmail: string;\n orgId?: string;\n orgDomain?: string;\n scopes: string[];\n clientId: string;\n} | null> {\n if (!resource) return null;\n try {\n const { payload } = await jose.jwtVerify(token, signingSecret(), {\n audience: resource,\n });\n if (payload.typ !== \"agent-native-mcp-oauth\") return null;\n if (payload.resource !== resource) return null;\n if (typeof payload.sub !== \"string\" || !payload.sub) return null;\n if (typeof payload.client_id !== \"string\" || !payload.client_id) {\n return null;\n }\n const scope = typeof payload.scope === \"string\" ? payload.scope : \"\";\n const scopes = scopeList(scope);\n if (!scopes.some((s) => MCP_OAUTH_SCOPES.includes(s as any))) {\n return null;\n }\n return {\n userEmail: payload.sub,\n orgId: typeof payload.org_id === \"string\" ? payload.org_id : undefined,\n orgDomain:\n typeof payload.org_domain === \"string\" ? payload.org_domain : undefined,\n scopes,\n clientId: payload.client_id,\n };\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -87,7 +87,10 @@ npx @agent-native/core@latest skills add assets
|
|
|
87
87
|
# Same install, using the image-generation alias for demos and tutorials.
|
|
88
88
|
npx @agent-native/core@latest skills add images
|
|
89
89
|
|
|
90
|
-
#
|
|
90
|
+
# One-command hosted install for Design exploration plus MCP connector.
|
|
91
|
+
npx @agent-native/core@latest skills add design-exploration
|
|
92
|
+
|
|
93
|
+
# Register a hosted MCP connector for local agent clients.
|
|
91
94
|
agent-native app-skill ensure --manifest templates/assets/agent-native.app-skill.json
|
|
92
95
|
|
|
93
96
|
# Materialize and run editable local source.
|
|
@@ -111,9 +114,9 @@ settings flow.
|
|
|
111
114
|
|
|
112
115
|
The Vercel Labs `skills` adapter is a portable `skills/<name>/SKILL.md` bundle
|
|
113
116
|
for `npx skills add ...`. For first-party hosted apps, prefer
|
|
114
|
-
`agent-native skills add images
|
|
115
|
-
|
|
116
|
-
together.
|
|
117
|
+
`agent-native skills add images`, `agent-native skills add assets`, or
|
|
118
|
+
`agent-native skills add design-exploration`; each installs the exported
|
|
119
|
+
instructions and runs the MCP registration step together.
|
|
117
120
|
|
|
118
121
|
The Claude Code marketplace adapter writes
|
|
119
122
|
`adapters/claude-marketplace/.claude-plugin/marketplace.json` plus a nested
|
|
@@ -22,6 +22,17 @@ Use it when you want a polished landing page concept, product UI direction, bran
|
|
|
22
22
|
4. **Export when it is useful.** Download HTML, ZIP, or PDF once the prototype
|
|
23
23
|
is ready to hand to another tool or teammate.
|
|
24
24
|
|
|
25
|
+
For Codex, Claude Code, and other local agent clients, the hosted Design app can
|
|
26
|
+
be installed as an app-backed skill plus MCP connector:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx @agent-native/core@latest skills add design-exploration
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
That gives the agent instructions to create a design shell, present three visual
|
|
33
|
+
directions in the inline Design MCP app, wait for your pick, and iterate from
|
|
34
|
+
the selected prototype.
|
|
35
|
+
|
|
25
36
|
## Useful Prompts
|
|
26
37
|
|
|
27
38
|
- "Create three landing-page directions for a technical analytics product."
|