@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":"index.d.ts","names":["_$__definition0.McpHooksMap","_$__services0.AuthPersistenceChanges"],"sources":["../../src/index.ts"],"mappings":";;;;;wBAUgB,kBACd,QAAQ,mBACR,cAAc,4DAA8B,gEAAA,oDAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oIAA9BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuB8uS;IAA2B;IAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAPnzS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BATJ,8DAAA,uBAAAA,mEAAA,wBAAA;wBAEe,yBAAyB,eAAc"}
@@ -0,0 +1,26 @@
1
+ import { mcpFragmentDefinition } from "./definition.js";
2
+ import { mcpRoutesFactory } from "./routes.js";
3
+ import { createClientBuilder } from "@fragno-dev/core/client";
4
+ import { instantiate } from "@fragno-dev/core";
5
+ //#region src/index.ts
6
+ const routes = [mcpRoutesFactory];
7
+ function createMcpFragment(config, fragnoConfig) {
8
+ return instantiate(mcpFragmentDefinition).withConfig(config).withRoutes(routes).withOptions(fragnoConfig).build();
9
+ }
10
+ function createMcpFragmentClients(fragnoConfig = {}) {
11
+ const builder = createClientBuilder(mcpFragmentDefinition, fragnoConfig, routes);
12
+ return {
13
+ useServers: builder.createHook("/servers"),
14
+ useServer: builder.createHook("/servers/:slug"),
15
+ createServer: builder.createMutator("POST", "/servers"),
16
+ refreshServer: builder.createMutator("POST", "/servers/:slug/refresh"),
17
+ callTool: builder.createMutator("POST", "/servers/:slug/tools/execute"),
18
+ setToken: builder.createMutator("POST", "/servers/:slug/auth/token"),
19
+ startOAuth: builder.createMutator("POST", "/servers/:slug/auth/start"),
20
+ deleteAuth: builder.createMutator("DELETE", "/servers/:slug/auth")
21
+ };
22
+ }
23
+ //#endregion
24
+ export { createMcpFragment, createMcpFragmentClients };
25
+
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { createClientBuilder, type FragnoPublicClientConfig } from \"@fragno-dev/core/client\";\n\nimport { instantiate } from \"@fragno-dev/core\";\nimport type { FragnoPublicConfigWithDatabase } from \"@fragno-dev/db\";\n\nimport { mcpFragmentDefinition, type McpFragmentConfig } from \"./definition\";\nimport { mcpRoutesFactory } from \"./routes\";\n\nconst routes = [mcpRoutesFactory] as const;\n\nexport function createMcpFragment(\n config: McpFragmentConfig,\n fragnoConfig: FragnoPublicConfigWithDatabase,\n) {\n return instantiate(mcpFragmentDefinition)\n .withConfig(config)\n .withRoutes(routes)\n .withOptions(fragnoConfig)\n .build();\n}\n\nexport function createMcpFragmentClients(fragnoConfig: FragnoPublicClientConfig = {}) {\n const builder = createClientBuilder(mcpFragmentDefinition, fragnoConfig, routes);\n\n return {\n useServers: builder.createHook(\"/servers\"),\n useServer: builder.createHook(\"/servers/:slug\"),\n createServer: builder.createMutator(\"POST\", \"/servers\"),\n refreshServer: builder.createMutator(\"POST\", \"/servers/:slug/refresh\"),\n callTool: builder.createMutator(\"POST\", \"/servers/:slug/tools/execute\"),\n setToken: builder.createMutator(\"POST\", \"/servers/:slug/auth/token\"),\n startOAuth: builder.createMutator(\"POST\", \"/servers/:slug/auth/start\"),\n deleteAuth: builder.createMutator(\"DELETE\", \"/servers/:slug/auth\"),\n };\n}\n"],"mappings":";;;;;AAQA,MAAM,SAAS,CAAC,gBAAgB;AAEhC,SAAgB,kBACd,QACA,cACA;CACA,OAAO,YAAY,qBAAqB,CAAC,CACtC,WAAW,MAAM,CAAC,CAClB,WAAW,MAAM,CAAC,CAClB,YAAY,YAAY,CAAC,CACzB,MAAM;AACX;AAEA,SAAgB,yBAAyB,eAAyC,CAAC,GAAG;CACpF,MAAM,UAAU,oBAAoB,uBAAuB,cAAc,MAAM;CAE/E,OAAO;EACL,YAAY,QAAQ,WAAW,UAAU;EACzC,WAAW,QAAQ,WAAW,gBAAgB;EAC9C,cAAc,QAAQ,cAAc,QAAQ,UAAU;EACtD,eAAe,QAAQ,cAAc,QAAQ,wBAAwB;EACrE,UAAU,QAAQ,cAAc,QAAQ,8BAA8B;EACtE,UAAU,QAAQ,cAAc,QAAQ,2BAA2B;EACnE,YAAY,QAAQ,cAAc,QAAQ,2BAA2B;EACrE,YAAY,QAAQ,cAAc,UAAU,qBAAqB;CACnE;AACF"}
@@ -0,0 +1,2 @@
1
+ import "./mcp-types.js";
2
+ import "@modelcontextprotocol/client";
@@ -0,0 +1,87 @@
1
+ import { Client, StreamableHTTPClientTransport } from "@modelcontextprotocol/client";
2
+ //#region src/mcp-api.ts
3
+ function assertAllowedEndpoint(endpointUrl, config) {
4
+ const url = new URL(endpointUrl);
5
+ if (url.protocol !== "https:" && url.protocol !== "http:") throw new Error("MCP endpoint must be an HTTP(S) URL");
6
+ if (config.allowedEndpointUrls && !config.allowedEndpointUrls(url)) throw new Error("MCP endpoint is not allowed");
7
+ return url;
8
+ }
9
+ function stringifySecretPayload(value) {
10
+ return JSON.stringify(value);
11
+ }
12
+ function parseSecretPayload(value) {
13
+ return JSON.parse(value);
14
+ }
15
+ function bearerRequestInit(token) {
16
+ if (!token) return;
17
+ return { headers: { Authorization: `Bearer ${token}` } };
18
+ }
19
+ const authProvider = (auth) => auth?.type === "provider" ? auth.provider : void 0;
20
+ const authRequestInit = (auth) => auth?.type === "bearer" ? bearerRequestInit(auth.token) : void 0;
21
+ async function readAuthChanges(auth) {
22
+ return auth?.type === "provider" ? await auth.readAuthChanges() : void 0;
23
+ }
24
+ async function withMcpClient(args) {
25
+ const client = new Client({
26
+ name: "fragno-mcp-fragment",
27
+ version: "0.1.0"
28
+ }, {
29
+ capabilities: {},
30
+ versionNegotiation: { mode: "auto" }
31
+ });
32
+ const transport = new StreamableHTTPClientTransport(new URL(args.endpointUrl), {
33
+ fetch: args.fetchImplementation,
34
+ requestInit: authRequestInit(args.auth),
35
+ authProvider: authProvider(args.auth)
36
+ });
37
+ try {
38
+ await client.connect(transport, { timeout: args.timeoutMs });
39
+ const capabilities = client.getServerCapabilities();
40
+ const metadata = {
41
+ protocolVersion: client.getNegotiatedProtocolVersion(),
42
+ serverInfo: client.getServerVersion(),
43
+ capabilities
44
+ };
45
+ return {
46
+ ok: true,
47
+ result: await args.operation(client),
48
+ metadata,
49
+ authChanges: await readAuthChanges(args.auth)
50
+ };
51
+ } catch (error) {
52
+ return {
53
+ ok: false,
54
+ error,
55
+ authChanges: await readAuthChanges(args.auth)
56
+ };
57
+ } finally {
58
+ await transport.close().catch(() => void 0);
59
+ await client.close().catch(() => void 0);
60
+ }
61
+ }
62
+ async function listMcpTools(args) {
63
+ return await withMcpClient({
64
+ ...args,
65
+ operation: (client) => client.listTools(void 0, { timeout: args.timeoutMs })
66
+ });
67
+ }
68
+ async function callMcpTool(args) {
69
+ return await withMcpClient({
70
+ ...args,
71
+ operation: async (client) => {
72
+ const result = await client.callTool({
73
+ name: args.name,
74
+ arguments: args.toolArguments ?? {}
75
+ }, { timeout: args.timeoutMs });
76
+ return {
77
+ isError: result.isError === true,
78
+ content: Array.isArray(result.content) ? result.content : [],
79
+ structuredContent: result.structuredContent ?? null
80
+ };
81
+ }
82
+ });
83
+ }
84
+ //#endregion
85
+ export { assertAllowedEndpoint, callMcpTool, listMcpTools, parseSecretPayload, stringifySecretPayload };
86
+
87
+ //# sourceMappingURL=mcp-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-api.js","names":[],"sources":["../../src/mcp-api.ts"],"sourcesContent":["import {\n Client,\n StreamableHTTPClientTransport,\n type OAuthClientProvider,\n} from \"@modelcontextprotocol/client\";\n\nimport type { McpFragmentConfig, McpToolCallResult } from \"./mcp-types\";\n\nexport interface StoredServerAuth {\n mode: string;\n payload?: unknown;\n}\n\nexport interface McpConnectionMetadata {\n protocolVersion?: string;\n serverInfo?: unknown;\n capabilities?: unknown;\n}\n\nexport type McpClientAuth<TAuthChanges = unknown> =\n | { type: \"bearer\"; token?: string }\n | {\n type: \"provider\";\n provider: OAuthClientProvider;\n readAuthChanges: () => Promise<TAuthChanges | undefined>;\n };\n\nexport type McpOperationResult<T, TAuthChanges = unknown> =\n | {\n ok: true;\n result: T;\n metadata: McpConnectionMetadata;\n authChanges?: TAuthChanges;\n }\n | { ok: false; error: unknown; authChanges?: TAuthChanges };\n\nexport function assertAllowedEndpoint(endpointUrl: string, config: McpFragmentConfig) {\n const url = new URL(endpointUrl);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n throw new Error(\"MCP endpoint must be an HTTP(S) URL\");\n }\n if (config.allowedEndpointUrls && !config.allowedEndpointUrls(url)) {\n throw new Error(\"MCP endpoint is not allowed\");\n }\n return url;\n}\n\nexport function stringifySecretPayload(value: unknown) {\n return JSON.stringify(value);\n}\n\n// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Secret consumers select the stored payload shape at this trusted serialization boundary.\nexport function parseSecretPayload<T>(value: string) {\n return JSON.parse(value) as T;\n}\n\nfunction bearerRequestInit(token: string | undefined): RequestInit | undefined {\n if (!token) {\n return undefined;\n }\n return { headers: { Authorization: `Bearer ${token}` } };\n}\n\nconst authProvider = (auth: McpClientAuth | undefined) =>\n auth?.type === \"provider\" ? auth.provider : undefined;\n\nconst authRequestInit = (auth: McpClientAuth | undefined) =>\n auth?.type === \"bearer\" ? bearerRequestInit(auth.token) : undefined;\n\nasync function readAuthChanges<TAuthChanges>(auth: McpClientAuth<TAuthChanges> | undefined) {\n return auth?.type === \"provider\" ? await auth.readAuthChanges() : undefined;\n}\n\nasync function withMcpClient<T, TAuthChanges = unknown>(args: {\n endpointUrl: string;\n auth?: McpClientAuth<TAuthChanges>;\n timeoutMs?: number;\n fetchImplementation?: typeof fetch;\n operation: (client: Client) => Promise<T>;\n}): Promise<McpOperationResult<T, TAuthChanges>> {\n const client = new Client(\n { name: \"fragno-mcp-fragment\", version: \"0.1.0\" },\n { capabilities: {}, versionNegotiation: { mode: \"auto\" } },\n );\n const transport = new StreamableHTTPClientTransport(new URL(args.endpointUrl), {\n fetch: args.fetchImplementation,\n requestInit: authRequestInit(args.auth),\n authProvider: authProvider(args.auth),\n });\n\n try {\n await client.connect(transport, { timeout: args.timeoutMs });\n const capabilities = client.getServerCapabilities();\n\n const metadata: McpConnectionMetadata = {\n protocolVersion: client.getNegotiatedProtocolVersion(),\n serverInfo: client.getServerVersion(),\n capabilities,\n };\n const result = await args.operation(client);\n return { ok: true, result, metadata, authChanges: await readAuthChanges(args.auth) };\n } catch (error) {\n return { ok: false, error, authChanges: await readAuthChanges(args.auth) };\n } finally {\n await transport.close().catch(() => undefined);\n await client.close().catch(() => undefined);\n }\n}\n\nexport async function listMcpTools<TAuthChanges = unknown>(args: {\n endpointUrl: string;\n auth?: McpClientAuth<TAuthChanges>;\n timeoutMs?: number;\n fetchImplementation?: typeof fetch;\n}) {\n return await withMcpClient({\n ...args,\n operation: (client) => client.listTools(undefined, { timeout: args.timeoutMs }),\n });\n}\n\nexport async function callMcpTool<TAuthChanges = unknown>(args: {\n endpointUrl: string;\n auth?: McpClientAuth<TAuthChanges>;\n name: string;\n toolArguments?: Record<string, unknown>;\n timeoutMs?: number;\n fetchImplementation?: typeof fetch;\n}) {\n return await withMcpClient({\n ...args,\n operation: async (client) => {\n const result = await client.callTool(\n { name: args.name, arguments: args.toolArguments ?? {} },\n { timeout: args.timeoutMs },\n );\n // Tool errors are results for the caller, not protocol failures (MCP spec, tools/call).\n return {\n isError: result.isError === true,\n content: Array.isArray(result.content) ? result.content : [],\n structuredContent: result.structuredContent ?? null,\n } satisfies McpToolCallResult;\n },\n });\n}\n"],"mappings":";;AAoCA,SAAgB,sBAAsB,aAAqB,QAA2B;CACpF,MAAM,MAAM,IAAI,IAAI,WAAW;CAC/B,IAAI,IAAI,aAAa,YAAY,IAAI,aAAa,SAChD,MAAM,IAAI,MAAM,qCAAqC;CAEvD,IAAI,OAAO,uBAAuB,CAAC,OAAO,oBAAoB,GAAG,GAC/D,MAAM,IAAI,MAAM,6BAA6B;CAE/C,OAAO;AACT;AAEA,SAAgB,uBAAuB,OAAgB;CACrD,OAAO,KAAK,UAAU,KAAK;AAC7B;AAGA,SAAgB,mBAAsB,OAAe;CACnD,OAAO,KAAK,MAAM,KAAK;AACzB;AAEA,SAAS,kBAAkB,OAAoD;CAC7E,IAAI,CAAC,OACH;CAEF,OAAO,EAAE,SAAS,EAAE,eAAe,UAAU,QAAQ,EAAE;AACzD;AAEA,MAAM,gBAAgB,SACpB,MAAM,SAAS,aAAa,KAAK,WAAW,KAAA;AAE9C,MAAM,mBAAmB,SACvB,MAAM,SAAS,WAAW,kBAAkB,KAAK,KAAK,IAAI,KAAA;AAE5D,eAAe,gBAA8B,MAA+C;CAC1F,OAAO,MAAM,SAAS,aAAa,MAAM,KAAK,gBAAgB,IAAI,KAAA;AACpE;AAEA,eAAe,cAAyC,MAMP;CAC/C,MAAM,SAAS,IAAI,OACjB;EAAE,MAAM;EAAuB,SAAS;CAAQ,GAChD;EAAE,cAAc,CAAC;EAAG,oBAAoB,EAAE,MAAM,OAAO;CAAE,CAC3D;CACA,MAAM,YAAY,IAAI,8BAA8B,IAAI,IAAI,KAAK,WAAW,GAAG;EAC7E,OAAO,KAAK;EACZ,aAAa,gBAAgB,KAAK,IAAI;EACtC,cAAc,aAAa,KAAK,IAAI;CACtC,CAAC;CAED,IAAI;EACF,MAAM,OAAO,QAAQ,WAAW,EAAE,SAAS,KAAK,UAAU,CAAC;EAC3D,MAAM,eAAe,OAAO,sBAAsB;EAElD,MAAM,WAAkC;GACtC,iBAAiB,OAAO,6BAA6B;GACrD,YAAY,OAAO,iBAAiB;GACpC;EACF;EAEA,OAAO;GAAE,IAAI;GAAM,QAAA,MADE,KAAK,UAAU,MAAM;GACf;GAAU,aAAa,MAAM,gBAAgB,KAAK,IAAI;EAAE;CACrF,SAAS,OAAO;EACd,OAAO;GAAE,IAAI;GAAO;GAAO,aAAa,MAAM,gBAAgB,KAAK,IAAI;EAAE;CAC3E,UAAU;EACR,MAAM,UAAU,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;EAC7C,MAAM,OAAO,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;CAC5C;AACF;AAEA,eAAsB,aAAqC,MAKxD;CACD,OAAO,MAAM,cAAc;EACzB,GAAG;EACH,YAAY,WAAW,OAAO,UAAU,KAAA,GAAW,EAAE,SAAS,KAAK,UAAU,CAAC;CAChF,CAAC;AACH;AAEA,eAAsB,YAAoC,MAOvD;CACD,OAAO,MAAM,cAAc;EACzB,GAAG;EACH,WAAW,OAAO,WAAW;GAC3B,MAAM,SAAS,MAAM,OAAO,SAC1B;IAAE,MAAM,KAAK;IAAM,WAAW,KAAK,iBAAiB,CAAC;GAAE,GACvD,EAAE,SAAS,KAAK,UAAU,CAC5B;GAEA,OAAO;IACL,SAAS,OAAO,YAAY;IAC5B,SAAS,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC;IAC3D,mBAAmB,OAAO,qBAAqB;GACjD;EACF;CACF,CAAC;AACH"}
@@ -0,0 +1,146 @@
1
+ import { z } from "zod";
2
+ //#region src/mcp-types.d.ts
3
+ export interface McpFragmentConfig {
4
+ /** Optional URL allow-list. If omitted, only http(s) URL syntax is checked. */
5
+ allowedEndpointUrls?: (url: URL) => boolean;
6
+ /** Allows OAuth callback URLs. OAuth start is rejected when this policy is omitted. */
7
+ allowedOAuthRedirectUris?: (url: URL) => boolean;
8
+ /** Optional fetch implementation for tests/custom runtimes. */
9
+ fetch?: typeof fetch;
10
+ }
11
+ export declare const authConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
12
+ type: z.ZodLiteral<"none">;
13
+ }, z.core.$strip>, z.ZodObject<{
14
+ type: z.ZodLiteral<"bearer">;
15
+ token: z.ZodString;
16
+ }, z.core.$strip>, z.ZodObject<{
17
+ type: z.ZodLiteral<"client_credentials">;
18
+ clientId: z.ZodString;
19
+ clientSecret: z.ZodString;
20
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ type: z.ZodLiteral<"oauth">;
23
+ clientId: z.ZodOptional<z.ZodString>;
24
+ clientSecret: z.ZodOptional<z.ZodString>;
25
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ }, z.core.$strip>], "type">;
27
+ /** Slugs are URL path segments and OAuth state prefixes, so they exclude ':' and dot segments. */
28
+ export declare const mcpServerSlugSchema: z.ZodString;
29
+ export declare const createServerInputSchema: z.ZodObject<{
30
+ slug: z.ZodString;
31
+ name: z.ZodOptional<z.ZodString>;
32
+ endpointUrl: z.ZodURL;
33
+ auth: z.ZodDefault<z.ZodDiscriminatedUnion<[z.ZodObject<{
34
+ type: z.ZodLiteral<"none">;
35
+ }, z.core.$strip>, z.ZodObject<{
36
+ type: z.ZodLiteral<"bearer">;
37
+ token: z.ZodString;
38
+ }, z.core.$strip>, z.ZodObject<{
39
+ type: z.ZodLiteral<"client_credentials">;
40
+ clientId: z.ZodString;
41
+ clientSecret: z.ZodString;
42
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
43
+ }, z.core.$strip>, z.ZodObject<{
44
+ type: z.ZodLiteral<"oauth">;
45
+ clientId: z.ZodOptional<z.ZodString>;
46
+ clientSecret: z.ZodOptional<z.ZodString>;
47
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
48
+ }, z.core.$strip>], "type">>;
49
+ }, z.core.$strip>;
50
+ /** Replacement keeps the slug and creation time; everything else is supplied again. */
51
+ export declare const replaceServerConfigurationInputSchema: z.ZodObject<{
52
+ name: z.ZodOptional<z.ZodString>;
53
+ endpointUrl: z.ZodURL;
54
+ auth: z.ZodDefault<z.ZodDiscriminatedUnion<[z.ZodObject<{
55
+ type: z.ZodLiteral<"none">;
56
+ }, z.core.$strip>, z.ZodObject<{
57
+ type: z.ZodLiteral<"bearer">;
58
+ token: z.ZodString;
59
+ }, z.core.$strip>, z.ZodObject<{
60
+ type: z.ZodLiteral<"client_credentials">;
61
+ clientId: z.ZodString;
62
+ clientSecret: z.ZodString;
63
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
64
+ }, z.core.$strip>, z.ZodObject<{
65
+ type: z.ZodLiteral<"oauth">;
66
+ clientId: z.ZodOptional<z.ZodString>;
67
+ clientSecret: z.ZodOptional<z.ZodString>;
68
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
+ }, z.core.$strip>], "type">>;
70
+ }, z.core.$strip>;
71
+ export declare const toolCallInputSchema: z.ZodObject<{
72
+ name: z.ZodString;
73
+ arguments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
74
+ timeoutMs: z.ZodOptional<z.ZodNumber>;
75
+ }, z.core.$strip>;
76
+ export declare const tokenAuthInputSchema: z.ZodObject<{
77
+ token: z.ZodString;
78
+ }, z.core.$strip>;
79
+ /** Sanitized auth state derived from stored configuration; it never proves live server access. */
80
+ export declare const mcpAuthStatusSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
81
+ mode: z.ZodLiteral<"none">;
82
+ }, z.core.$strip>, z.ZodObject<{
83
+ mode: z.ZodLiteral<"bearer">;
84
+ credentials: z.ZodEnum<{
85
+ present: "present";
86
+ missing: "missing";
87
+ }>;
88
+ }, z.core.$strip>, z.ZodObject<{
89
+ mode: z.ZodLiteral<"client_credentials">;
90
+ credentials: z.ZodEnum<{
91
+ present: "present";
92
+ missing: "missing";
93
+ }>;
94
+ }, z.core.$strip>, z.ZodObject<{
95
+ mode: z.ZodLiteral<"oauth">;
96
+ state: z.ZodEnum<{
97
+ "consent-required": "consent-required";
98
+ "consent-pending": "consent-pending";
99
+ authorized: "authorized";
100
+ expired: "expired";
101
+ }>;
102
+ }, z.core.$strip>], "mode">;
103
+ /** The pending link embeds the callback state, so reading it needs server-create authority. */
104
+ export declare const mcpOAuthPendingSchema: z.ZodObject<{
105
+ pending: z.ZodNullable<z.ZodObject<{
106
+ authorizationUrl: z.ZodURL;
107
+ expiresAt: z.ZodUnion<readonly [z.ZodString, z.ZodDate]>;
108
+ }, z.core.$strip>>;
109
+ }, z.core.$strip>;
110
+ /**
111
+ * Mirrors the MCP protocol's tool definition, whose optional members are defined by the spec.
112
+ * Loose so newer spec members, such as icons, survive the cache and the API.
113
+ */
114
+ export declare const mcpToolSchema: z.ZodObject<{
115
+ name: z.ZodString;
116
+ title: z.ZodOptional<z.ZodString>;
117
+ description: z.ZodOptional<z.ZodString>;
118
+ inputSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
119
+ outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
120
+ annotations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
121
+ _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
122
+ }, z.core.$loose>;
123
+ /** Tool errors are results the model should see; transport and auth failures are route errors. */
124
+ export declare const mcpToolCallResultSchema: z.ZodObject<{
125
+ isError: z.ZodBoolean;
126
+ content: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
127
+ structuredContent: z.ZodUnknown;
128
+ }, z.core.$strip>;
129
+ /** Query parameter carrying the OAuth callback URI for an MCP OAuth start request. */
130
+ export declare const MCP_OAUTH_REDIRECT_URI_QUERY_PARAMETER = "redirectUri";
131
+ export declare const mcpOAuthRedirectUriSchema: z.ZodURL;
132
+ export declare const oauthStartInputSchema: z.ZodObject<{
133
+ scope: z.ZodOptional<z.ZodString>;
134
+ clientId: z.ZodOptional<z.ZodString>;
135
+ clientSecret: z.ZodOptional<z.ZodString>;
136
+ discardTokens: z.ZodDefault<z.ZodBoolean>;
137
+ }, z.core.$strip>;
138
+ export type AuthConfig = z.infer<typeof authConfigSchema>;
139
+ export type CreateServerInput = z.infer<typeof createServerInputSchema>;
140
+ export type ToolCallInput = z.infer<typeof toolCallInputSchema>;
141
+ export type McpAuthStatus = z.infer<typeof mcpAuthStatusSchema>;
142
+ export type McpOAuthPending = z.infer<typeof mcpOAuthPendingSchema>;
143
+ export type McpTool = z.infer<typeof mcpToolSchema>;
144
+ export type McpToolCallResult = z.infer<typeof mcpToolCallResultSchema>;
145
+ //#endregion
146
+ //# sourceMappingURL=mcp-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-types.d.ts","names":[],"sources":["../../src/mcp-types.ts"],"mappings":";;iBAEiB;;EAEf,uBAAuB,KAAK;;EAE5B,4BAA4B,KAAK;;EAEjC,eAAe;;qBAGJ,kBAAgB,EAAA,uBAAA,EAAA;;;;;;;;;;;;;;;GAe3B,EAAA,KAAA;;qBAGW,qBAAmB,EAAA;qBAEnB,yBAAuB,EAAA;;;;;;;;;;;;;;;;;;;;GAKlC,EAAA,KAAA;;qBAGW,uCAAqC,EAAA;;;;;;;;;;;;;;;;;;;GAA+C,EAAA,KAAA;qBAEpF,qBAAmB,EAAA;;;;GAI9B,EAAA,KAAA;qBAEW,sBAAoB,EAAA;;GAE/B,EAAA,KAAA;;qBAOW,qBAAmB,EAAA,uBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;GAY9B,EAAA,KAAA;;qBAGW,uBAAqB,EAAA;;;;;GAOhC,EAAA,KAAA;;;;;qBAMW,eAAa,EAAA;;;;;;;;GAQxB,EAAA,KAAA;;qBAGW,yBAAuB,EAAA;;;;GAKlC,EAAA,KAAA;;qBAGW;qBAEA,2BAAyB,EAAA;qBAKzB,uBAAqB,EAAA;;;;;GAUhC,EAAA,KAAA;YAEU,aAAa,EAAE,aAAa;YAC5B,oBAAoB,EAAE,aAAa;YACnC,gBAAgB,EAAE,aAAa;YAC/B,gBAAgB,EAAE,aAAa;YAC/B,kBAAkB,EAAE,aAAa;YACjC,UAAU,EAAE,aAAa;YACzB,oBAAoB,EAAE,aAAa"}
@@ -0,0 +1,100 @@
1
+ import { z } from "zod";
2
+ //#region src/mcp-types.ts
3
+ const authConfigSchema = z.discriminatedUnion("type", [
4
+ z.object({ type: z.literal("none") }),
5
+ z.object({
6
+ type: z.literal("bearer"),
7
+ token: z.string().min(1)
8
+ }),
9
+ z.object({
10
+ type: z.literal("client_credentials"),
11
+ clientId: z.string().min(1),
12
+ clientSecret: z.string().min(1),
13
+ scopes: z.array(z.string()).optional()
14
+ }),
15
+ z.object({
16
+ type: z.literal("oauth"),
17
+ clientId: z.string().optional(),
18
+ clientSecret: z.string().optional(),
19
+ scopes: z.array(z.string()).optional()
20
+ })
21
+ ]);
22
+ /** Slugs are URL path segments and OAuth state prefixes, so they exclude ':' and dot segments. */
23
+ const mcpServerSlugSchema = z.string().regex(/^[a-z0-9][a-z0-9-]*$/);
24
+ const createServerInputSchema = z.object({
25
+ slug: mcpServerSlugSchema,
26
+ name: z.string().optional(),
27
+ endpointUrl: z.url(),
28
+ auth: authConfigSchema.default({ type: "none" })
29
+ });
30
+ /** Replacement keeps the slug and creation time; everything else is supplied again. */
31
+ const replaceServerConfigurationInputSchema = createServerInputSchema.omit({ slug: true });
32
+ const toolCallInputSchema = z.object({
33
+ name: z.string().min(1),
34
+ arguments: z.record(z.string(), z.unknown()).optional(),
35
+ timeoutMs: z.number().int().positive().max(12e4).optional()
36
+ });
37
+ const tokenAuthInputSchema = z.object({ token: z.string().min(1) });
38
+ const mcpCredentialsPresenceSchema = z.enum(["present", "missing"]).describe("Whether credentials are stored, not whether the server accepts them.");
39
+ /** Sanitized auth state derived from stored configuration; it never proves live server access. */
40
+ const mcpAuthStatusSchema = z.discriminatedUnion("mode", [
41
+ z.object({ mode: z.literal("none") }),
42
+ z.object({
43
+ mode: z.literal("bearer"),
44
+ credentials: mcpCredentialsPresenceSchema
45
+ }),
46
+ z.object({
47
+ mode: z.literal("client_credentials"),
48
+ credentials: mcpCredentialsPresenceSchema
49
+ }),
50
+ z.object({
51
+ mode: z.literal("oauth"),
52
+ state: z.enum([
53
+ "consent-required",
54
+ "consent-pending",
55
+ "authorized",
56
+ "expired"
57
+ ]).describe("Expired means the access token expired and no refresh token is stored; pending means an unexpired authorization link exists.")
58
+ })
59
+ ]);
60
+ /** The pending link embeds the callback state, so reading it needs server-create authority. */
61
+ const mcpOAuthPendingSchema = z.object({ pending: z.object({
62
+ authorizationUrl: z.url(),
63
+ expiresAt: z.union([z.string(), z.date()])
64
+ }).nullable().describe("The newest unexpired, unconsumed authorization link; any pending link completes it.") });
65
+ /**
66
+ * Mirrors the MCP protocol's tool definition, whose optional members are defined by the spec.
67
+ * Loose so newer spec members, such as icons, survive the cache and the API.
68
+ */
69
+ const mcpToolSchema = z.looseObject({
70
+ name: z.string(),
71
+ title: z.string().optional(),
72
+ description: z.string().optional(),
73
+ inputSchema: z.record(z.string(), z.unknown()),
74
+ outputSchema: z.record(z.string(), z.unknown()).optional(),
75
+ annotations: z.record(z.string(), z.unknown()).optional(),
76
+ _meta: z.record(z.string(), z.unknown()).optional()
77
+ });
78
+ /** Tool errors are results the model should see; transport and auth failures are route errors. */
79
+ const mcpToolCallResultSchema = z.object({
80
+ isError: z.boolean(),
81
+ content: z.array(z.record(z.string(), z.unknown())),
82
+ /** Since MCP 2026-07-28 any JSON value; null when the tool returned none. */
83
+ structuredContent: z.unknown()
84
+ });
85
+ /** Query parameter carrying the OAuth callback URI for an MCP OAuth start request. */
86
+ const MCP_OAUTH_REDIRECT_URI_QUERY_PARAMETER = "redirectUri";
87
+ const mcpOAuthRedirectUriSchema = z.url().refine((value) => {
88
+ const protocol = new URL(value).protocol;
89
+ return protocol === "https:" || protocol === "http:";
90
+ }, "MCP OAuth redirect URI must use HTTP or HTTPS");
91
+ const oauthStartInputSchema = z.object({
92
+ scope: z.string().optional(),
93
+ clientId: z.string().min(1).optional(),
94
+ clientSecret: z.string().min(1).optional(),
95
+ discardTokens: z.boolean().default(false).describe("Drop stored tokens so status reports pending consent until this new consent completes.")
96
+ });
97
+ //#endregion
98
+ export { MCP_OAUTH_REDIRECT_URI_QUERY_PARAMETER, authConfigSchema, createServerInputSchema, mcpAuthStatusSchema, mcpOAuthPendingSchema, mcpOAuthRedirectUriSchema, mcpServerSlugSchema, mcpToolCallResultSchema, mcpToolSchema, oauthStartInputSchema, replaceServerConfigurationInputSchema, tokenAuthInputSchema, toolCallInputSchema };
99
+
100
+ //# sourceMappingURL=mcp-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-types.js","names":[],"sources":["../../src/mcp-types.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport interface McpFragmentConfig {\n /** Optional URL allow-list. If omitted, only http(s) URL syntax is checked. */\n allowedEndpointUrls?: (url: URL) => boolean;\n /** Allows OAuth callback URLs. OAuth start is rejected when this policy is omitted. */\n allowedOAuthRedirectUris?: (url: URL) => boolean;\n /** Optional fetch implementation for tests/custom runtimes. */\n fetch?: typeof fetch;\n}\n\nexport const authConfigSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"none\") }),\n z.object({ type: z.literal(\"bearer\"), token: z.string().min(1) }),\n z.object({\n type: z.literal(\"client_credentials\"),\n clientId: z.string().min(1),\n clientSecret: z.string().min(1),\n scopes: z.array(z.string()).optional(),\n }),\n z.object({\n type: z.literal(\"oauth\"),\n clientId: z.string().optional(),\n clientSecret: z.string().optional(),\n scopes: z.array(z.string()).optional(),\n }),\n]);\n\n/** Slugs are URL path segments and OAuth state prefixes, so they exclude ':' and dot segments. */\nexport const mcpServerSlugSchema = z.string().regex(/^[a-z0-9][a-z0-9-]*$/);\n\nexport const createServerInputSchema = z.object({\n slug: mcpServerSlugSchema,\n name: z.string().optional(),\n endpointUrl: z.url(),\n auth: authConfigSchema.default({ type: \"none\" }),\n});\n\n/** Replacement keeps the slug and creation time; everything else is supplied again. */\nexport const replaceServerConfigurationInputSchema = createServerInputSchema.omit({ slug: true });\n\nexport const toolCallInputSchema = z.object({\n name: z.string().min(1),\n arguments: z.record(z.string(), z.unknown()).optional(),\n timeoutMs: z.number().int().positive().max(120_000).optional(),\n});\n\nexport const tokenAuthInputSchema = z.object({\n token: z.string().min(1),\n});\n\nconst mcpCredentialsPresenceSchema = z\n .enum([\"present\", \"missing\"])\n .describe(\"Whether credentials are stored, not whether the server accepts them.\");\n\n/** Sanitized auth state derived from stored configuration; it never proves live server access. */\nexport const mcpAuthStatusSchema = z.discriminatedUnion(\"mode\", [\n z.object({ mode: z.literal(\"none\") }),\n z.object({ mode: z.literal(\"bearer\"), credentials: mcpCredentialsPresenceSchema }),\n z.object({ mode: z.literal(\"client_credentials\"), credentials: mcpCredentialsPresenceSchema }),\n z.object({\n mode: z.literal(\"oauth\"),\n state: z\n .enum([\"consent-required\", \"consent-pending\", \"authorized\", \"expired\"])\n .describe(\n \"Expired means the access token expired and no refresh token is stored; pending means an unexpired authorization link exists.\",\n ),\n }),\n]);\n\n/** The pending link embeds the callback state, so reading it needs server-create authority. */\nexport const mcpOAuthPendingSchema = z.object({\n pending: z\n .object({ authorizationUrl: z.url(), expiresAt: z.union([z.string(), z.date()]) })\n .nullable()\n .describe(\n \"The newest unexpired, unconsumed authorization link; any pending link completes it.\",\n ),\n});\n\n/**\n * Mirrors the MCP protocol's tool definition, whose optional members are defined by the spec.\n * Loose so newer spec members, such as icons, survive the cache and the API.\n */\nexport const mcpToolSchema = z.looseObject({\n name: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n inputSchema: z.record(z.string(), z.unknown()),\n outputSchema: z.record(z.string(), z.unknown()).optional(),\n annotations: z.record(z.string(), z.unknown()).optional(),\n _meta: z.record(z.string(), z.unknown()).optional(),\n});\n\n/** Tool errors are results the model should see; transport and auth failures are route errors. */\nexport const mcpToolCallResultSchema = z.object({\n isError: z.boolean(),\n content: z.array(z.record(z.string(), z.unknown())),\n /** Since MCP 2026-07-28 any JSON value; null when the tool returned none. */\n structuredContent: z.unknown(),\n});\n\n/** Query parameter carrying the OAuth callback URI for an MCP OAuth start request. */\nexport const MCP_OAUTH_REDIRECT_URI_QUERY_PARAMETER = \"redirectUri\";\n\nexport const mcpOAuthRedirectUriSchema = z.url().refine((value) => {\n const protocol = new URL(value).protocol;\n return protocol === \"https:\" || protocol === \"http:\";\n}, \"MCP OAuth redirect URI must use HTTP or HTTPS\");\n\nexport const oauthStartInputSchema = z.object({\n scope: z.string().optional(),\n clientId: z.string().min(1).optional(),\n clientSecret: z.string().min(1).optional(),\n discardTokens: z\n .boolean()\n .default(false)\n .describe(\n \"Drop stored tokens so status reports pending consent until this new consent completes.\",\n ),\n});\n\nexport type AuthConfig = z.infer<typeof authConfigSchema>;\nexport type CreateServerInput = z.infer<typeof createServerInputSchema>;\nexport type ToolCallInput = z.infer<typeof toolCallInputSchema>;\nexport type McpAuthStatus = z.infer<typeof mcpAuthStatusSchema>;\nexport type McpOAuthPending = z.infer<typeof mcpOAuthPendingSchema>;\nexport type McpTool = z.infer<typeof mcpToolSchema>;\nexport type McpToolCallResult = z.infer<typeof mcpToolCallResultSchema>;\n"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { OAuthClientInformationMixed, OAuthDiscoveryState, OAuthTokens } from "@modelcontextprotocol/client";
2
+ //#region src/oauth-provider.d.ts
3
+ export interface OAuthProviderChanges {
4
+ authorizationUrl?: URL;
5
+ clientInformation?: OAuthClientInformationMixed;
6
+ tokens?: OAuthTokens;
7
+ discoveryState?: OAuthDiscoveryState;
8
+ oauthState?: {
9
+ id: string;
10
+ codeVerifier: string;
11
+ redirectUri: string;
12
+ scope?: string;
13
+ expiresAt: Date;
14
+ };
15
+ consumeStateId?: string;
16
+ /** The server rejected the stored tokens, so they must be removed unless new ones were saved. */
17
+ tokensInvalidated?: boolean;
18
+ /** The server rejected the registered client, so it must be removed unless a new one was saved. */
19
+ clientInvalidated?: boolean;
20
+ /** The discovered metadata failed, so it must be removed unless it was discovered again. */
21
+ discoveryInvalidated?: boolean;
22
+ }
23
+ //#endregion
24
+ //# sourceMappingURL=oauth-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-provider.d.ts","names":[],"sources":["../../src/oauth-provider.ts"],"mappings":";;iBA+BiB;EACf,mBAAmB;EACnB,oBAAoB;EACpB,SAAS;EACT,iBAAiB;EACjB;IACE;IACA;IACA;IACA;IACA,WAAW;;EAEb;;EAEA;;EAEA;;EAEA"}
@@ -0,0 +1,113 @@
1
+ //#region src/oauth-provider.ts
2
+ var BufferedOAuthClientProvider = class {
3
+ snapshot;
4
+ changes = {};
5
+ constructor(snapshot) {
6
+ this.snapshot = snapshot;
7
+ }
8
+ get redirectUrl() {
9
+ return this.snapshot.redirectUrl;
10
+ }
11
+ get clientMetadata() {
12
+ if (this.snapshot.flow === "client_credentials") return {
13
+ redirect_uris: [],
14
+ token_endpoint_auth_method: "client_secret_basic",
15
+ grant_types: ["client_credentials"],
16
+ client_name: this.snapshot.clientName ?? "Fragno MCP Fragment",
17
+ scope: this.snapshot.scope
18
+ };
19
+ return {
20
+ redirect_uris: this.snapshot.redirectUrl ? [this.snapshot.redirectUrl] : [],
21
+ token_endpoint_auth_method: this.snapshot.clientSecret ? "client_secret_basic" : "none",
22
+ grant_types: ["authorization_code", "refresh_token"],
23
+ response_types: ["code"],
24
+ client_name: this.snapshot.clientName ?? "Fragno MCP Fragment",
25
+ scope: this.snapshot.scope
26
+ };
27
+ }
28
+ state() {
29
+ if (!this.snapshot.stateId) throw new Error("OAuth state is required to start authorization");
30
+ return this.snapshot.stateId;
31
+ }
32
+ clientInformation() {
33
+ if (this.changes.clientInformation) return this.changes.clientInformation;
34
+ if (this.snapshot.clientId) {
35
+ const clientInformation = {
36
+ client_id: this.snapshot.clientId,
37
+ client_secret: this.snapshot.clientSecret
38
+ };
39
+ this.changes.clientInformation = clientInformation;
40
+ return clientInformation;
41
+ }
42
+ return this.changes.clientInvalidated ? void 0 : this.snapshot.clientInformation;
43
+ }
44
+ saveClientInformation(clientInformation) {
45
+ this.changes.clientInformation = clientInformation;
46
+ }
47
+ tokens() {
48
+ return this.changes.tokens ?? (this.changes.tokensInvalidated ? void 0 : this.snapshot.tokens);
49
+ }
50
+ saveTokens(tokens) {
51
+ this.changes.tokens = tokens;
52
+ }
53
+ redirectToAuthorization(authorizationUrl) {
54
+ this.changes.authorizationUrl = authorizationUrl;
55
+ }
56
+ saveCodeVerifier(codeVerifier) {
57
+ if (this.snapshot.flow === "client_credentials") return;
58
+ if (!this.snapshot.stateId || !this.snapshot.redirectUrl) throw new Error("OAuth state and redirect URL are required");
59
+ this.changes.oauthState = {
60
+ id: this.snapshot.stateId,
61
+ codeVerifier,
62
+ redirectUri: this.snapshot.redirectUrl,
63
+ scope: this.snapshot.scope,
64
+ expiresAt: new Date(Date.now() + 6e5)
65
+ };
66
+ }
67
+ codeVerifier() {
68
+ if (this.snapshot.flow === "client_credentials") throw new Error("codeVerifier is not used for client_credentials flow");
69
+ const state = this.snapshot.oauthState;
70
+ if (!state || state.consumedAt) throw new Error("Invalid OAuth state");
71
+ if (state.expiresAt.getTime() < Date.now()) throw new Error("OAuth state expired");
72
+ return state.codeVerifier;
73
+ }
74
+ saveDiscoveryState(state) {
75
+ this.changes.discoveryState = state;
76
+ }
77
+ discoveryState() {
78
+ return this.changes.discoveryState ?? (this.changes.discoveryInvalidated ? void 0 : this.snapshot.discoveryState);
79
+ }
80
+ /**
81
+ * The SDK retries authorization right after invalidating, so later reads skip what it dropped:
82
+ * retrying a rejected client or token fails the same way. A configured client is configuration,
83
+ * not a registration, so it is kept. The code verifier lives in the pending OAuth state, which
84
+ * the callback consumes either way.
85
+ */
86
+ invalidateCredentials(scope) {
87
+ if (scope === "all" || scope === "tokens") {
88
+ this.changes.tokens = void 0;
89
+ this.changes.tokensInvalidated = true;
90
+ }
91
+ if (scope === "all" || scope === "client") {
92
+ this.changes.clientInformation = void 0;
93
+ this.changes.clientInvalidated = true;
94
+ }
95
+ if (scope === "all" || scope === "discovery") {
96
+ this.changes.discoveryState = void 0;
97
+ this.changes.discoveryInvalidated = true;
98
+ }
99
+ }
100
+ prepareTokenRequest(scope) {
101
+ if (this.snapshot.flow !== "client_credentials") return;
102
+ const params = new URLSearchParams({ grant_type: "client_credentials" });
103
+ if (scope) params.set("scope", scope);
104
+ return params;
105
+ }
106
+ consumeState() {
107
+ if (this.snapshot.stateId) this.changes.consumeStateId = this.snapshot.stateId;
108
+ }
109
+ };
110
+ //#endregion
111
+ export { BufferedOAuthClientProvider };
112
+
113
+ //# sourceMappingURL=oauth-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-provider.js","names":[],"sources":["../../src/oauth-provider.ts"],"sourcesContent":["import type {\n OAuthClientProvider,\n OAuthDiscoveryState,\n OAuthClientInformationMixed,\n OAuthClientMetadata,\n OAuthTokens,\n} from \"@modelcontextprotocol/client\";\n\nexport interface OAuthProviderSnapshot {\n serverId: string;\n endpointUrl: string;\n redirectUrl?: string;\n scope?: string;\n stateId?: string;\n clientId?: string;\n clientSecret?: string;\n clientName?: string;\n clientInformation?: OAuthClientInformationMixed;\n tokens?: OAuthTokens;\n discoveryState?: OAuthDiscoveryState;\n flow?: \"authorization_code\" | \"client_credentials\";\n oauthState?: {\n id: string;\n codeVerifier: string;\n redirectUri: string;\n scope?: string;\n expiresAt: Date;\n consumedAt?: Date | null;\n };\n}\n\nexport interface OAuthProviderChanges {\n authorizationUrl?: URL;\n clientInformation?: OAuthClientInformationMixed;\n tokens?: OAuthTokens;\n discoveryState?: OAuthDiscoveryState;\n oauthState?: {\n id: string;\n codeVerifier: string;\n redirectUri: string;\n scope?: string;\n expiresAt: Date;\n };\n consumeStateId?: string;\n /** The server rejected the stored tokens, so they must be removed unless new ones were saved. */\n tokensInvalidated?: boolean;\n /** The server rejected the registered client, so it must be removed unless a new one was saved. */\n clientInvalidated?: boolean;\n /** The discovered metadata failed, so it must be removed unless it was discovered again. */\n discoveryInvalidated?: boolean;\n}\n\nexport class BufferedOAuthClientProvider implements OAuthClientProvider {\n readonly changes: OAuthProviderChanges = {};\n\n constructor(private readonly snapshot: OAuthProviderSnapshot) {}\n\n get redirectUrl() {\n return this.snapshot.redirectUrl;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n if (this.snapshot.flow === \"client_credentials\") {\n return {\n redirect_uris: [],\n token_endpoint_auth_method: \"client_secret_basic\",\n grant_types: [\"client_credentials\"],\n client_name: this.snapshot.clientName ?? \"Fragno MCP Fragment\",\n scope: this.snapshot.scope,\n };\n }\n return {\n redirect_uris: this.snapshot.redirectUrl ? [this.snapshot.redirectUrl] : [],\n token_endpoint_auth_method: this.snapshot.clientSecret ? \"client_secret_basic\" : \"none\",\n grant_types: [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"],\n client_name: this.snapshot.clientName ?? \"Fragno MCP Fragment\",\n scope: this.snapshot.scope,\n };\n }\n\n state() {\n if (!this.snapshot.stateId) {\n throw new Error(\"OAuth state is required to start authorization\");\n }\n return this.snapshot.stateId;\n }\n\n clientInformation() {\n // Preserve the SDK's issuer stamp instead of rebuilding static credentials after discovery.\n if (this.changes.clientInformation) {\n return this.changes.clientInformation;\n }\n if (this.snapshot.clientId) {\n const clientInformation = {\n client_id: this.snapshot.clientId,\n client_secret: this.snapshot.clientSecret,\n };\n this.changes.clientInformation = clientInformation;\n return clientInformation;\n }\n return this.changes.clientInvalidated ? undefined : this.snapshot.clientInformation;\n }\n\n saveClientInformation(clientInformation: OAuthClientInformationMixed) {\n this.changes.clientInformation = clientInformation;\n }\n\n tokens() {\n return (\n this.changes.tokens ?? (this.changes.tokensInvalidated ? undefined : this.snapshot.tokens)\n );\n }\n\n saveTokens(tokens: OAuthTokens) {\n this.changes.tokens = tokens;\n }\n\n redirectToAuthorization(authorizationUrl: URL) {\n this.changes.authorizationUrl = authorizationUrl;\n }\n\n saveCodeVerifier(codeVerifier: string) {\n if (this.snapshot.flow === \"client_credentials\") {\n return;\n }\n if (!this.snapshot.stateId || !this.snapshot.redirectUrl) {\n throw new Error(\"OAuth state and redirect URL are required\");\n }\n this.changes.oauthState = {\n id: this.snapshot.stateId,\n codeVerifier,\n redirectUri: this.snapshot.redirectUrl,\n scope: this.snapshot.scope,\n expiresAt: new Date(Date.now() + 10 * 60 * 1000),\n };\n }\n\n codeVerifier() {\n if (this.snapshot.flow === \"client_credentials\") {\n throw new Error(\"codeVerifier is not used for client_credentials flow\");\n }\n const state = this.snapshot.oauthState;\n if (!state || state.consumedAt) {\n throw new Error(\"Invalid OAuth state\");\n }\n if (state.expiresAt.getTime() < Date.now()) {\n throw new Error(\"OAuth state expired\");\n }\n return state.codeVerifier;\n }\n\n saveDiscoveryState(state: OAuthDiscoveryState) {\n this.changes.discoveryState = state;\n }\n\n discoveryState() {\n return (\n this.changes.discoveryState ??\n (this.changes.discoveryInvalidated ? undefined : this.snapshot.discoveryState)\n );\n }\n\n /**\n * The SDK retries authorization right after invalidating, so later reads skip what it dropped:\n * retrying a rejected client or token fails the same way. A configured client is configuration,\n * not a registration, so it is kept. The code verifier lives in the pending OAuth state, which\n * the callback consumes either way.\n */\n invalidateCredentials(scope: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\") {\n if (scope === \"all\" || scope === \"tokens\") {\n this.changes.tokens = undefined;\n this.changes.tokensInvalidated = true;\n }\n if (scope === \"all\" || scope === \"client\") {\n this.changes.clientInformation = undefined;\n this.changes.clientInvalidated = true;\n }\n if (scope === \"all\" || scope === \"discovery\") {\n this.changes.discoveryState = undefined;\n this.changes.discoveryInvalidated = true;\n }\n }\n\n prepareTokenRequest(scope?: string) {\n if (this.snapshot.flow !== \"client_credentials\") {\n return undefined;\n }\n const params = new URLSearchParams({ grant_type: \"client_credentials\" });\n if (scope) {\n params.set(\"scope\", scope);\n }\n return params;\n }\n\n consumeState() {\n if (this.snapshot.stateId) {\n this.changes.consumeStateId = this.snapshot.stateId;\n }\n }\n}\n"],"mappings":"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"}