From 5b0ce84c5984fe445239df01da6c8418be3e9b7c Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Mon, 17 Feb 2025 11:03:49 +0100 Subject: [PATCH 1/4] Add package Signed-off-by: Alexis Rico --- .../dbagent/src/components/chats/chats-ui.tsx | 2 +- packages/mcp/eslint.config.mjs | 20 +++ packages/mcp/package.json | 23 ++++ packages/mcp/src/ai-sdk.ts | 78 ++++++++++++ packages/mcp/src/index.ts | 1 + packages/mcp/tsconfig.json | 6 + pnpm-lock.yaml | 115 ++++++++++++++++++ 7 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 packages/mcp/eslint.config.mjs create mode 100644 packages/mcp/package.json create mode 100644 packages/mcp/src/ai-sdk.ts create mode 100644 packages/mcp/src/index.ts create mode 100644 packages/mcp/tsconfig.json diff --git a/apps/dbagent/src/components/chats/chats-ui.tsx b/apps/dbagent/src/components/chats/chats-ui.tsx index daa2ee72..24562830 100644 --- a/apps/dbagent/src/components/chats/chats-ui.tsx +++ b/apps/dbagent/src/components/chats/chats-ui.tsx @@ -96,7 +96,7 @@ export function ChatsUI({ connections }: { connections: DbConnection[] }) { } // Include the context in the message - await handleSubmit(e, { + handleSubmit(e, { body: { connectionId, model, diff --git a/packages/mcp/eslint.config.mjs b/packages/mcp/eslint.config.mjs new file mode 100644 index 00000000..db08f3fc --- /dev/null +++ b/packages/mcp/eslint.config.mjs @@ -0,0 +1,20 @@ +import { base } from '@internal/eslint-config'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export default [ + { + ignores: ['eslint.config.mjs'] + }, + ...base, + { + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: __dirname + } + } + } +]; diff --git a/packages/mcp/package.json b/packages/mcp/package.json new file mode 100644 index 00000000..dbe19f92 --- /dev/null +++ b/packages/mcp/package.json @@ -0,0 +1,23 @@ +{ + "name": "@dbagent/mcp", + "version": "0.0.1", + "private": true, + "exports": { + ".": "./src/index.ts" + }, + "scripts": { + "lint": "eslint ./src", + "tsc": "tsc --noEmit" + }, + "devDependencies": { + "@internal/tsconfig": "workspace:*", + "@types/node": "^22.13.4" + }, + "dependencies": { + "typescript": "^5.7.3" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.5.0", + "ai": "^4.1.41" + } +} diff --git a/packages/mcp/src/ai-sdk.ts b/packages/mcp/src/ai-sdk.ts new file mode 100644 index 00000000..25e71321 --- /dev/null +++ b/packages/mcp/src/ai-sdk.ts @@ -0,0 +1,78 @@ +import { Client } from '@modelcontextprotocol/sdk/client/index.js'; +import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; +import { jsonSchema, type Tool } from 'ai'; + +type ToolSetConfig = { + mcpServers: { + [key: string]: { + command: string; + args: string[]; + env?: Record; + }; + }; + onToolCall?: (serverName: string, toolName: string, args: any, result: Promise) => void; +}; + +type ToolSet = { + tools: { + [key: string]: Tool; + }; + clients: { + [key: string]: Client; + }; +}; + +export async function createToolSet(config: ToolSetConfig): Promise { + let toolset: ToolSet = { + tools: {}, + clients: {} + }; + + // could probably speed this up by spinning these up in parallel + for (const [serverName, serverConfig] of Object.entries(config.mcpServers)) { + const transport = new StdioClientTransport({ + ...serverConfig, + stderr: process.stderr + }); + + const client = new Client( + { + name: `${serverName}-client`, + version: '1.0.0' + }, + { + capabilities: {} + } + ); + toolset.clients[serverName] = client; + await client.connect(transport); + + // Get list of tools and add them to the toolset + const toolList = await client.listTools(); + for (const tool of toolList.tools) { + let toolName = tool.name; + if (toolName !== serverName) { + toolName = `${serverName}_${toolName}`; + } + toolset.tools[toolName] = { + description: tool.description || '', + parameters: jsonSchema(tool.inputSchema as any), + execute: async (args) => { + const resultPromise = (async () => { + const result = await client.callTool({ + name: tool.name, + arguments: args + }); + return JSON.stringify(result); + })(); + + config.onToolCall?.(serverName, toolName, args, resultPromise); + + return resultPromise; + } + }; + } + } + + return toolset; +} diff --git a/packages/mcp/src/index.ts b/packages/mcp/src/index.ts new file mode 100644 index 00000000..12e58a9c --- /dev/null +++ b/packages/mcp/src/index.ts @@ -0,0 +1 @@ +export { createToolSet } from './ai-sdk'; diff --git a/packages/mcp/tsconfig.json b/packages/mcp/tsconfig.json new file mode 100644 index 00000000..f0e11a10 --- /dev/null +++ b/packages/mcp/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@internal/tsconfig/base.json", + "include": ["."], + "exclude": ["dist", "build", "node_modules"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e8310ed..e5e57cc5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -395,6 +395,25 @@ importers: specifier: ^5.7.3 version: 5.7.3 + packages/mcp: + dependencies: + '@modelcontextprotocol/sdk': + specifier: ^1.5.0 + version: 1.5.0 + ai: + specifier: ^4.1.41 + version: 4.1.41(react@19.0.0)(zod@3.24.2) + typescript: + specifier: ^5.7.3 + version: 5.7.3 + devDependencies: + '@internal/tsconfig': + specifier: workspace:* + version: link:../../configs/tsconfig + '@types/node': + specifier: ^22.13.4 + version: 22.13.4 + packages/theme: dependencies: chroma-js: @@ -1154,6 +1173,10 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@modelcontextprotocol/sdk@1.5.0': + resolution: {integrity: sha512-IJ+5iVVs8FCumIHxWqpwgkwOzyhtHVKy45s6Ug7Dv0MfRpaYisH8QQ87rIWeWdOzlk8sfhitZ7HCyQZk7d6b8w==} + engines: {node: '>=18'} + '@next/env@15.1.7': resolution: {integrity: sha512-d9jnRrkuOH7Mhi+LHav2XW91HOgTAWHxjMPkXMGBc9B2b7614P7kjt8tAplRvJpbSt4nbO1lugcT/kAaWzjlLQ==} @@ -2907,6 +2930,10 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -3057,6 +3084,10 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -3290,6 +3321,10 @@ packages: resolution: {integrity: sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==} engines: {node: '>=18.0.0'} + eventsource@3.0.5: + resolution: {integrity: sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==} + engines: {node: '>=18.0.0'} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -3506,6 +3541,10 @@ packages: html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -3515,6 +3554,10 @@ packages: engines: {node: '>=18'} hasBin: true + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -3530,6 +3573,9 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + inline-style-parser@0.2.4: resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} @@ -4406,6 +4452,10 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} + react-dom@19.0.0: resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} peerDependencies: @@ -4591,6 +4641,9 @@ packages: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sass@1.77.4: resolution: {integrity: sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==} engines: {node: '>=14.0.0'} @@ -4629,6 +4682,9 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sharp@0.33.5: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4705,6 +4761,10 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + std-env@3.8.0: resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} @@ -4860,6 +4920,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -4993,6 +5057,10 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + update-browserslist-db@1.1.2: resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} hasBin: true @@ -6062,6 +6130,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@modelcontextprotocol/sdk@1.5.0': + dependencies: + content-type: 1.0.5 + eventsource: 3.0.5 + raw-body: 3.0.0 + zod: 3.24.2 + zod-to-json-schema: 3.24.1(zod@3.24.2) + '@next/env@15.1.7': {} '@next/eslint-plugin-next@15.1.6': @@ -8009,6 +8085,8 @@ snapshots: concat-map@0.0.1: {} + content-type@1.0.5: {} + create-require@1.1.1: {} cross-spawn@7.0.6: @@ -8143,6 +8221,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + depd@2.0.0: {} + dequal@2.0.3: {} detect-libc@1.0.3: {} @@ -8579,6 +8659,10 @@ snapshots: eventsource-parser@3.0.0: {} + eventsource@3.0.5: + dependencies: + eventsource-parser: 3.0.0 + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -8812,10 +8896,22 @@ snapshots: html-url-attributes@3.0.1: {} + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + human-signals@5.0.0: {} husky@9.1.7: {} + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ignore@5.3.2: {} immutable@4.3.7: @@ -8828,6 +8924,8 @@ snapshots: imurmurhash@0.1.4: {} + inherits@2.0.4: {} + inline-style-parser@0.2.4: {} input-otp@1.4.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): @@ -9747,6 +9845,13 @@ snapshots: queue-microtask@1.2.3: {} + raw-body@3.0.0: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + unpipe: 1.0.0 + react-dom@19.0.0(react@19.0.0): dependencies: react: 19.0.0 @@ -10007,6 +10112,8 @@ snapshots: es-errors: 1.3.0 is-regex: 1.2.1 + safer-buffer@2.1.2: {} + sass@1.77.4: dependencies: chokidar: 3.6.0 @@ -10048,6 +10155,8 @@ snapshots: es-errors: 1.3.0 es-object-atoms: 1.0.0 + setprototypeof@1.2.0: {} + sharp@0.33.5: dependencies: color: 4.2.3 @@ -10152,6 +10261,8 @@ snapshots: stackback@0.0.2: {} + statuses@2.0.1: {} + std-env@3.8.0: {} streamsearch@1.1.0: {} @@ -10308,6 +10419,8 @@ snapshots: dependencies: is-number: 7.0.0 + toidentifier@1.0.1: {} + trim-lines@3.0.1: {} trough@2.2.0: {} @@ -10472,6 +10585,8 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 + unpipe@1.0.0: {} + update-browserslist-db@1.1.2(browserslist@4.24.4): dependencies: browserslist: 4.24.4 From 1c39d1cd703e4ea9b6b67e01d8c1c4f2031de77f Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Mon, 17 Feb 2025 11:10:13 +0100 Subject: [PATCH 2/4] Clean-up Signed-off-by: Alexis Rico --- packages/mcp/src/ai-sdk.ts | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/packages/mcp/src/ai-sdk.ts b/packages/mcp/src/ai-sdk.ts index 25e71321..01177972 100644 --- a/packages/mcp/src/ai-sdk.ts +++ b/packages/mcp/src/ai-sdk.ts @@ -10,7 +10,7 @@ type ToolSetConfig = { env?: Record; }; }; - onToolCall?: (serverName: string, toolName: string, args: any, result: Promise) => void; + onToolCall?: (serverName: string, toolName: string, args: any, result: Result) => void; }; type ToolSet = { @@ -23,12 +23,11 @@ type ToolSet = { }; export async function createToolSet(config: ToolSetConfig): Promise { - let toolset: ToolSet = { + const toolset: ToolSet = { tools: {}, clients: {} }; - // could probably speed this up by spinning these up in parallel for (const [serverName, serverConfig] of Object.entries(config.mcpServers)) { const transport = new StdioClientTransport({ ...serverConfig, @@ -44,31 +43,26 @@ export async function createToolSet(config: ToolSetConfig): Promise { capabilities: {} } ); + toolset.clients[serverName] = client; await client.connect(transport); - // Get list of tools and add them to the toolset - const toolList = await client.listTools(); - for (const tool of toolList.tools) { - let toolName = tool.name; - if (toolName !== serverName) { - toolName = `${serverName}_${toolName}`; - } + const { tools } = await client.listTools(); + for (const tool of tools) { + const toolName = tool.name === serverName ? tool.name : `${serverName}_${tool.name}`; + toolset.tools[toolName] = { description: tool.description || '', parameters: jsonSchema(tool.inputSchema as any), execute: async (args) => { - const resultPromise = (async () => { - const result = await client.callTool({ - name: tool.name, - arguments: args - }); - return JSON.stringify(result); - })(); + const result = await client.callTool({ + name: tool.name, + arguments: args + }); - config.onToolCall?.(serverName, toolName, args, resultPromise); + config.onToolCall?.(serverName, toolName, args, result); - return resultPromise; + return JSON.stringify(result); } }; } From 8c09f26e65dbd9124ee097262aef9bad29558f11 Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Mon, 24 Feb 2025 08:00:32 +0100 Subject: [PATCH 3/4] Update server files Signed-off-by: Alexis Rico --- packages/mcp/package.json | 12 ++-- packages/mcp/src/index.ts | 2 +- packages/mcp/src/servers/postgres/index.ts | 83 ++++++++++++++++++++++ packages/mcp/src/{ => utils}/ai-sdk.ts | 0 4 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 packages/mcp/src/servers/postgres/index.ts rename packages/mcp/src/{ => utils}/ai-sdk.ts (100%) diff --git a/packages/mcp/package.json b/packages/mcp/package.json index d18d43dd..4b13e72f 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -9,12 +9,16 @@ "lint": "eslint ./src", "tsc": "tsc --noEmit" }, + "dependencies": { + "fastmcp": "^1.17.0", + "pg": "8.13.3", + "typescript": "^5.7.3", + "zod": "^3.24.2" + }, "devDependencies": { "@internal/tsconfig": "workspace:*", - "@types/node": "^22.13.4" - }, - "dependencies": { - "typescript": "^5.7.3" + "@types/node": "^22.13.4", + "@types/pg": "^8.11.11" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.5.0", diff --git a/packages/mcp/src/index.ts b/packages/mcp/src/index.ts index 12e58a9c..ad9e8fe3 100644 --- a/packages/mcp/src/index.ts +++ b/packages/mcp/src/index.ts @@ -1 +1 @@ -export { createToolSet } from './ai-sdk'; +export { createToolSet } from './utils/ai-sdk'; diff --git a/packages/mcp/src/servers/postgres/index.ts b/packages/mcp/src/servers/postgres/index.ts new file mode 100644 index 00000000..ff571346 --- /dev/null +++ b/packages/mcp/src/servers/postgres/index.ts @@ -0,0 +1,83 @@ +#!/usr/bin/env node + +import { FastMCP } from 'fastmcp'; +import pg from 'pg'; +import { z } from 'zod'; + +async function buildServer(databaseUrl: string) { + const server = new FastMCP({ + name: 'PostgreSQL', + version: '0.1.0' + }); + + const resourceBaseUrl = new URL(databaseUrl); + resourceBaseUrl.protocol = 'postgres:'; + resourceBaseUrl.password = ''; + + const client = new pg.Pool({ + connectionString: databaseUrl + }); + + server.addTool({ + name: 'get-slow-queries', + description: `Get a list of slow queries formatted as a JSON array. + Contains how many times the query was called, the max execution time in seconds, + the mean execution time in seconds, the total execution time (all calls together) + in seconds, and the query itself.`, + parameters: z.object({ + thresholdMs: z.number().optional().default(5000) + }), + execute: async ({ thresholdMs }) => { + const result = await client.query( + ` + SELECT + calls, + round(max_exec_time/1000) max_exec_secs, + round(mean_exec_time/1000) mean_exec_secs, + round(total_exec_time/1000) total_exec_secs, + query + FROM pg_stat_statements + WHERE max_exec_time > $1 + ORDER BY total_exec_time DESC + LIMIT 10;`, + [thresholdMs] + ); + + return JSON.stringify(result.rows); + } + }); + + server.addTool({ + name: 'explain-query', + description: `Run explain on a a query. Returns the explain plan as received from PostgreSQL. + The query needs to be complete, it cannot contain $1, $2, etc. If you need to, replace the parameters with your own made up values. + It's very important that $1, $2, etc. are not passed to this tool. Use the tool describeTable to get the types of the columns. + If you know the schema, pass it in as well.`, + parameters: z.object({ + schema: z.string(), + query: z.string() + }), + execute: async ({ schema, query }) => { + if (query.includes('$1') || query.includes('$2') || query.includes('$3') || query.includes('$4')) { + return 'The query seems to contain placeholders ($1, $2, etc). Replace them with actual values and try again.'; + } + await client.query('BEGIN'); + try { + await client.query(`SET search_path TO ${schema}`); + const explainQuery = `EXPLAIN ${query}`; + console.log(schema); + console.log(explainQuery); + const result = await client.query(explainQuery); + console.log(result.rows); + return result.rows.map((row: { [key: string]: string }) => row['QUERY PLAN']).join('\n'); + } catch (error) { + console.error('Error explaining query', error); + return 'I could not run EXPLAIN on that query. Try a different method.'; + } finally { + await client.query('ROLLBACK'); + } + } + }); + + return server; +} diff --git a/packages/mcp/src/ai-sdk.ts b/packages/mcp/src/utils/ai-sdk.ts similarity index 100% rename from packages/mcp/src/ai-sdk.ts rename to packages/mcp/src/utils/ai-sdk.ts From c88a53421ced32894fa19d2d77202d158624e8fb Mon Sep 17 00:00:00 2001 From: Alexis Rico Date: Mon, 24 Feb 2025 08:01:57 +0100 Subject: [PATCH 4/4] Update lockfile Signed-off-by: Alexis Rico --- pnpm-lock.yaml | 294 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 36eb3184..37a14412 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -400,9 +400,18 @@ importers: ai: specifier: ^4.1.44 version: 4.1.44(react@19.0.0)(zod@3.24.2) + fastmcp: + specifier: ^1.17.0 + version: 1.18.0 + pg: + specifier: 8.13.3 + version: 8.13.3 typescript: specifier: ^5.7.3 version: 5.7.3 + zod: + specifier: ^3.24.2 + version: 3.24.2 devDependencies: '@internal/tsconfig': specifier: workspace:* @@ -410,6 +419,9 @@ importers: '@types/node': specifier: ^22.13.4 version: 22.13.4 + '@types/pg': + specifier: ^8.11.11 + version: 8.11.11 packages/theme: dependencies: @@ -1989,6 +2001,13 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@smithy/abort-controller@4.0.1': resolution: {integrity: sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g==} engines: {node: '>=18.0.0'} @@ -2260,6 +2279,9 @@ packages: peerDependencies: react: ^18 || ^19 + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + '@types/bytes@3.1.5': resolution: {integrity: sha512-VgZkrJckypj85YxEsEavcMmmSOIzkUHqWmM4CCyia5dc54YwsXzJ5uT4fYxBQNEXx+oF1krlhgCbvfubXqZYsQ==} @@ -2542,6 +2564,10 @@ packages: resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} engines: {node: '>=6'} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + ansi-regex@6.1.0: resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} @@ -2780,6 +2806,10 @@ packages: cliui@5.0.0: resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -3030,6 +3060,9 @@ packages: emoji-regex@7.0.3: resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} @@ -3221,6 +3254,10 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + execa@9.5.2: + resolution: {integrity: sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==} + engines: {node: ^18.19.0 || >=20.5.0} + expect-type@1.1.0: resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} engines: {node: '>=12.0.0'} @@ -3253,6 +3290,10 @@ packages: resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} hasBin: true + fastmcp@1.18.0: + resolution: {integrity: sha512-LtLqJjYNxdZYhf0EYOgiBWJMh7STGNm0OWt5snpQK9bpNnBseIPkBUp1bbLTaJYAX7go4ACkQJHu/R2or12Nzg==} + hasBin: true + fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -3262,10 +3303,18 @@ packages: fflate@0.8.1: resolution: {integrity: sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-type@19.6.0: + resolution: {integrity: sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==} + engines: {node: '>=18'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -3329,6 +3378,10 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + fuse.js@7.1.0: + resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} + engines: {node: '>=10'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -3353,6 +3406,10 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} @@ -3441,6 +3498,10 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} + human-signals@8.0.0: + resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==} + engines: {node: '>=18.18.0'} + husky@9.1.7: resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} engines: {node: '>=18'} @@ -3450,6 +3511,9 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -3554,6 +3618,10 @@ packages: resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} engines: {node: '>=4'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-fullwidth-code-point@4.0.0: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} @@ -3616,6 +3684,10 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -3628,6 +3700,10 @@ packages: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -3839,6 +3915,10 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mcp-proxy@2.4.0: + resolution: {integrity: sha512-TFZIXRHVxziKKb1meQPQzyeyLo/r2ITR9u8YGddJi87v8cFWj9ifzUAA/POvwWJMKqJzmgLtSfkDSv+e7ChYyA==} + hasBin: true + mdast-util-from-markdown@2.0.2: resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} @@ -4014,6 +4094,10 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -4099,6 +4183,10 @@ packages: parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} @@ -4125,6 +4213,10 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} + peek-readable@5.4.2: + resolution: {integrity: sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==} + engines: {node: '>=14.16'} + pg-cloudflare@1.1.1: resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} @@ -4320,6 +4412,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-ms@9.2.0: + resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} + engines: {node: '>=18'} + prismjs@1.27.0: resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} engines: {node: '>=6'} @@ -4664,6 +4760,9 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + strict-event-emitter-types@2.0.0: + resolution: {integrity: sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -4672,6 +4771,10 @@ packages: resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} engines: {node: '>=6'} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} @@ -4709,6 +4812,10 @@ packages: resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} engines: {node: '>=6'} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + strip-ansi@7.1.0: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} @@ -4721,6 +4828,10 @@ packages: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -4728,6 +4839,10 @@ packages: strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + strtok3@9.1.1: + resolution: {integrity: sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==} + engines: {node: '>=16'} + style-to-object@1.0.8: resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} @@ -4816,6 +4931,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + token-types@6.0.0: + resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==} + engines: {node: '>=14.16'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -4910,6 +5029,10 @@ packages: engines: {node: '>=14.17'} hasBin: true + uint8array-extras@1.4.0: + resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} + engines: {node: '>=18'} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -4917,6 +5040,10 @@ packages: undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -4948,6 +5075,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + uri-templates@0.2.0: + resolution: {integrity: sha512-EWkjYEN0L6KOfEoOH6Wj4ghQqU7eBZMJqRHQnxQAq+dSEzRPClkWjf8557HkWQXF6BrAUoLSAyy9i3RVTliaNg==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -5105,6 +5235,10 @@ packages: resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} engines: {node: '>=6'} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + wrap-ansi@9.0.0: resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} engines: {node: '>=18'} @@ -5116,6 +5250,10 @@ packages: y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yaml@2.7.0: resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} engines: {node: '>= 14'} @@ -5124,13 +5262,25 @@ packages: yargs-parser@13.1.2: resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + yargs@13.3.2: resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + zod-to-json-schema@3.24.1: resolution: {integrity: sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==} peerDependencies: @@ -6847,6 +6997,10 @@ snapshots: '@rtsao/scc@1.1.0': {} + '@sec-ant/readable-stream@0.4.1': {} + + '@sindresorhus/merge-streams@4.0.0': {} + '@smithy/abort-controller@4.0.1': dependencies: '@smithy/types': 4.1.0 @@ -7216,6 +7370,8 @@ snapshots: '@tanstack/query-core': 5.66.4 react: 19.0.0 + '@tokenizer/token@0.3.0': {} + '@types/bytes@3.1.5': {} '@types/chroma-js@3.1.1': {} @@ -7558,6 +7714,8 @@ snapshots: ansi-regex@4.1.1: {} + ansi-regex@5.0.1: {} + ansi-regex@6.1.0: {} ansi-styles@3.2.1: @@ -7825,6 +7983,12 @@ snapshots: strip-ansi: 5.2.0 wrap-ansi: 5.1.0 + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clsx@2.1.1: {} cmdk@1.0.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): @@ -8050,6 +8214,8 @@ snapshots: emoji-regex@7.0.3: {} + emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} enhanced-resolve@5.18.1: @@ -8463,6 +8629,21 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + execa@9.5.2: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.2.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + expect-type@1.1.0: {} extend@3.0.2: {} @@ -8495,6 +8676,19 @@ snapshots: dependencies: strnum: 1.0.5 + fastmcp@1.18.0: + dependencies: + '@modelcontextprotocol/sdk': 1.5.0 + execa: 9.5.2 + file-type: 19.6.0 + fuse.js: 7.1.0 + mcp-proxy: 2.4.0 + strict-event-emitter-types: 2.0.0 + uri-templates: 0.2.0 + yargs: 17.7.2 + zod: 3.24.2 + zod-to-json-schema: 3.24.1(zod@3.24.2) + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -8505,10 +8699,21 @@ snapshots: fflate@0.8.1: {} + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 + file-type@19.6.0: + dependencies: + get-stream: 9.0.1 + strtok3: 9.1.1 + token-types: 6.0.0 + uint8array-extras: 1.4.0 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -8565,6 +8770,8 @@ snapshots: functions-have-names@1.2.3: {} + fuse.js@7.1.0: {} + get-caller-file@2.0.5: {} get-east-asian-width@1.3.0: {} @@ -8591,6 +8798,11 @@ snapshots: get-stream@8.0.1: {} + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + get-symbol-description@1.1.0: dependencies: call-bound: 1.0.3 @@ -8694,12 +8906,16 @@ snapshots: human-signals@5.0.0: {} + human-signals@8.0.0: {} + husky@9.1.7: {} iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 + ieee754@1.2.1: {} + ignore@5.3.2: {} immutable@4.3.7: @@ -8798,6 +9014,8 @@ snapshots: is-fullwidth-code-point@2.0.0: {} + is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@4.0.0: {} is-fullwidth-code-point@5.0.0: @@ -8849,6 +9067,8 @@ snapshots: is-stream@3.0.0: {} + is-stream@4.0.1: {} + is-string@1.1.1: dependencies: call-bound: 1.0.3 @@ -8864,6 +9084,8 @@ snapshots: dependencies: which-typed-array: 1.1.18 + is-unicode-supported@2.1.0: {} + is-weakmap@2.0.2: {} is-weakref@1.1.0: @@ -9063,6 +9285,13 @@ snapshots: math-intrinsics@1.1.0: {} + mcp-proxy@2.4.0: + dependencies: + '@modelcontextprotocol/sdk': 1.5.0 + eventsource: 3.0.5 + fastmcp: 1.18.0 + yargs: 17.7.2 + mdast-util-from-markdown@2.0.2: dependencies: '@types/mdast': 4.0.4 @@ -9363,6 +9592,11 @@ snapshots: dependencies: path-key: 4.0.0 + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + object-assign@4.1.1: {} object-inspect@1.13.3: {} @@ -9476,6 +9710,8 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse-ms@4.0.0: {} + path-exists@3.0.0: {} path-exists@4.0.0: {} @@ -9490,6 +9726,8 @@ snapshots: pathval@2.0.0: {} + peek-readable@5.4.2: {} + pg-cloudflare@1.1.1: optional: true @@ -9613,6 +9851,10 @@ snapshots: prettier@3.5.1: {} + pretty-ms@9.2.0: + dependencies: + parse-ms: 4.0.0 + prismjs@1.27.0: {} prismjs@1.29.0: {} @@ -10055,6 +10297,8 @@ snapshots: streamsearch@1.1.0: {} + strict-event-emitter-types@2.0.0: {} + string-argv@0.3.2: {} string-width@3.1.0: @@ -10063,6 +10307,12 @@ snapshots: is-fullwidth-code-point: 2.0.0 strip-ansi: 5.2.0 + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + string-width@7.2.0: dependencies: emoji-regex: 10.4.0 @@ -10134,6 +10384,10 @@ snapshots: dependencies: ansi-regex: 4.1.1 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + strip-ansi@7.1.0: dependencies: ansi-regex: 6.1.0 @@ -10142,10 +10396,17 @@ snapshots: strip-final-newline@3.0.0: {} + strip-final-newline@4.0.0: {} + strip-json-comments@3.1.1: {} strnum@1.0.5: {} + strtok3@9.1.1: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 5.4.2 + style-to-object@1.0.8: dependencies: inline-style-parser: 0.2.4 @@ -10209,6 +10470,11 @@ snapshots: toidentifier@1.0.1: {} + token-types@6.0.0: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + trim-lines@3.0.1: {} trough@2.2.0: {} @@ -10311,6 +10577,8 @@ snapshots: typescript@5.7.3: {} + uint8array-extras@1.4.0: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.3 @@ -10320,6 +10588,8 @@ snapshots: undici-types@6.20.0: {} + unicorn-magic@0.3.0: {} + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -10365,6 +10635,8 @@ snapshots: dependencies: punycode: 2.3.1 + uri-templates@0.2.0: {} + use-callback-ref@1.3.3(@types/react@19.0.10)(react@19.0.0): dependencies: react: 19.0.0 @@ -10558,6 +10830,12 @@ snapshots: string-width: 3.1.0 strip-ansi: 5.2.0 + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@9.0.0: dependencies: ansi-styles: 6.2.1 @@ -10568,6 +10846,8 @@ snapshots: y18n@4.0.3: {} + y18n@5.0.8: {} + yaml@2.7.0: {} yargs-parser@13.1.2: @@ -10575,6 +10855,8 @@ snapshots: camelcase: 5.3.1 decamelize: 1.2.0 + yargs-parser@21.1.1: {} + yargs@13.3.2: dependencies: cliui: 5.0.0 @@ -10588,8 +10870,20 @@ snapshots: y18n: 4.0.3 yargs-parser: 13.1.2 + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yocto-queue@0.1.0: {} + yoctocolors@2.1.1: {} + zod-to-json-schema@3.24.1(zod@3.24.2): dependencies: zod: 3.24.2