@fragno-dev/mcp-fragment 0.0.0-stage → 0.0.3
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/LICENSE.md +16 -0
- package/README.md +312 -2
- package/bin/run.js +7 -0
- package/dist/browser/client/react.d.ts +253 -0
- package/dist/browser/client/react.d.ts.map +1 -0
- package/dist/browser/client/react.js +194 -0
- package/dist/browser/client/react.js.map +1 -0
- package/dist/browser/client/solid.d.ts +256 -0
- package/dist/browser/client/solid.d.ts.map +1 -0
- package/dist/browser/client/solid.js +129 -0
- package/dist/browser/client/solid.js.map +1 -0
- package/dist/browser/client/svelte.d.ts +256 -0
- package/dist/browser/client/svelte.d.ts.map +1 -0
- package/dist/browser/client/svelte.js +131 -0
- package/dist/browser/client/svelte.js.map +1 -0
- package/dist/browser/client/vanilla.d.ts +283 -0
- package/dist/browser/client/vanilla.d.ts.map +1 -0
- package/dist/browser/client/vanilla.js +159 -0
- package/dist/browser/client/vanilla.js.map +1 -0
- package/dist/browser/client/vue.d.ts +256 -0
- package/dist/browser/client/vue.d.ts.map +1 -0
- package/dist/browser/client/vue.js +127 -0
- package/dist/browser/client/vue.js.map +1 -0
- package/dist/browser/client-BCzNDSlW.d.ts +711 -0
- package/dist/browser/client-BCzNDSlW.d.ts.map +1 -0
- package/dist/browser/index.d.ts +813 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +1 -0
- package/dist/browser/src-B6dHZXqB.js +2303 -0
- package/dist/browser/src-B6dHZXqB.js.map +1 -0
- package/dist/cli/cli.d.ts +6 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +227 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/definition.js +330 -0
- package/dist/cli/definition.js.map +1 -0
- package/dist/cli/diagnostics.js +93 -0
- package/dist/cli/diagnostics.js.map +1 -0
- package/dist/cli/index.js +13 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mcp-api.js +87 -0
- package/dist/cli/mcp-api.js.map +1 -0
- package/dist/cli/mcp-types.js +100 -0
- package/dist/cli/mcp-types.js.map +1 -0
- package/dist/cli/oauth-provider.js +113 -0
- package/dist/cli/oauth-provider.js.map +1 -0
- package/dist/cli/routes.js +743 -0
- package/dist/cli/routes.js.map +1 -0
- package/dist/cli/schema.js +13 -0
- package/dist/cli/schema.js.map +1 -0
- package/dist/cli/services.js +330 -0
- package/dist/cli/services.js.map +1 -0
- package/dist/node/definition.d.ts +260 -0
- package/dist/node/definition.d.ts.map +1 -0
- package/dist/node/definition.js +330 -0
- package/dist/node/definition.js.map +1 -0
- package/dist/node/diagnostics.js +93 -0
- package/dist/node/diagnostics.js.map +1 -0
- package/dist/node/index.d.ts +694 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +26 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/mcp-api.d.ts +2 -0
- package/dist/node/mcp-api.js +87 -0
- package/dist/node/mcp-api.js.map +1 -0
- package/dist/node/mcp-types.d.ts +146 -0
- package/dist/node/mcp-types.d.ts.map +1 -0
- package/dist/node/mcp-types.js +100 -0
- package/dist/node/mcp-types.js.map +1 -0
- package/dist/node/oauth-provider.d.ts +24 -0
- package/dist/node/oauth-provider.d.ts.map +1 -0
- package/dist/node/oauth-provider.js +113 -0
- package/dist/node/oauth-provider.js.map +1 -0
- package/dist/node/routes.d.ts +466 -0
- package/dist/node/routes.d.ts.map +1 -0
- package/dist/node/routes.js +743 -0
- package/dist/node/routes.js.map +1 -0
- package/dist/node/schema.d.ts +9 -0
- package/dist/node/schema.d.ts.map +1 -0
- package/dist/node/schema.js +13 -0
- package/dist/node/schema.js.map +1 -0
- package/dist/node/services.d.ts +40 -0
- package/dist/node/services.d.ts.map +1 -0
- package/dist/node/services.js +330 -0
- package/dist/node/services.js.map +1 -0
- package/dist/node/testing/mcp-test-server.d.ts +42 -0
- package/dist/node/testing/mcp-test-server.d.ts.map +1 -0
- package/dist/node/testing/mcp-test-server.js +218 -0
- package/dist/node/testing/mcp-test-server.js.map +1 -0
- package/package.json +130 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","names":[],"sources":["../../src/routes.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { defineRoutes } from \"@fragno-dev/core\";\n\nimport { mcpFragmentDefinition, scheduleMcpAuthExpiry } from \"./definition\";\nimport { buildAuthDiagnostics, errorMessage, refreshOutputSchema } from \"./diagnostics\";\nimport {\n assertAllowedEndpoint,\n callMcpTool,\n stringifySecretPayload,\n listMcpTools,\n} from \"./mcp-api\";\nimport {\n createServerInputSchema,\n MCP_OAUTH_REDIRECT_URI_QUERY_PARAMETER,\n mcpAuthStatusSchema,\n mcpOAuthPendingSchema,\n mcpOAuthRedirectUriSchema,\n mcpToolCallResultSchema,\n mcpToolSchema,\n oauthStartInputSchema,\n replaceServerConfigurationInputSchema,\n tokenAuthInputSchema,\n toolCallInputSchema,\n type AuthConfig,\n type McpTool,\n} from \"./mcp-types\";\nimport { mcpSchema } from \"./schema\";\nimport {\n createMcpOperationAuth,\n isMcpAuthReady,\n projectMcpAuthStatus,\n pendingOAuthLink,\n withoutOAuthConsent,\n writeOAuthSecretChanges,\n type AuthPersistenceChanges,\n} from \"./services\";\n\nconst serverConnectionCacheOutputSchema = z.object({\n protocolVersion: z.string().nullable().optional(),\n serverInfo: z.unknown().nullable().optional(),\n capabilities: z.unknown().nullable().optional(),\n tools: z.array(mcpToolSchema).nullable().optional(),\n updatedAt: z.union([z.string(), z.date()]).optional(),\n});\n\nconst serverOutputSchema = z.object({\n slug: z.string(),\n name: z.string().nullable().optional(),\n endpointUrl: z.string(),\n authMode: z.string(),\n cache: serverConnectionCacheOutputSchema.nullable().optional(),\n});\n\nfunction publicServer(\n server: {\n id: { toString(): string } | string;\n name?: string | null;\n endpointUrl: string;\n authMode: string;\n },\n cache?: {\n protocolVersion?: string | null;\n serverInfo?: unknown;\n capabilities?: unknown;\n tools?: unknown;\n updatedAt?: Date;\n } | null,\n) {\n return {\n slug: server.id.toString(),\n name: server.name,\n endpointUrl: server.endpointUrl,\n authMode: server.authMode,\n ...(cache\n ? {\n cache: {\n protocolVersion: cache.protocolVersion ?? null,\n serverInfo: cache.serverInfo ?? null,\n capabilities: cache.capabilities ?? null,\n // Cached tools come from the SDK's validated tools/list result.\n tools: Array.isArray(cache.tools) ? (cache.tools as McpTool[]) : null,\n updatedAt: cache.updatedAt,\n },\n }\n : {}),\n };\n}\n\nfunction authMode(auth: AuthConfig) {\n return auth.type;\n}\n\nexport const mcpRoutesFactory = defineRoutes(mcpFragmentDefinition).create(\n ({ services, defineRoute, config }) => {\n return [\n defineRoute({\n method: \"POST\",\n path: \"/servers\",\n inputSchema: createServerInputSchema,\n outputSchema: serverOutputSchema,\n errorCodes: [\"SERVER_EXISTS\", \"ENDPOINT_NOT_ALLOWED\"],\n handler: async function ({ input }, { json, error }) {\n const body = await input.valid();\n try {\n assertAllowedEndpoint(body.endpointUrl, config);\n } catch (err) {\n return error({ code: \"ENDPOINT_NOT_ALLOWED\", message: (err as Error).message }, 400);\n }\n\n const payload = body.auth.type === \"none\" ? undefined : stringifySecretPayload(body.auth);\n\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema).findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", body.slug)),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [existing] }) => {\n if (existing) {\n return { exists: true as const };\n }\n\n const uow = forSchema(mcpSchema);\n uow.create(\"server_configuration\", {\n id: body.slug,\n name: body.name ?? null,\n endpointUrl: body.endpointUrl,\n authMode: authMode(body.auth),\n });\n if (payload) {\n uow.create(\"secret\", {\n id: `${body.slug}:auth`,\n serverId: body.slug,\n kind: \"auth\",\n payload,\n expiresAt: null,\n });\n }\n if (body.auth.type !== \"oauth\") {\n uow.triggerHook(\"internalRefreshServerConfiguration\", { serverId: body.slug });\n }\n uow.triggerHook(\"onServerReadinessChanged\", {\n serverId: body.slug,\n ready: isMcpAuthReady(\n authMode(body.auth),\n payload === undefined ? undefined : { payload, expiresAt: null },\n ),\n });\n return { exists: false as const };\n })\n .execute();\n\n if (result.exists) {\n return error({ code: \"SERVER_EXISTS\", message: \"MCP server already exists\" }, 409);\n }\n\n return json(publicServer({ ...body, id: body.slug, authMode: authMode(body.auth) }), 201);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/servers\",\n outputSchema: z.object({ servers: z.array(serverOutputSchema) }),\n handler: async function (_, { json }) {\n const [servers, caches] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .find(\"server_configuration\", (b) => b.whereIndex(\"primary\"))\n .find(\"server_connection_cache\", (b) => b.whereIndex(\"primary\")),\n )\n .execute();\n const cacheByServerId = new Map(caches.map((cache) => [cache.id.toString(), cache]));\n return json({\n servers: servers.map((server) =>\n publicServer(server, cacheByServerId.get(server.id.toString())),\n ),\n });\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/servers/:slug\",\n outputSchema: serverOutputSchema,\n errorCodes: [\"SERVER_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const [server, cache] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .findFirst(\"server_connection_cache\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n ),\n )\n .execute();\n if (!server) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return json(publicServer(server, cache));\n },\n }),\n\n defineRoute({\n method: \"PUT\",\n path: \"/servers/:slug/configuration\",\n inputSchema: replaceServerConfigurationInputSchema,\n outputSchema: serverOutputSchema,\n errorCodes: [\"SERVER_NOT_FOUND\", \"ENDPOINT_NOT_ALLOWED\"],\n handler: async function ({ input, pathParams }, { json, error }) {\n const body = await input.valid();\n try {\n assertAllowedEndpoint(body.endpointUrl, config);\n } catch (err) {\n return error({ code: \"ENDPOINT_NOT_ALLOWED\", message: (err as Error).message }, 400);\n }\n const payload = body.auth.type === \"none\" ? null : stringifySecretPayload(body.auth);\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_server_kind\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n )\n .find(\"oauthState\", (b) =>\n b.whereIndex(\"idx_oauth_state_server\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n )\n .findFirst(\"server_connection_cache\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [server, secrets, oauthStates, cache] }) => {\n if (!server) {\n return { server: null };\n }\n const uow = forSchema(mcpSchema);\n const replaced = {\n ...server,\n name: body.name ?? null,\n endpointUrl: body.endpointUrl,\n authMode: authMode(body.auth),\n };\n uow.update(\"server_configuration\", server.id, (b) =>\n b\n .set({\n name: replaced.name,\n endpointUrl: replaced.endpointUrl,\n authMode: replaced.authMode,\n updatedAt: b.now(),\n })\n .check(),\n );\n // Tokens, registered clients, discovery state, and pending links belong to the old\n // endpoint and credentials, so only the replacement auth survives.\n const authSecret = secrets.find((secret) => secret.kind === \"auth\");\n for (const secret of secrets) {\n if (secret !== authSecret || payload === null) {\n uow.delete(\"secret\", secret.id);\n }\n }\n if (payload !== null) {\n if (authSecret) {\n uow.update(\"secret\", authSecret.id, (b) =>\n b.set({ payload, expiresAt: null, updatedAt: b.now() }).check(),\n );\n } else {\n uow.create(\"secret\", {\n id: `${pathParams.slug}:auth`,\n serverId: pathParams.slug,\n kind: \"auth\",\n payload,\n expiresAt: null,\n });\n }\n }\n for (const oauthState of oauthStates) {\n uow.delete(\"oauthState\", oauthState.id);\n }\n if (cache) {\n uow.delete(\"server_connection_cache\", cache.id);\n }\n if (body.auth.type !== \"oauth\") {\n uow.triggerHook(\"internalRefreshServerConfiguration\", {\n serverId: pathParams.slug,\n });\n }\n const ready = isMcpAuthReady(\n replaced.authMode,\n payload === null ? undefined : { payload, expiresAt: null },\n );\n if (ready !== isMcpAuthReady(server.authMode, authSecret)) {\n uow.triggerHook(\"onServerReadinessChanged\", { serverId: pathParams.slug, ready });\n }\n return { server: replaced };\n })\n .execute();\n if (!result.server) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return json(publicServer(result.server));\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/servers/:slug\",\n errorCodes: [\"SERVER_NOT_FOUND\"],\n handler: async function ({ pathParams }, { empty, error }) {\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_server_kind\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n )\n .find(\"oauthState\", (b) =>\n b.whereIndex(\"idx_oauth_state_server\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n )\n .findFirst(\"server_connection_cache\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [server, secrets, oauthStates, cache] }) => {\n if (!server) {\n return { deleted: false as const };\n }\n const uow = forSchema(mcpSchema);\n for (const secret of secrets) {\n uow.delete(\"secret\", secret.id);\n }\n for (const oauthState of oauthStates) {\n uow.delete(\"oauthState\", oauthState.id);\n }\n if (cache) {\n uow.delete(\"server_connection_cache\", cache.id);\n }\n uow.delete(\"server_configuration\", server.id);\n uow.triggerHook(\"onServerConfigurationDeleted\", { serverId: pathParams.slug });\n return { deleted: true as const };\n })\n .execute();\n if (!result.deleted) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return empty(204);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/servers/:slug/auth/status\",\n outputSchema: mcpAuthStatusSchema,\n errorCodes: [\"SERVER_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const [server, secret, pendingState] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .findFirst(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_server_kind\", (eb) =>\n eb.and(eb(\"serverId\", \"=\", pathParams.slug), eb(\"kind\", \"=\", \"auth\")),\n ),\n )\n .findFirst(\"oauthState\", (b) =>\n b\n .whereIndex(\"idx_oauth_state_pending\", (eb) =>\n eb.and(\n eb(\"serverId\", \"=\", pathParams.slug),\n eb.isNull(\"consumedAt\"),\n eb(\"expiresAt\", \">\", eb.now()),\n ),\n )\n .orderByIndex(\"idx_oauth_state_pending\", \"desc\"),\n ),\n )\n .execute();\n if (!server) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return json(\n projectMcpAuthStatus({\n authMode: server.authMode,\n authSecret: secret ?? undefined,\n hasPendingOAuth: pendingOAuthLink(pendingState) !== null,\n }),\n );\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/servers/:slug/auth/pending\",\n outputSchema: mcpOAuthPendingSchema,\n errorCodes: [\"SERVER_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const [server, pendingState] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .findFirst(\"oauthState\", (b) =>\n b\n .whereIndex(\"idx_oauth_state_pending\", (eb) =>\n eb.and(\n eb(\"serverId\", \"=\", pathParams.slug),\n eb.isNull(\"consumedAt\"),\n eb(\"expiresAt\", \">\", eb.now()),\n ),\n )\n .orderByIndex(\"idx_oauth_state_pending\", \"desc\"),\n ),\n )\n .execute();\n if (!server) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return json({ pending: pendingOAuthLink(pendingState) });\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/servers/:slug/auth/token\",\n inputSchema: tokenAuthInputSchema,\n outputSchema: mcpAuthStatusSchema,\n errorCodes: [\"SERVER_NOT_FOUND\"],\n handler: async function ({ input, pathParams }, { json, error }) {\n const { token } = await input.valid();\n const payload = stringifySecretPayload({ type: \"bearer\", token });\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .findFirst(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_server_kind\", (eb) =>\n eb.and(eb(\"serverId\", \"=\", pathParams.slug), eb(\"kind\", \"=\", \"auth\")),\n ),\n )\n .findFirst(\"server_connection_cache\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [server, secret, cache] }) => {\n if (!server) {\n return { found: false as const };\n }\n const uow = forSchema(mcpSchema);\n uow.update(\"server_configuration\", server.id, (b) =>\n b.set({ authMode: \"bearer\", updatedAt: b.now() }).check(),\n );\n if (cache) {\n uow.delete(\"server_connection_cache\", cache.id);\n }\n if (secret) {\n uow.update(\"secret\", secret.id, (b) =>\n b.set({ payload, expiresAt: null, updatedAt: b.now() }).check(),\n );\n } else {\n uow.create(\"secret\", {\n id: `${pathParams.slug}:auth`,\n serverId: pathParams.slug,\n kind: \"auth\",\n payload,\n expiresAt: null,\n });\n }\n uow.triggerHook(\"internalRefreshServerConfiguration\", { serverId: pathParams.slug });\n if (!isMcpAuthReady(server.authMode, secret ?? undefined)) {\n uow.triggerHook(\"onServerReadinessChanged\", {\n serverId: pathParams.slug,\n ready: true,\n });\n }\n return { found: true as const };\n })\n .execute();\n if (!result.found) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return json({ mode: \"bearer\" as const, credentials: \"present\" as const });\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/servers/:slug/auth/start\",\n inputSchema: oauthStartInputSchema,\n outputSchema: z.object({ authorizationUrl: z.string(), state: z.string() }),\n queryParameters: [MCP_OAUTH_REDIRECT_URI_QUERY_PARAMETER],\n errorCodes: [\n \"INVALID_OAUTH_REDIRECT_URI\",\n \"OAUTH_REDIRECT_URI_NOT_ALLOWED\",\n \"SERVER_NOT_FOUND\",\n \"OAUTH_ERROR\",\n ],\n handler: async function ({ input, pathParams, query }, { json, error }) {\n const body = await input.valid();\n const redirectUri = mcpOAuthRedirectUriSchema.safeParse(\n query.get(MCP_OAUTH_REDIRECT_URI_QUERY_PARAMETER),\n );\n if (!redirectUri.success) {\n return error(\n {\n code: \"INVALID_OAUTH_REDIRECT_URI\",\n message: \"MCP OAuth redirect URI must be an HTTP or HTTPS URL\",\n },\n 400,\n );\n }\n const oauthRedirectUri = new URL(redirectUri.data);\n if (!config.allowedOAuthRedirectUris?.(oauthRedirectUri)) {\n return error(\n {\n code: \"OAUTH_REDIRECT_URI_NOT_ALLOWED\",\n message: \"MCP OAuth redirect URI is not allowed by the fragment configuration\",\n },\n 400,\n );\n }\n const state = `${pathParams.slug}:${crypto.randomUUID()}`;\n try {\n const [result] = await this.handlerTx()\n .withServiceCalls(\n () =>\n [\n services.startOAuth({\n serverId: pathParams.slug,\n stateId: state,\n redirectUri: oauthRedirectUri.toString(),\n scope: body.scope,\n clientId: body.clientId,\n clientSecret: body.clientSecret,\n discardTokens: body.discardTokens,\n }),\n ] as const,\n )\n .execute();\n if (!result.found) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return json({ authorizationUrl: result.authorizationUrl, state });\n } catch (err) {\n return error({ code: \"OAUTH_ERROR\", message: (err as Error).message }, 502);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/oauth/callback\",\n outputSchema: z.object({ authenticated: z.boolean(), mode: z.string() }),\n errorCodes: [\"SERVER_NOT_FOUND\", \"OAUTH_ERROR\", \"INVALID_OAUTH_STATE\"],\n handler: async function ({ query }, { json, error }) {\n const code = query.get(\"code\");\n const stateId = query.get(\"state\");\n if (!code || !stateId) {\n return error(\n { code: \"INVALID_OAUTH_STATE\", message: \"Missing OAuth code or state\" },\n 400,\n );\n }\n try {\n const [result] = await this.handlerTx()\n .withServiceCalls(\n () =>\n [\n services.completeOAuthCallback({\n stateId,\n code,\n iss: query.get(\"iss\") ?? undefined,\n }),\n ] as const,\n )\n .execute();\n if (!result.found) {\n if (result.reason === \"server_not_found\") {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return error({ code: \"INVALID_OAUTH_STATE\", message: \"Invalid OAuth state\" }, 400);\n }\n return json({ authenticated: true, mode: \"oauth\" });\n } catch (err) {\n return error({ code: \"OAUTH_ERROR\", message: (err as Error).message }, 502);\n }\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/servers/:slug/auth\",\n outputSchema: mcpAuthStatusSchema,\n errorCodes: [\"SERVER_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_server_kind\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n )\n .find(\"oauthState\", (b) =>\n b.whereIndex(\"idx_oauth_state_server\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n )\n .findFirst(\"server_connection_cache\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [server, secrets, oauthStates, cache] }) => {\n if (!server) {\n return { found: false as const };\n }\n const uow = forSchema(mcpSchema);\n const authSecret = secrets.find((secret) => secret.kind === \"auth\");\n // Only OAuth consent is cleared: the registered client and discovery state stay usable.\n const remainingAuth =\n server.authMode === \"oauth\" && authSecret\n ? { payload: withoutOAuthConsent(authSecret.payload), expiresAt: null }\n : undefined;\n if (server.authMode === \"oauth\") {\n if (authSecret && remainingAuth) {\n uow.update(\"secret\", authSecret.id, (b) =>\n b\n .set({ payload: remainingAuth.payload, expiresAt: null, updatedAt: b.now() })\n .check(),\n );\n }\n } else {\n for (const secret of secrets) {\n uow.delete(\"secret\", secret.id);\n }\n }\n const ready = isMcpAuthReady(server.authMode, remainingAuth);\n if (ready !== isMcpAuthReady(server.authMode, authSecret)) {\n uow.triggerHook(\"onServerReadinessChanged\", { serverId: pathParams.slug, ready });\n }\n for (const oauthState of oauthStates) {\n uow.delete(\"oauthState\", oauthState.id);\n }\n if (cache) {\n uow.delete(\"server_connection_cache\", cache.id);\n }\n // Keep the mode: clearing credentials must not turn the server unauthenticated.\n uow.update(\"server_configuration\", server.id, (b) =>\n b.set({ updatedAt: b.now() }).check(),\n );\n return {\n found: true as const,\n status: projectMcpAuthStatus({\n authMode: server.authMode,\n authSecret: undefined,\n hasPendingOAuth: false,\n }),\n };\n })\n .execute();\n if (!result.found) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n return json(result.status);\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/servers/:slug/refresh\",\n outputSchema: refreshOutputSchema,\n errorCodes: [\"SERVER_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const checkedAt = new Date().toISOString();\n let prepared:\n | {\n authChanges?: AuthPersistenceChanges;\n toolsOperation: Awaited<ReturnType<typeof listMcpTools<AuthPersistenceChanges>>>;\n }\n | undefined;\n let authError: unknown;\n\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_server_kind\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n )\n .findFirst(\"server_connection_cache\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"oauthState\", (b) =>\n b.whereIndex(\"idx_oauth_state_server\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n ),\n )\n .afterRetrieve(async (_uow, [server, secrets]) => {\n if (!server) {\n return;\n }\n\n try {\n const auth = await createMcpOperationAuth({ config, server, secrets });\n const toolsOperation = await listMcpTools({\n endpointUrl: server.endpointUrl,\n auth,\n fetchImplementation: config.fetch,\n });\n prepared = {\n authChanges: toolsOperation.authChanges,\n toolsOperation,\n };\n } catch (err) {\n authError = err;\n }\n })\n .mutate(({ forSchema, retrieveResult: [server, secrets, cache, oauthStates] }) => {\n if (!server) {\n return { found: false as const };\n }\n\n const serverId = server.id.toString();\n const previousTools = Array.isArray(cache?.tools) ? cache.tools : null;\n const baseDiagnostics = {\n checkedAt,\n server: publicServer(server),\n cache: {\n presentBeforeCheck: Boolean(cache),\n previousToolCount: previousTools?.length ?? null,\n updatedToolCount: null,\n },\n };\n\n if (authError) {\n return {\n found: true as const,\n refresh: {\n ...baseDiagnostics,\n ok: false,\n tools: [],\n stage: \"auth\" as const,\n auth: buildAuthDiagnostics({\n mode: server.authMode,\n secrets,\n oauthStates,\n }),\n live: {\n reachable: false,\n listToolsOk: false,\n toolCount: null,\n protocolVersion: null,\n serverInfo: null,\n capabilities: null,\n },\n error: { code: \"AUTH_ERROR\", message: errorMessage(authError) },\n },\n };\n }\n\n if (!prepared) {\n throw new Error(\"MCP refresh operation was not prepared\");\n }\n\n const preparedOperation = prepared;\n const uow = forSchema(mcpSchema);\n const upsertSecret = (kind: string, payload: string, expiresAt: Date | null) => {\n const existing = secrets.find((secret) => secret.kind === kind);\n if (existing) {\n uow.update(\"secret\", existing.id, (b) =>\n b.set({ payload, expiresAt, updatedAt: b.now() }).check(),\n );\n return;\n }\n uow.create(\"secret\", {\n id: `${serverId}:${kind}`,\n serverId,\n kind,\n payload,\n expiresAt,\n });\n };\n\n if (preparedOperation.authChanges) {\n writeOAuthSecretChanges(preparedOperation.authChanges, {\n upsert: (kind, payload) => {\n upsertSecret(kind, payload, null);\n },\n remove: (kind) => {\n const existing = secrets.find((secret) => secret.kind === kind);\n if (existing) {\n uow.delete(\"secret\", existing.id);\n }\n },\n });\n }\n if (preparedOperation.authChanges?.authPayload) {\n const after = {\n payload: preparedOperation.authChanges.authPayload,\n expiresAt: preparedOperation.authChanges.authExpiresAt ?? null,\n };\n upsertSecret(\"auth\", after.payload, after.expiresAt);\n const before = secrets.find((secret) => secret.kind === \"auth\");\n const ready = isMcpAuthReady(server.authMode, after);\n if (ready !== isMcpAuthReady(server.authMode, before)) {\n uow.triggerHook(\"onServerReadinessChanged\", { serverId, ready });\n }\n scheduleMcpAuthExpiry(uow, serverId, server.authMode, after);\n }\n\n const auth = buildAuthDiagnostics({\n mode: server.authMode,\n secrets,\n oauthStates,\n authChanges: preparedOperation.authChanges,\n });\n\n if (!preparedOperation.toolsOperation.ok) {\n return {\n found: true as const,\n refresh: {\n ...baseDiagnostics,\n ok: false,\n tools: [],\n stage: \"list_tools\" as const,\n auth,\n live: {\n reachable: false,\n listToolsOk: false,\n toolCount: null,\n protocolVersion: null,\n serverInfo: null,\n capabilities: null,\n },\n error: {\n code: \"MCP_ERROR\",\n message: errorMessage(preparedOperation.toolsOperation.error),\n },\n },\n };\n }\n\n const tools = Array.isArray(preparedOperation.toolsOperation.result.tools)\n ? preparedOperation.toolsOperation.result.tools\n : [];\n if (!previousTools || JSON.stringify(previousTools) !== JSON.stringify(tools)) {\n uow.triggerHook(\"onServerConfigurationChanged\", {\n serverId,\n current: { tools },\n });\n }\n uow.delete(\"server_connection_cache\", serverId);\n uow.create(\"server_connection_cache\", {\n id: serverId,\n serverId,\n protocolVersion: preparedOperation.toolsOperation.metadata.protocolVersion ?? null,\n serverInfo: preparedOperation.toolsOperation.metadata.serverInfo ?? null,\n capabilities: preparedOperation.toolsOperation.metadata.capabilities ?? null,\n tools,\n });\n\n return {\n found: true as const,\n refresh: {\n ...baseDiagnostics,\n ok: true,\n tools,\n stage: null,\n auth,\n live: {\n reachable: true,\n listToolsOk: true,\n toolCount: tools.length,\n protocolVersion:\n preparedOperation.toolsOperation.metadata.protocolVersion ?? null,\n serverInfo: preparedOperation.toolsOperation.metadata.serverInfo ?? null,\n capabilities: preparedOperation.toolsOperation.metadata.capabilities ?? null,\n },\n cache: {\n ...baseDiagnostics.cache,\n updatedToolCount: tools.length,\n },\n error: null,\n },\n };\n })\n .execute();\n\n if (!result.found) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n\n return json(result.refresh);\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/servers/:slug/tools/execute\",\n inputSchema: toolCallInputSchema,\n outputSchema: mcpToolCallResultSchema,\n errorCodes: [\"SERVER_NOT_FOUND\", \"MCP_ERROR\"],\n handler: async function ({ input, pathParams }, { json, error }) {\n const body = await input.valid();\n try {\n let prepared:\n | {\n serverId: string;\n authChanges?: AuthPersistenceChanges;\n toolOperation: Awaited<ReturnType<typeof callMcpTool<AuthPersistenceChanges>>>;\n }\n | undefined;\n\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(mcpSchema)\n .findFirst(\"server_configuration\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_server_kind\", (eb) =>\n eb(\"serverId\", \"=\", pathParams.slug),\n ),\n )\n .findFirst(\"server_connection_cache\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n ),\n )\n .afterRetrieve(async (_uow, [server, secrets]) => {\n if (!server) {\n return;\n }\n\n const auth = await createMcpOperationAuth({ config, server, secrets });\n const toolOperation = await callMcpTool({\n endpointUrl: server.endpointUrl,\n auth,\n name: body.name,\n toolArguments: body.arguments,\n timeoutMs: body.timeoutMs,\n fetchImplementation: config.fetch,\n });\n prepared = {\n serverId: server.id.toString(),\n authChanges: toolOperation.authChanges,\n toolOperation,\n };\n })\n .mutate(({ forSchema, retrieveResult: [server, secrets, cache] }) => {\n if (!server) {\n return { found: false as const };\n }\n if (!prepared) {\n throw new Error(\"MCP operation was not prepared\");\n }\n\n const preparedOperation = prepared;\n const uow = forSchema(mcpSchema);\n const upsertSecret = (kind: string, payload: string, expiresAt: Date | null) => {\n const existing = secrets.find((secret) => secret.kind === kind);\n if (existing) {\n uow.update(\"secret\", existing.id, (b) =>\n b.set({ payload, expiresAt, updatedAt: b.now() }).check(),\n );\n return;\n }\n uow.create(\"secret\", {\n id: `${preparedOperation.serverId}:${kind}`,\n serverId: preparedOperation.serverId,\n kind,\n payload,\n expiresAt,\n });\n };\n\n if (preparedOperation.authChanges) {\n writeOAuthSecretChanges(preparedOperation.authChanges, {\n upsert: (kind, payload) => {\n upsertSecret(kind, payload, null);\n },\n remove: (kind) => {\n const existing = secrets.find((secret) => secret.kind === kind);\n if (existing) {\n uow.delete(\"secret\", existing.id);\n }\n },\n });\n }\n if (preparedOperation.authChanges?.authPayload) {\n const after = {\n payload: preparedOperation.authChanges.authPayload,\n expiresAt: preparedOperation.authChanges.authExpiresAt ?? null,\n };\n upsertSecret(\"auth\", after.payload, after.expiresAt);\n const before = secrets.find((secret) => secret.kind === \"auth\");\n const ready = isMcpAuthReady(server.authMode, after);\n if (ready !== isMcpAuthReady(server.authMode, before)) {\n uow.triggerHook(\"onServerReadinessChanged\", {\n serverId: preparedOperation.serverId,\n ready,\n });\n }\n scheduleMcpAuthExpiry(uow, preparedOperation.serverId, server.authMode, after);\n }\n\n const toolOperation = preparedOperation.toolOperation;\n if (!toolOperation.ok) {\n return {\n found: true as const,\n error:\n toolOperation.error instanceof Error\n ? toolOperation.error.message\n : String(toolOperation.error),\n };\n }\n\n if (cache) {\n uow.update(\"server_connection_cache\", cache.id, (b) =>\n b\n .set({\n protocolVersion: toolOperation.metadata.protocolVersion ?? null,\n serverInfo: toolOperation.metadata.serverInfo ?? null,\n capabilities: toolOperation.metadata.capabilities ?? null,\n updatedAt: b.now(),\n })\n .check(),\n );\n } else {\n uow.create(\"server_connection_cache\", {\n id: pathParams.slug,\n serverId: pathParams.slug,\n protocolVersion: toolOperation.metadata.protocolVersion ?? null,\n serverInfo: toolOperation.metadata.serverInfo ?? null,\n capabilities: toolOperation.metadata.capabilities ?? null,\n tools: null,\n });\n }\n return { found: true as const, result: toolOperation.result };\n })\n .execute();\n\n if (!result.found) {\n return error({ code: \"SERVER_NOT_FOUND\", message: \"MCP server not found\" }, 404);\n }\n if (\"error\" in result) {\n return error(\n { code: \"MCP_ERROR\", message: result.error ?? \"MCP operation failed\" },\n 502,\n );\n }\n return json(result.result);\n } catch (err) {\n return error({ code: \"MCP_ERROR\", message: (err as Error).message }, 502);\n }\n },\n }),\n ];\n },\n);\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/schema.d.ts
|
|
2
|
+
export declare const mcpSchema: import("@fragno-dev/db/schema").Schema<{
|
|
3
|
+
server_configuration: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"name", import("@fragno-dev/db/schema").Column<"string", string | null, string | null>> & Record<"endpointUrl", import("@fragno-dev/db/schema").Column<"string", string, string>> & Record<"authMode", import("@fragno-dev/db/schema").Column<"string", string, string>> & Record<"createdAt", import("@fragno-dev/db/schema").Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>> & Record<"updatedAt", import("@fragno-dev/db/schema").Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>>, {}>;
|
|
4
|
+
secret: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"serverId", import("@fragno-dev/db/schema").Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>> & Record<"kind", import("@fragno-dev/db/schema").Column<"string", string, string>> & Record<"payload", import("@fragno-dev/db/schema").Column<"text", string, string>> & Record<"expiresAt", import("@fragno-dev/db/schema").Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date | null>> & Record<"updatedAt", import("@fragno-dev/db/schema").Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>>, Record<"idx_secret_server_kind", import("@fragno-dev/db/schema").Index<readonly [import("@fragno-dev/db/schema").Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>, import("@fragno-dev/db/schema").Column<"string", string, string>] & import("@fragno-dev/db/schema").AnyColumn[], readonly ["serverId", "kind"]>>>;
|
|
5
|
+
oauthState: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"serverId", import("@fragno-dev/db/schema").Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>> & Record<"codeVerifier", import("@fragno-dev/db/schema").Column<"text", string, string>> & Record<"redirectUri", import("@fragno-dev/db/schema").Column<"string", string, string>> & Record<"scope", import("@fragno-dev/db/schema").Column<"string", string | null, string | null>> & Record<"expiresAt", import("@fragno-dev/db/schema").Column<"timestamp", Date | import("@fragno-dev/db").DbNow, Date>> & Record<"consumedAt", import("@fragno-dev/db/schema").Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date | null>> & Record<"authorizationUrl", import("@fragno-dev/db/schema").Column<"text", string | null, string | null>>, Record<"idx_oauth_state_server", import("@fragno-dev/db/schema").Index<readonly [import("@fragno-dev/db/schema").Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>] & import("@fragno-dev/db/schema").AnyColumn[], readonly ["serverId"]>> & Record<"idx_oauth_state_pending", import("@fragno-dev/db/schema").Index<readonly [import("@fragno-dev/db/schema").Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>, import("@fragno-dev/db/schema").Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date | null>, import("@fragno-dev/db/schema").Column<"timestamp", Date | import("@fragno-dev/db").DbNow, Date>] & import("@fragno-dev/db/schema").AnyColumn[], readonly ["serverId", "consumedAt", "expiresAt"]>>>;
|
|
6
|
+
server_connection_cache: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"serverId", import("@fragno-dev/db/schema").Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>> & Record<"protocolVersion", import("@fragno-dev/db/schema").Column<"string", string | null, string | null>> & Record<"serverInfo", import("@fragno-dev/db/schema").Column<"json", unknown, unknown>> & Record<"capabilities", import("@fragno-dev/db/schema").Column<"json", unknown, unknown>> & Record<"tools", import("@fragno-dev/db/schema").Column<"json", unknown, unknown>> & Record<"updatedAt", import("@fragno-dev/db/schema").Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>>, Record<"idx_server_connection_cache_server", import("@fragno-dev/db/schema").Index<readonly [import("@fragno-dev/db/schema").Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>] & import("@fragno-dev/db/schema").AnyColumn[], readonly ["serverId"]>>>;
|
|
7
|
+
}>;
|
|
8
|
+
//#endregion
|
|
9
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","names":[],"sources":["../../src/schema.ts"],"mappings":";qBAEa,2CAAS"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { column, idColumn, referenceColumn, schema } from "@fragno-dev/db/schema";
|
|
2
|
+
//#region src/schema.ts
|
|
3
|
+
const mcpSchema = schema("mcp-fragment", (s) => {
|
|
4
|
+
return s.addTable("server_configuration", (t) => t.addColumn("id", idColumn()).addColumn("name", column("string").nullable()).addColumn("endpointUrl", column("string")).addColumn("authMode", column("string")).addColumn("createdAt", column("timestamp").defaultTo((b) => b.now())).addColumn("updatedAt", column("timestamp").defaultTo((b) => b.now()))).addTable("secret", (t) => t.addColumn("id", idColumn()).addColumn("serverId", referenceColumn({ table: "server_configuration" })).addColumn("kind", column("string")).addColumn("payload", column("text")).addColumn("expiresAt", column("timestamp").nullable()).addColumn("updatedAt", column("timestamp").defaultTo((b) => b.now())).createIndex("idx_secret_server_kind", ["serverId", "kind"], { unique: true })).addTable("oauthState", (t) => t.addColumn("id", idColumn()).addColumn("serverId", referenceColumn({ table: "server_configuration" })).addColumn("codeVerifier", column("text")).addColumn("redirectUri", column("string")).addColumn("scope", column("string").nullable()).addColumn("expiresAt", column("timestamp")).addColumn("consumedAt", column("timestamp").nullable()).createIndex("idx_oauth_state_server", ["serverId"])).addTable("server_connection_cache", (t) => t.addColumn("id", idColumn()).addColumn("serverId", referenceColumn({ table: "server_configuration" })).addColumn("protocolVersion", column("string").nullable()).addColumn("serverInfo", column("json").nullable()).addColumn("capabilities", column("json").nullable()).addColumn("tools", column("json").nullable()).addColumn("updatedAt", column("timestamp").defaultTo((b) => b.now())).createIndex("idx_server_connection_cache_server", ["serverId"], { unique: true })).alterTable("oauthState", (t) => t.addColumn("authorizationUrl", column("text").nullable())).alterTable("oauthState", (t) => t.createIndex("idx_oauth_state_pending", [
|
|
5
|
+
"serverId",
|
|
6
|
+
"consumedAt",
|
|
7
|
+
"expiresAt"
|
|
8
|
+
]));
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
export { mcpSchema };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","names":[],"sources":["../../src/schema.ts"],"sourcesContent":["import { column, idColumn, referenceColumn, schema } from \"@fragno-dev/db/schema\";\n\nexport const mcpSchema = schema(\"mcp-fragment\", (s) => {\n return s\n .addTable(\"server_configuration\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"name\", column(\"string\").nullable())\n .addColumn(\"endpointUrl\", column(\"string\"))\n .addColumn(\"authMode\", column(\"string\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n ),\n )\n .addTable(\"secret\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"serverId\", referenceColumn({ table: \"server_configuration\" }))\n .addColumn(\"kind\", column(\"string\"))\n .addColumn(\"payload\", column(\"text\"))\n .addColumn(\"expiresAt\", column(\"timestamp\").nullable())\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_secret_server_kind\", [\"serverId\", \"kind\"], { unique: true }),\n )\n .addTable(\"oauthState\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"serverId\", referenceColumn({ table: \"server_configuration\" }))\n .addColumn(\"codeVerifier\", column(\"text\"))\n .addColumn(\"redirectUri\", column(\"string\"))\n .addColumn(\"scope\", column(\"string\").nullable())\n .addColumn(\"expiresAt\", column(\"timestamp\"))\n .addColumn(\"consumedAt\", column(\"timestamp\").nullable())\n .createIndex(\"idx_oauth_state_server\", [\"serverId\"]),\n )\n .addTable(\"server_connection_cache\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"serverId\", referenceColumn({ table: \"server_configuration\" }))\n .addColumn(\"protocolVersion\", column(\"string\").nullable())\n .addColumn(\"serverInfo\", column(\"json\").nullable())\n .addColumn(\"capabilities\", column(\"json\").nullable())\n .addColumn(\"tools\", column(\"json\").nullable())\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_server_connection_cache_server\", [\"serverId\"], { unique: true }),\n )\n .alterTable(\"oauthState\", (t) =>\n // Null only for states started before links were retained; those cannot be resumed.\n t.addColumn(\"authorizationUrl\", column(\"text\").nullable()),\n )\n .alterTable(\"oauthState\", (t) =>\n // States are retained after use, so pending reads seek the newest live one instead of scanning.\n t.createIndex(\"idx_oauth_state_pending\", [\"serverId\", \"consumedAt\", \"expiresAt\"]),\n );\n});\n"],"mappings":";;AAEA,MAAa,YAAY,OAAO,iBAAiB,MAAM;CACrD,OAAO,EACJ,SAAS,yBAAyB,MACjC,EACG,UAAU,MAAM,SAAS,CAAC,CAAC,CAC3B,UAAU,QAAQ,OAAO,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAC9C,UAAU,eAAe,OAAO,QAAQ,CAAC,CAAC,CAC1C,UAAU,YAAY,OAAO,QAAQ,CAAC,CAAC,CACvC,UACC,aACA,OAAO,WAAW,CAAC,CAAC,WAAW,MAAM,EAAE,IAAI,CAAC,CAC9C,CAAC,CACA,UACC,aACA,OAAO,WAAW,CAAC,CAAC,WAAW,MAAM,EAAE,IAAI,CAAC,CAC9C,CACJ,CAAC,CACA,SAAS,WAAW,MACnB,EACG,UAAU,MAAM,SAAS,CAAC,CAAC,CAC3B,UAAU,YAAY,gBAAgB,EAAE,OAAO,uBAAuB,CAAC,CAAC,CAAC,CACzE,UAAU,QAAQ,OAAO,QAAQ,CAAC,CAAC,CACnC,UAAU,WAAW,OAAO,MAAM,CAAC,CAAC,CACpC,UAAU,aAAa,OAAO,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CACtD,UACC,aACA,OAAO,WAAW,CAAC,CAAC,WAAW,MAAM,EAAE,IAAI,CAAC,CAC9C,CAAC,CACA,YAAY,0BAA0B,CAAC,YAAY,MAAM,GAAG,EAAE,QAAQ,KAAK,CAAC,CACjF,CAAC,CACA,SAAS,eAAe,MACvB,EACG,UAAU,MAAM,SAAS,CAAC,CAAC,CAC3B,UAAU,YAAY,gBAAgB,EAAE,OAAO,uBAAuB,CAAC,CAAC,CAAC,CACzE,UAAU,gBAAgB,OAAO,MAAM,CAAC,CAAC,CACzC,UAAU,eAAe,OAAO,QAAQ,CAAC,CAAC,CAC1C,UAAU,SAAS,OAAO,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAC/C,UAAU,aAAa,OAAO,WAAW,CAAC,CAAC,CAC3C,UAAU,cAAc,OAAO,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,CACvD,YAAY,0BAA0B,CAAC,UAAU,CAAC,CACvD,CAAC,CACA,SAAS,4BAA4B,MACpC,EACG,UAAU,MAAM,SAAS,CAAC,CAAC,CAC3B,UAAU,YAAY,gBAAgB,EAAE,OAAO,uBAAuB,CAAC,CAAC,CAAC,CACzE,UAAU,mBAAmB,OAAO,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CACzD,UAAU,cAAc,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAClD,UAAU,gBAAgB,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CACpD,UAAU,SAAS,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAC7C,UACC,aACA,OAAO,WAAW,CAAC,CAAC,WAAW,MAAM,EAAE,IAAI,CAAC,CAC9C,CAAC,CACA,YAAY,sCAAsC,CAAC,UAAU,GAAG,EAAE,QAAQ,KAAK,CAAC,CACrF,CAAC,CACA,WAAW,eAAe,MAEzB,EAAE,UAAU,oBAAoB,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,CAC3D,CAAC,CACA,WAAW,eAAe,MAEzB,EAAE,YAAY,2BAA2B;EAAC;EAAY;EAAc;CAAW,CAAC,CAClF;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import "./mcp-types.js";
|
|
2
|
+
import "./mcp-api.js";
|
|
3
|
+
import { OAuthProviderChanges } from "./oauth-provider.js";
|
|
4
|
+
import { OAuthTokens } from "@modelcontextprotocol/client";
|
|
5
|
+
//#region src/services.d.ts
|
|
6
|
+
/** A buffered OAuth secret is kept, replaced, or removed because the server rejected it. */
|
|
7
|
+
type OAuthSecretChange = {
|
|
8
|
+
action: "keep";
|
|
9
|
+
} | {
|
|
10
|
+
action: "save";
|
|
11
|
+
payload: string;
|
|
12
|
+
} | {
|
|
13
|
+
action: "remove";
|
|
14
|
+
};
|
|
15
|
+
export declare function prepareOAuthChanges(changes: OAuthProviderChanges): Promise<{
|
|
16
|
+
clientChange: OAuthSecretChange;
|
|
17
|
+
discoveryChange: OAuthSecretChange;
|
|
18
|
+
authorizationUrl?: URL;
|
|
19
|
+
clientInformation?: import("@modelcontextprotocol/server").OAuthClientInformationMixed;
|
|
20
|
+
tokens?: OAuthTokens;
|
|
21
|
+
discoveryState?: import("@modelcontextprotocol/client").OAuthDiscoveryState;
|
|
22
|
+
oauthState?: {
|
|
23
|
+
id: string;
|
|
24
|
+
codeVerifier: string;
|
|
25
|
+
redirectUri: string;
|
|
26
|
+
scope?: string;
|
|
27
|
+
expiresAt: Date;
|
|
28
|
+
};
|
|
29
|
+
consumeStateId?: string;
|
|
30
|
+
tokensInvalidated?: boolean;
|
|
31
|
+
clientInvalidated?: boolean;
|
|
32
|
+
discoveryInvalidated?: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
export type AuthPersistenceChanges = Awaited<ReturnType<typeof prepareOAuthChanges>> & {
|
|
35
|
+
authPayload?: string;
|
|
36
|
+
authExpiresAt?: Date | null;
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=services.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.d.ts","names":[],"sources":["../../src/services.ts"],"mappings":";;;;;;KAWK;EACC;;EACA;EAAgB;;EAChB;;wBASgB,oBAAoB,SAAS,uBAAoB;;;;;;;;;;;IAGpB;;;;;;;;YAmCvC,yBAAyB,QAAQ,kBAAkB;EAC7D;EACA,gBAAgB"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { parseSecretPayload, stringifySecretPayload } from "./mcp-api.js";
|
|
2
|
+
import { BufferedOAuthClientProvider } from "./oauth-provider.js";
|
|
3
|
+
import { auth } from "@modelcontextprotocol/client";
|
|
4
|
+
//#region src/services.ts
|
|
5
|
+
function oauthSecretChange(value, invalidated) {
|
|
6
|
+
if (value) return {
|
|
7
|
+
action: "save",
|
|
8
|
+
payload: stringifySecretPayload(value)
|
|
9
|
+
};
|
|
10
|
+
return invalidated ? { action: "remove" } : { action: "keep" };
|
|
11
|
+
}
|
|
12
|
+
async function prepareOAuthChanges(changes) {
|
|
13
|
+
return {
|
|
14
|
+
...changes,
|
|
15
|
+
clientChange: oauthSecretChange(changes.clientInformation, changes.clientInvalidated),
|
|
16
|
+
discoveryChange: oauthSecretChange(changes.discoveryState, changes.discoveryInvalidated)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** Applies the client and discovery changes through a write site's own secret writers. */
|
|
20
|
+
function writeOAuthSecretChanges(changes, writers) {
|
|
21
|
+
for (const [kind, change] of [["oauth-client", changes.clientChange], ["oauth-discovery", changes.discoveryChange]]) switch (change.action) {
|
|
22
|
+
case "keep": break;
|
|
23
|
+
case "save":
|
|
24
|
+
writers.upsert(kind, change.payload);
|
|
25
|
+
break;
|
|
26
|
+
case "remove":
|
|
27
|
+
writers.remove(kind);
|
|
28
|
+
break;
|
|
29
|
+
default: throw new Error("Unknown OAuth secret change.", { cause: change });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function tokenExpiry(tokens) {
|
|
33
|
+
return typeof tokens.expires_in === "number" ? new Date(Date.now() + tokens.expires_in * 1e3) : null;
|
|
34
|
+
}
|
|
35
|
+
function secretByKind(secrets, kind) {
|
|
36
|
+
return secrets.find((secret) => secret.kind === kind);
|
|
37
|
+
}
|
|
38
|
+
const TOKEN_EXPIRY_SKEW_MS = 3e4;
|
|
39
|
+
function secretExpiresInFuture(secret) {
|
|
40
|
+
if (!secret?.expiresAt) return false;
|
|
41
|
+
return new Date(secret.expiresAt).getTime() > Date.now() + TOKEN_EXPIRY_SKEW_MS;
|
|
42
|
+
}
|
|
43
|
+
function secretIsUnexpired(secret) {
|
|
44
|
+
return !secret?.expiresAt || secretExpiresInFuture(secret);
|
|
45
|
+
}
|
|
46
|
+
/** Projects stored auth without secrets; whether credentials work can only be learned by using them. */
|
|
47
|
+
function projectMcpAuthStatus(args) {
|
|
48
|
+
const mode = args.authMode;
|
|
49
|
+
if (mode === "none") return { mode };
|
|
50
|
+
if (mode !== "oauth") return {
|
|
51
|
+
mode,
|
|
52
|
+
credentials: args.authSecret ? "present" : "missing"
|
|
53
|
+
};
|
|
54
|
+
const auth = args.authSecret ? parseSecretPayload(args.authSecret.payload) : void 0;
|
|
55
|
+
const tokens = auth?.type === "oauth" ? auth.tokens : void 0;
|
|
56
|
+
if (tokens?.access_token && (tokens.refresh_token || secretIsUnexpired(args.authSecret))) return {
|
|
57
|
+
mode,
|
|
58
|
+
state: "authorized"
|
|
59
|
+
};
|
|
60
|
+
if (args.hasPendingOAuth) return {
|
|
61
|
+
mode,
|
|
62
|
+
state: "consent-pending"
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
mode,
|
|
66
|
+
state: tokens?.access_token ? "expired" : "consent-required"
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Whether stored auth can authorize operations without new consent or credentials. */
|
|
70
|
+
function isMcpAuthReady(authMode, authSecret) {
|
|
71
|
+
const status = projectMcpAuthStatus({
|
|
72
|
+
authMode,
|
|
73
|
+
authSecret,
|
|
74
|
+
hasPendingOAuth: false
|
|
75
|
+
});
|
|
76
|
+
switch (status.mode) {
|
|
77
|
+
case "none": return true;
|
|
78
|
+
case "oauth": return status.state === "authorized";
|
|
79
|
+
case "bearer":
|
|
80
|
+
case "client_credentials": return status.credentials === "present";
|
|
81
|
+
default: throw new Error("Unknown MCP auth mode.", { cause: status });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* When stored auth stops authorizing operations because its access token expires without renewal,
|
|
86
|
+
* whether or not that moment has passed. Null when a refresh token renews it or nothing expires.
|
|
87
|
+
*/
|
|
88
|
+
function mcpAuthReadyUntil(authMode, authSecret) {
|
|
89
|
+
if (authMode !== "oauth" || !authSecret.expiresAt) return null;
|
|
90
|
+
const auth = parseSecretPayload(authSecret.payload);
|
|
91
|
+
if (auth.type !== "oauth" || !auth.tokens?.access_token || auth.tokens.refresh_token) return null;
|
|
92
|
+
return /* @__PURE__ */ new Date(new Date(authSecret.expiresAt).getTime() - TOKEN_EXPIRY_SKEW_MS);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Projects the newest unexpired, unconsumed state; any such state completes the same server.
|
|
96
|
+
* States started before links were retained have no URL and cannot be resumed.
|
|
97
|
+
*/
|
|
98
|
+
function pendingOAuthLink(state) {
|
|
99
|
+
return state?.authorizationUrl ? {
|
|
100
|
+
authorizationUrl: state.authorizationUrl,
|
|
101
|
+
expiresAt: state.expiresAt
|
|
102
|
+
} : null;
|
|
103
|
+
}
|
|
104
|
+
/** Start requests may override the configured client; otherwise the stored configuration applies. */
|
|
105
|
+
function resolveOAuthStartClient(secrets, input) {
|
|
106
|
+
const authSecret = secretByKind(secrets, "auth");
|
|
107
|
+
const stored = authSecret ? parseSecretPayload(authSecret.payload) : void 0;
|
|
108
|
+
const configured = stored?.type === "oauth" ? stored : void 0;
|
|
109
|
+
return {
|
|
110
|
+
scope: input.scope ?? configured?.scopes?.join(" "),
|
|
111
|
+
...input.clientId ? {
|
|
112
|
+
clientId: input.clientId,
|
|
113
|
+
clientSecret: input.clientSecret
|
|
114
|
+
} : {
|
|
115
|
+
clientId: configured?.clientId,
|
|
116
|
+
clientSecret: configured?.clientSecret
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** Clearing OAuth consent keeps the configured client and scopes for the next start. */
|
|
121
|
+
function withoutOAuthConsent(payload) {
|
|
122
|
+
const { tokens: _tokens, redirectUri: _redirectUri, ...configuration } = parseSecretPayload(payload);
|
|
123
|
+
return stringifySecretPayload(configuration);
|
|
124
|
+
}
|
|
125
|
+
async function parseSecretKind(secrets, kind) {
|
|
126
|
+
const secret = secretByKind(secrets, kind);
|
|
127
|
+
return secret ? parseSecretPayload(secret.payload) : void 0;
|
|
128
|
+
}
|
|
129
|
+
async function createOAuthStartSnapshot(args) {
|
|
130
|
+
const snapshot = {
|
|
131
|
+
serverId: args.server.id.toString(),
|
|
132
|
+
endpointUrl: args.server.endpointUrl,
|
|
133
|
+
redirectUrl: args.redirectUri,
|
|
134
|
+
scope: args.scope,
|
|
135
|
+
stateId: args.stateId,
|
|
136
|
+
clientId: args.clientId,
|
|
137
|
+
clientSecret: args.clientSecret,
|
|
138
|
+
clientInformation: await parseSecretKind(args.secrets, "oauth-client"),
|
|
139
|
+
discoveryState: await parseSecretKind(args.secrets, "oauth-discovery")
|
|
140
|
+
};
|
|
141
|
+
const provider = new BufferedOAuthClientProvider(snapshot);
|
|
142
|
+
await auth(provider, {
|
|
143
|
+
serverUrl: snapshot.endpointUrl,
|
|
144
|
+
scope: args.scope,
|
|
145
|
+
fetchFn: args.config.fetch
|
|
146
|
+
});
|
|
147
|
+
const authorizationUrl = provider.changes.authorizationUrl;
|
|
148
|
+
if (!authorizationUrl) throw new Error("OAuth authorization did not produce a redirect URL");
|
|
149
|
+
return {
|
|
150
|
+
authorizationUrl,
|
|
151
|
+
changes: await prepareOAuthChanges(provider.changes)
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
async function createOAuthCallbackSnapshot(args) {
|
|
155
|
+
const authPayload = await parseSecretKind(args.secrets, "auth");
|
|
156
|
+
const snapshot = {
|
|
157
|
+
serverId: args.server.id.toString(),
|
|
158
|
+
endpointUrl: args.server.endpointUrl,
|
|
159
|
+
redirectUrl: args.state.redirectUri,
|
|
160
|
+
scope: args.state.scope ?? void 0,
|
|
161
|
+
stateId: args.stateId,
|
|
162
|
+
clientInformation: await parseSecretKind(args.secrets, "oauth-client"),
|
|
163
|
+
tokens: authPayload?.tokens,
|
|
164
|
+
discoveryState: await parseSecretKind(args.secrets, "oauth-discovery"),
|
|
165
|
+
oauthState: {
|
|
166
|
+
id: args.state.id.toString(),
|
|
167
|
+
codeVerifier: args.state.codeVerifier,
|
|
168
|
+
redirectUri: args.state.redirectUri,
|
|
169
|
+
scope: args.state.scope ?? void 0,
|
|
170
|
+
expiresAt: new Date(args.state.expiresAt),
|
|
171
|
+
consumedAt: args.state.consumedAt ? new Date(args.state.consumedAt) : null
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const provider = new BufferedOAuthClientProvider(snapshot);
|
|
175
|
+
await auth(provider, {
|
|
176
|
+
serverUrl: snapshot.endpointUrl,
|
|
177
|
+
authorizationCode: args.code,
|
|
178
|
+
iss: args.iss,
|
|
179
|
+
scope: snapshot.scope,
|
|
180
|
+
fetchFn: args.config.fetch
|
|
181
|
+
});
|
|
182
|
+
provider.consumeState();
|
|
183
|
+
const changes = await prepareOAuthChanges(provider.changes);
|
|
184
|
+
return {
|
|
185
|
+
...changes,
|
|
186
|
+
...changes.tokens ? {
|
|
187
|
+
authPayload: stringifySecretPayload({
|
|
188
|
+
...authPayload,
|
|
189
|
+
type: "oauth",
|
|
190
|
+
redirectUri: args.state.redirectUri,
|
|
191
|
+
tokens: changes.tokens
|
|
192
|
+
}),
|
|
193
|
+
authExpiresAt: tokenExpiry(changes.tokens)
|
|
194
|
+
} : {}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const providerHasChanges = (changes) => Boolean(changes.clientInformation || changes.discoveryState || changes.tokens || changes.tokensInvalidated || changes.clientInvalidated || changes.discoveryInvalidated);
|
|
198
|
+
function authChangesReader(provider, authPayload) {
|
|
199
|
+
return async () => {
|
|
200
|
+
if (!providerHasChanges(provider.changes)) return;
|
|
201
|
+
const tokens = provider.tokens();
|
|
202
|
+
return {
|
|
203
|
+
...await prepareOAuthChanges(provider.changes),
|
|
204
|
+
...provider.changes.tokens || provider.changes.tokensInvalidated ? {
|
|
205
|
+
authPayload: stringifySecretPayload({
|
|
206
|
+
...authPayload,
|
|
207
|
+
tokens
|
|
208
|
+
}),
|
|
209
|
+
authExpiresAt: tokens ? tokenExpiry(tokens) : null
|
|
210
|
+
} : {}
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
async function createMcpOperationAuth(args) {
|
|
215
|
+
const authSecret = secretByKind(args.secrets, "auth");
|
|
216
|
+
const authPayload = authSecret ? parseSecretPayload(authSecret.payload) : void 0;
|
|
217
|
+
if (!authPayload) return;
|
|
218
|
+
if (authPayload.type === "bearer") return {
|
|
219
|
+
type: "bearer",
|
|
220
|
+
token: authPayload.token
|
|
221
|
+
};
|
|
222
|
+
if (authPayload.type === "oauth") {
|
|
223
|
+
if (!authPayload.tokens?.access_token) return;
|
|
224
|
+
const clientSecret = secretByKind(args.secrets, "oauth-client");
|
|
225
|
+
const discoverySecret = secretByKind(args.secrets, "oauth-discovery");
|
|
226
|
+
const provider = new BufferedOAuthClientProvider({
|
|
227
|
+
serverId: args.server.id.toString(),
|
|
228
|
+
endpointUrl: args.server.endpointUrl,
|
|
229
|
+
redirectUrl: authPayload.redirectUri,
|
|
230
|
+
scope: authPayload.tokens.scope,
|
|
231
|
+
clientInformation: clientSecret ? parseSecretPayload(clientSecret.payload) : void 0,
|
|
232
|
+
tokens: authPayload.tokens,
|
|
233
|
+
discoveryState: discoverySecret ? parseSecretPayload(discoverySecret.payload) : void 0
|
|
234
|
+
});
|
|
235
|
+
return {
|
|
236
|
+
type: "provider",
|
|
237
|
+
provider,
|
|
238
|
+
readAuthChanges: authChangesReader(provider, authPayload)
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
const discoverySecret = secretByKind(args.secrets, "oauth-discovery");
|
|
242
|
+
const provider = new BufferedOAuthClientProvider({
|
|
243
|
+
serverId: args.server.id.toString(),
|
|
244
|
+
endpointUrl: args.server.endpointUrl,
|
|
245
|
+
scope: authPayload.scopes?.join(" "),
|
|
246
|
+
clientId: authPayload.clientId,
|
|
247
|
+
clientSecret: authPayload.clientSecret,
|
|
248
|
+
tokens: authPayload.tokens,
|
|
249
|
+
discoveryState: discoverySecret ? parseSecretPayload(discoverySecret.payload) : void 0,
|
|
250
|
+
flow: "client_credentials"
|
|
251
|
+
});
|
|
252
|
+
return {
|
|
253
|
+
type: "provider",
|
|
254
|
+
provider,
|
|
255
|
+
readAuthChanges: authChangesReader(provider, authPayload)
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
async function resolveMcpOperationAuth(args) {
|
|
259
|
+
const authSecret = secretByKind(args.secrets, "auth");
|
|
260
|
+
const authPayload = authSecret ? parseSecretPayload(authSecret.payload) : void 0;
|
|
261
|
+
if (!authPayload || authPayload.type === "bearer") return { token: authPayload?.token };
|
|
262
|
+
if (authPayload.type === "oauth") {
|
|
263
|
+
if (!authPayload.tokens?.access_token) return {};
|
|
264
|
+
if (secretIsUnexpired(authSecret)) return { token: authPayload.tokens.access_token };
|
|
265
|
+
if (!authPayload.tokens.refresh_token) throw new Error("OAuth access token expired and no refresh token is available");
|
|
266
|
+
const clientSecret = secretByKind(args.secrets, "oauth-client");
|
|
267
|
+
const discoverySecret = secretByKind(args.secrets, "oauth-discovery");
|
|
268
|
+
const provider = new BufferedOAuthClientProvider({
|
|
269
|
+
serverId: args.server.id.toString(),
|
|
270
|
+
endpointUrl: args.server.endpointUrl,
|
|
271
|
+
redirectUrl: authPayload.redirectUri,
|
|
272
|
+
scope: authPayload.tokens.scope,
|
|
273
|
+
clientInformation: clientSecret ? parseSecretPayload(clientSecret.payload) : void 0,
|
|
274
|
+
tokens: authPayload.tokens,
|
|
275
|
+
discoveryState: discoverySecret ? parseSecretPayload(discoverySecret.payload) : void 0
|
|
276
|
+
});
|
|
277
|
+
await auth(provider, {
|
|
278
|
+
serverUrl: args.server.endpointUrl,
|
|
279
|
+
scope: authPayload.tokens.scope,
|
|
280
|
+
fetchFn: args.config.fetch
|
|
281
|
+
});
|
|
282
|
+
const tokens = provider.changes.tokens ?? authPayload.tokens;
|
|
283
|
+
if (!tokens.access_token) throw new Error("OAuth refresh did not return an access token");
|
|
284
|
+
return {
|
|
285
|
+
token: tokens.access_token,
|
|
286
|
+
authChanges: {
|
|
287
|
+
...await prepareOAuthChanges(provider.changes),
|
|
288
|
+
authPayload: stringifySecretPayload({
|
|
289
|
+
...authPayload,
|
|
290
|
+
tokens
|
|
291
|
+
}),
|
|
292
|
+
authExpiresAt: tokenExpiry(tokens)
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
if (authPayload.tokens?.access_token && secretExpiresInFuture(authSecret)) return { token: authPayload.tokens.access_token };
|
|
297
|
+
const discoverySecret = secretByKind(args.secrets, "oauth-discovery");
|
|
298
|
+
const provider = new BufferedOAuthClientProvider({
|
|
299
|
+
serverId: args.server.id.toString(),
|
|
300
|
+
endpointUrl: args.server.endpointUrl,
|
|
301
|
+
scope: authPayload.scopes?.join(" "),
|
|
302
|
+
clientId: authPayload.clientId,
|
|
303
|
+
clientSecret: authPayload.clientSecret,
|
|
304
|
+
tokens: authPayload.tokens,
|
|
305
|
+
discoveryState: discoverySecret ? parseSecretPayload(discoverySecret.payload) : void 0,
|
|
306
|
+
flow: "client_credentials"
|
|
307
|
+
});
|
|
308
|
+
await auth(provider, {
|
|
309
|
+
serverUrl: args.server.endpointUrl,
|
|
310
|
+
scope: authPayload.scopes?.join(" "),
|
|
311
|
+
fetchFn: args.config.fetch
|
|
312
|
+
});
|
|
313
|
+
const tokens = provider.changes.tokens ?? authPayload.tokens;
|
|
314
|
+
if (!tokens?.access_token) throw new Error("Client credentials flow did not return an access token");
|
|
315
|
+
return {
|
|
316
|
+
token: tokens.access_token,
|
|
317
|
+
authChanges: {
|
|
318
|
+
...await prepareOAuthChanges(provider.changes),
|
|
319
|
+
authPayload: stringifySecretPayload({
|
|
320
|
+
...authPayload,
|
|
321
|
+
tokens
|
|
322
|
+
}),
|
|
323
|
+
authExpiresAt: tokenExpiry(tokens)
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
//#endregion
|
|
328
|
+
export { createMcpOperationAuth, createOAuthCallbackSnapshot, createOAuthStartSnapshot, isMcpAuthReady, mcpAuthReadyUntil, pendingOAuthLink, prepareOAuthChanges, projectMcpAuthStatus, resolveMcpOperationAuth, resolveOAuthStartClient, tokenExpiry, withoutOAuthConsent, writeOAuthSecretChanges };
|
|
329
|
+
|
|
330
|
+
//# sourceMappingURL=services.js.map
|