From e2de76ca9f23b825c54fd3f0a903811af244584e Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 15 Mar 2026 13:04:27 -0500 Subject: [PATCH] feat(gateway): add MCP server endpoint with streamable HTTP transport (#52) - Install @modelcontextprotocol/sdk and zod in apps/gateway - Create McpModule with McpService and controller at /mcp endpoint - Implement stateful streamable HTTP transport (MCP spec 2025-03-26) - Expose 14 tools: brain (projects/tasks/missions), memory, coord - Require valid BetterAuth session for all MCP connections - Per-session McpServer + StreamableHTTPServerTransport instances - Follows same Fastify onRequest hook pattern as auth handler - Add mcp.dto.ts with McpToolDescriptor and McpServerInfo interfaces Co-Authored-By: Claude Sonnet 4.6 --- apps/gateway/package.json | 4 +- apps/gateway/src/app.module.ts | 2 + apps/gateway/src/main.ts | 3 + apps/gateway/src/mcp/mcp.controller.ts | 142 ++++++ apps/gateway/src/mcp/mcp.dto.ts | 19 + apps/gateway/src/mcp/mcp.module.ts | 10 + apps/gateway/src/mcp/mcp.service.ts | 429 ++++++++++++++++++ apps/gateway/src/mcp/mcp.tokens.ts | 1 + pnpm-lock.yaml | 597 ++++++++++++++++++++++++- 9 files changed, 1196 insertions(+), 11 deletions(-) create mode 100644 apps/gateway/src/mcp/mcp.controller.ts create mode 100644 apps/gateway/src/mcp/mcp.dto.ts create mode 100644 apps/gateway/src/mcp/mcp.module.ts create mode 100644 apps/gateway/src/mcp/mcp.service.ts create mode 100644 apps/gateway/src/mcp/mcp.tokens.ts diff --git a/apps/gateway/package.json b/apps/gateway/package.json index 66f5706..28a8813 100644 --- a/apps/gateway/package.json +++ b/apps/gateway/package.json @@ -15,6 +15,7 @@ "@fastify/helmet": "^13.0.2", "@mariozechner/pi-ai": "~0.57.1", "@mariozechner/pi-coding-agent": "~0.57.1", + "@modelcontextprotocol/sdk": "^1.27.1", "@mosaic/auth": "workspace:^", "@mosaic/brain": "workspace:^", "@mosaic/coord": "workspace:^", @@ -47,7 +48,8 @@ "reflect-metadata": "^0.2.0", "rxjs": "^7.8.0", "socket.io": "^4.8.0", - "uuid": "^11.0.0" + "uuid": "^11.0.0", + "zod": "^4.3.6" }, "devDependencies": { "@types/node": "^22.0.0", diff --git a/apps/gateway/src/app.module.ts b/apps/gateway/src/app.module.ts index 38e5069..5848e7a 100644 --- a/apps/gateway/src/app.module.ts +++ b/apps/gateway/src/app.module.ts @@ -15,6 +15,7 @@ import { MemoryModule } from './memory/memory.module.js'; import { LogModule } from './log/log.module.js'; import { SkillsModule } from './skills/skills.module.js'; import { PluginModule } from './plugin/plugin.module.js'; +import { McpModule } from './mcp/mcp.module.js'; import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler'; @Module({ @@ -34,6 +35,7 @@ import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler'; LogModule, SkillsModule, PluginModule, + McpModule, ], controllers: [HealthController], providers: [ diff --git a/apps/gateway/src/main.ts b/apps/gateway/src/main.ts index 8eb3b8d..d44ee18 100644 --- a/apps/gateway/src/main.ts +++ b/apps/gateway/src/main.ts @@ -13,6 +13,8 @@ import { FastifyAdapter, type NestFastifyApplication } from '@nestjs/platform-fa import helmet from '@fastify/helmet'; import { AppModule } from './app.module.js'; import { mountAuthHandler } from './auth/auth.controller.js'; +import { mountMcpHandler } from './mcp/mcp.controller.js'; +import { McpService } from './mcp/mcp.service.js'; async function bootstrap(): Promise { const logger = new Logger('Bootstrap'); @@ -50,6 +52,7 @@ async function bootstrap(): Promise { ); mountAuthHandler(app); + mountMcpHandler(app, app.get(McpService)); const port = Number(process.env['GATEWAY_PORT'] ?? 4000); await app.listen(port, '0.0.0.0'); diff --git a/apps/gateway/src/mcp/mcp.controller.ts b/apps/gateway/src/mcp/mcp.controller.ts new file mode 100644 index 0000000..b6a162d --- /dev/null +++ b/apps/gateway/src/mcp/mcp.controller.ts @@ -0,0 +1,142 @@ +import type { IncomingMessage, ServerResponse } from 'node:http'; +import { Logger } from '@nestjs/common'; +import { fromNodeHeaders } from 'better-auth/node'; +import type { Auth } from '@mosaic/auth'; +import type { NestFastifyApplication } from '@nestjs/platform-fastify'; +import type { McpService } from './mcp.service.js'; +import { AUTH } from '../auth/auth.tokens.js'; + +/** + * Mounts the MCP streamable HTTP transport endpoint at /mcp on the Fastify instance. + * + * This follows the same low-level Fastify hook pattern used by the auth controller, + * bypassing NestJS routing to directly delegate to the MCP SDK transport handlers. + * + * Endpoint: POST /mcp (and GET /mcp for SSE stream reconnect) + * Auth: Requires a valid BetterAuth session (cookie or Authorization header). + * Session: Stateful — each initialized client gets a session ID via Mcp-Session-Id header. + */ +export function mountMcpHandler(app: NestFastifyApplication, mcpService: McpService): void { + const auth = app.get(AUTH); + const logger = new Logger('McpController'); + const fastify = app.getHttpAdapter().getInstance(); + + fastify.addHook( + 'onRequest', + ( + req: { raw: IncomingMessage; url: string; method: string }, + reply: { raw: ServerResponse; hijack: () => void }, + done: () => void, + ) => { + if (!req.url.startsWith('/mcp')) { + done(); + return; + } + + reply.hijack(); + + handleMcpRequest(req, reply, auth, mcpService, logger).catch((err: unknown) => { + logger.error( + `MCP request handler error: ${err instanceof Error ? err.message : String(err)}`, + ); + if (!reply.raw.headersSent) { + reply.raw.writeHead(500, { 'Content-Type': 'application/json' }); + } + if (!reply.raw.writableEnded) { + reply.raw.end(JSON.stringify({ error: 'Internal server error' })); + } + }); + }, + ); +} + +async function handleMcpRequest( + req: { raw: IncomingMessage; url: string; method: string }, + reply: { raw: ServerResponse; hijack: () => void }, + auth: Auth, + mcpService: McpService, + logger: Logger, +): Promise { + // ─── Authentication ───────────────────────────────────────────────────── + const headers = fromNodeHeaders(req.raw.headers); + const result = await auth.api.getSession({ headers }); + + if (!result) { + reply.raw.writeHead(401, { 'Content-Type': 'application/json' }); + reply.raw.end(JSON.stringify({ error: 'Unauthorized: valid session required' })); + return; + } + + const userId = result.user.id; + + // ─── Session routing ───────────────────────────────────────────────────── + const sessionId = req.raw.headers['mcp-session-id']; + + if (typeof sessionId === 'string' && sessionId.length > 0) { + // Existing session request + const transport = mcpService.getSession(sessionId); + if (!transport) { + logger.warn(`MCP session not found: ${sessionId}`); + reply.raw.writeHead(404, { 'Content-Type': 'application/json' }); + reply.raw.end(JSON.stringify({ error: 'Session not found' })); + return; + } + + await transport.handleRequest(req.raw, reply.raw); + return; + } + + // ─── Initialize new session ─────────────────────────────────────────────── + // Only POST requests can initialize a new session (must be initialize message) + if (req.method !== 'POST') { + reply.raw.writeHead(400, { 'Content-Type': 'application/json' }); + reply.raw.end( + JSON.stringify({ + error: 'New session must be established via POST with initialize message', + }), + ); + return; + } + + // Parse body to verify this is an initialize request before creating a session + let body: unknown; + try { + body = await readRequestBody(req.raw); + } catch (err) { + logger.warn( + `Failed to parse MCP request body: ${err instanceof Error ? err.message : String(err)}`, + ); + reply.raw.writeHead(400, { 'Content-Type': 'application/json' }); + reply.raw.end(JSON.stringify({ error: 'Invalid request body' })); + return; + } + + // Create new session and handle this initializing request + const { transport } = mcpService.createSession(userId); + logger.log(`New MCP session created for user ${userId}`); + + await transport.handleRequest(req.raw, reply.raw, body); +} + +/** + * Reads and parses the JSON body from a Node.js IncomingMessage. + */ +function readRequestBody(req: IncomingMessage): Promise { + return new Promise((resolve, reject) => { + const chunks: Buffer[] = []; + req.on('data', (chunk: Buffer) => chunks.push(chunk)); + req.on('end', () => { + const raw = Buffer.concat(chunks).toString('utf8'); + if (!raw) { + resolve(undefined); + return; + } + try { + resolve(JSON.parse(raw)); + } catch (err) { + reject(err); + } + }); + req.on('error', reject); + }); +} diff --git a/apps/gateway/src/mcp/mcp.dto.ts b/apps/gateway/src/mcp/mcp.dto.ts new file mode 100644 index 0000000..ca27f3d --- /dev/null +++ b/apps/gateway/src/mcp/mcp.dto.ts @@ -0,0 +1,19 @@ +/** + * MCP (Model Context Protocol) DTOs + * + * Defines the data transfer objects for the MCP streamable HTTP transport. + * See: https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http + */ + +export interface McpToolDescriptor { + name: string; + description: string; + inputSchema: Record; +} + +export interface McpServerInfo { + name: string; + version: string; + protocolVersion: string; + tools: McpToolDescriptor[]; +} diff --git a/apps/gateway/src/mcp/mcp.module.ts b/apps/gateway/src/mcp/mcp.module.ts new file mode 100644 index 0000000..5c3aae3 --- /dev/null +++ b/apps/gateway/src/mcp/mcp.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { McpService } from './mcp.service.js'; +import { CoordModule } from '../coord/coord.module.js'; + +@Module({ + imports: [CoordModule], + providers: [McpService], + exports: [McpService], +}) +export class McpModule {} diff --git a/apps/gateway/src/mcp/mcp.service.ts b/apps/gateway/src/mcp/mcp.service.ts new file mode 100644 index 0000000..65d0498 --- /dev/null +++ b/apps/gateway/src/mcp/mcp.service.ts @@ -0,0 +1,429 @@ +import { Injectable, Logger, Inject, OnModuleDestroy } from '@nestjs/common'; +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; +import { randomUUID } from 'node:crypto'; +import { z } from 'zod'; +import type { Brain } from '@mosaic/brain'; +import type { Memory } from '@mosaic/memory'; +import { BRAIN } from '../brain/brain.tokens.js'; +import { MEMORY } from '../memory/memory.tokens.js'; +import { EmbeddingService } from '../memory/embedding.service.js'; +import { CoordService } from '../coord/coord.service.js'; + +interface SessionEntry { + server: McpServer; + transport: StreamableHTTPServerTransport; + createdAt: Date; + userId: string; +} + +@Injectable() +export class McpService implements OnModuleDestroy { + private readonly logger = new Logger(McpService.name); + private readonly sessions = new Map(); + + constructor( + @Inject(BRAIN) private readonly brain: Brain, + @Inject(MEMORY) private readonly memory: Memory, + @Inject(EmbeddingService) private readonly embeddings: EmbeddingService, + @Inject(CoordService) private readonly coordService: CoordService, + ) {} + + /** + * Creates a new MCP session with its own server + transport pair. + * Returns the transport for use by the controller. + */ + createSession(userId: string): { sessionId: string; transport: StreamableHTTPServerTransport } { + const sessionId = randomUUID(); + + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: () => sessionId, + onsessioninitialized: (id) => { + this.logger.log(`MCP session initialized: ${id} for user ${userId}`); + }, + }); + + const server = new McpServer( + { name: 'mosaic-gateway', version: '1.0.0' }, + { capabilities: { tools: {} } }, + ); + + this.registerTools(server, userId); + + transport.onclose = () => { + this.logger.log(`MCP session closed: ${sessionId}`); + this.sessions.delete(sessionId); + }; + + server.connect(transport).catch((err: unknown) => { + this.logger.error( + `MCP server connect error for session ${sessionId}: ${err instanceof Error ? err.message : String(err)}`, + ); + }); + + this.sessions.set(sessionId, { server, transport, createdAt: new Date(), userId }); + return { sessionId, transport }; + } + + /** + * Returns the transport for an existing session, or null if not found. + */ + getSession(sessionId: string): StreamableHTTPServerTransport | null { + return this.sessions.get(sessionId)?.transport ?? null; + } + + /** + * Registers all platform tools on the given McpServer instance. + */ + private registerTools(server: McpServer, _userId: string): void { + // ─── Brain: Project tools ──────────────────────────────────────────── + + server.registerTool( + 'brain_list_projects', + { + description: 'List all projects in the brain.', + inputSchema: z.object({}), + }, + async () => { + const projects = await this.brain.projects.findAll(); + return { + content: [{ type: 'text' as const, text: JSON.stringify(projects, null, 2) }], + }; + }, + ); + + server.registerTool( + 'brain_get_project', + { + description: 'Get a project by ID.', + inputSchema: z.object({ + id: z.string().describe('Project ID (UUID)'), + }), + }, + async ({ id }) => { + const project = await this.brain.projects.findById(id); + return { + content: [ + { + type: 'text' as const, + text: project ? JSON.stringify(project, null, 2) : `Project not found: ${id}`, + }, + ], + }; + }, + ); + + // ─── Brain: Task tools ─────────────────────────────────────────────── + + server.registerTool( + 'brain_list_tasks', + { + description: 'List tasks, optionally filtered by project, mission, or status.', + inputSchema: z.object({ + projectId: z.string().optional().describe('Filter by project ID'), + missionId: z.string().optional().describe('Filter by mission ID'), + status: z.string().optional().describe('Filter by status'), + }), + }, + async ({ projectId, missionId, status }) => { + type TaskStatus = 'not-started' | 'in-progress' | 'blocked' | 'done' | 'cancelled'; + let tasks; + if (projectId) tasks = await this.brain.tasks.findByProject(projectId); + else if (missionId) tasks = await this.brain.tasks.findByMission(missionId); + else if (status) tasks = await this.brain.tasks.findByStatus(status as TaskStatus); + else tasks = await this.brain.tasks.findAll(); + return { content: [{ type: 'text' as const, text: JSON.stringify(tasks, null, 2) }] }; + }, + ); + + server.registerTool( + 'brain_create_task', + { + description: 'Create a new task in the brain.', + inputSchema: z.object({ + title: z.string().describe('Task title'), + description: z.string().optional().describe('Task description'), + projectId: z.string().optional().describe('Project ID'), + missionId: z.string().optional().describe('Mission ID'), + priority: z.string().optional().describe('Priority: low, medium, high, critical'), + }), + }, + async (params) => { + type Priority = 'low' | 'medium' | 'high' | 'critical'; + const task = await this.brain.tasks.create({ + ...params, + priority: params.priority as Priority | undefined, + }); + return { content: [{ type: 'text' as const, text: JSON.stringify(task, null, 2) }] }; + }, + ); + + server.registerTool( + 'brain_update_task', + { + description: 'Update an existing task.', + inputSchema: z.object({ + id: z.string().describe('Task ID'), + title: z.string().optional(), + description: z.string().optional(), + status: z + .string() + .optional() + .describe('not-started, in-progress, blocked, done, cancelled'), + priority: z.string().optional(), + }), + }, + async ({ id, ...updates }) => { + type TaskStatus = 'not-started' | 'in-progress' | 'blocked' | 'done' | 'cancelled'; + type Priority = 'low' | 'medium' | 'high' | 'critical'; + const task = await this.brain.tasks.update(id, { + ...updates, + status: updates.status as TaskStatus | undefined, + priority: updates.priority as Priority | undefined, + }); + return { + content: [ + { + type: 'text' as const, + text: task ? JSON.stringify(task, null, 2) : `Task not found: ${id}`, + }, + ], + }; + }, + ); + + // ─── Brain: Mission tools ──────────────────────────────────────────── + + server.registerTool( + 'brain_list_missions', + { + description: 'List all missions, optionally filtered by project.', + inputSchema: z.object({ + projectId: z.string().optional().describe('Filter by project ID'), + }), + }, + async ({ projectId }) => { + const missions = projectId + ? await this.brain.missions.findByProject(projectId) + : await this.brain.missions.findAll(); + return { content: [{ type: 'text' as const, text: JSON.stringify(missions, null, 2) }] }; + }, + ); + + server.registerTool( + 'brain_list_conversations', + { + description: 'List conversations for a user.', + inputSchema: z.object({ + userId: z.string().describe('User ID'), + }), + }, + async ({ userId }) => { + const conversations = await this.brain.conversations.findAll(userId); + return { + content: [{ type: 'text' as const, text: JSON.stringify(conversations, null, 2) }], + }; + }, + ); + + // ─── Memory tools ──────────────────────────────────────────────────── + + server.registerTool( + 'memory_search', + { + description: + 'Search across stored insights and knowledge using natural language. Returns semantically similar results.', + inputSchema: z.object({ + userId: z.string().describe('User ID to search memory for'), + query: z.string().describe('Natural language search query'), + limit: z.number().optional().describe('Max results (default 5)'), + }), + }, + async ({ userId, query, limit }) => { + if (!this.embeddings.available) { + return { + content: [ + { + type: 'text' as const, + text: 'Semantic search unavailable — no embedding provider configured', + }, + ], + }; + } + const embedding = await this.embeddings.embed(query); + const results = await this.memory.insights.searchByEmbedding(userId, embedding, limit ?? 5); + return { content: [{ type: 'text' as const, text: JSON.stringify(results, null, 2) }] }; + }, + ); + + server.registerTool( + 'memory_get_preferences', + { + description: 'Retrieve stored preferences for a user.', + inputSchema: z.object({ + userId: z.string().describe('User ID'), + category: z + .string() + .optional() + .describe('Filter by category: communication, coding, workflow, appearance, general'), + }), + }, + async ({ userId, category }) => { + type Cat = 'communication' | 'coding' | 'workflow' | 'appearance' | 'general'; + const prefs = category + ? await this.memory.preferences.findByUserAndCategory(userId, category as Cat) + : await this.memory.preferences.findByUser(userId); + return { content: [{ type: 'text' as const, text: JSON.stringify(prefs, null, 2) }] }; + }, + ); + + server.registerTool( + 'memory_save_preference', + { + description: + 'Store a learned user preference (e.g., "prefers tables over paragraphs", "timezone: America/Chicago").', + inputSchema: z.object({ + userId: z.string().describe('User ID'), + key: z.string().describe('Preference key'), + value: z.string().describe('Preference value (JSON string)'), + category: z + .string() + .optional() + .describe('Category: communication, coding, workflow, appearance, general'), + }), + }, + async ({ userId, key, value, category }) => { + type Cat = 'communication' | 'coding' | 'workflow' | 'appearance' | 'general'; + let parsedValue: unknown; + try { + parsedValue = JSON.parse(value); + } catch { + parsedValue = value; + } + const pref = await this.memory.preferences.upsert({ + userId, + key, + value: parsedValue, + category: (category as Cat) ?? 'general', + source: 'agent', + }); + return { content: [{ type: 'text' as const, text: JSON.stringify(pref, null, 2) }] }; + }, + ); + + server.registerTool( + 'memory_save_insight', + { + description: + 'Store a learned insight, decision, or knowledge extracted from the current interaction.', + inputSchema: z.object({ + userId: z.string().describe('User ID'), + content: z.string().describe('The insight or knowledge to store'), + category: z + .string() + .optional() + .describe('Category: decision, learning, preference, fact, pattern, general'), + }), + }, + async ({ userId, content, category }) => { + type Cat = 'decision' | 'learning' | 'preference' | 'fact' | 'pattern' | 'general'; + const embedding = this.embeddings.available ? await this.embeddings.embed(content) : null; + const insight = await this.memory.insights.create({ + userId, + content, + embedding, + source: 'agent', + category: (category as Cat) ?? 'learning', + }); + return { content: [{ type: 'text' as const, text: JSON.stringify(insight, null, 2) }] }; + }, + ); + + // ─── Coord tools ───────────────────────────────────────────────────── + + server.registerTool( + 'coord_mission_status', + { + description: + 'Get the current orchestration mission status including milestones, tasks, and active session.', + inputSchema: z.object({ + projectPath: z + .string() + .optional() + .describe('Project path. Defaults to gateway working directory.'), + }), + }, + async ({ projectPath }) => { + const resolvedPath = projectPath ?? process.cwd(); + const status = await this.coordService.getMissionStatus(resolvedPath); + return { + content: [ + { + type: 'text' as const, + text: status ? JSON.stringify(status, null, 2) : 'No active coord mission found.', + }, + ], + }; + }, + ); + + server.registerTool( + 'coord_list_tasks', + { + description: 'List all tasks from the orchestration TASKS.md file.', + inputSchema: z.object({ + projectPath: z + .string() + .optional() + .describe('Project path. Defaults to gateway working directory.'), + }), + }, + async ({ projectPath }) => { + const resolvedPath = projectPath ?? process.cwd(); + const tasks = await this.coordService.listTasks(resolvedPath); + return { content: [{ type: 'text' as const, text: JSON.stringify(tasks, null, 2) }] }; + }, + ); + + server.registerTool( + 'coord_task_detail', + { + description: 'Get detailed status for a specific orchestration task.', + inputSchema: z.object({ + taskId: z.string().describe('Task ID (e.g. P2-005)'), + projectPath: z + .string() + .optional() + .describe('Project path. Defaults to gateway working directory.'), + }), + }, + async ({ taskId, projectPath }) => { + const resolvedPath = projectPath ?? process.cwd(); + const detail = await this.coordService.getTaskStatus(resolvedPath, taskId); + return { + content: [ + { + type: 'text' as const, + text: detail + ? JSON.stringify(detail, null, 2) + : `Task ${taskId} not found in coord mission.`, + }, + ], + }; + }, + ); + } + + async onModuleDestroy(): Promise { + this.logger.log(`Closing ${this.sessions.size} MCP sessions on shutdown`); + const closePromises = Array.from(this.sessions.values()).map(({ transport }) => + transport.close().catch((err: unknown) => { + this.logger.warn( + `Error closing MCP transport: ${err instanceof Error ? err.message : String(err)}`, + ); + }), + ); + await Promise.all(closePromises); + this.sessions.clear(); + } +} diff --git a/apps/gateway/src/mcp/mcp.tokens.ts b/apps/gateway/src/mcp/mcp.tokens.ts new file mode 100644 index 0000000..8ef326f --- /dev/null +++ b/apps/gateway/src/mcp/mcp.tokens.ts @@ -0,0 +1 @@ +export const MCP_SERVICE = 'MCP_SERVICE'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c50c30c..fd0c158 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,10 +46,13 @@ importers: version: 13.0.2 '@mariozechner/pi-ai': specifier: ~0.57.1 - version: 0.57.1(ws@8.19.0)(zod@4.3.6) + version: 0.57.1(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(ws@8.19.0)(zod@4.3.6) '@mariozechner/pi-coding-agent': specifier: ~0.57.1 - version: 0.57.1(ws@8.19.0)(zod@4.3.6) + version: 0.57.1(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(ws@8.19.0)(zod@4.3.6) + '@modelcontextprotocol/sdk': + specifier: ^1.27.1 + version: 1.27.1(zod@4.3.6) '@mosaic/auth': specifier: workspace:^ version: link:../../packages/auth @@ -149,6 +152,9 @@ importers: uuid: specifier: ^11.0.0 version: 11.1.0 + zod: + specifier: ^4.3.6 + version: 4.3.6 devDependencies: '@types/node': specifier: ^22.0.0 @@ -1479,6 +1485,12 @@ packages: engines: {node: '>=6'} hasBin: true + '@hono/node-server@1.19.11': + resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1750,6 +1762,16 @@ packages: '@mistralai/mistralai@1.14.1': resolution: {integrity: sha512-IiLmmZFCCTReQgPAT33r7KQ1nYo5JPdvGkrkZqA8qQ2qB1GHgs5LoP5K2ICyrjnpw2n8oSxMM/VP+liiKcGNlQ==} + '@modelcontextprotocol/sdk@1.27.1': + resolution: {integrity: sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + '@mongodb-js/saslprep@1.4.6': resolution: {integrity: sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==} @@ -3016,6 +3038,10 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: @@ -3190,6 +3216,10 @@ packages: bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + bowser@2.14.1: resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} @@ -3229,10 +3259,22 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -3337,10 +3379,22 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + convert-to-spaces@2.0.1: resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -3395,6 +3449,10 @@ packages: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} + 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'} @@ -3514,12 +3572,19 @@ packages: sqlite3: optional: true + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -3529,6 +3594,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -3551,9 +3620,21 @@ packages: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + es-toolkit@1.45.1: resolution: {integrity: sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw==} @@ -3586,6 +3667,9 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} @@ -3653,6 +3737,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -3660,6 +3748,14 @@ packages: eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -3668,6 +3764,16 @@ packages: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + express-rate-limit@8.3.1: + resolution: {integrity: sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -3747,6 +3853,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + find-my-way@9.5.0: resolution: {integrity: sha512-VW2RfnmscZO5KgBY5XVyKREMW5nMZcxDy+buTOsL+zIPnBlbKm+00sgzoQzq1EVh4aALZLfKdwv6atBGcjvjrQ==} engines: {node: '>=20'} @@ -3773,11 +3883,22 @@ packages: forwarded-parse@2.1.2: resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gaxios@7.1.3: resolution: {integrity: sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==} engines: {node: '>=18'} @@ -3794,6 +3915,14 @@ packages: resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} @@ -3834,6 +3963,10 @@ packages: resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} engines: {node: '>=14'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -3841,6 +3974,14 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + helmet@8.1.0: resolution: {integrity: sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==} engines: {node: '>=18.0.0'} @@ -3848,10 +3989,18 @@ packages: highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + hono@4.12.8: + resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==} + engines: {node: '>=16.9.0'} + hosted-git-info@9.0.2: resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} engines: {node: ^20.17.0 || >=22.9.0} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -3869,6 +4018,10 @@ packages: engines: {node: '>=18'} hasBin: true + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -3896,6 +4049,9 @@ packages: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ink-spinner@5.0.0: resolution: {integrity: sha512-EYEasbEjkqLGyPOUc8hBJZNuC5GvXGMLu0w5gdTNskPc7Izc5vO3tdQEYnzvshucyGCBXc86ig0ujXPMWaQCdA==} engines: {node: '>=14.16'} @@ -3931,6 +4087,10 @@ packages: resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} engines: {node: '>= 12'} + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + ipaddr.js@2.3.0: resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} engines: {node: '>= 10'} @@ -3964,6 +4124,9 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4011,6 +4174,9 @@ packages: json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -4185,9 +4351,21 @@ packages: engines: {node: '>= 18'} hasBin: true + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + memory-pager@1.5.0: resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -4298,6 +4476,10 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + netmask@2.0.2: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} @@ -4357,10 +4539,18 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -4432,6 +4622,10 @@ packages: parse5@6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + partial-json@0.1.7: resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} @@ -4513,6 +4707,10 @@ packages: resolution: {integrity: sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==} hasBin: true + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + postcss@8.4.31: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} @@ -4563,6 +4761,10 @@ packages: resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} engines: {node: '>=12.0.0'} + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + proxy-agent@6.5.0: resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} engines: {node: '>= 14'} @@ -4577,9 +4779,21 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + react-dom@19.2.4: resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: @@ -4672,6 +4886,10 @@ packages: rou3@0.7.12: resolution: {integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==} + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} @@ -4689,6 +4907,9 @@ packages: resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} engines: {node: '>=10'} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sandwich-stream@2.0.2: resolution: {integrity: sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==} engines: {node: '>= 0.10'} @@ -4707,12 +4928,23 @@ packages: engines: {node: '>=10'} hasBin: true + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} set-cookie-parser@3.0.1: resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sharp@0.34.5: resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -4725,6 +4957,22 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -4804,6 +5052,10 @@ packages: standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} @@ -4919,6 +5171,10 @@ packages: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + token-types@6.1.2: resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} engines: {node: '>=14.16'} @@ -4992,6 +5248,10 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + typescript-eslint@8.57.0: resolution: {integrity: sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5023,6 +5283,10 @@ packages: resolution: {integrity: sha512-jxytwMHhsbdpBXxLAcuu0fzlQeXCNnWdDyRHpvWsUl8vd98UwYdl9YTyn8/HcpcJPC3pwUveefsa3zTxyD/ERg==} engines: {node: '>=20.18.1'} + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -6129,12 +6393,14 @@ snapshots: '@fastify/forwarded': 3.0.1 ipaddr.js: 2.3.0 - '@google/genai@1.45.0': + '@google/genai@1.45.0(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))': dependencies: google-auth-library: 10.6.1 p-retry: 4.6.2 protobufjs: 7.5.4 ws: 8.19.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.27.1(zod@4.3.6) transitivePeerDependencies: - bufferutil - supports-color @@ -6152,6 +6418,10 @@ snapshots: protobufjs: 7.5.4 yargs: 17.7.2 + '@hono/node-server@1.19.11(hono@4.12.8)': + dependencies: + hono: 4.12.8 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -6343,9 +6613,9 @@ snapshots: std-env: 3.10.0 yoctocolors: 2.1.2 - '@mariozechner/pi-agent-core@0.57.1(ws@8.19.0)(zod@4.3.6)': + '@mariozechner/pi-agent-core@0.57.1(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(ws@8.19.0)(zod@4.3.6)': dependencies: - '@mariozechner/pi-ai': 0.57.1(ws@8.19.0)(zod@4.3.6) + '@mariozechner/pi-ai': 0.57.1(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(ws@8.19.0)(zod@4.3.6) transitivePeerDependencies: - '@modelcontextprotocol/sdk' - aws-crt @@ -6355,11 +6625,11 @@ snapshots: - ws - zod - '@mariozechner/pi-ai@0.57.1(ws@8.19.0)(zod@4.3.6)': + '@mariozechner/pi-ai@0.57.1(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(ws@8.19.0)(zod@4.3.6)': dependencies: '@anthropic-ai/sdk': 0.73.0(zod@4.3.6) '@aws-sdk/client-bedrock-runtime': 3.1008.0 - '@google/genai': 1.45.0 + '@google/genai': 1.45.0(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6)) '@mistralai/mistralai': 1.14.1 '@sinclair/typebox': 0.34.48 ajv: 8.18.0 @@ -6379,11 +6649,11 @@ snapshots: - ws - zod - '@mariozechner/pi-coding-agent@0.57.1(ws@8.19.0)(zod@4.3.6)': + '@mariozechner/pi-coding-agent@0.57.1(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(ws@8.19.0)(zod@4.3.6)': dependencies: '@mariozechner/jiti': 2.6.5 - '@mariozechner/pi-agent-core': 0.57.1(ws@8.19.0)(zod@4.3.6) - '@mariozechner/pi-ai': 0.57.1(ws@8.19.0)(zod@4.3.6) + '@mariozechner/pi-agent-core': 0.57.1(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(ws@8.19.0)(zod@4.3.6) + '@mariozechner/pi-ai': 0.57.1(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(ws@8.19.0)(zod@4.3.6) '@mariozechner/pi-tui': 0.57.1 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 @@ -6430,6 +6700,28 @@ snapshots: - bufferutil - utf-8-validate + '@modelcontextprotocol/sdk@1.27.1(zod@4.3.6)': + dependencies: + '@hono/node-server': 1.19.11(hono@4.12.8) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.3.1(express@5.2.1) + hono: 4.12.8 + jose: 6.2.1 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.1(zod@4.3.6) + transitivePeerDependencies: + - supports-color + '@mongodb-js/saslprep@1.4.6': dependencies: sparse-bitfield: 3.0.3 @@ -7971,6 +8263,11 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + acorn-import-attributes@1.9.5(acorn@8.16.0): dependencies: acorn: 8.16.0 @@ -8087,6 +8384,20 @@ snapshots: bignumber.js@9.3.1: {} + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.15.0 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + bowser@2.14.1: {} brace-expansion@1.1.12: @@ -8123,8 +8434,20 @@ snapshots: buffer-from@1.1.2: {} + bytes@3.1.2: {} + cac@6.7.14: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} caniuse-lite@1.0.30001778: {} @@ -8220,8 +8543,14 @@ snapshots: consola@3.4.2: {} + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + convert-to-spaces@2.0.1: {} + cookie-signature@1.2.2: {} + cookie@0.7.2: {} cookie@1.1.1: {} @@ -8261,6 +8590,8 @@ snapshots: denque@2.1.0: {} + depd@2.0.0: {} + dequal@2.0.3: {} detect-libc@2.1.2: {} @@ -8306,18 +8637,28 @@ snapshots: kysely: 0.28.11 postgres: 3.4.8 + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + eastasianwidth@0.2.0: {} ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 + ee-first@1.1.1: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} + encodeurl@2.0.0: {} + end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -8360,8 +8701,16 @@ snapshots: environment@1.1.0: {} + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + es-toolkit@1.45.1: {} esbuild-register@3.6.0(esbuild@0.25.12): @@ -8482,6 +8831,8 @@ snapshots: escalade@3.2.0: {} + escape-html@1.0.3: {} + escape-string-regexp@2.0.0: {} escape-string-regexp@4.0.0: {} @@ -8570,10 +8921,18 @@ snapshots: esutils@2.0.3: {} + etag@1.8.1: {} + event-target-shim@5.0.1: {} eventemitter3@5.0.4: {} + eventsource-parser@3.0.6: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.6 + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -8588,6 +8947,44 @@ snapshots: expect-type@1.3.0: {} + express-rate-limit@8.3.1(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.1.0 + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.15.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + extend@3.0.2: {} extract-zip@2.0.1: @@ -8706,6 +9103,17 @@ snapshots: dependencies: to-regex-range: 5.0.1 + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + find-my-way@9.5.0: dependencies: fast-deep-equal: 3.1.3 @@ -8735,9 +9143,15 @@ snapshots: forwarded-parse@2.1.2: {} + forwarded@0.2.0: {} + + fresh@2.0.0: {} + fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + gaxios@7.1.3: dependencies: extend: 3.0.2 @@ -8759,6 +9173,24 @@ snapshots: get-east-asian-width@1.5.0: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + get-stream@5.2.0: dependencies: pump: 3.0.4 @@ -8811,18 +9243,36 @@ snapshots: google-logging-utils@1.1.3: {} + gopd@1.2.0: {} + graceful-fs@4.2.11: {} has-flag@4.0.0: {} + has-symbols@1.1.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + helmet@8.1.0: {} highlight.js@10.7.3: {} + hono@4.12.8: {} + hosted-git-info@9.0.2: dependencies: lru-cache: 11.2.6 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -8841,6 +9291,10 @@ snapshots: husky@9.1.7: {} + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -8863,6 +9317,8 @@ snapshots: indent-string@5.0.0: {} + inherits@2.0.4: {} + ink-spinner@5.0.0(ink@5.2.1(@types/react@18.3.28)(react@18.3.1))(react@18.3.1): dependencies: cli-spinners: 2.9.2 @@ -8925,6 +9381,8 @@ snapshots: ip-address@10.1.0: {} + ipaddr.js@1.9.1: {} + ipaddr.js@2.3.0: {} is-extglob@2.1.1: {} @@ -8945,6 +9403,8 @@ snapshots: is-number@7.0.0: {} + is-promise@4.0.0: {} + is-stream@3.0.0: {} isexe@2.0.0: {} @@ -8986,6 +9446,8 @@ snapshots: json-schema-traverse@1.0.0: {} + json-schema-typed@8.0.2: {} + json-stable-stringify-without-jsonify@1.0.1: {} jwa@2.0.1: @@ -9144,8 +9606,14 @@ snapshots: marked@15.0.12: {} + math-intrinsics@1.1.0: {} + + media-typer@1.1.0: {} + memory-pager@1.5.0: {} + merge-descriptors@2.0.0: {} + merge-stream@2.0.0: {} micromatch@4.0.8: @@ -9218,6 +9686,8 @@ snapshots: negotiator@0.6.3: {} + negotiator@1.0.0: {} + netmask@2.0.2: {} next@16.1.6(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): @@ -9267,8 +9737,14 @@ snapshots: object-hash@3.0.0: {} + object-inspect@1.13.4: {} + on-exit-leak-free@2.1.2: {} + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -9346,6 +9822,8 @@ snapshots: parse5@6.0.1: {} + parseurl@1.3.3: {} + partial-json@0.1.7: {} patch-console@2.0.0: {} @@ -9416,6 +9894,8 @@ snapshots: sonic-boom: 4.2.1 thread-stream: 4.0.0 + pkce-challenge@5.0.1: {} + postcss@8.4.31: dependencies: nanoid: 3.3.11 @@ -9469,6 +9949,11 @@ snapshots: '@types/node': 22.19.15 long: 5.3.2 + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + proxy-agent@6.5.0: dependencies: agent-base: 7.1.4 @@ -9491,8 +9976,21 @@ snapshots: punycode@2.3.1: {} + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + quick-format-unescaped@4.0.4: {} + range-parser@1.2.1: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + unpipe: 1.0.0 + react-dom@19.2.4(react@19.2.4): dependencies: react: 19.2.4 @@ -9592,6 +10090,16 @@ snapshots: rou3@0.7.12: {} + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + rxjs@7.8.2: dependencies: tslib: 2.8.1 @@ -9608,6 +10116,8 @@ snapshots: safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} + sandwich-stream@2.0.2: {} scheduler@0.23.2: @@ -9620,10 +10130,37 @@ snapshots: semver@7.7.4: {} + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + set-cookie-parser@2.7.2: {} set-cookie-parser@3.0.1: {} + setprototypeof@1.2.0: {} + sharp@0.34.5: dependencies: '@img/colour': 1.1.0 @@ -9662,6 +10199,34 @@ snapshots: shebang-regex@3.0.0: {} + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -9763,6 +10328,8 @@ snapshots: standard-as-callback@2.1.0: {} + statuses@2.0.2: {} + std-env@3.10.0: {} string-argv@0.3.2: {} @@ -9865,6 +10432,8 @@ snapshots: toad-cache@3.7.0: {} + toidentifier@1.0.1: {} + token-types@6.1.2: dependencies: '@borewit/text-codec': 0.2.2 @@ -9927,6 +10496,12 @@ snapshots: type-fest@4.41.0: {} + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + typescript-eslint@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: '@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) @@ -9952,6 +10527,8 @@ snapshots: undici@7.24.0: {} + unpipe@1.0.0: {} + uri-js@4.4.1: dependencies: punycode: 2.3.1