From b9aa34da713628f3cd76550eb1aa353c9428da54 Mon Sep 17 00:00:00 2001 From: masnwilliams <43387599+masnwilliams@users.noreply.github.com> Date: Fri, 31 Jul 2026 15:38:50 +0000 Subject: [PATCH 1/3] Classify Kernel API failures on tool errors --- src/lib/mcp/responses.ts | 34 +++++++++++++++++++++-- src/lib/mcp/tools/api-keys.ts | 4 +-- src/lib/mcp/tools/apps.ts | 4 +-- src/lib/mcp/tools/auth-connections.ts | 8 ++---- src/lib/mcp/tools/browser-curl.ts | 4 +-- src/lib/mcp/tools/browser-pools.ts | 4 +-- src/lib/mcp/tools/browsers.ts | 4 +-- src/lib/mcp/tools/computer-action.ts | 4 +-- src/lib/mcp/tools/credential-providers.ts | 8 ++---- src/lib/mcp/tools/credentials.ts | 4 +-- src/lib/mcp/tools/extensions.ts | 4 +-- src/lib/mcp/tools/profiles.ts | 4 +-- src/lib/mcp/tools/projects.ts | 4 +-- src/lib/mcp/tools/proxies.ts | 4 +-- src/lib/mcp/tools/replays.ts | 4 +-- 15 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/lib/mcp/responses.ts b/src/lib/mcp/responses.ts index c97f76c..b0a3cfd 100644 --- a/src/lib/mcp/responses.ts +++ b/src/lib/mcp/responses.ts @@ -1,3 +1,5 @@ +import { APIError } from "@onkernel/sdk"; + type PaginatedPage = { getPaginatedItems(): T[]; has_more?: boolean | null; @@ -64,12 +66,38 @@ function errorMessage(error: unknown) { return error instanceof Error ? error.message : String(error); } -export function toolErrorResponse( +// Named after what the API said, so a stale session id (404) is distinguishable from an +// org hitting its limits (429) or a fault on our side (5xx). Status codes only; the +// message stays out. +class ToolCallError extends Error { + constructor(name: string, message: string) { + super(message); + this.name = name; + } +} + +function errorName(error: unknown) { + if (error instanceof APIError && typeof error.status === "number") { + return `KernelApiError${error.status}`; + } + return error instanceof Error ? error.constructor.name : "Error"; +} + +/** + * Fails a tool call that a Kernel API request rejected. + * + * Throws rather than returning an isError result: analytics reads the error category + * from a thrown error's name, while a returned result only ever coerces to a generic + * "Error". The MCP SDK turns the throw back into the same isError text result the client + * saw before, so agents see no difference. + */ +export function throwToolError( toolName: string, action: string, error: unknown, -) { - return errorResponse( +): never { + throw new ToolCallError( + errorName(error), `Error in ${toolName} (${action}): ${errorMessage(error)}`, ); } diff --git a/src/lib/mcp/tools/api-keys.ts b/src/lib/mcp/tools/api-keys.ts index 9c34f2a..8690a03 100644 --- a/src/lib/mcp/tools/api-keys.ts +++ b/src/lib/mcp/tools/api-keys.ts @@ -6,7 +6,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -107,7 +107,7 @@ export function registerAPIKeyCapabilities(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_api_keys", params.action, error); + throwToolError("manage_api_keys", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/apps.ts b/src/lib/mcp/tools/apps.ts index 8c969a1..e395fc7 100644 --- a/src/lib/mcp/tools/apps.ts +++ b/src/lib/mcp/tools/apps.ts @@ -7,7 +7,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -206,7 +206,7 @@ export function registerAppCapabilities(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_apps", params.action, error); + throwToolError("manage_apps", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/auth-connections.ts b/src/lib/mcp/tools/auth-connections.ts index 73206f1..70e8bee 100644 --- a/src/lib/mcp/tools/auth-connections.ts +++ b/src/lib/mcp/tools/auth-connections.ts @@ -6,7 +6,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -255,11 +255,7 @@ export function registerAuthConnectionTools(server: McpServer) { } } } catch (error) { - return toolErrorResponse( - "manage_auth_connections", - params.action, - error, - ); + throwToolError("manage_auth_connections", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/browser-curl.ts b/src/lib/mcp/tools/browser-curl.ts index c7a2687..eb297cf 100644 --- a/src/lib/mcp/tools/browser-curl.ts +++ b/src/lib/mcp/tools/browser-curl.ts @@ -4,7 +4,7 @@ import { createKernelClient, type KernelClient } from "@/lib/mcp/kernel-client"; import { errorResponse, jsonResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; type BrowserCurlParams = Parameters[1]; @@ -74,7 +74,7 @@ export function registerBrowserCurlTool(server: McpServer) { const response = await client.browsers.curl(session_id, curlParams); return jsonResponse(response); } catch (error) { - return toolErrorResponse("browser_curl", "request", error); + throwToolError("browser_curl", "request", error); } }, ); diff --git a/src/lib/mcp/tools/browser-pools.ts b/src/lib/mcp/tools/browser-pools.ts index 20ced89..ae6072f 100644 --- a/src/lib/mcp/tools/browser-pools.ts +++ b/src/lib/mcp/tools/browser-pools.ts @@ -12,7 +12,7 @@ import { errorResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -474,7 +474,7 @@ export function registerBrowserPoolCapabilities(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_browser_pools", params.action, error); + throwToolError("manage_browser_pools", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/browsers.ts b/src/lib/mcp/tools/browsers.ts index 6865fe2..3fe0781 100644 --- a/src/lib/mcp/tools/browsers.ts +++ b/src/lib/mcp/tools/browsers.ts @@ -13,7 +13,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; import { @@ -695,7 +695,7 @@ export function registerBrowserCapabilities(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_browsers", params.action, error); + throwToolError("manage_browsers", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/computer-action.ts b/src/lib/mcp/tools/computer-action.ts index 58291da..9a2100b 100644 --- a/src/lib/mcp/tools/computer-action.ts +++ b/src/lib/mcp/tools/computer-action.ts @@ -5,7 +5,7 @@ import { errorResponse, jsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; type ComputerClient = KernelClient["browsers"]["computer"]; @@ -353,7 +353,7 @@ export function registerComputerActionTool(server: McpServer) { `Executed ${executedActionCount} action(s) successfully`, ); } catch (error) { - return toolErrorResponse("computer_action", "actions", error); + throwToolError("computer_action", "actions", error); } }, ); diff --git a/src/lib/mcp/tools/credential-providers.ts b/src/lib/mcp/tools/credential-providers.ts index e13f05e..9a7b744 100644 --- a/src/lib/mcp/tools/credential-providers.ts +++ b/src/lib/mcp/tools/credential-providers.ts @@ -6,7 +6,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -164,11 +164,7 @@ export function registerCredentialProviderTools(server: McpServer) { } } } catch (error) { - return toolErrorResponse( - "manage_credential_providers", - params.action, - error, - ); + throwToolError("manage_credential_providers", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/credentials.ts b/src/lib/mcp/tools/credentials.ts index cb7f2c3..04a865d 100644 --- a/src/lib/mcp/tools/credentials.ts +++ b/src/lib/mcp/tools/credentials.ts @@ -6,7 +6,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -152,7 +152,7 @@ export function registerCredentialTools(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_credentials", params.action, error); + throwToolError("manage_credentials", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/extensions.ts b/src/lib/mcp/tools/extensions.ts index f20d831..320472d 100644 --- a/src/lib/mcp/tools/extensions.ts +++ b/src/lib/mcp/tools/extensions.ts @@ -5,7 +5,7 @@ import { errorResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -53,7 +53,7 @@ export function registerExtensionTools(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_extensions", params.action, error); + throwToolError("manage_extensions", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/profiles.ts b/src/lib/mcp/tools/profiles.ts index f0b30a4..c444a3e 100644 --- a/src/lib/mcp/tools/profiles.ts +++ b/src/lib/mcp/tools/profiles.ts @@ -8,7 +8,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -214,7 +214,7 @@ export function registerProfileCapabilities(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_profiles", params.action, error); + throwToolError("manage_profiles", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/projects.ts b/src/lib/mcp/tools/projects.ts index 5bb7239..f8af0e0 100644 --- a/src/lib/mcp/tools/projects.ts +++ b/src/lib/mcp/tools/projects.ts @@ -6,7 +6,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -175,7 +175,7 @@ export function registerProjectCapabilities(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_projects", params.action, error); + throwToolError("manage_projects", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/proxies.ts b/src/lib/mcp/tools/proxies.ts index 632ed10..974503f 100644 --- a/src/lib/mcp/tools/proxies.ts +++ b/src/lib/mcp/tools/proxies.ts @@ -6,7 +6,7 @@ import { jsonResponse, paginatedJsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; import { paginationParams } from "@/lib/mcp/schemas"; @@ -169,7 +169,7 @@ export function registerProxyTools(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_proxies", params.action, error); + throwToolError("manage_proxies", params.action, error); } }, ); diff --git a/src/lib/mcp/tools/replays.ts b/src/lib/mcp/tools/replays.ts index d754a16..12c728a 100644 --- a/src/lib/mcp/tools/replays.ts +++ b/src/lib/mcp/tools/replays.ts @@ -6,7 +6,7 @@ import { itemsJsonResponse, jsonResponse, textResponse, - toolErrorResponse, + throwToolError, } from "@/lib/mcp/responses"; export function registerReplayTools(server: McpServer) { @@ -90,7 +90,7 @@ export function registerReplayTools(server: McpServer) { } } } catch (error) { - return toolErrorResponse("manage_replays", params.action, error); + throwToolError("manage_replays", params.action, error); } }, ); From 8f04c5d636a3ec4c5f48a9b89e7d10060cf13c67 Mon Sep 17 00:00:00 2001 From: masnwilliams <43387599+masnwilliams@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:18:52 +0000 Subject: [PATCH 2/3] Test error classification, and stop naming transport failures after minified classes The transport branch read error.constructor.name, which the production bundle minifies to a mangled identifier, so a timeout would have been recorded as a one-letter error type. Classify by instance instead, and fall back to error.name rather than the constructor's. Adds bun test to CI. --- .github/workflows/ci.yml | 3 + bun.lock | 5 ++ package.json | 2 + src/lib/mcp/responses.test.ts | 114 ++++++++++++++++++++++++++++++++++ src/lib/mcp/responses.ts | 21 +++++-- 5 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 src/lib/mcp/responses.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6b331d..1f26374 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,3 +17,6 @@ jobs: - name: Type check run: bunx tsc --noEmit + + - name: Test + run: bun test diff --git a/bun.lock b/bun.lock index 98bc3f1..50c57b0 100644 --- a/bun.lock +++ b/bun.lock @@ -33,6 +33,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4.1.11", + "@types/bun": "^1.3.14", "@types/jszip": "^3.4.1", "@types/node": "^20", "@types/react": "^19", @@ -201,6 +202,8 @@ "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.11", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "postcss": "^8.4.41", "tailwindcss": "4.1.11" } }, "sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA=="], + "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], + "@types/jsonwebtoken": ["@types/jsonwebtoken@9.0.10", "", { "dependencies": { "@types/ms": "*", "@types/node": "*" } }, "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA=="], "@types/jszip": ["@types/jszip@3.4.1", "", { "dependencies": { "jszip": "*" } }, "sha512-TezXjmf3lj+zQ651r6hPqvSScqBLvyPI9FxdXBqpEwBijNGQ2NXpaFW/7joGzveYkKQUil7iiDHLo6LV71Pc0A=="], @@ -229,6 +232,8 @@ "builtin-modules": ["builtin-modules@5.0.0", "", {}, "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg=="], + "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], diff --git a/package.json b/package.json index 57f008c..50da6c6 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "build": "next build", "start": "next start -p 3002", "lint": "next lint", + "test": "bun test", "format": "prettier --write \"**/*.{ts,js,json,md}\"", "format:check": "prettier --check \"**/*.{ts,js,json,md}\"" }, @@ -57,6 +58,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4.1.11", + "@types/bun": "^1.3.14", "@types/jszip": "^3.4.1", "@types/node": "^20", "@types/react": "^19", diff --git a/src/lib/mcp/responses.test.ts b/src/lib/mcp/responses.test.ts new file mode 100644 index 0000000..e7ebd05 --- /dev/null +++ b/src/lib/mcp/responses.test.ts @@ -0,0 +1,114 @@ +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { Client } from "@modelcontextprotocol/sdk/client/index.js"; +import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js"; +import { + APIConnectionError, + APIConnectionTimeoutError, + APIError, + APIUserAbortError, +} from "@onkernel/sdk"; +import { describe, expect, test } from "bun:test"; + +import { errorResponse, throwToolError } from "@/lib/mcp/responses"; + +function apiError(status: number, message: string) { + return APIError.generate(status, undefined, message, new Headers()); +} + +function caught(error: unknown) { + try { + throwToolError("manage_browsers", "get", error); + } catch (thrown) { + return thrown as Error; + } + throw new Error("throwToolError did not throw"); +} + +describe("throwToolError classification", () => { + test("names Kernel API failures after their status", () => { + expect(caught(apiError(404, "not found")).name).toBe("KernelApiError404"); + expect(caught(apiError(429, "too many requests")).name).toBe( + "KernelApiError429", + ); + expect(caught(apiError(502, "bad gateway")).name).toBe("KernelApiError502"); + }); + + test("names transport failures without relying on class names", () => { + // The SDK's error classes are minified in the production bundle, so + // constructor.name reads as a mangled identifier there. These come from + // instanceof checks instead. + expect(caught(new APIConnectionTimeoutError({})).name).toBe( + "KernelApiTimeout", + ); + expect( + caught(new APIConnectionError({ message: "socket hang up" })).name, + ).toBe("KernelApiConnectionError"); + expect(caught(new APIUserAbortError({})).name).toBe("KernelApiAborted"); + }); + + test("falls back to a generic name for everything else", () => { + expect(caught(new Error("boom")).name).toBe("Error"); + expect(caught(new TypeError("bad arg")).name).toBe("TypeError"); + expect(caught("plain string").name).toBe("Error"); + }); + + test("keeps the message the tool already produced", () => { + expect(caught(apiError(404, "not found")).message).toBe( + "Error in manage_browsers (get): 404 not found", + ); + expect(caught("plain string").message).toBe( + "Error in manage_browsers (get): plain string", + ); + }); +}); + +describe("what the client receives", () => { + async function callTool(name: string) { + const server = new McpServer({ name: "test", version: "0.0.0" }); + + server.tool("api_failure", {}, async () => { + throwToolError( + "manage_browsers", + "get", + apiError(404, "browser session not found"), + ); + }); + + server.tool("input_guard", {}, async () => + errorResponse("Error: session_id is required for get action."), + ); + + const client = new Client({ name: "test-client", version: "0.0.0" }); + const [clientTransport, serverTransport] = + InMemoryTransport.createLinkedPair(); + await Promise.all([ + server.connect(serverTransport), + client.connect(clientTransport), + ]); + + const result = await client.callTool({ name, arguments: {} }); + await client.close(); + return result; + } + + test("a thrown API failure still arrives as an isError text result", async () => { + const result = await callTool("api_failure"); + + expect(result.isError).toBe(true); + expect(result.content).toEqual([ + { + type: "text", + text: "Error in manage_browsers (get): 404 browser session not found", + }, + ]); + }); + + test("input guards are unchanged", async () => { + const result = await callTool("input_guard"); + + expect(result.isError).toBe(true); + expect(result.content).toEqual([ + { type: "text", text: "Error: session_id is required for get action." }, + ]); + }); +}); diff --git a/src/lib/mcp/responses.ts b/src/lib/mcp/responses.ts index b0a3cfd..1481dac 100644 --- a/src/lib/mcp/responses.ts +++ b/src/lib/mcp/responses.ts @@ -1,4 +1,9 @@ -import { APIError } from "@onkernel/sdk"; +import { + APIConnectionError, + APIConnectionTimeoutError, + APIError, + APIUserAbortError, +} from "@onkernel/sdk"; type PaginatedPage = { getPaginatedItems(): T[]; @@ -77,10 +82,18 @@ class ToolCallError extends Error { } function errorName(error: unknown) { - if (error instanceof APIError && typeof error.status === "number") { - return `KernelApiError${error.status}`; + if (error instanceof APIError) { + if (typeof error.status === "number") { + return `KernelApiError${error.status}`; + } + // No status means the request never got a response. Classified by instance + // rather than class name, which the production bundle minifies. + if (error instanceof APIConnectionTimeoutError) return "KernelApiTimeout"; + if (error instanceof APIConnectionError) return "KernelApiConnectionError"; + if (error instanceof APIUserAbortError) return "KernelApiAborted"; + return "KernelApiError"; } - return error instanceof Error ? error.constructor.name : "Error"; + return error instanceof Error ? error.name : "Error"; } /** From 8d803116fb8b806a3744ade6423df719741b56a4 Mon Sep 17 00:00:00 2001 From: masnwilliams <43387599+masnwilliams@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:26:08 +0000 Subject: [PATCH 3/3] Use bun-types directly instead of the DefinitelyTyped wrapper @types/bun only re-exports bun-types. Depending on bun-types removes the extra hop and takes the types from the package Bun's own team publishes. Referenced from the test file rather than tsconfig's types array, which would drop the automatic @types/* includes. --- bun.lock | 4 +--- package.json | 2 +- src/lib/mcp/responses.test.ts | 2 ++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bun.lock b/bun.lock index 50c57b0..7db18e2 100644 --- a/bun.lock +++ b/bun.lock @@ -33,11 +33,11 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4.1.11", - "@types/bun": "^1.3.14", "@types/jszip": "^3.4.1", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", + "bun-types": "^1.3.14", "postcss": "^8.5.6", "tailwindcss": "^4.1.11", }, @@ -202,8 +202,6 @@ "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.11", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "postcss": "^8.4.41", "tailwindcss": "4.1.11" } }, "sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA=="], - "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], - "@types/jsonwebtoken": ["@types/jsonwebtoken@9.0.10", "", { "dependencies": { "@types/ms": "*", "@types/node": "*" } }, "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA=="], "@types/jszip": ["@types/jszip@3.4.1", "", { "dependencies": { "jszip": "*" } }, "sha512-TezXjmf3lj+zQ651r6hPqvSScqBLvyPI9FxdXBqpEwBijNGQ2NXpaFW/7joGzveYkKQUil7iiDHLo6LV71Pc0A=="], diff --git a/package.json b/package.json index 50da6c6..77aa08b 100644 --- a/package.json +++ b/package.json @@ -58,11 +58,11 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4.1.11", - "@types/bun": "^1.3.14", "@types/jszip": "^3.4.1", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", + "bun-types": "^1.3.14", "postcss": "^8.5.6", "tailwindcss": "^4.1.11" } diff --git a/src/lib/mcp/responses.test.ts b/src/lib/mcp/responses.test.ts index e7ebd05..b13332e 100644 --- a/src/lib/mcp/responses.test.ts +++ b/src/lib/mcp/responses.test.ts @@ -1,3 +1,5 @@ +/// + import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";