@executor-js/plugin-mcp 1.5.14 → 1.5.15

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  mcpPresets
3
- } from "./chunk-QEAVWCYB.js";
3
+ } from "./chunk-CLAWPLDI.js";
4
4
  import {
5
5
  addMcpServer,
6
6
  mcpAuthMethodInputFromEditorValue,
@@ -592,4 +592,4 @@ function AddMcpSource(props) {
592
592
  export {
593
593
  AddMcpSource as default
594
594
  };
595
- //# sourceMappingURL=AddMcpSource-BSJDTWMP.js.map
595
+ //# sourceMappingURL=AddMcpSource-URN7Y5IO.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  mcpPresets
3
- } from "./chunk-QEAVWCYB.js";
3
+ } from "./chunk-CLAWPLDI.js";
4
4
  import {
5
5
  McpAuthMethodInput,
6
6
  McpAuthShorthand,
@@ -1365,4 +1365,4 @@ export {
1365
1365
  userFacingProbeMessage,
1366
1366
  mcpPlugin
1367
1367
  };
1368
- //# sourceMappingURL=chunk-ENRA2SPE.js.map
1368
+ //# sourceMappingURL=chunk-3AGPV4QE.js.map
@@ -1,5 +1,13 @@
1
1
  // src/sdk/presets.ts
2
2
  var mcpPresets = [
3
+ {
4
+ id: "emulate-mcp",
5
+ name: "Emulate MCP",
6
+ summary: "Deterministic MCP fixtures for validating native text and image content.",
7
+ url: "https://emulators.dev/mcp/query/mcp?token=demo-token",
8
+ endpoint: "https://emulators.dev/mcp/query/mcp?token=demo-token",
9
+ icon: "https://emulators.dev/favicon.ico"
10
+ },
3
11
  {
4
12
  id: "deepwiki",
5
13
  name: "DeepWiki",
@@ -112,4 +120,4 @@ var mcpPresets = [
112
120
  export {
113
121
  mcpPresets
114
122
  };
115
- //# sourceMappingURL=chunk-QEAVWCYB.js.map
123
+ //# sourceMappingURL=chunk-CLAWPLDI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sdk/presets.ts"],"sourcesContent":["export interface McpRemotePreset {\n readonly id: string;\n readonly name: string;\n readonly summary: string;\n readonly url: string;\n readonly endpoint: string;\n readonly icon?: string;\n readonly featured?: boolean;\n readonly transport?: undefined;\n}\n\nexport interface McpStdioPreset {\n readonly id: string;\n readonly name: string;\n readonly summary: string;\n readonly icon?: string;\n readonly featured?: boolean;\n readonly transport: \"stdio\";\n readonly command: string;\n readonly args?: readonly string[];\n readonly env?: Readonly<Record<string, string>>;\n}\n\nexport type McpPreset = McpRemotePreset | McpStdioPreset;\n\nexport const mcpPresets: readonly McpPreset[] = [\n {\n id: \"emulate-mcp\",\n name: \"Emulate MCP\",\n summary: \"Deterministic MCP fixtures for validating native text and image content.\",\n url: \"https://emulators.dev/mcp/query/mcp?token=demo-token\",\n endpoint: \"https://emulators.dev/mcp/query/mcp?token=demo-token\",\n icon: \"https://emulators.dev/favicon.ico\",\n },\n {\n id: \"deepwiki\",\n name: \"DeepWiki\",\n summary: \"Search and read documentation from any GitHub repo.\",\n url: \"https://mcp.deepwiki.com/mcp\",\n endpoint: \"https://mcp.deepwiki.com/mcp\",\n icon: \"https://deepwiki.com/favicon.ico\",\n featured: true,\n },\n {\n id: \"context7\",\n name: \"Context7\",\n summary: \"Up-to-date docs and code examples for any library.\",\n url: \"https://mcp.context7.com/mcp\",\n endpoint: \"https://mcp.context7.com/mcp\",\n icon: \"https://context7.com/favicon.ico\",\n featured: true,\n },\n {\n id: \"browserbase\",\n name: \"Browserbase\",\n summary: \"Cloud browser sessions for web scraping and automation.\",\n url: \"https://mcp.browserbase.com/mcp\",\n endpoint: \"https://mcp.browserbase.com/mcp\",\n icon: \"https://www.browserbase.com/favicon.ico\",\n featured: true,\n },\n {\n id: \"firecrawl\",\n name: \"Firecrawl\",\n summary: \"Crawl and scrape websites into structured data.\",\n url: \"https://mcp.firecrawl.dev/mcp\",\n endpoint: \"https://mcp.firecrawl.dev/mcp\",\n icon: \"https://www.firecrawl.dev/favicon.ico\",\n featured: true,\n },\n {\n id: \"neon\",\n name: \"Neon\",\n summary: \"Serverless Postgres — branches, queries, and management.\",\n url: \"https://mcp.neon.tech/mcp\",\n endpoint: \"https://mcp.neon.tech/mcp\",\n icon: \"https://neon.tech/favicon/favicon.ico\",\n featured: true,\n },\n {\n id: \"axiom\",\n name: \"Axiom\",\n summary: \"Query, analyze, and monitor your logs and event data.\",\n url: \"https://mcp.axiom.co/mcp\",\n endpoint: \"https://mcp.axiom.co/mcp\",\n icon: \"https://axiom.co/favicon.ico\",\n featured: true,\n },\n {\n id: \"stripe\",\n name: \"Stripe\",\n summary: \"Manage payments, subscriptions, and billing via MCP.\",\n url: \"https://mcp.stripe.com\",\n endpoint: \"https://mcp.stripe.com\",\n icon: \"https://stripe.com/favicon.ico\",\n featured: true,\n },\n {\n id: \"linear\",\n name: \"Linear\",\n summary: \"Issues, projects, teams, and cycles via MCP.\",\n url: \"https://mcp.linear.app/mcp\",\n endpoint: \"https://mcp.linear.app/mcp\",\n icon: \"https://linear.app/favicon.ico\",\n featured: true,\n },\n {\n id: \"notion\",\n name: \"Notion\",\n summary: \"Databases, pages, blocks, and search via MCP.\",\n url: \"https://mcp.notion.com/mcp\",\n endpoint: \"https://mcp.notion.com/mcp\",\n icon: \"https://www.notion.com/front-static/favicon.ico\",\n featured: true,\n },\n {\n id: \"sentry\",\n name: \"Sentry\",\n summary: \"Error monitoring, issues, and performance data.\",\n url: \"https://mcp.sentry.dev/mcp\",\n endpoint: \"https://mcp.sentry.dev/mcp\",\n icon: \"https://svgl.app/library/sentry.svg\",\n },\n {\n id: \"cloudflare\",\n name: \"Cloudflare\",\n summary: \"Workers, KV, D1, R2, and DNS management via MCP.\",\n url: \"https://mcp.cloudflare.com/mcp\",\n endpoint: \"https://mcp.cloudflare.com/mcp\",\n icon: \"https://cloudflare.com/favicon.ico\",\n },\n {\n id: \"chrome-devtools\",\n name: \"Chrome DevTools\",\n summary: \"Debug a live Chrome browser session via local stdio.\",\n icon: \"https://www.google.com/chrome/static/images/favicons/favicon-32x32.png\",\n featured: true,\n transport: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"chrome-devtools-mcp@latest\"],\n },\n];\n"],"mappings":";AAyBO,IAAM,aAAmC;AAAA,EAC9C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,IACX,SAAS;AAAA,IACT,MAAM,CAAC,MAAM,4BAA4B;AAAA,EAC3C;AACF;","names":[]}
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  mcpPresets
3
- } from "./chunk-QEAVWCYB.js";
3
+ } from "./chunk-CLAWPLDI.js";
4
4
 
5
5
  // src/react/plugin-client.tsx
6
6
  import { defineClientPlugin } from "@executor-js/sdk/client";
@@ -8,7 +8,7 @@ import { defineClientPlugin } from "@executor-js/sdk/client";
8
8
  // src/react/source-plugin.tsx
9
9
  import { lazy } from "react";
10
10
  import { jsx } from "react/jsx-runtime";
11
- var importAdd = () => import("./AddMcpSource-BSJDTWMP.js");
11
+ var importAdd = () => import("./AddMcpSource-URN7Y5IO.js");
12
12
  var importEditSheet = () => import("./EditMcpSource-3S6FUVCR.js");
13
13
  var importAccounts = () => import("./McpAccountsPanel-273WNH3T.js");
14
14
  var LazyAddMcpSource = lazy(importAdd);
package/dist/core.js CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  joinToolPath,
5
5
  mcpPlugin,
6
6
  userFacingProbeMessage
7
- } from "./chunk-ENRA2SPE.js";
8
- import "./chunk-QEAVWCYB.js";
7
+ } from "./chunk-3AGPV4QE.js";
8
+ import "./chunk-CLAWPLDI.js";
9
9
  import {
10
10
  McpAuthMethod,
11
11
  McpAuthMethodInput,
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  mcpPlugin
3
- } from "./chunk-ENRA2SPE.js";
4
- import "./chunk-QEAVWCYB.js";
3
+ } from "./chunk-3AGPV4QE.js";
4
+ import "./chunk-CLAWPLDI.js";
5
5
  import "./chunk-3H5Y7JCQ.js";
