@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.
Files changed (90) hide show
  1. package/LICENSE.md +16 -0
  2. package/README.md +312 -2
  3. package/bin/run.js +7 -0
  4. package/dist/browser/client/react.d.ts +253 -0
  5. package/dist/browser/client/react.d.ts.map +1 -0
  6. package/dist/browser/client/react.js +194 -0
  7. package/dist/browser/client/react.js.map +1 -0
  8. package/dist/browser/client/solid.d.ts +256 -0
  9. package/dist/browser/client/solid.d.ts.map +1 -0
  10. package/dist/browser/client/solid.js +129 -0
  11. package/dist/browser/client/solid.js.map +1 -0
  12. package/dist/browser/client/svelte.d.ts +256 -0
  13. package/dist/browser/client/svelte.d.ts.map +1 -0
  14. package/dist/browser/client/svelte.js +131 -0
  15. package/dist/browser/client/svelte.js.map +1 -0
  16. package/dist/browser/client/vanilla.d.ts +283 -0
  17. package/dist/browser/client/vanilla.d.ts.map +1 -0
  18. package/dist/browser/client/vanilla.js +159 -0
  19. package/dist/browser/client/vanilla.js.map +1 -0
  20. package/dist/browser/client/vue.d.ts +256 -0
  21. package/dist/browser/client/vue.d.ts.map +1 -0
  22. package/dist/browser/client/vue.js +127 -0
  23. package/dist/browser/client/vue.js.map +1 -0
  24. package/dist/browser/client-BCzNDSlW.d.ts +711 -0
  25. package/dist/browser/client-BCzNDSlW.d.ts.map +1 -0
  26. package/dist/browser/index.d.ts +813 -0
  27. package/dist/browser/index.d.ts.map +1 -0
  28. package/dist/browser/index.js +1 -0
  29. package/dist/browser/src-B6dHZXqB.js +2303 -0
  30. package/dist/browser/src-B6dHZXqB.js.map +1 -0
  31. package/dist/cli/cli.d.ts +6 -0
  32. package/dist/cli/cli.d.ts.map +1 -0
  33. package/dist/cli/cli.js +227 -0
  34. package/dist/cli/cli.js.map +1 -0
  35. package/dist/cli/definition.js +330 -0
  36. package/dist/cli/definition.js.map +1 -0
  37. package/dist/cli/diagnostics.js +93 -0
  38. package/dist/cli/diagnostics.js.map +1 -0
  39. package/dist/cli/index.js +13 -0
  40. package/dist/cli/index.js.map +1 -0
  41. package/dist/cli/mcp-api.js +87 -0
  42. package/dist/cli/mcp-api.js.map +1 -0
  43. package/dist/cli/mcp-types.js +100 -0
  44. package/dist/cli/mcp-types.js.map +1 -0
  45. package/dist/cli/oauth-provider.js +113 -0
  46. package/dist/cli/oauth-provider.js.map +1 -0
  47. package/dist/cli/routes.js +743 -0
  48. package/dist/cli/routes.js.map +1 -0
  49. package/dist/cli/schema.js +13 -0
  50. package/dist/cli/schema.js.map +1 -0
  51. package/dist/cli/services.js +330 -0
  52. package/dist/cli/services.js.map +1 -0
  53. package/dist/node/definition.d.ts +260 -0
  54. package/dist/node/definition.d.ts.map +1 -0
  55. package/dist/node/definition.js +330 -0
  56. package/dist/node/definition.js.map +1 -0
  57. package/dist/node/diagnostics.js +93 -0
  58. package/dist/node/diagnostics.js.map +1 -0
  59. package/dist/node/index.d.ts +694 -0
  60. package/dist/node/index.d.ts.map +1 -0
  61. package/dist/node/index.js +26 -0
  62. package/dist/node/index.js.map +1 -0
  63. package/dist/node/mcp-api.d.ts +2 -0
  64. package/dist/node/mcp-api.js +87 -0
  65. package/dist/node/mcp-api.js.map +1 -0
  66. package/dist/node/mcp-types.d.ts +146 -0
  67. package/dist/node/mcp-types.d.ts.map +1 -0
  68. package/dist/node/mcp-types.js +100 -0
  69. package/dist/node/mcp-types.js.map +1 -0
  70. package/dist/node/oauth-provider.d.ts +24 -0
  71. package/dist/node/oauth-provider.d.ts.map +1 -0
  72. package/dist/node/oauth-provider.js +113 -0
  73. package/dist/node/oauth-provider.js.map +1 -0
  74. package/dist/node/routes.d.ts +466 -0
  75. package/dist/node/routes.d.ts.map +1 -0
  76. package/dist/node/routes.js +743 -0
  77. package/dist/node/routes.js.map +1 -0
  78. package/dist/node/schema.d.ts +9 -0
  79. package/dist/node/schema.d.ts.map +1 -0
  80. package/dist/node/schema.js +13 -0
  81. package/dist/node/schema.js.map +1 -0
  82. package/dist/node/services.d.ts +40 -0
  83. package/dist/node/services.d.ts.map +1 -0
  84. package/dist/node/services.js +330 -0
  85. package/dist/node/services.js.map +1 -0
  86. package/dist/node/testing/mcp-test-server.d.ts +42 -0
  87. package/dist/node/testing/mcp-test-server.d.ts.map +1 -0
  88. package/dist/node/testing/mcp-test-server.js +218 -0
  89. package/dist/node/testing/mcp-test-server.js.map +1 -0
  90. 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