6
6
  export {
7
7
  mcpPlugin
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- export { McpTestServerError, McpTestServerLayer, makeAnnotationsMcpServer, makeEchoMcpServer, makeElicitationMcpServer, makeGreetingMcpServer, serveMcpServer, serveMcpServerWithOAuth, type McpTestRequest, type McpTestServer, type McpTestServerOptions, } from "./server";
1
+ export { McpTestServerError, McpTestServerLayer, TEST_IMAGE_MIME_TYPE, TEST_IMAGE_PNG_BASE64, makeAnnotationsMcpServer, makeEchoMcpServer, makeElicitationMcpServer, makeGreetingMcpServer, makeImageMcpServer, serveMcpServer, serveMcpServerWithOAuth, type McpTestRequest, type McpTestServer, type McpTestServerOptions, } from "./server";
@@ -63,6 +63,9 @@ export declare const makeGreetingMcpServer: (options?: {
63
63
  readonly toolDescription?: string;
64
64
  readonly text?: string;
65
65
  }) => McpServer;
66
+ export declare const TEST_IMAGE_MIME_TYPE = "image/png";
67
+ export declare const TEST_IMAGE_PNG_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAFgwJ/l8N1wwAAAABJRU5ErkJggg==";
68
+ export declare const makeImageMcpServer: () => McpServer;
66
69
  export declare const makeEchoMcpServer: (options?: {
67
70
  readonly name?: string;
68
71
  readonly version?: string;
package/dist/testing.js CHANGED
@@ -191,6 +191,58 @@ var makeGreetingMcpServer = (options = {}) => {
191
191
  );
192
192
  return server;
193
193
  };
194
+ var TEST_IMAGE_MIME_TYPE = "image/png";
195
+ var TEST_IMAGE_PNG_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAFgwJ/l8N1wwAAAABJRU5ErkJggg==";
196
+ var testImageMetadata = () => ({
197
+ name: "mcp-image-fixture.png",
198
+ mimeType: TEST_IMAGE_MIME_TYPE,
199
+ byteLength: Buffer.from(TEST_IMAGE_PNG_BASE64, "base64").byteLength
200
+ });
201
+ var makeImageMcpServer = () => {
202
+ const server = new McpServer(
203
+ { name: "image-test-server", version: "1.0.0" },
204
+ { capabilities: {} }
205
+ );
206
+ server.registerTool(
207
+ "image_fixture",
208
+ {
209
+ description: "Returns a deterministic PNG as MCP image content",
210
+ inputSchema: {}
211
+ },
212
+ async () => ({
213
+ content: [
214
+ {
215
+ type: "image",
216
+ data: TEST_IMAGE_PNG_BASE64,
217
+ mimeType: TEST_IMAGE_MIME_TYPE
218
+ }
219
+ ],
220
+ structuredContent: testImageMetadata()
221
+ })
222
+ );
223
+ server.registerTool(
224
+ "image_fixture_with_metadata",
225
+ {
226
+ description: "Returns text metadata followed by MCP image content",
227
+ inputSchema: {}
228
+ },
229
+ async () => ({
230
+ content: [
231
+ {
232
+ type: "text",
233
+ text: "Deterministic image fixture: mcp-image-fixture.png (image/png, 70 bytes)"
234
+ },
235
+ {
236
+ type: "image",
237
+ data: TEST_IMAGE_PNG_BASE64,
238
+ mimeType: TEST_IMAGE_MIME_TYPE
239
+ }
240
+ ],
241
+ structuredContent: testImageMetadata()
242
+ })
243
+ );
244
+ return server;
245
+ };
194
246
  var makeEchoMcpServer = (options = {}) => {
195
247
  const inputName = options.inputName ?? "value";
196
248
  const server = new McpServer(
@@ -320,10 +372,13 @@ var makeAnnotationsMcpServer = () => {
320
372
  export {
321
373
  McpTestServerError,
322
374
  McpTestServerLayer,
375
+ TEST_IMAGE_MIME_TYPE,
376
+ TEST_IMAGE_PNG_BASE64,
323
377
  makeAnnotationsMcpServer,
324
378
  makeEchoMcpServer,
325
379
  makeElicitationMcpServer,
326
380
  makeGreetingMcpServer,
381
+ makeImageMcpServer,
327
382
  serveMcpServer,
328
383
  serveMcpServerWithOAuth
329
384
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing/server.ts"],"sourcesContent":["import { Context, Data, Effect, Layer, Ref, Scope } from \"effect\";\nimport * as http from \"node:http\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { OAuthTestServer } from \"@executor-js/sdk/testing\";\nimport z from \"zod\";\n\nexport type McpTestServer = {\n readonly url: string;\n readonly endpoint: string;\n /** Number of MCP sessions created (each connect = 1 session) */\n readonly sessionCount: () => number;\n readonly requests: Effect.Effect<readonly McpTestRequest[]>;\n readonly clearRequests: Effect.Effect<void>;\n};\n\nexport type McpTestRequest = {\n readonly method: string;\n readonly url: string;\n readonly authorization: string | undefined;\n readonly sessionId: string | undefined;\n};\n\nexport type McpTestServerOptions = {\n readonly path?: string;\n readonly auth?: {\n readonly validateAuthorization: (authorization: string | undefined) => Effect.Effect<boolean>;\n readonly authorizationServerUrls?: readonly string[];\n readonly scopes?: readonly string[];\n readonly wwwAuthenticate?: string;\n };\n};\n\nexport class McpTestServerError extends Data.TaggedError(\"McpTestServerError\")<{\n readonly cause: unknown;\n}> {}\n\nconst writeJson = (\n response: http.ServerResponse,\n status: number,\n body: Readonly<Record<string, unknown>>,\n headers: Readonly<Record<string, string>> = {},\n) => {\n response.writeHead(status, {\n \"content-type\": \"application/json\",\n ...headers,\n });\n response.end(JSON.stringify(body));\n};\n\nconst writeText = (response: http.ServerResponse, status: number, body: string) => {\n response.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" });\n response.end(body);\n};\n\nconst isMcpPath = (url: string, path: string): boolean => {\n const parsed = new URL(url, \"http://executor.test\");\n return parsed.pathname === path;\n};\n\nconst protectedResourcePath = \"/.well-known/oauth-protected-resource\";\n\nexport const serveMcpServer = (factory: () => McpServer, options: McpTestServerOptions = {}) =>\n Effect.acquireRelease(\n Effect.gen(function* () {\n const transports = new Map<string, StreamableHTTPServerTransport>();\n const requests = yield* Ref.make<readonly McpTestRequest[]>([]);\n const path = options.path ?? \"/\";\n let sessions = 0;\n\n const handleMcpRequest = (\n request: http.IncomingMessage,\n response: http.ServerResponse,\n ): Effect.Effect<void> =>\n Effect.gen(function* () {\n const requestUrl = request.url ?? \"/\";\n const sessionId = Array.isArray(request.headers[\"mcp-session-id\"])\n ? request.headers[\"mcp-session-id\"][0]\n : request.headers[\"mcp-session-id\"];\n const authorization = Array.isArray(request.headers.authorization)\n ? request.headers.authorization[0]\n : request.headers.authorization;\n const origin = request.headers.host\n ? `http://${request.headers.host}`\n : \"http://127.0.0.1\";\n\n yield* Ref.update(requests, (all) => [\n ...all,\n {\n method: request.method ?? \"GET\",\n url: requestUrl,\n authorization,\n sessionId,\n },\n ]);\n\n if (\n options.auth?.authorizationServerUrls &&\n requestUrl.startsWith(protectedResourcePath)\n ) {\n const resourcePath = requestUrl.slice(protectedResourcePath.length);\n writeJson(response, 200, {\n resource: `${origin}${resourcePath}`,\n authorization_servers: options.auth.authorizationServerUrls,\n bearer_methods_supported: [\"header\"],\n scopes_supported: options.auth.scopes ?? [\"read\"],\n });\n return;\n }\n\n if (!isMcpPath(requestUrl, path)) {\n writeJson(response, 404, { error: \"not_found\" });\n return;\n }\n\n if (options.auth) {\n const accepted = yield* options.auth.validateAuthorization(authorization);\n if (!accepted) {\n writeJson(\n response,\n 401,\n { error: \"invalid_token\" },\n {\n \"www-authenticate\":\n options.auth.wwwAuthenticate ??\n `Bearer resource_metadata=\"${origin}${protectedResourcePath}${path}\", error=\"invalid_token\"`,\n },\n );\n return;\n }\n }\n\n const existingTransport = sessionId ? transports.get(sessionId) : undefined;\n if (sessionId && !existingTransport) {\n writeText(response, 404, \"Session not found\");\n return;\n }\n\n if (existingTransport) {\n yield* Effect.tryPromise({\n try: () => existingTransport.handleRequest(request, response),\n catch: (cause) => new McpTestServerError({ cause }),\n });\n return;\n }\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => crypto.randomUUID(),\n onsessioninitialized: (sid) => {\n transports.set(sid, transport);\n },\n });\n sessions += 1;\n\n const mcpServer = factory();\n yield* Effect.tryPromise({\n try: () => mcpServer.connect(transport),\n catch: (cause) => new McpTestServerError({ cause }),\n });\n yield* Effect.tryPromise({\n try: () => transport.handleRequest(request, response),\n catch: (cause) => new McpTestServerError({ cause }),\n });\n }).pipe(\n Effect.catch(() =>\n Effect.sync(() => {\n if (!response.headersSent) {\n writeJson(response, 500, { error: \"mcp_test_server_failed\" });\n } else if (!response.writableEnded) {\n response.end();\n }\n }),\n ),\n );\n\n const nodeServer = http.createServer((request, response) => {\n void Effect.runPromise(handleMcpRequest(request, response));\n });\n\n const port = yield* Effect.callback<number, McpTestServerError>((resume) => {\n const onError = (cause: Error) => {\n nodeServer.off(\"error\", onError);\n resume(Effect.fail(new McpTestServerError({ cause })));\n };\n nodeServer.once(\"error\", onError);\n nodeServer.listen(0, () => {\n nodeServer.off(\"error\", onError);\n const address = nodeServer.address();\n if (typeof address === \"object\" && address) {\n resume(Effect.succeed(address.port));\n return;\n }\n resume(Effect.fail(new McpTestServerError({ cause: address })));\n });\n });\n\n const baseUrl = `http://127.0.0.1:${port}`;\n const endpoint = path === \"/\" ? baseUrl : new URL(path, baseUrl).toString();\n return {\n url: endpoint,\n endpoint,\n sessionCount: () => sessions,\n requests: Ref.get(requests),\n clearRequests: Ref.set(requests, []),\n close: Effect.gen(function* () {\n for (const transport of transports.values()) {\n yield* Effect.tryPromise({\n try: () => transport.close(),\n catch: (cause) => new McpTestServerError({ cause }),\n }).pipe(Effect.ignore);\n }\n yield* Effect.sync(() => {\n nodeServer.close();\n nodeServer.closeAllConnections?.();\n });\n }),\n };\n }),\n (server) => server.close,\n ).pipe(Effect.map(({ close: _close, ...server }) => server));\n\nexport const serveMcpServerWithOAuth = (\n factory: () => McpServer,\n options: Omit<McpTestServerOptions, \"auth\"> & {\n readonly scopes?: readonly string[];\n readonly wwwAuthenticate?: string;\n } = {},\n) =>\n Effect.gen(function* () {\n const oauth = yield* OAuthTestServer;\n return yield* serveMcpServer(factory, {\n path: options.path,\n auth: {\n validateAuthorization: oauth.acceptsAuthorizationHeader,\n authorizationServerUrls: [oauth.issuerUrl],\n scopes: options.scopes ?? [\"read\"],\n wwwAuthenticate: options.wwwAuthenticate,\n },\n });\n });\n\nexport class McpTestServerLayer extends Context.Service<McpTestServerLayer, McpTestServer>()(\n \"@executor-js/plugin-mcp/testing/McpTestServer\",\n) {\n static readonly layer = (\n factory: () => McpServer,\n options?: McpTestServerOptions,\n ): Layer.Layer<McpTestServerLayer, McpTestServerError, Scope.Scope> =>\n Layer.effect(McpTestServerLayer, serveMcpServer(factory, options));\n\n static readonly layerWithOAuth = (\n factory: () => McpServer,\n options?: Omit<McpTestServerOptions, \"auth\"> & {\n readonly scopes?: readonly string[];\n readonly wwwAuthenticate?: string;\n },\n ): Layer.Layer<McpTestServerLayer, McpTestServerError, Scope.Scope | OAuthTestServer> =>\n Layer.effect(McpTestServerLayer, serveMcpServerWithOAuth(factory, options));\n}\n\nexport const makeGreetingMcpServer = (\n options: {\n readonly name?: string;\n readonly version?: string;\n readonly toolName?: string;\n readonly toolDescription?: string;\n readonly text?: string;\n } = {},\n) => {\n const server = new McpServer(\n {\n name: options.name ?? \"executor-test-mcp\",\n version: options.version ?? \"1.0.0\",\n },\n { capabilities: {} },\n );\n\n server.registerTool(\n options.toolName ?? \"simple_echo\",\n {\n description: options.toolDescription ?? \"Echoes from the executor MCP test server\",\n inputSchema: {},\n },\n async () => ({\n content: [{ type: \"text\" as const, text: options.text ?? \"mcp-ok\" }],\n }),\n );\n\n return server;\n};\n\nexport const makeEchoMcpServer = (\n options: {\n readonly name?: string;\n readonly version?: string;\n readonly toolName?: string;\n readonly toolDescription?: string;\n readonly inputName?: \"name\" | \"value\" | \"marker\";\n readonly text?: (value: string) => string;\n } = {},\n) => {\n const inputName = options.inputName ?? \"value\";\n const server = new McpServer(\n {\n name: options.name ?? \"executor-echo-mcp\",\n version: options.version ?? \"1.0.0\",\n },\n { capabilities: {} },\n );\n\n server.registerTool(\n options.toolName ?? \"echo\",\n {\n description: options.toolDescription ?? \"Echoes a string value\",\n inputSchema: { [inputName]: z.string() },\n },\n async (input) => ({\n content: [\n {\n type: \"text\" as const,\n text: options.text ? options.text(input[inputName]) : input[inputName],\n },\n ],\n }),\n );\n\n return server;\n};\n\nexport const makeElicitationMcpServer = () => {\n const server = new McpServer(\n { name: \"elicitation-test-server\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n\n server.registerTool(\n \"gated_echo\",\n {\n description: \"Asks for approval before echoing a value\",\n inputSchema: { value: z.string() },\n },\n async ({ value }: { value: string }) => {\n const response = await server.server.elicitInput({\n mode: \"form\",\n message: `Approve echo for \"${value}\"?`,\n requestedSchema: {\n type: \"object\",\n properties: {\n approved: { type: \"boolean\", title: \"Approve\" },\n },\n required: [\"approved\"],\n },\n });\n\n if (response.action !== \"accept\" || !response.content || response.content.approved !== true) {\n return {\n content: [{ type: \"text\" as const, text: `denied:${value}` }],\n };\n }\n\n return {\n content: [{ type: \"text\" as const, text: `approved:${value}` }],\n };\n },\n );\n\n server.registerTool(\n \"simple_echo\",\n {\n description: \"Echoes a value without elicitation\",\n inputSchema: { value: z.string() },\n },\n async ({ value }: { value: string }) => ({\n content: [{ type: \"text\" as const, text: value }],\n }),\n );\n\n server.registerTool(\n \"structured_echo\",\n {\n description: \"Returns text plus structured data\",\n inputSchema: { value: z.string() },\n outputSchema: {\n value: z.string(),\n upper: z.string(),\n },\n },\n async ({ value }: { value: string }) => ({\n content: [{ type: \"text\" as const, text: value }],\n structuredContent: { value, upper: value.toUpperCase() },\n _meta: { trace: \"kept\" },\n }),\n );\n\n return server;\n};\n\nexport const makeAnnotationsMcpServer = () => {\n const server = new McpServer(\n { name: \"annotations-test-server\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n\n server.registerTool(\n \"delete\",\n {\n description: \"A destructive tool\",\n inputSchema: { id: z.string() },\n annotations: { destructiveHint: true },\n },\n async () => ({ content: [] }),\n );\n\n server.registerTool(\n \"delete_titled\",\n {\n description: \"A destructive tool with a title annotation\",\n inputSchema: { id: z.string() },\n annotations: { destructiveHint: true, title: \"Delete dataset\" },\n },\n async () => ({ content: [] }),\n );\n\n server.registerTool(\n \"list\",\n {\n description: \"A read-only tool\",\n inputSchema: {},\n annotations: { readOnlyHint: true },\n },\n async () => ({ content: [] }),\n );\n\n server.registerTool(\n \"ping\",\n { description: \"An unannotated tool\", inputSchema: {} },\n async () => ({ content: [] }),\n );\n\n return server;\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/testing/server.ts"],"sourcesContent":["import { Context, Data, Effect, Layer, Ref, Scope } from \"effect\";\nimport * as http from \"node:http\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { OAuthTestServer } from \"@executor-js/sdk/testing\";\nimport z from \"zod\";\n\nexport type McpTestServer = {\n readonly url: string;\n readonly endpoint: string;\n /** Number of MCP sessions created (each connect = 1 session) */\n readonly sessionCount: () => number;\n readonly requests: Effect.Effect<readonly McpTestRequest[]>;\n readonly clearRequests: Effect.Effect<void>;\n};\n\nexport type McpTestRequest = {\n readonly method: string;\n readonly url: string;\n readonly authorization: string | undefined;\n readonly sessionId: string | undefined;\n};\n\nexport type McpTestServerOptions = {\n readonly path?: string;\n readonly auth?: {\n readonly validateAuthorization: (authorization: string | undefined) => Effect.Effect<boolean>;\n readonly authorizationServerUrls?: readonly string[];\n readonly scopes?: readonly string[];\n readonly wwwAuthenticate?: string;\n };\n};\n\nexport class McpTestServerError extends Data.TaggedError(\"McpTestServerError\")<{\n readonly cause: unknown;\n}> {}\n\nconst writeJson = (\n response: http.ServerResponse,\n status: number,\n body: Readonly<Record<string, unknown>>,\n headers: Readonly<Record<string, string>> = {},\n) => {\n response.writeHead(status, {\n \"content-type\": \"application/json\",\n ...headers,\n });\n response.end(JSON.stringify(body));\n};\n\nconst writeText = (response: http.ServerResponse, status: number, body: string) => {\n response.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" });\n response.end(body);\n};\n\nconst isMcpPath = (url: string, path: string): boolean => {\n const parsed = new URL(url, \"http://executor.test\");\n return parsed.pathname === path;\n};\n\nconst protectedResourcePath = \"/.well-known/oauth-protected-resource\";\n\nexport const serveMcpServer = (factory: () => McpServer, options: McpTestServerOptions = {}) =>\n Effect.acquireRelease(\n Effect.gen(function* () {\n const transports = new Map<string, StreamableHTTPServerTransport>();\n const requests = yield* Ref.make<readonly McpTestRequest[]>([]);\n const path = options.path ?? \"/\";\n let sessions = 0;\n\n const handleMcpRequest = (\n request: http.IncomingMessage,\n response: http.ServerResponse,\n ): Effect.Effect<void> =>\n Effect.gen(function* () {\n const requestUrl = request.url ?? \"/\";\n const sessionId = Array.isArray(request.headers[\"mcp-session-id\"])\n ? request.headers[\"mcp-session-id\"][0]\n : request.headers[\"mcp-session-id\"];\n const authorization = Array.isArray(request.headers.authorization)\n ? request.headers.authorization[0]\n : request.headers.authorization;\n const origin = request.headers.host\n ? `http://${request.headers.host}`\n : \"http://127.0.0.1\";\n\n yield* Ref.update(requests, (all) => [\n ...all,\n {\n method: request.method ?? \"GET\",\n url: requestUrl,\n authorization,\n sessionId,\n },\n ]);\n\n if (\n options.auth?.authorizationServerUrls &&\n requestUrl.startsWith(protectedResourcePath)\n ) {\n const resourcePath = requestUrl.slice(protectedResourcePath.length);\n writeJson(response, 200, {\n resource: `${origin}${resourcePath}`,\n authorization_servers: options.auth.authorizationServerUrls,\n bearer_methods_supported: [\"header\"],\n scopes_supported: options.auth.scopes ?? [\"read\"],\n });\n return;\n }\n\n if (!isMcpPath(requestUrl, path)) {\n writeJson(response, 404, { error: \"not_found\" });\n return;\n }\n\n if (options.auth) {\n const accepted = yield* options.auth.validateAuthorization(authorization);\n if (!accepted) {\n writeJson(\n response,\n 401,\n { error: \"invalid_token\" },\n {\n \"www-authenticate\":\n options.auth.wwwAuthenticate ??\n `Bearer resource_metadata=\"${origin}${protectedResourcePath}${path}\", error=\"invalid_token\"`,\n },\n );\n return;\n }\n }\n\n const existingTransport = sessionId ? transports.get(sessionId) : undefined;\n if (sessionId && !existingTransport) {\n writeText(response, 404, \"Session not found\");\n return;\n }\n\n if (existingTransport) {\n yield* Effect.tryPromise({\n try: () => existingTransport.handleRequest(request, response),\n catch: (cause) => new McpTestServerError({ cause }),\n });\n return;\n }\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => crypto.randomUUID(),\n onsessioninitialized: (sid) => {\n transports.set(sid, transport);\n },\n });\n sessions += 1;\n\n const mcpServer = factory();\n yield* Effect.tryPromise({\n try: () => mcpServer.connect(transport),\n catch: (cause) => new McpTestServerError({ cause }),\n });\n yield* Effect.tryPromise({\n try: () => transport.handleRequest(request, response),\n catch: (cause) => new McpTestServerError({ cause }),\n });\n }).pipe(\n Effect.catch(() =>\n Effect.sync(() => {\n if (!response.headersSent) {\n writeJson(response, 500, { error: \"mcp_test_server_failed\" });\n } else if (!response.writableEnded) {\n response.end();\n }\n }),\n ),\n );\n\n const nodeServer = http.createServer((request, response) => {\n void Effect.runPromise(handleMcpRequest(request, response));\n });\n\n const port = yield* Effect.callback<number, McpTestServerError>((resume) => {\n const onError = (cause: Error) => {\n nodeServer.off(\"error\", onError);\n resume(Effect.fail(new McpTestServerError({ cause })));\n };\n nodeServer.once(\"error\", onError);\n nodeServer.listen(0, () => {\n nodeServer.off(\"error\", onError);\n const address = nodeServer.address();\n if (typeof address === \"object\" && address) {\n resume(Effect.succeed(address.port));\n return;\n }\n resume(Effect.fail(new McpTestServerError({ cause: address })));\n });\n });\n\n const baseUrl = `http://127.0.0.1:${port}`;\n const endpoint = path === \"/\" ? baseUrl : new URL(path, baseUrl).toString();\n return {\n url: endpoint,\n endpoint,\n sessionCount: () => sessions,\n requests: Ref.get(requests),\n clearRequests: Ref.set(requests, []),\n close: Effect.gen(function* () {\n for (const transport of transports.values()) {\n yield* Effect.tryPromise({\n try: () => transport.close(),\n catch: (cause) => new McpTestServerError({ cause }),\n }).pipe(Effect.ignore);\n }\n yield* Effect.sync(() => {\n nodeServer.close();\n nodeServer.closeAllConnections?.();\n });\n }),\n };\n }),\n (server) => server.close,\n ).pipe(Effect.map(({ close: _close, ...server }) => server));\n\nexport const serveMcpServerWithOAuth = (\n factory: () => McpServer,\n options: Omit<McpTestServerOptions, \"auth\"> & {\n readonly scopes?: readonly string[];\n readonly wwwAuthenticate?: string;\n } = {},\n) =>\n Effect.gen(function* () {\n const oauth = yield* OAuthTestServer;\n return yield* serveMcpServer(factory, {\n path: options.path,\n auth: {\n validateAuthorization: oauth.acceptsAuthorizationHeader,\n authorizationServerUrls: [oauth.issuerUrl],\n scopes: options.scopes ?? [\"read\"],\n wwwAuthenticate: options.wwwAuthenticate,\n },\n });\n });\n\nexport class McpTestServerLayer extends Context.Service<McpTestServerLayer, McpTestServer>()(\n \"@executor-js/plugin-mcp/testing/McpTestServer\",\n) {\n static readonly layer = (\n factory: () => McpServer,\n options?: McpTestServerOptions,\n ): Layer.Layer<McpTestServerLayer, McpTestServerError, Scope.Scope> =>\n Layer.effect(McpTestServerLayer, serveMcpServer(factory, options));\n\n static readonly layerWithOAuth = (\n factory: () => McpServer,\n options?: Omit<McpTestServerOptions, \"auth\"> & {\n readonly scopes?: readonly string[];\n readonly wwwAuthenticate?: string;\n },\n ): Layer.Layer<McpTestServerLayer, McpTestServerError, Scope.Scope | OAuthTestServer> =>\n Layer.effect(McpTestServerLayer, serveMcpServerWithOAuth(factory, options));\n}\n\nexport const makeGreetingMcpServer = (\n options: {\n readonly name?: string;\n readonly version?: string;\n readonly toolName?: string;\n readonly toolDescription?: string;\n readonly text?: string;\n } = {},\n) => {\n const server = new McpServer(\n {\n name: options.name ?? \"executor-test-mcp\",\n version: options.version ?? \"1.0.0\",\n },\n { capabilities: {} },\n );\n\n server.registerTool(\n options.toolName ?? \"simple_echo\",\n {\n description: options.toolDescription ?? \"Echoes from the executor MCP test server\",\n inputSchema: {},\n },\n async () => ({\n content: [{ type: \"text\" as const, text: options.text ?? \"mcp-ok\" }],\n }),\n );\n\n return server;\n};\n\nexport const TEST_IMAGE_MIME_TYPE = \"image/png\";\nexport const TEST_IMAGE_PNG_BASE64 =\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAFgwJ/l8N1wwAAAABJRU5ErkJggg==\";\n\nconst testImageMetadata = () => ({\n name: \"mcp-image-fixture.png\",\n mimeType: TEST_IMAGE_MIME_TYPE,\n byteLength: Buffer.from(TEST_IMAGE_PNG_BASE64, \"base64\").byteLength,\n});\n\nexport const makeImageMcpServer = () => {\n const server = new McpServer(\n { name: \"image-test-server\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n\n server.registerTool(\n \"image_fixture\",\n {\n description: \"Returns a deterministic PNG as MCP image content\",\n inputSchema: {},\n },\n async () => ({\n content: [\n {\n type: \"image\" as const,\n data: TEST_IMAGE_PNG_BASE64,\n mimeType: TEST_IMAGE_MIME_TYPE,\n },\n ],\n structuredContent: testImageMetadata(),\n }),\n );\n\n server.registerTool(\n \"image_fixture_with_metadata\",\n {\n description: \"Returns text metadata followed by MCP image content\",\n inputSchema: {},\n },\n async () => ({\n content: [\n {\n type: \"text\" as const,\n text: \"Deterministic image fixture: mcp-image-fixture.png (image/png, 70 bytes)\",\n },\n {\n type: \"image\" as const,\n data: TEST_IMAGE_PNG_BASE64,\n mimeType: TEST_IMAGE_MIME_TYPE,\n },\n ],\n structuredContent: testImageMetadata(),\n }),\n );\n\n return server;\n};\n\nexport const makeEchoMcpServer = (\n options: {\n readonly name?: string;\n readonly version?: string;\n readonly toolName?: string;\n readonly toolDescription?: string;\n readonly inputName?: \"name\" | \"value\" | \"marker\";\n readonly text?: (value: string) => string;\n } = {},\n) => {\n const inputName = options.inputName ?? \"value\";\n const server = new McpServer(\n {\n name: options.name ?? \"executor-echo-mcp\",\n version: options.version ?? \"1.0.0\",\n },\n { capabilities: {} },\n );\n\n server.registerTool(\n options.toolName ?? \"echo\",\n {\n description: options.toolDescription ?? \"Echoes a string value\",\n inputSchema: { [inputName]: z.string() },\n },\n async (input) => ({\n content: [\n {\n type: \"text\" as const,\n text: options.text ? options.text(input[inputName]) : input[inputName],\n },\n ],\n }),\n );\n\n return server;\n};\n\nexport const makeElicitationMcpServer = () => {\n const server = new McpServer(\n { name: \"elicitation-test-server\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n\n server.registerTool(\n \"gated_echo\",\n {\n description: \"Asks for approval before echoing a value\",\n inputSchema: { value: z.string() },\n },\n async ({ value }: { value: string }) => {\n const response = await server.server.elicitInput({\n mode: \"form\",\n message: `Approve echo for \"${value}\"?`,\n requestedSchema: {\n type: \"object\",\n properties: {\n approved: { type: \"boolean\", title: \"Approve\" },\n },\n required: [\"approved\"],\n },\n });\n\n if (response.action !== \"accept\" || !response.content || response.content.approved !== true) {\n return {\n content: [{ type: \"text\" as const, text: `denied:${value}` }],\n };\n }\n\n return {\n content: [{ type: \"text\" as const, text: `approved:${value}` }],\n };\n },\n );\n\n server.registerTool(\n \"simple_echo\",\n {\n description: \"Echoes a value without elicitation\",\n inputSchema: { value: z.string() },\n },\n async ({ value }: { value: string }) => ({\n content: [{ type: \"text\" as const, text: value }],\n }),\n );\n\n server.registerTool(\n \"structured_echo\",\n {\n description: \"Returns text plus structured data\",\n inputSchema: { value: z.string() },\n outputSchema: {\n value: z.string(),\n upper: z.string(),\n },\n },\n async ({ value }: { value: string }) => ({\n content: [{ type: \"text\" as const, text: value }],\n structuredContent: { value, upper: value.toUpperCase() },\n _meta: { trace: \"kept\" },\n }),\n );\n\n return server;\n};\n\nexport const makeAnnotationsMcpServer = () => {\n const server = new McpServer(\n { name: \"annotations-test-server\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n\n server.registerTool(\n \"delete\",\n {\n description: \"A destructive tool\",\n inputSchema: { id: z.string() },\n annotations: { destructiveHint: true },\n },\n async () => ({ content: [] }),\n );\n\n server.registerTool(\n \"delete_titled\",\n {\n description: \"A destructive tool with a title annotation\",\n inputSchema: { id: z.string() },\n annotations: { destructiveHint: true, title: \"Delete dataset\" },\n },\n async () => ({ content: [] }),\n );\n\n server.registerTool(\n \"list\",\n {\n description: \"A read-only tool\",\n inputSchema: {},\n annotations: { readOnlyHint: true },\n },\n async () => ({ content: [] }),\n );\n\n server.registerTool(\n \"ping\",\n { description: \"An unannotated tool\", inputSchema: {} },\n async () => ({ content: [] }),\n );\n\n return server;\n};\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@executor-js/plugin-mcp",
3
- "version": "1.5.14",
3
+ "version": "1.5.15",
4
4
  "homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/plugins/mcp",
5
5
  "bugs": {
6
6
  "url": "https://github.com/RhysSullivan/executor/issues"
@@ -54,8 +54,8 @@
54
54
  "dependencies": {
55
55
  "@cfworker/json-schema": "^4.1.1",
56
56
  "@effect/platform-node": "4.0.0-beta.59",
57
- "@executor-js/config": "1.5.14",
58
- "@executor-js/sdk": "1.5.14",
57
+ "@executor-js/config": "1.5.15",
58
+ "@executor-js/sdk": "1.5.15",
59
59
  "@modelcontextprotocol/sdk": "^1.29.0",
60
60
  "zod": "4.3.6"
61
61
  },
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sdk/presets.ts"],"sourcesContent":["export interface McpRemotePreset {\n readonly id: string;\n readonly name: string;\n readonly summary: string;\n readonly url: string;\n readonly endpoint: string;\n readonly icon?: string;\n readonly featured?: boolean;\n readonly transport?: undefined;\n}\n\nexport interface McpStdioPreset {\n readonly id: string;\n readonly name: string;\n readonly summary: string;\n readonly icon?: string;\n readonly featured?: boolean;\n readonly transport: \"stdio\";\n readonly command: string;\n readonly args?: readonly string[];\n readonly env?: Readonly<Record<string, string>>;\n}\n\nexport type McpPreset = McpRemotePreset | McpStdioPreset;\n\nexport const mcpPresets: readonly McpPreset[] = [\n {\n id: \"deepwiki\",\n name: \"DeepWiki\",\n summary: \"Search and read documentation from any GitHub repo.\",\n url: \"https://mcp.deepwiki.com/mcp\",\n endpoint: \"https://mcp.deepwiki.com/mcp\",\n icon: \"https://deepwiki.com/favicon.ico\",\n featured: true,\n },\n {\n id: \"context7\",\n name: \"Context7\",\n summary: \"Up-to-date docs and code examples for any library.\",\n url: \"https://mcp.context7.com/mcp\",\n endpoint: \"https://mcp.context7.com/mcp\",\n icon: \"https://context7.com/favicon.ico\",\n featured: true,\n },\n {\n id: \"browserbase\",\n name: \"Browserbase\",\n summary: \"Cloud browser sessions for web scraping and automation.\",\n url: \"https://mcp.browserbase.com/mcp\",\n endpoint: \"https://mcp.browserbase.com/mcp\",\n icon: \"https://www.browserbase.com/favicon.ico\",\n featured: true,\n },\n {\n id: \"firecrawl\",\n name: \"Firecrawl\",\n summary: \"Crawl and scrape websites into structured data.\",\n url: \"https://mcp.firecrawl.dev/mcp\",\n endpoint: \"https://mcp.firecrawl.dev/mcp\",\n icon: \"https://www.firecrawl.dev/favicon.ico\",\n featured: true,\n },\n {\n id: \"neon\",\n name: \"Neon\",\n summary: \"Serverless Postgres — branches, queries, and management.\",\n url: \"https://mcp.neon.tech/mcp\",\n endpoint: \"https://mcp.neon.tech/mcp\",\n icon: \"https://neon.tech/favicon/favicon.ico\",\n featured: true,\n },\n {\n id: \"axiom\",\n name: \"Axiom\",\n summary: \"Query, analyze, and monitor your logs and event data.\",\n url: \"https://mcp.axiom.co/mcp\",\n endpoint: \"https://mcp.axiom.co/mcp\",\n icon: \"https://axiom.co/favicon.ico\",\n featured: true,\n },\n {\n id: \"stripe\",\n name: \"Stripe\",\n summary: \"Manage payments, subscriptions, and billing via MCP.\",\n url: \"https://mcp.stripe.com\",\n endpoint: \"https://mcp.stripe.com\",\n icon: \"https://stripe.com/favicon.ico\",\n featured: true,\n },\n {\n id: \"linear\",\n name: \"Linear\",\n summary: \"Issues, projects, teams, and cycles via MCP.\",\n url: \"https://mcp.linear.app/mcp\",\n endpoint: \"https://mcp.linear.app/mcp\",\n icon: \"https://linear.app/favicon.ico\",\n featured: true,\n },\n {\n id: \"notion\",\n name: \"Notion\",\n summary: \"Databases, pages, blocks, and search via MCP.\",\n url: \"https://mcp.notion.com/mcp\",\n endpoint: \"https://mcp.notion.com/mcp\",\n icon: \"https://www.notion.com/front-static/favicon.ico\",\n featured: true,\n },\n {\n id: \"sentry\",\n name: \"Sentry\",\n summary: \"Error monitoring, issues, and performance data.\",\n url: \"https://mcp.sentry.dev/mcp\",\n endpoint: \"https://mcp.sentry.dev/mcp\",\n icon: \"https://svgl.app/library/sentry.svg\",\n },\n {\n id: \"cloudflare\",\n name: \"Cloudflare\",\n summary: \"Workers, KV, D1, R2, and DNS management via MCP.\",\n url: \"https://mcp.cloudflare.com/mcp\",\n endpoint: \"https://mcp.cloudflare.com/mcp\",\n icon: \"https://cloudflare.com/favicon.ico\",\n },\n {\n id: \"chrome-devtools\",\n name: \"Chrome DevTools\",\n summary: \"Debug a live Chrome browser session via local stdio.\",\n icon: \"https://www.google.com/chrome/static/images/favicons/favicon-32x32.png\",\n featured: true,\n transport: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"chrome-devtools-mcp@latest\"],\n },\n];\n"],"mappings":";AAyBO,IAAM,aAAmC;AAAA,EAC9C;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,IACX,SAAS;AAAA,IACT,MAAM,CAAC,MAAM,4BAA4B;AAAA,EAC3C;AACF;","names":[]}