@usewhisper/mcp-server 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +182 -154
  2. package/dist/autosubscribe-6EDKPBE2.js +4068 -4068
  3. package/dist/autosubscribe-GHO6YR5A.js +4068 -4068
  4. package/dist/autosubscribe-ISDETQIB.js +435 -435
  5. package/dist/chunk-3WGYBAYR.js +8387 -8387
  6. package/dist/chunk-52VJYCZ7.js +455 -455
  7. package/dist/chunk-5KBZQHDL.js +189 -189
  8. package/dist/chunk-5KIJNY6Z.js +370 -370
  9. package/dist/chunk-7SN3CKDK.js +1076 -1076
  10. package/dist/chunk-B3VWOHUA.js +271 -271
  11. package/dist/chunk-C57DHKTL.js +459 -459
  12. package/dist/chunk-EI5CE3EY.js +616 -616
  13. package/dist/chunk-FTWUJBAH.js +386 -386
  14. package/dist/chunk-H3HSKH2P.js +4841 -4841
  15. package/dist/chunk-JO3ORBZD.js +616 -616
  16. package/dist/chunk-L6DXSM2U.js +456 -456
  17. package/dist/chunk-LMEYV4JD.js +368 -368
  18. package/dist/chunk-MEFLJ4PV.js +8385 -8385
  19. package/dist/chunk-OBLI4FE4.js +275 -275
  20. package/dist/chunk-PPGYJJED.js +271 -271
  21. package/dist/chunk-QGM4M3NI.js +37 -37
  22. package/dist/chunk-T7KMSTWP.js +399 -399
  23. package/dist/chunk-TWEIYHI6.js +399 -399
  24. package/dist/chunk-UYWE7HSU.js +368 -368
  25. package/dist/chunk-X2DL2GWT.js +32 -32
  26. package/dist/chunk-X7HNNNJJ.js +1079 -1079
  27. package/dist/consolidation-2GCKI4RE.js +220 -220
  28. package/dist/consolidation-4JOPW6BG.js +220 -220
  29. package/dist/consolidation-FOVQTWNQ.js +222 -222
  30. package/dist/consolidation-IFQ52E44.js +209 -209
  31. package/dist/context-sharing-4ITCNKG4.js +307 -307
  32. package/dist/context-sharing-6CCFIAKL.js +275 -275
  33. package/dist/context-sharing-GYKLXHZA.js +307 -307
  34. package/dist/context-sharing-PH64JTXS.js +308 -308
  35. package/dist/context-sharing-Y6LTZZOF.js +307 -307
  36. package/dist/cost-optimization-6OIKRSBV.js +195 -195
  37. package/dist/cost-optimization-7DVSTL6R.js +307 -307
  38. package/dist/cost-optimization-BH5NAX33.js +286 -286
  39. package/dist/cost-optimization-F3L5BS5F.js +303 -303
  40. package/dist/ingest-2LPTWUUM.js +16 -16
  41. package/dist/ingest-7T5FAZNC.js +15 -15
  42. package/dist/ingest-EBNIE7XB.js +15 -15
  43. package/dist/ingest-FSHT5BCS.js +15 -15
  44. package/dist/ingest-QE2BTV72.js +14 -14
  45. package/dist/oracle-3RLQF3DP.js +259 -259
  46. package/dist/oracle-FKRTQUUG.js +282 -282
  47. package/dist/oracle-J47QCSEW.js +263 -263
  48. package/dist/oracle-MDP5MZRC.js +256 -256
  49. package/dist/search-BLVHWLWC.js +14 -14
  50. package/dist/search-CZ5NYL5B.js +12 -12
  51. package/dist/search-EG6TYWWW.js +13 -13
  52. package/dist/search-I22QQA7T.js +13 -13
  53. package/dist/search-T7H5G6DW.js +13 -13
  54. package/dist/server.d.ts +2 -2
  55. package/dist/server.js +1973 -169
  56. package/dist/server.js.map +1 -1
  57. package/package.json +51 -51
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/server.ts","../../src/engine/compressor.ts","../../src/engine/retriever.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { prisma } from \"../db/index.js\";\nimport { retrieve } from \"../engine/retriever.js\";\nimport { ingestDocument } from \"../engine/ingest.js\";\nimport { embedSingle } from \"../engine/embeddings.js\";\n\nconst ORG_ID = process.env.WHISPER_ORG_ID || \"\";\n\nconst server = new McpServer({\n name: \"whisper-context\",\n version: \"0.1.0\",\n});\n\nasync function resolveProject(name: string) {\n const proj = await prisma.project.findFirst({\n where: {\n orgId: ORG_ID,\n OR: [\n { name },\n { slug: name },\n ],\n },\n });\n return proj;\n}\n\n// ─── query_context ──────────────────────────────────────────\n\nserver.tool(\n \"query_context\",\n \"Search your knowledge base for relevant context. Returns packed context ready for LLM consumption. Supports hybrid vector+keyword search, memory inclusion, and knowledge graph traversal.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n query: z.string().describe(\"What are you looking for?\"),\n top_k: z.number().optional().default(10).describe(\"Number of results\"),\n chunk_types: z.array(z.string()).optional().describe(\"Filter: code, function, class, documentation, api_spec, schema, config, text\"),\n include_memories: z.boolean().optional().default(false).describe(\"Include relevant memories\"),\n include_graph: z.boolean().optional().default(false).describe(\"Include knowledge graph traversal\"),\n user_id: z.string().optional().describe(\"User ID for memory scoping\"),\n session_id: z.string().optional().describe(\"Session ID for memory scoping\"),\n max_tokens: z.number().optional().describe(\"Max tokens for packed context\"),\n },\n async ({ project, query, top_k, chunk_types, include_memories, include_graph, user_id, session_id, max_tokens }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const response = await retrieve({\n projectId: proj.id,\n query,\n topK: top_k,\n chunkTypes: chunk_types,\n includeMemories: include_memories,\n includeGraph: include_graph,\n userId: user_id,\n sessionId: session_id,\n maxTokens: max_tokens,\n });\n\n if (response.results.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No relevant context found.\" }] };\n }\n\n const header = `Found ${response.meta.totalResults} results (${response.meta.latencyMs}ms${response.meta.cacheHit ? \", cached\" : \"\"}):\\n\\n`;\n return { content: [{ type: \"text\" as const, text: header + response.context }] };\n }\n);\n\n// ─── add_memory ─────────────────────────────────────────────\n\nserver.tool(\n \"add_memory\",\n \"Store a memory (fact, preference, decision) that persists across conversations. Memories can be scoped to a user, session, or agent.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n content: z.string().describe(\"The memory content to store\"),\n memory_type: z.enum([\"factual\", \"episodic\", \"semantic\", \"procedural\"]).optional().default(\"factual\"),\n user_id: z.string().optional().describe(\"User this memory belongs to\"),\n session_id: z.string().optional().describe(\"Session scope\"),\n agent_id: z.string().optional().describe(\"Agent scope\"),\n importance: z.number().optional().default(0.5).describe(\"Importance 0-1\"),\n },\n async ({ project, content, memory_type, user_id, session_id, agent_id, importance }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const embedding = await embedSingle(content);\n const memory = await prisma.memory.create({\n data: {\n projectId: proj.id,\n content,\n memoryType: memory_type,\n userId: user_id,\n sessionId: session_id,\n agentId: agent_id,\n importance,\n embedding,\n } as any,\n });\n\n return { content: [{ type: \"text\" as const, text: `Memory stored (id: ${memory.id}, type: ${memory_type}).` }] };\n }\n);\n\n// ─── search_memories ────────────────────────────────────────\n\nserver.tool(\n \"search_memories\",\n \"Search stored memories by semantic similarity. Recall facts, preferences, past decisions from previous interactions.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n query: z.string().describe(\"What to search for\"),\n user_id: z.string().optional().describe(\"Filter by user\"),\n session_id: z.string().optional().describe(\"Filter by session\"),\n top_k: z.number().optional().default(10).describe(\"Number of results\"),\n },\n async ({ project, query, user_id, session_id, top_k }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const queryEmbedding = await embedSingle(query);\n \n // Using raw query for vector search with dynamic conditions\n let whereClause = `\n project_id = '${proj.id}' \n AND is_active = true \n AND (expires_at IS NULL OR expires_at > NOW())\n `;\n if (user_id) whereClause += ` AND user_id = '${user_id}'`;\n if (session_id) whereClause += ` AND session_id = '${session_id}'`;\n\n const results = await prisma.$queryRawUnsafe(`\n SELECT \n id, content, memory_type as \"memoryType\", importance,\n 1 - (embedding <=> '${JSON.stringify(queryEmbedding)}'::vector) as similarity\n FROM memories\n WHERE ${whereClause}\n ORDER BY embedding <=> '${JSON.stringify(queryEmbedding)}'::vector\n LIMIT ${top_k}\n `);\n\n if ((results as any[]).length === 0) return { content: [{ type: \"text\" as const, text: \"No memories found.\" }] };\n\n const text = (results as any[])\n .map((r, i) => `${i + 1}. [${r.memoryType}, importance: ${r.importance}, score: ${(r.similarity as number).toFixed(3)}]\\n${r.content}`)\n .join(\"\\n\\n\");\n\n return { content: [{ type: \"text\" as const, text }] };\n }\n);\n\n// ─── list_projects ──────────────────────────────────────────\n\nserver.tool(\n \"list_projects\",\n \"List all available context projects.\",\n {},\n async () => {\n const projs = await prisma.project.findMany({\n where: { orgId: ORG_ID },\n });\n const text = projs.length === 0\n ? \"No projects found.\"\n : projs.map((p) => `- ${p.name} (${p.slug})${p.description ? `: ${p.description}` : \"\"}`).join(\"\\n\");\n return { content: [{ type: \"text\" as const, text }] };\n }\n);\n\n// ─── list_sources ───────────────────────────────────────────\n\nserver.tool(\n \"list_sources\",\n \"List all data sources connected to a project.\",\n { project: z.string().describe(\"Project name or slug\") },\n async ({ project }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const srcs = await prisma.source.findMany({\n where: { projectId: proj.id },\n });\n const text = srcs.length === 0\n ? \"No sources connected.\"\n : srcs.map((s) => `- ${s.name} (${s.connectorType}) — ${s.status} | ${s.documentCount} docs, ${s.chunkCount} chunks`).join(\"\\n\");\n return { content: [{ type: \"text\" as const, text }] };\n }\n);\n\n// ─── add_context ────────────────────────────────────────────\n\nserver.tool(\n \"add_context\",\n \"Add text content to a project's knowledge base.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n title: z.string().describe(\"Title for this content\"),\n content: z.string().describe(\"The text content to index\"),\n },\n async ({ project, title, content }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n let directSource = await prisma.source.findFirst({\n where: {\n projectId: proj.id,\n connectorType: \"custom\",\n name: \"mcp-ingest\",\n },\n });\n\n if (!directSource) {\n directSource = await prisma.source.create({\n data: {\n orgId: ORG_ID,\n projectId: proj.id,\n name: \"mcp-ingest\",\n type: \"custom\",\n connectorType: \"custom\",\n config: {},\n status: \"READY\",\n },\n });\n }\n\n await ingestDocument({ sourceId: directSource.id, projectId: proj.id, externalId: `mcp-${title}`, title, content });\n return { content: [{ type: \"text\" as const, text: `Indexed \"${title}\" (${content.length} chars) into '${project}'.` }] };\n }\n);\n\n// ─── track_conversation ─────────────────────────────────────\n\nserver.tool(\n \"track_conversation\",\n \"Add a message to a conversation. Creates the conversation if it doesn't exist.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n session_id: z.string().describe(\"Unique session identifier\"),\n role: z.enum([\"user\", \"assistant\", \"system\", \"tool\"]),\n content: z.string().describe(\"Message content\"),\n user_id: z.string().optional().describe(\"User identifier\"),\n },\n async ({ project, session_id, role, content, user_id }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n let conv = await prisma.session.findFirst({\n where: {\n projectId: proj.id,\n sessionId: session_id,\n },\n });\n\n if (!conv) {\n conv = await prisma.session.create({\n data: {\n projectId: proj.id,\n sessionId: session_id,\n userId: user_id,\n },\n });\n }\n\n await prisma.message.create({\n data: {\n conversationId: conv.id,\n role,\n content,\n },\n });\n\n await prisma.session.update({\n where: { id: conv.id },\n data: {\n messageCount: { increment: 1 },\n updatedAt: new Date(),\n },\n });\n\n return { content: [{ type: \"text\" as const, text: `Message added (session: ${session_id}).` }] };\n }\n);\n\n// ─── get_conversation ───────────────────────────────────────\n\nserver.tool(\n \"get_conversation\",\n \"Retrieve conversation history for a session.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n session_id: z.string().describe(\"Session identifier\"),\n limit: z.number().optional().default(50),\n },\n async ({ project, session_id, limit }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const conv = await prisma.session.findFirst({\n where: {\n projectId: proj.id,\n sessionId: session_id,\n },\n });\n\n if (!conv) return { content: [{ type: \"text\" as const, text: \"No conversation found for this session.\" }] };\n\n const msgs = await prisma.message.findMany({\n where: { conversationId: conv.id },\n orderBy: { createdAt: 'asc' },\n take: limit,\n });\n\n const text = msgs.map((m) => `[${m.role}]: ${m.content}`).join(\"\\n\\n\");\n return { content: [{ type: \"text\" as const, text: text || \"No messages yet.\" }] };\n }\n);\n\n// ─── SOTA MEMORY TOOLS ──────────────────────────────────────\n\nserver.tool(\n \"memory_search_sota\",\n \"SOTA memory search with temporal reasoning and relation graphs. Searches memories with support for temporal queries ('what did I say yesterday?'), type filtering, and knowledge graph traversal.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n query: z.string().describe(\"Search query (supports temporal: 'yesterday', 'last week')\"),\n user_id: z.string().optional().describe(\"Filter by user\"),\n session_id: z.string().optional().describe(\"Filter by session\"),\n question_date: z.string().optional().describe(\"ISO datetime for temporal grounding\"),\n memory_types: z.array(z.enum([\"factual\", \"preference\", \"event\", \"relationship\", \"opinion\", \"goal\", \"instruction\"])).optional(),\n top_k: z.number().optional().default(10),\n include_relations: z.boolean().optional().default(true).describe(\"Include related memories via knowledge graph\"),\n },\n async ({ project, query, user_id, session_id, question_date, memory_types, top_k, include_relations }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n // Import SOTA search function\n const { searchMemories } = await import(\"../engine/memory/search.js\");\n\n const results = await searchMemories({\n query,\n questionDate: question_date ? new Date(question_date) : new Date(),\n projectId: proj.id,\n orgId: ORG_ID,\n userId: user_id,\n sessionId: session_id,\n topK: top_k,\n memoryTypes: memory_types,\n });\n\n if (results.length === 0) return { content: [{ type: \"text\" as const, text: \"No memories found.\" }] };\n\n const text = results.map((r, i) => {\n let line = `${i + 1}. [${r.memory.memoryType}, confidence: ${r.memory.confidence.toFixed(2)}, score: ${r.similarity.toFixed(3)}]\\n`;\n line += ` ${r.memory.content}\\n`;\n if (r.memory.temporal.eventDate) {\n line += ` Event: ${r.memory.temporal.eventDate.toISOString().split('T')[0]}\\n`;\n }\n if (include_relations && r.relations && r.relations.length > 0) {\n line += ` Relations: ${r.relations.map(rel => rel.relationType).join(\", \")}\\n`;\n }\n return line;\n }).join(\"\\n\");\n\n return { content: [{ type: \"text\" as const, text }] };\n }\n);\n\nserver.tool(\n \"ingest_conversation\",\n \"Extract memories from a conversation session. Automatically handles disambiguation, temporal grounding, and relation detection.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n session_id: z.string().describe(\"Session identifier\"),\n user_id: z.string().optional().describe(\"User identifier\"),\n messages: z.array(z.object({\n role: z.string(),\n content: z.string(),\n timestamp: z.string(),\n })).describe(\"Array of conversation messages with timestamps\"),\n },\n async ({ project, session_id, user_id, messages }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const { ingestSession } = await import(\"../engine/memory/ingest.js\");\n\n const result = await ingestSession({\n sessionId: session_id,\n projectId: proj.id,\n orgId: ORG_ID,\n userId: user_id,\n messages: messages.map(m => ({\n role: m.role,\n content: m.content,\n timestamp: new Date(m.timestamp),\n })),\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text: `Processed ${messages.length} messages:\\n` +\n `- Created ${result.memoriesCreated} memories\\n` +\n `- Detected ${result.relationsCreated} relations\\n` +\n `- Updated ${result.memoriesInvalidated} outdated memories` +\n (result.errors && result.errors.length > 0 ? `\\n- Errors: ${result.errors.join(\", \")}` : \"\"),\n }],\n };\n }\n);\n\n// ─── CONTEXT LAYER TOOLS ────────────────────────────────────\n\nserver.tool(\n \"oracle_search\",\n \"Oracle Research Mode - Tree-guided document navigation with multi-step reasoning. More precise than standard search, especially for bleeding-edge features.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n query: z.string().describe(\"Research question\"),\n mode: z.enum([\"search\", \"research\"]).optional().default(\"search\").describe(\"'search' for tree-guided, 'research' for multi-step reasoning\"),\n max_results: z.number().optional().default(5),\n max_steps: z.number().optional().default(5).describe(\"For research mode: max reasoning steps\"),\n },\n async ({ project, query, mode, max_results, max_steps }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const { oracleSearch, oracleResearch } = await import(\"../engine/oracle.js\");\n\n if (mode === \"research\") {\n const result = await oracleResearch({\n question: query,\n projectId: proj.id,\n maxSteps: max_steps,\n });\n\n let text = `Answer: ${result.answer}\\n\\nReasoning Steps:\\n`;\n result.steps.forEach((step, i) => {\n text += `${i + 1}. Query: ${step.query}\\n Reasoning: ${step.reasoning}\\n Results: ${step.results.length} items\\n`;\n });\n\n return { content: [{ type: \"text\" as const, text }] };\n } else {\n const results = await oracleSearch({\n query,\n projectId: proj.id,\n topK: max_results,\n });\n\n if (results.length === 0) return { content: [{ type: \"text\" as const, text: \"No results found.\" }] };\n\n const text = results.map((r, i) =>\n `${i + 1}. [${r.path}] (relevance: ${r.relevance.toFixed(3)})\\n${r.content.slice(0, 200)}...`\n ).join(\"\\n\\n\");\n\n return { content: [{ type: \"text\" as const, text }] };\n }\n }\n);\n\nserver.tool(\n \"autosubscribe_dependencies\",\n \"Automatically index a project's dependencies (package.json, requirements.txt, etc.). Resolves docs URLs and indexes documentation.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n source_type: z.enum([\"github\", \"local\"]).describe(\"Source location\"),\n github_owner: z.string().optional().describe(\"For GitHub: owner/org name\"),\n github_repo: z.string().optional().describe(\"For GitHub: repository name\"),\n local_path: z.string().optional().describe(\"For local: path to dependency file\"),\n dependency_file: z.enum([\"package.json\", \"requirements.txt\", \"Cargo.toml\", \"go.mod\", \"Gemfile\"]).optional(),\n index_limit: z.number().optional().default(20).describe(\"Max dependencies to index\"),\n },\n async ({ project, source_type, github_owner, github_repo, local_path, dependency_file, index_limit }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const { autosubscribe } = await import(\"../engine/autosubscribe.js\");\n\n const result = await autosubscribe({\n projectId: proj.id,\n orgId: ORG_ID,\n source: source_type === \"github\"\n ? { type: \"github\", owner: github_owner!, repo: github_repo! }\n : { type: \"local\", filePath: local_path! },\n indexLimit: index_limit,\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text: `Autosubscribe completed:\\n` +\n `- Discovered: ${result.discovered} dependencies\\n` +\n `- Indexed: ${result.indexed} successfully\\n` +\n `- Skipped: ${result.skipped} (already indexed)\\n` +\n `- Errors: ${result.errors.length}`,\n }],\n };\n }\n);\n\nserver.tool(\n \"share_context\",\n \"Create a shareable snapshot of a conversation with memories. Returns a URL that can be shared or resumed later.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n session_id: z.string().describe(\"Session to share\"),\n title: z.string().optional().describe(\"Title for the shared context\"),\n expiry_days: z.number().optional().default(30).describe(\"Days until expiry\"),\n },\n async ({ project, session_id, title, expiry_days }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const { createSharedContext } = await import(\"../engine/context-sharing.js\");\n\n const result = await createSharedContext({\n sessionId: session_id,\n projectId: proj.id,\n orgId: ORG_ID,\n includeMemories: true,\n expiryDays: expiry_days,\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text: `Shared context created:\\n` +\n `- Share ID: ${result.id}\\n` +\n `- Memories: ${result.memories?.length || 0}\\n` +\n `- Messages: ${result.messages?.length || 0}\\n` +\n `- Expires: ${result.expiresAt?.toISOString() || 'Never'}\\n` +\n `\\nShare URL: ${result.shareUrl}`,\n }],\n };\n }\n);\n\n// ─── OPTIMIZATION TOOLS ─────────────────────────────────────\n\nserver.tool(\n \"consolidate_memories\",\n \"Find and merge duplicate memories to reduce bloat. Uses vector similarity + LLM merging.\",\n {\n project: z.string().describe(\"Project name or slug\"),\n similarity_threshold: z.number().optional().default(0.95).describe(\"Similarity threshold (0-1)\"),\n dry_run: z.boolean().optional().default(false).describe(\"Preview without merging\"),\n },\n async ({ project, similarity_threshold, dry_run }) => {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n\n const { findDuplicateMemories, consolidateMemories } = await import(\"../engine/memory/consolidation.js\");\n\n if (dry_run) {\n const clusters = await findDuplicateMemories({\n projectId: proj.id,\n similarityThreshold: similarity_threshold,\n });\n\n const totalDuplicates = clusters.reduce((sum, c) => sum + c.duplicates.length, 0);\n\n return {\n content: [{\n type: \"text\" as const,\n text: `Found ${clusters.length} duplicate clusters:\\n` +\n `- Total duplicates: ${totalDuplicates}\\n` +\n `- Estimated savings: ${totalDuplicates} memories\\n` +\n `\\nRun without dry_run to merge.`,\n }],\n };\n } else {\n const result = await consolidateMemories({\n projectId: proj.id,\n similarityThreshold: similarity_threshold,\n dryRun: false,\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text: `Consolidation complete:\\n` +\n `- Clusters found: ${result.clustersFound}\\n` +\n `- Memories merged: ${result.memoriesMerged}\\n` +\n `- Memories deactivated: ${result.memoriesDeactivated}`,\n }],\n };\n }\n }\n);\n\nserver.tool(\n \"get_cost_summary\",\n \"Get cost tracking summary showing spending by model and task. Includes savings vs always-Opus.\",\n {\n project: z.string().optional().describe(\"Project name or slug (optional for org-wide)\"),\n days: z.number().optional().default(30).describe(\"Time period in days\"),\n },\n async ({ project, days }) => {\n let projectId: string | undefined;\n if (project) {\n const proj = await resolveProject(project);\n if (!proj) return { content: [{ type: \"text\" as const, text: `Project '${project}' not found.` }] };\n projectId = proj.id;\n }\n\n const { getCostSummary, calculateSavings } = await import(\"../engine/cost-optimization.js\");\n\n const endDate = new Date();\n const startDate = new Date(endDate.getTime() - days * 24 * 60 * 60 * 1000);\n\n const summary = getCostSummary({\n since: startDate,\n groupBy: \"model\",\n });\n\n const savings = calculateSavings({\n since: startDate,\n });\n\n let text = `Cost Summary (last ${days} days):\\n\\n`;\n text += `Total Cost: $${savings.actualCost.toFixed(2)}\\n`;\n text += `Total Requests: ${Object.values(summary).reduce((sum, s) => sum + s.calls, 0)}\\n`;\n text += `Avg Cost/Request: $${(savings.actualCost / (Object.values(summary).reduce((sum, s) => sum + s.calls, 0) || 1)).toFixed(4)}\\n\\n`;\n text += `By Model:\\n`;\n Object.entries(summary).forEach(([model, stats]) => {\n text += `- ${model}: $${stats.totalCost.toFixed(2)} (${stats.calls} calls)\\n`;\n });\n text += `\\nSavings vs Always-Opus:\\n`;\n text += `- Actual: $${savings.actualCost.toFixed(2)}\\n`;\n text += `- Opus-only: $${savings.opusCost.toFixed(2)}\\n`;\n text += `- Saved: $${savings.savings.toFixed(2)} (${savings.savingsPercent.toFixed(1)}%)\\n`;\n\n return { content: [{ type: \"text\" as const, text }] };\n }\n);\n\n// ─── Start ──────────────────────────────────────────────────\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Whisper Context MCP server running on stdio\");\n}\n\nmain().catch(console.error);\n","import OpenAI from \"openai\";\nimport { createHash } from \"crypto\";\n\nconst openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });\n\n// ─── Types ───────────────────────────────────────────────────\n\nexport interface CompressedContext {\n context: string;\n originalTokens: number;\n compressedTokens: number;\n reductionPercent: number;\n strategy: string;\n}\n\nexport interface CompressionOptions {\n maxTokens?: number;\n strategy?: \"summarize\" | \"extract\" | \"delta\" | \"adaptive\";\n previousContextHash?: string; // for delta mode\n previousContext?: string; // for delta mode\n targetReduction?: number; // 0-1, e.g. 0.6 = reduce by 60%\n}\n\n// ─── In-memory delta cache ──────────────────────────────────\n\nconst deltaCache = new Map<string, { context: string; hash: string; timestamp: number }>();\nconst DELTA_CACHE_TTL = 600_000; // 10 min\n\nfunction hashContext(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\").slice(0, 16);\n}\n\n// ─── Main Compression Function ──────────────────────────────\n\nexport async function compressContext(\n rawContext: string,\n opts: CompressionOptions = {}\n): Promise<CompressedContext> {\n const {\n maxTokens = 4000,\n strategy = \"adaptive\",\n previousContextHash,\n previousContext,\n targetReduction = 0.5,\n } = opts;\n\n const originalTokens = estimateTokens(rawContext);\n\n // If already under budget, return as-is\n if (originalTokens <= maxTokens) {\n return {\n context: rawContext,\n originalTokens,\n compressedTokens: originalTokens,\n reductionPercent: 0,\n strategy: \"none\",\n };\n }\n\n switch (strategy) {\n case \"delta\":\n return deltaCompress(rawContext, originalTokens, maxTokens, previousContextHash, previousContext);\n case \"summarize\":\n return summarizeCompress(rawContext, originalTokens, maxTokens);\n case \"extract\":\n return extractCompress(rawContext, originalTokens, maxTokens);\n case \"adaptive\":\n default:\n return adaptiveCompress(rawContext, originalTokens, maxTokens, previousContextHash, previousContext);\n }\n}\n\n// ─── Adaptive Strategy ──────────────────────────────────────\n// Picks the best strategy based on context characteristics\n\nasync function adaptiveCompress(\n rawContext: string,\n originalTokens: number,\n maxTokens: number,\n previousHash?: string,\n previousCtx?: string\n): Promise<CompressedContext> {\n const ratio = originalTokens / maxTokens;\n\n // If we have previous context and it's similar, use delta\n if (previousHash || previousCtx) {\n const delta = await deltaCompress(rawContext, originalTokens, maxTokens, previousHash, previousCtx);\n if (delta.compressedTokens <= maxTokens) return delta;\n }\n\n // Light compression (under 2x budget): extract key info\n if (ratio < 2) {\n return extractCompress(rawContext, originalTokens, maxTokens);\n }\n\n // Heavy compression (over 2x budget): summarize\n return summarizeCompress(rawContext, originalTokens, maxTokens);\n}\n\n// ─── Delta Compression ──────────────────────────────────────\n// Only sends what changed since the last context\n\nasync function deltaCompress(\n rawContext: string,\n originalTokens: number,\n maxTokens: number,\n previousHash?: string,\n previousCtx?: string\n): Promise<CompressedContext> {\n const currentHash = hashContext(rawContext);\n\n // Check if identical\n if (previousHash && previousHash === currentHash) {\n return {\n context: \"[No changes since last context]\",\n originalTokens,\n compressedTokens: 8,\n reductionPercent: 99,\n strategy: \"delta-identical\",\n };\n }\n\n // Get previous context from cache or parameter\n let prevCtx = previousCtx;\n if (!prevCtx && previousHash) {\n const cached = deltaCache.get(previousHash);\n if (cached && Date.now() - cached.timestamp < DELTA_CACHE_TTL) {\n prevCtx = cached.context;\n }\n }\n\n if (!prevCtx) {\n // No previous context to diff against, fall back to extract\n return extractCompress(rawContext, originalTokens, maxTokens);\n }\n\n // Split into blocks and find differences\n const prevBlocks = new Set(prevCtx.split(\"\\n---\\n\").map((b) => b.trim()));\n const currentBlocks = rawContext.split(\"\\n---\\n\").map((b) => b.trim());\n\n const newBlocks: string[] = [];\n const unchangedCount = { count: 0 };\n\n for (const block of currentBlocks) {\n if (prevBlocks.has(block)) {\n unchangedCount.count++;\n } else {\n newBlocks.push(block);\n }\n }\n\n let deltaContext: string;\n if (newBlocks.length === 0) {\n deltaContext = \"[No new information since last query]\";\n } else {\n const header = `[${unchangedCount.count} unchanged results omitted, ${newBlocks.length} new/updated]\\n\\n`;\n deltaContext = header + newBlocks.join(\"\\n---\\n\");\n }\n\n // Trim if still over budget\n const deltaTokens = estimateTokens(deltaContext);\n if (deltaTokens > maxTokens) {\n const truncated = truncateToTokens(deltaContext, maxTokens);\n deltaCache.set(currentHash, { context: rawContext, hash: currentHash, timestamp: Date.now() });\n\n return {\n context: truncated,\n originalTokens,\n compressedTokens: estimateTokens(truncated),\n reductionPercent: Math.round((1 - estimateTokens(truncated) / originalTokens) * 100),\n strategy: \"delta-truncated\",\n };\n }\n\n // Cache current context for next delta\n deltaCache.set(currentHash, { context: rawContext, hash: currentHash, timestamp: Date.now() });\n\n return {\n context: deltaContext,\n originalTokens,\n compressedTokens: estimateTokens(deltaContext),\n reductionPercent: Math.round((1 - estimateTokens(deltaContext) / originalTokens) * 100),\n strategy: \"delta\",\n };\n}\n\n// ─── Extract Compression ────────────────────────────────────\n// LLM extracts only the most relevant parts\n\nasync function extractCompress(\n rawContext: string,\n originalTokens: number,\n maxTokens: number\n): Promise<CompressedContext> {\n try {\n const res = await openai.chat.completions.create({\n model: \"gpt-4.1-nano\",\n messages: [\n {\n role: \"system\",\n content: `You are a context compressor. Extract and preserve ONLY the most important information from the provided context. Remove redundancy, boilerplate, and low-value content. Keep code snippets, key facts, API signatures, and important relationships. Output should be ${maxTokens} tokens or less. Do NOT add commentary — just output the compressed context.`,\n },\n { role: \"user\", content: rawContext },\n ],\n max_tokens: maxTokens,\n temperature: 0,\n });\n\n const compressed = res.choices[0]?.message?.content?.trim() || rawContext;\n const compressedTokens = estimateTokens(compressed);\n\n return {\n context: compressed,\n originalTokens,\n compressedTokens,\n reductionPercent: Math.round((1 - compressedTokens / originalTokens) * 100),\n strategy: \"extract\",\n };\n } catch {\n // Fallback to truncation\n const truncated = truncateToTokens(rawContext, maxTokens);\n return {\n context: truncated,\n originalTokens,\n compressedTokens: estimateTokens(truncated),\n reductionPercent: Math.round((1 - estimateTokens(truncated) / originalTokens) * 100),\n strategy: \"truncate-fallback\",\n };\n }\n}\n\n// ─── Summarize Compression ──────────────────────────────────\n// For heavy compression — summarizes each block then combines\n\nasync function summarizeCompress(\n rawContext: string,\n originalTokens: number,\n maxTokens: number\n): Promise<CompressedContext> {\n const blocks = rawContext.split(\"\\n---\\n\").filter((b) => b.trim());\n\n // If few blocks, summarize the whole thing\n if (blocks.length <= 3) {\n return extractCompress(rawContext, originalTokens, maxTokens);\n }\n\n // Summarize each block individually, then combine\n const budgetPerBlock = Math.floor(maxTokens / blocks.length);\n\n try {\n const summaries = await Promise.all(\n blocks.map(async (block) => {\n if (estimateTokens(block) <= budgetPerBlock) return block;\n\n const res = await openai.chat.completions.create({\n model: \"gpt-4.1-nano\",\n messages: [\n {\n role: \"system\",\n content: `Summarize this context block in ${budgetPerBlock} tokens or less. Preserve code signatures, key facts, and important details. Output only the summary.`,\n },\n { role: \"user\", content: block },\n ],\n max_tokens: budgetPerBlock,\n temperature: 0,\n });\n\n return res.choices[0]?.message?.content?.trim() || block.slice(0, budgetPerBlock * 4);\n })\n );\n\n const compressed = summaries.join(\"\\n\\n---\\n\\n\");\n let compressedTokens = estimateTokens(compressed);\n\n // Final trim if still over\n let finalContext = compressed;\n if (compressedTokens > maxTokens) {\n finalContext = truncateToTokens(compressed, maxTokens);\n compressedTokens = estimateTokens(finalContext);\n }\n\n return {\n context: finalContext,\n originalTokens,\n compressedTokens,\n reductionPercent: Math.round((1 - compressedTokens / originalTokens) * 100),\n strategy: \"summarize\",\n };\n } catch {\n const truncated = truncateToTokens(rawContext, maxTokens);\n return {\n context: truncated,\n originalTokens,\n compressedTokens: estimateTokens(truncated),\n reductionPercent: Math.round((1 - estimateTokens(truncated) / originalTokens) * 100),\n strategy: \"truncate-fallback\",\n };\n }\n}\n\n// ─── Pre-computed Chunk Summaries ────────────────────────────\n// Summarize chunks at ingest time so retrieval is cheaper\n\nexport async function summarizeChunk(content: string, chunkType: string): Promise<string> {\n // Only summarize large chunks\n if (estimateTokens(content) < 200) return content;\n\n try {\n const prompt = chunkType === \"code\"\n ? \"Summarize this code in 2-3 sentences. Include: function/class names, what it does, parameters, return type.\"\n : \"Summarize this text in 2-3 sentences. Preserve key facts, names, and important details.\";\n\n const res = await openai.chat.completions.create({\n model: \"gpt-4.1-nano\",\n messages: [\n { role: \"system\", content: prompt },\n { role: \"user\", content: content.slice(0, 3000) },\n ],\n max_tokens: 150,\n temperature: 0,\n });\n\n return res.choices[0]?.message?.content?.trim() || content;\n } catch {\n return content;\n }\n}\n\n// ─── Helpers ─────────────────────────────────────────────────\n\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\nfunction truncateToTokens(text: string, maxTokens: number): string {\n const maxChars = maxTokens * 4;\n if (text.length <= maxChars) return text;\n return text.slice(0, maxChars) + \"\\n\\n[...truncated]\";\n}\n\n// Cleanup stale delta cache entries periodically\nsetInterval(() => {\n const now = Date.now();\n for (const [key, val] of deltaCache) {\n if (now - val.timestamp > DELTA_CACHE_TTL) deltaCache.delete(key);\n }\n}, 60_000);\n","import { prisma } from \"../db/index.js\";\nimport { embedSingle } from \"./embeddings.js\";\nimport { compressContext, type CompressionOptions } from \"./compressor.js\";\nimport { createHash } from \"crypto\";\nimport OpenAI from \"openai\";\n\nconst openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });\n\n// ─── Types ───────────────────────────────────────────────────\n\nexport interface RetrievalResult {\n id: string;\n content: string;\n score: number;\n metadata: Record<string, any>;\n documentTitle?: string;\n sourceName?: string;\n chunkType: string;\n source: \"vector\" | \"bm25\" | \"hybrid\" | \"memory\" | \"graph\";\n}\n\nexport interface QueryOptions {\n projectId: string;\n query: string;\n topK?: number;\n threshold?: number;\n chunkTypes?: string[];\n sourceIds?: string[];\n // Hybrid search\n hybridSearch?: boolean;\n vectorWeight?: number; // 0-1, default 0.7\n bm25Weight?: number; // 0-1, default 0.3\n // Reranking\n rerank?: boolean;\n rerankTopK?: number;\n // Memory inclusion\n includeMemories?: boolean;\n userId?: string;\n sessionId?: string;\n agentId?: string;\n // Graph\n includeGraph?: boolean;\n graphDepth?: number;\n // Context packing\n maxTokens?: number;\n // Compression\n compress?: boolean;\n compressionStrategy?: \"summarize\" | \"extract\" | \"delta\" | \"adaptive\";\n previousContextHash?: string;\n // Caching\n useCache?: boolean;\n cacheTtlSeconds?: number;\n}\n\nexport interface ContextResponse {\n results: RetrievalResult[];\n context: string; // packed context string ready for LLM\n meta: {\n totalResults: number;\n latencyMs: number;\n cacheHit: boolean;\n tokensUsed: number;\n contextHash?: string;\n compression?: {\n originalTokens: number;\n compressedTokens: number;\n reductionPercent: number;\n strategy: string;\n };\n };\n}\n\n// ─── Main Query Function ─────────────────────────────────────\n\nexport async function retrieve(opts: QueryOptions): Promise<ContextResponse> {\n const {\n projectId,\n query,\n topK = 10,\n threshold = 0.3,\n chunkTypes,\n hybridSearch = true,\n vectorWeight = 0.7,\n bm25Weight = 0.3,\n rerank = true,\n rerankTopK,\n includeMemories = false,\n userId,\n sessionId,\n agentId,\n includeGraph = false,\n graphDepth = 1,\n maxTokens,\n compress = false,\n compressionStrategy = \"adaptive\",\n previousContextHash,\n useCache = true,\n cacheTtlSeconds = 300,\n } = opts;\n\n const startTime = Date.now();\n\n // ─── Check Cache ─────────────────────────────────────────\n if (useCache) {\n const cached = await checkCache(projectId, query);\n if (cached) {\n const cachedResults = cached as unknown as RetrievalResult[];\n return {\n results: cachedResults,\n context: packContext(cachedResults, maxTokens),\n meta: {\n totalResults: cachedResults.length,\n latencyMs: Date.now() - startTime,\n cacheHit: true,\n tokensUsed: 0,\n },\n };\n }\n }\n\n // ─── Embed Query ─────────────────────────────────────────\n const queryEmbedding = await embedSingle(query);\n\n let allResults: RetrievalResult[] = [];\n\n // ─── Vector Search ───────────────────────────────────────\n const vectorResults = await vectorSearch(projectId, queryEmbedding, topK * 2, chunkTypes);\n allResults.push(...vectorResults);\n\n // ─── BM25 Full-Text Search ───────────────────────────────\n if (hybridSearch) {\n const bm25Results = await fullTextSearch(projectId, query, topK * 2, chunkTypes);\n allResults.push(...bm25Results);\n }\n\n // ─── Memory Search ───────────────────────────────────────\n if (includeMemories) {\n const memoryResults = await memorySearch(projectId, queryEmbedding, {\n userId,\n sessionId,\n agentId,\n topK: Math.ceil(topK / 3),\n });\n allResults.push(...memoryResults);\n }\n\n // ─── Graph Traversal ─────────────────────────────────────\n if (includeGraph) {\n const graphResults = await graphSearch(projectId, queryEmbedding, {\n depth: graphDepth,\n topK: Math.ceil(topK / 3),\n });\n allResults.push(...graphResults);\n }\n\n // ─── Deduplicate ─────────────────────────────────────────\n allResults = deduplicateResults(allResults);\n\n // ─── Reciprocal Rank Fusion (for hybrid) ─────────────────\n if (hybridSearch) {\n allResults = reciprocalRankFusion(allResults, vectorWeight, bm25Weight);\n }\n\n // ─── Filter by threshold ─────────────────────────────────\n allResults = allResults.filter((r) => r.score >= threshold);\n\n // ─── Rerank with LLM ────────────────────────────────────\n if (rerank && allResults.length > 0) {\n const reranked = await rerankResults(query, allResults, rerankTopK || topK);\n allResults = reranked;\n }\n\n // ─── Limit to topK ──────────────────────────────────────\n allResults = allResults.slice(0, topK);\n\n // ─── Enrich with document/source metadata ────────────────\n allResults = await enrichResults(allResults);\n\n // ─── Context packing ─────────────────────────────────────\n let context = packContext(allResults, maxTokens);\n const contextHash = createHash(\"sha256\").update(context).digest(\"hex\").slice(0, 16);\n\n // ─── Compression ──────────────────────────────────────────\n let compressionMeta: ContextResponse[\"meta\"][\"compression\"];\n if (compress && context.length > 0) {\n const compressed = await compressContext(context, {\n maxTokens: maxTokens || 4000,\n strategy: compressionStrategy,\n previousContextHash,\n });\n context = compressed.context;\n compressionMeta = {\n originalTokens: compressed.originalTokens,\n compressedTokens: compressed.compressedTokens,\n reductionPercent: compressed.reductionPercent,\n strategy: compressed.strategy,\n };\n }\n\n // ─── Cache results ───────────────────────────────────────\n if (useCache && allResults.length > 0) {\n await setCache(projectId, query, allResults, cacheTtlSeconds);\n }\n\n const latencyMs = Date.now() - startTime;\n\n return {\n results: allResults,\n context,\n meta: {\n totalResults: allResults.length,\n latencyMs,\n cacheHit: false,\n tokensUsed: estimateTokens(context),\n contextHash,\n compression: compressionMeta,\n },\n };\n}\n\n// ─── Vector Search ───────────────────────────────────────────\n\nasync function vectorSearch(\n projectId: string,\n queryEmbedding: number[],\n limit: number,\n chunkTypes?: string[]\n): Promise<RetrievalResult[]> {\n let whereClause = `\"projectId\" = '${projectId}'`;\n if (chunkTypes && chunkTypes.length > 0) {\n whereClause += ` AND \"chunkType\" IN (${chunkTypes.map(t => `'${t}'`).join(',')})`;\n }\n\n const results = await prisma.$queryRawUnsafe(`\n SELECT\n id, content, \"chunkType\", metadata,\n 1 - (embedding <=> '${JSON.stringify(queryEmbedding)}'::vector) as similarity\n FROM chunks\n WHERE ${whereClause}\n ORDER BY embedding <=> '${JSON.stringify(queryEmbedding)}'::vector\n LIMIT ${limit}\n `);\n\n return (results as any[]).map((r) => ({\n id: r.id,\n content: r.content,\n score: r.similarity,\n metadata: r.metadata || {},\n chunkType: r.chunkType,\n source: \"vector\" as const,\n }));\n}\n\n// ─── Full-Text Search (BM25-style via pg tsvector) ───────────\n\nasync function fullTextSearch(\n projectId: string,\n query: string,\n limit: number,\n chunkTypes?: string[]\n): Promise<RetrievalResult[]> {\n // Sanitize query for tsquery\n const tsQuery = query\n .replace(/[^\\w\\s]/g, \" \")\n .trim()\n .split(/\\s+/)\n .filter((w) => w.length > 1)\n .join(\" & \");\n\n if (!tsQuery) return [];\n\n let whereClause = `\"projectId\" = '${projectId}'`;\n if (chunkTypes && chunkTypes.length > 0) {\n whereClause += ` AND \"chunkType\" IN (${chunkTypes.map(t => `'${t}'`).join(',')})`;\n }\n\n const results = await prisma.$queryRawUnsafe(`\n SELECT\n id, content, \"chunkType\", metadata,\n ts_rank(to_tsvector('english', coalesce(\"searchContent\", content)), to_tsquery('english', '${tsQuery}')) as rank\n FROM chunks\n WHERE ${whereClause}\n AND to_tsvector('english', coalesce(\"searchContent\", content)) @@ to_tsquery('english', '${tsQuery}')\n ORDER BY rank DESC\n LIMIT ${limit}\n `);\n\n // Normalize ranks to 0-1\n const maxRank = (results as any[]).length > 0 ? Math.max(...(results as any[]).map((r) => r.rank)) : 1;\n\n return (results as any[]).map((r) => ({\n id: r.id,\n content: r.content,\n score: maxRank > 0 ? r.rank / maxRank : 0,\n metadata: r.metadata || {},\n chunkType: r.chunkType,\n source: \"bm25\" as const,\n }));\n}\n\n// ─── Memory Search ───────────────────────────────────────────\n\nasync function memorySearch(\n projectId: string,\n queryEmbedding: number[],\n opts: { userId?: string; sessionId?: string; agentId?: string; topK: number }\n): Promise<RetrievalResult[]> {\n let whereClause = `\n project_id = '${projectId}' \n AND is_active = true \n AND (expires_at IS NULL OR expires_at > NOW())\n `;\n\n if (opts.userId) whereClause += ` AND user_id = '${opts.userId}'`;\n if (opts.sessionId) whereClause += ` AND session_id = '${opts.sessionId}'`;\n if (opts.agentId) whereClause += ` AND agent_id = '${opts.agentId}'`;\n\n const results = await prisma.$queryRawUnsafe(`\n SELECT \n id, content, memory_type as \"memoryType\", metadata, importance,\n 1 - (embedding <=> '${JSON.stringify(queryEmbedding)}'::vector) as similarity\n FROM memories\n WHERE ${whereClause}\n ORDER BY embedding <=> '${JSON.stringify(queryEmbedding)}'::vector\n LIMIT ${opts.topK}\n `);\n\n // Update access counts\n const ids = (results as any[]).map((r) => r.id);\n if (ids.length > 0) {\n await prisma.memory.updateMany({\n where: { id: { in: ids } },\n data: {\n accessCount: { increment: 1 },\n lastAccessedAt: new Date(),\n },\n });\n }\n\n return (results as any[]).map((r) => ({\n id: r.id,\n content: r.content,\n score: r.similarity * (r.importance || 0.5),\n metadata: { ...(r.metadata || {}), memoryType: r.memoryType },\n chunkType: \"memory\" as any,\n source: \"memory\" as const,\n }));\n}\n\n// ─── Graph Search ────────────────────────────────────────────\n\nasync function graphSearch(\n projectId: string,\n queryEmbedding: number[],\n opts: { depth: number; topK: number }\n): Promise<RetrievalResult[]> {\n // Find most relevant entities using vector search\n const relevantEntities = await prisma.$queryRawUnsafe(`\n SELECT \n id, name, entity_type as \"entityType\", description, metadata, source_chunk_id as \"sourceChunkId\",\n 1 - (embedding <=> '${JSON.stringify(queryEmbedding)}'::vector) as similarity\n FROM entities\n WHERE project_id = '${projectId}'\n ORDER BY embedding <=> '${JSON.stringify(queryEmbedding)}'::vector\n LIMIT 5\n `);\n\n if ((relevantEntities as any[]).length === 0) return [];\n\n // Traverse relationships\n const entityIds = (relevantEntities as any[]).map((e) => e.id);\n const entityIdsStr = entityIds.map(id => `'${id}'`).join(',');\n\n const relatedEntities = await prisma.$queryRawUnsafe(`\n SELECT \n e.id, e.name, e.entity_type as \"entityType\", e.description, e.metadata, e.source_chunk_id as \"sourceChunkId\",\n er.relation_type as \"relationType\", er.weight\n FROM entity_relations er\n INNER JOIN entities e ON er.to_entity_id = e.id\n WHERE er.project_id = '${projectId}'\n AND er.from_entity_id IN (${entityIdsStr})\n LIMIT ${opts.topK}\n `);\n\n // Get chunks for related entities\n const chunkIds = [\n ...(relevantEntities as any[]).map((e) => e.sourceChunkId).filter(Boolean),\n ...(relatedEntities as any[]).map((e) => e.sourceChunkId).filter(Boolean),\n ] as string[];\n\n if (chunkIds.length === 0) return [];\n\n const relatedChunks = await prisma.chunk.findMany({\n where: { id: { in: chunkIds } },\n });\n\n return relatedChunks.map((c) => {\n const entity = (relevantEntities as any[]).find((e) => e.sourceChunkId === c.id);\n return {\n id: c.id,\n content: c.content,\n score: entity ? entity.similarity * 0.8 : 0.5,\n metadata: {\n ...(c.metadata as any),\n entityName: entity?.name,\n entityType: entity?.entityType,\n },\n chunkType: c.chunkType || \"text\",\n source: \"graph\" as const,\n };\n });\n}\n\n// ─── Reciprocal Rank Fusion ──────────────────────────────────\n\nfunction reciprocalRankFusion(\n results: RetrievalResult[],\n vectorWeight: number,\n bm25Weight: number,\n k = 60\n): RetrievalResult[] {\n const scoreMap = new Map<string, { result: RetrievalResult; score: number }>();\n\n // Group by source type and rank\n const vectorResults = results.filter((r) => r.source === \"vector\");\n const bm25Results = results.filter((r) => r.source === \"bm25\");\n const otherResults = results.filter((r) => r.source !== \"vector\" && r.source !== \"bm25\");\n\n // RRF scoring for vector results\n vectorResults.forEach((r, rank) => {\n const existing = scoreMap.get(r.id);\n const rrfScore = vectorWeight / (k + rank + 1);\n if (existing) {\n existing.score += rrfScore;\n } else {\n scoreMap.set(r.id, { result: r, score: rrfScore });\n }\n });\n\n // RRF scoring for BM25 results\n bm25Results.forEach((r, rank) => {\n const existing = scoreMap.get(r.id);\n const rrfScore = bm25Weight / (k + rank + 1);\n if (existing) {\n existing.score += rrfScore;\n existing.result.source = \"hybrid\";\n } else {\n scoreMap.set(r.id, { result: { ...r, source: \"hybrid\" }, score: rrfScore });\n }\n });\n\n // Add other results with their original scores\n otherResults.forEach((r) => {\n if (!scoreMap.has(r.id)) {\n scoreMap.set(r.id, { result: r, score: r.score * 0.5 });\n }\n });\n\n return Array.from(scoreMap.values())\n .sort((a, b) => b.score - a.score)\n .map((entry) => ({ ...entry.result, score: entry.score }));\n}\n\n// ─── LLM Reranking ───────────────────────────────────────────\n\nasync function rerankResults(\n query: string,\n results: RetrievalResult[],\n topK: number\n): Promise<RetrievalResult[]> {\n if (results.length <= 3) return results; // not worth reranking\n\n // Take top candidates for reranking (limit to save tokens)\n const candidates = results.slice(0, Math.min(results.length, topK * 3));\n\n const prompt = `Given the query: \"${query}\"\n\nRank these ${candidates.length} text passages by relevance (most relevant first). Return ONLY a JSON array of indices (0-based), e.g. [2, 0, 4, 1, 3].\n\n${candidates.map((r, i) => `[${i}] ${r.content.slice(0, 300)}`).join(\"\\n\\n\")}`;\n\n try {\n const res = await openai.chat.completions.create({\n model: \"gpt-4.1-nano\",\n messages: [{ role: \"user\", content: prompt }],\n temperature: 0,\n max_tokens: 200,\n });\n\n const text = res.choices[0]?.message?.content?.trim() || \"\";\n const match = text.match(/\\[[\\d,\\s]+\\]/);\n if (!match) return results;\n\n const indices: number[] = JSON.parse(match[0]);\n const reranked: RetrievalResult[] = [];\n\n for (const idx of indices) {\n if (idx >= 0 && idx < candidates.length) {\n reranked.push({\n ...candidates[idx],\n score: 1 - reranked.length * (1 / indices.length), // normalize\n });\n }\n }\n\n // Add any results that weren't reranked\n for (const r of results) {\n if (!reranked.find((rr) => rr.id === r.id)) {\n reranked.push(r);\n }\n }\n\n return reranked.slice(0, topK);\n } catch {\n // Fallback to original ordering if reranking fails\n return results.slice(0, topK);\n }\n}\n\n// ─── Deduplication ───────────────────────────────────────────\n\nfunction deduplicateResults(results: RetrievalResult[]): RetrievalResult[] {\n const seen = new Map<string, RetrievalResult>();\n\n for (const r of results) {\n const existing = seen.get(r.id);\n if (!existing || r.score > existing.score) {\n seen.set(r.id, r);\n }\n }\n\n return Array.from(seen.values());\n}\n\n// ─── Context Packing ─────────────────────────────────────────\n\nfunction packContext(results: RetrievalResult[], maxTokens?: number): string {\n if (results.length === 0) return \"\";\n\n const limit = maxTokens || 8000;\n let totalTokens = 0;\n const packed: string[] = [];\n\n for (const r of results) {\n const header = buildChunkHeader(r);\n const block = `${header}\\n${r.content}\\n`;\n const tokens = estimateTokens(block);\n\n if (totalTokens + tokens > limit) break;\n\n packed.push(block);\n totalTokens += tokens;\n }\n\n return packed.join(\"\\n---\\n\\n\");\n}\n\nfunction buildChunkHeader(r: RetrievalResult): string {\n const parts: string[] = [];\n\n if (r.sourceName) parts.push(`Source: ${r.sourceName}`);\n if (r.documentTitle) parts.push(`Document: ${r.documentTitle}`);\n if (r.metadata?.filePath) parts.push(`File: ${r.metadata.filePath}`);\n if (r.metadata?.startLine) parts.push(`Lines: ${r.metadata.startLine}-${r.metadata.endLine || \"?\"}`);\n if (r.chunkType && r.chunkType !== \"text\") parts.push(`Type: ${r.chunkType}`);\n\n return parts.length > 0 ? `[${parts.join(\" | \")}]` : \"\";\n}\n\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n// ─── Enrich Results ──────────────────────────────────────────\n\nasync function enrichResults(results: RetrievalResult[]): Promise<RetrievalResult[]> {\n // Get unique document IDs from chunk results\n const chunkResults = results.filter((r) => r.source !== \"memory\");\n if (chunkResults.length === 0) return results;\n\n // We need document IDs — stored in metadata or we need to query\n const chunkIds = chunkResults.map((r) => r.id);\n\n const chunkDocs = await prisma.$queryRawUnsafe(`\n SELECT\n c.id as \"chunkId\", d.title as \"docTitle\", s.name as \"sourceName\"\n FROM chunks c\n INNER JOIN documents d ON c.\"documentId\" = d.id\n INNER JOIN sources s ON d.\"sourceId\" = s.id\n WHERE c.id IN (${chunkIds.map(id => `'${id}'`).join(',')})\n `);\n\n const enrichMap = new Map((chunkDocs as any[]).map((d) => [d.chunkId, d]));\n\n return results.map((r) => {\n const enrichment = enrichMap.get(r.id);\n if (enrichment) {\n return {\n ...r,\n documentTitle: enrichment.docTitle || undefined,\n sourceName: enrichment.sourceName || undefined,\n };\n }\n return r;\n });\n}\n\n// ─── Cache ───────────────────────────────────────────────────\n\nfunction hashQuery(query: string): string {\n return createHash(\"sha256\").update(query.toLowerCase().trim()).digest(\"hex\");\n}\n\nasync function checkCache(projectId: string, query: string) {\n const hash = hashQuery(query);\n\n const cached = await prisma.queryCache.findFirst({\n where: {\n projectId,\n queryHash: hash,\n expiresAt: { gt: new Date() },\n },\n });\n\n if (cached) {\n await prisma.queryCache.update({\n where: { id: cached.id },\n data: { hitCount: { increment: 1 } },\n });\n\n return cached.results;\n }\n\n return null;\n}\n\nasync function setCache(\n projectId: string,\n query: string,\n results: RetrievalResult[],\n ttlSeconds: number\n) {\n const hash = hashQuery(query);\n const expiresAt = new Date(Date.now() + ttlSeconds * 1000);\n\n await prisma.queryCache.upsert({\n where: {\n projectId_queryHash: {\n projectId,\n queryHash: hash,\n },\n },\n update: {\n results: results as any,\n expiresAt,\n hitCount: 0,\n },\n create: {\n projectId,\n queryHash: hash,\n query,\n results: results as any,\n expiresAt,\n },\n });\n}\n"],"mappings":"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","names":["createHash","OpenAI","openai","estimateTokens"]}
1
+ {"version":3,"sources":["../../src/mcp/server.ts","../../src/sdk/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { execSync, spawnSync } from \"child_process\";\nimport { readdirSync, readFileSync, statSync } from \"fs\";\nimport { join, relative, extname } from \"path\";\nimport { WhisperContext } from \"../sdk/index.js\";\n\n// Initialize Whisper SDK client\nconst API_KEY = process.env.WHISPER_API_KEY || \"\";\nconst DEFAULT_PROJECT = process.env.WHISPER_PROJECT || \"\";\nconst BASE_URL = process.env.WHISPER_BASE_URL;\n\nif (!API_KEY) {\n console.error(\"Error: WHISPER_API_KEY environment variable is required\");\n process.exit(1);\n}\n\nconst whisper = new WhisperContext({\n apiKey: API_KEY,\n project: DEFAULT_PROJECT,\n ...(BASE_URL && { baseUrl: BASE_URL }),\n});\n\nconst server = new McpServer({\n name: \"whisper-context\",\n version: \"0.2.8\",\n});\n\n// ─── query_context ──────────────────────────────────────────\n\nserver.tool(\n \"query_context\",\n \"Search your knowledge base for relevant context. Returns packed context ready for LLM consumption. Supports hybrid vector+keyword search, memory inclusion, and knowledge graph traversal.\",\n {\n project: z.string().optional().describe(\"Project name or slug (optional if WHISPER_PROJECT is set)\"),\n query: z.string().describe(\"What are you looking for?\"),\n top_k: z.number().optional().default(10).describe(\"Number of results\"),\n chunk_types: z.array(z.string()).optional().describe(\"Filter: code, function, class, documentation, api_spec, schema, config, text\"),\n include_memories: z.boolean().optional().default(false).describe(\"Include relevant memories\"),\n include_graph: z.boolean().optional().default(false).describe(\"Include knowledge graph traversal\"),\n user_id: z.string().optional().describe(\"User ID for memory scoping\"),\n session_id: z.string().optional().describe(\"Session ID for memory scoping\"),\n max_tokens: z.number().optional().describe(\"Max tokens for packed context\"),\n },\n async ({ project, query, top_k, chunk_types, include_memories, include_graph, user_id, session_id, max_tokens }) => {\n try {\n const response = await whisper.query({\n project,\n query,\n top_k,\n chunk_types,\n include_memories,\n include_graph,\n user_id,\n session_id,\n max_tokens,\n });\n\n if (response.results.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No relevant context found.\" }] };\n }\n\n const header = `Found ${response.meta.total} results (${response.meta.latency_ms}ms${response.meta.cache_hit ? \", cached\" : \"\"}):\\n\\n`;\n return { content: [{ type: \"text\" as const, text: header + response.context }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── add_memory ─────────────────────────────────────────────\n\nserver.tool(\n \"add_memory\",\n \"Store a memory (fact, preference, decision) that persists across conversations. Memories can be scoped to a user, session, or agent.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n content: z.string().describe(\"The memory content to store\"),\n memory_type: z.enum([\"factual\", \"preference\", \"event\", \"relationship\", \"opinion\", \"goal\", \"instruction\"]).optional().default(\"factual\"),\n user_id: z.string().optional().describe(\"User this memory belongs to\"),\n session_id: z.string().optional().describe(\"Session scope\"),\n agent_id: z.string().optional().describe(\"Agent scope\"),\n importance: z.number().optional().default(0.5).describe(\"Importance 0-1\"),\n },\n async ({ project, content, memory_type, user_id, session_id, agent_id, importance }) => {\n try {\n const result = await whisper.addMemory({\n project,\n content,\n memory_type,\n user_id,\n session_id,\n agent_id,\n importance,\n });\n\n return { content: [{ type: \"text\" as const, text: `Memory stored (id: ${result.id}, type: ${memory_type}).` }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── search_memories ────────────────────────────────────────\n\nserver.tool(\n \"search_memories\",\n \"Search stored memories by semantic similarity. Recall facts, preferences, past decisions from previous interactions.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n query: z.string().describe(\"What to search for\"),\n user_id: z.string().optional().describe(\"Filter by user\"),\n session_id: z.string().optional().describe(\"Filter by session\"),\n top_k: z.number().optional().default(10).describe(\"Number of results\"),\n memory_types: z.array(z.enum([\"factual\", \"preference\", \"event\", \"relationship\", \"opinion\", \"goal\", \"instruction\"])).optional(),\n },\n async ({ project, query, user_id, session_id, top_k, memory_types }) => {\n try {\n const results = await whisper.searchMemoriesSOTA({\n project,\n query,\n user_id,\n session_id,\n top_k,\n memory_types,\n });\n\n if (!results.memories || results.memories.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No memories found.\" }] };\n }\n\n const text = results.memories\n .map((r: any, i: number) => `${i + 1}. [${r.memory_type}, score: ${r.similarity?.toFixed(3) || 'N/A'}]\\n${r.content}`)\n .join(\"\\n\\n\");\n\n return { content: [{ type: \"text\" as const, text }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── list_projects ──────────────────────────────────────────\n\nserver.tool(\n \"list_projects\",\n \"List all available context projects.\",\n {},\n async () => {\n try {\n const { projects } = await whisper.listProjects();\n const text = projects.length === 0\n ? \"No projects found.\"\n : projects.map((p) => `- ${p.name} (${p.slug})${p.description ? `: ${p.description}` : \"\"}`).join(\"\\n\");\n return { content: [{ type: \"text\" as const, text }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── list_sources ───────────────────────────────────────────\n\nserver.tool(\n \"list_sources\",\n \"List all data sources connected to a project.\",\n { project: z.string().optional().describe(\"Project name or slug\") },\n async ({ project }) => {\n try {\n const projectData = await whisper.getProject(project || DEFAULT_PROJECT);\n const srcs = projectData.sources || [];\n const text = srcs.length === 0\n ? \"No sources connected.\"\n : srcs.map((s: any) => `- ${s.name} (${s.connectorType}) — ${s.status}`).join(\"\\n\");\n return { content: [{ type: \"text\" as const, text }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── add_context ────────────────────────────────────────────\n\nserver.tool(\n \"add_context\",\n \"Add text content to a project's knowledge base.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n title: z.string().describe(\"Title for this content\"),\n content: z.string().describe(\"The text content to index\"),\n },\n async ({ project, title, content }) => {\n try {\n await whisper.addContext({\n project,\n title,\n content,\n });\n return { content: [{ type: \"text\" as const, text: `Indexed \"${title}\" (${content.length} chars).` }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── memory_search_sota ─────────────────────────────────────\n\nserver.tool(\n \"memory_search_sota\",\n \"SOTA memory search with temporal reasoning and relation graphs. Searches memories with support for temporal queries ('what did I say yesterday?'), type filtering, and knowledge graph traversal.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n query: z.string().describe(\"Search query (supports temporal: 'yesterday', 'last week')\"),\n user_id: z.string().optional().describe(\"Filter by user\"),\n session_id: z.string().optional().describe(\"Filter by session\"),\n question_date: z.string().optional().describe(\"ISO datetime for temporal grounding\"),\n memory_types: z.array(z.enum([\"factual\", \"preference\", \"event\", \"relationship\", \"opinion\", \"goal\", \"instruction\"])).optional(),\n top_k: z.number().optional().default(10),\n include_relations: z.boolean().optional().default(true).describe(\"Include related memories via knowledge graph\"),\n },\n async ({ project, query, user_id, session_id, question_date, memory_types, top_k, include_relations }) => {\n try {\n const results = await whisper.searchMemoriesSOTA({\n project,\n query,\n user_id,\n session_id,\n question_date,\n memory_types,\n top_k,\n include_relations,\n });\n\n if (!results.memories || results.memories.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No memories found.\" }] };\n }\n\n const text = results.memories.map((r: any, i: number) => {\n let line = `${i + 1}. [${r.memory_type}, score: ${r.similarity?.toFixed(3) || 'N/A'}]\\n`;\n line += ` ${r.content}\\n`;\n if (r.event_date) {\n line += ` Event: ${new Date(r.event_date).toISOString().split('T')[0]}\\n`;\n }\n return line;\n }).join(\"\\n\");\n\n return { content: [{ type: \"text\" as const, text }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── ingest_conversation ────────────────────────────────────\n\nserver.tool(\n \"ingest_conversation\",\n \"Extract memories from a conversation session. Automatically handles disambiguation, temporal grounding, and relation detection.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n session_id: z.string().describe(\"Session identifier\"),\n user_id: z.string().optional().describe(\"User identifier\"),\n messages: z.array(z.object({\n role: z.string(),\n content: z.string(),\n timestamp: z.string(),\n })).describe(\"Array of conversation messages with timestamps\"),\n },\n async ({ project, session_id, user_id, messages }) => {\n try {\n const result = await whisper.ingestSession({\n project,\n session_id,\n user_id,\n messages,\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text: `Processed ${messages.length} messages:\\n` +\n `- Created ${result.memories_created} memories\\n` +\n `- Detected ${result.relations_created} relations\\n` +\n `- Updated ${result.memories_invalidated} outdated memories` +\n (result.errors && result.errors.length > 0 ? `\\n- Errors: ${result.errors.join(\", \")}` : \"\"),\n }],\n };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── oracle_search ──────────────────────────────────────────\n\nserver.tool(\n \"oracle_search\",\n \"Oracle Research Mode - Tree-guided document navigation with multi-step reasoning. More precise than standard search, especially for bleeding-edge features.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n query: z.string().describe(\"Research question\"),\n mode: z.enum([\"search\", \"research\"]).optional().default(\"search\").describe(\"'search' for tree-guided, 'research' for multi-step reasoning\"),\n max_results: z.number().optional().default(5),\n max_steps: z.number().optional().default(5).describe(\"For research mode: max reasoning steps\"),\n },\n async ({ project, query, mode, max_results, max_steps }) => {\n try {\n const results = await whisper.oracleSearch({\n project,\n query,\n mode,\n max_results,\n max_steps,\n });\n\n if (mode === \"research\" && results.answer) {\n let text = `Answer: ${results.answer}\\n\\nReasoning Steps:\\n`;\n if (results.steps) {\n results.steps.forEach((step: any, i: number) => {\n text += `${i + 1}. Query: ${step.query}\\n Reasoning: ${step.reasoning}\\n Results: ${step.results?.length || 0} items\\n`;\n });\n }\n return { content: [{ type: \"text\" as const, text }] };\n } else {\n if (!results.results || results.results.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No results found.\" }] };\n }\n\n const text = results.results.map((r: any, i: number) =>\n `${i + 1}. [${r.path || r.source}] (relevance: ${r.relevance?.toFixed(3) || r.score?.toFixed(3) || 'N/A'})\\n${r.content.slice(0, 200)}...`\n ).join(\"\\n\\n\");\n\n return { content: [{ type: \"text\" as const, text }] };\n }\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── autosubscribe_dependencies ─────────────────────────────\n\nserver.tool(\n \"autosubscribe_dependencies\",\n \"Automatically index a project's dependencies (package.json, requirements.txt, etc.). Resolves docs URLs and indexes documentation.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n source_type: z.enum([\"github\", \"local\"]).describe(\"Source location\"),\n github_owner: z.string().optional().describe(\"For GitHub: owner/org name\"),\n github_repo: z.string().optional().describe(\"For GitHub: repository name\"),\n local_path: z.string().optional().describe(\"For local: path to dependency file\"),\n dependency_file: z.enum([\"package.json\", \"requirements.txt\", \"Cargo.toml\", \"go.mod\", \"Gemfile\"]).optional(),\n index_limit: z.number().optional().default(20).describe(\"Max dependencies to index\"),\n },\n async ({ project, source_type, github_owner, github_repo, local_path, dependency_file, index_limit }) => {\n try {\n const result = await whisper.autosubscribe({\n project,\n source: source_type === \"github\"\n ? { type: \"github\", owner: github_owner!, repo: github_repo! }\n : { type: \"local\", path: local_path! },\n index_limit,\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text: `Autosubscribe completed:\\n` +\n `- Discovered: ${result.discovered} dependencies\\n` +\n `- Indexed: ${result.indexed} successfully\\n` +\n `- Errors: ${result.errors?.length || 0}`,\n }],\n };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── share_context ──────────────────────────────────────────\n\nserver.tool(\n \"share_context\",\n \"Create a shareable snapshot of a conversation with memories. Returns a URL that can be shared or resumed later.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n session_id: z.string().describe(\"Session to share\"),\n title: z.string().optional().describe(\"Title for the shared context\"),\n expiry_days: z.number().optional().default(30).describe(\"Days until expiry\"),\n },\n async ({ project, session_id, title, expiry_days }) => {\n try {\n const result = await whisper.createSharedContext({\n project,\n session_id,\n title,\n expiry_days,\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text: `Shared context created:\\n` +\n `- Share ID: ${result.share_id}\\n` +\n `- Memories: ${result.memories_count || 0}\\n` +\n `- Messages: ${result.messages_count || 0}\\n` +\n `- Expires: ${result.expires_at || 'Never'}\\n` +\n `\\nShare URL: ${result.share_url}`,\n }],\n };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── consolidate_memories ───────────────────────────────────\n\nserver.tool(\n \"consolidate_memories\",\n \"Find and merge duplicate memories to reduce bloat. Uses vector similarity + LLM merging.\",\n {\n project: z.string().optional().describe(\"Project name or slug\"),\n similarity_threshold: z.number().optional().default(0.95).describe(\"Similarity threshold (0-1)\"),\n dry_run: z.boolean().optional().default(false).describe(\"Preview without merging\"),\n },\n async ({ project, similarity_threshold, dry_run }) => {\n try {\n const result = await whisper.consolidateMemories({\n project,\n similarity_threshold,\n dry_run,\n });\n\n if (dry_run && result.clusters) {\n const totalDuplicates = result.clusters.reduce((sum: number, c: any) => sum + (c.duplicates?.length || 0), 0);\n return {\n content: [{\n type: \"text\" as const,\n text: `Found ${result.clusters.length} duplicate clusters:\\n` +\n `- Total duplicates: ${totalDuplicates}\\n` +\n `- Estimated savings: ${totalDuplicates} memories\\n` +\n `\\nRun without dry_run to merge.`,\n }],\n };\n } else {\n return {\n content: [{\n type: \"text\" as const,\n text: `Consolidation complete:\\n` +\n `- Clusters found: ${result.clusters_found || 0}\\n` +\n `- Memories merged: ${result.memories_merged || 0}\\n` +\n `- Memories deactivated: ${result.memories_deactivated || 0}`,\n }],\n };\n }\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── get_cost_summary ───────────────────────────────────────\n\nserver.tool(\n \"get_cost_summary\",\n \"Get cost tracking summary showing spending by model and task. Includes savings vs always-Opus.\",\n {\n project: z.string().optional().describe(\"Project name or slug (optional for org-wide)\"),\n days: z.number().optional().default(30).describe(\"Time period in days\"),\n },\n async ({ project, days }) => {\n try {\n const endDate = new Date();\n const startDate = new Date(endDate.getTime() - days * 24 * 60 * 60 * 1000);\n\n const summary = await whisper.getCostSummary({\n project,\n start_date: startDate.toISOString(),\n end_date: endDate.toISOString(),\n });\n\n const savings = await whisper.getCostSavings({\n project,\n start_date: startDate.toISOString(),\n end_date: endDate.toISOString(),\n });\n\n let text = `Cost Summary (last ${days} days):\\n\\n`;\n text += `Total Cost: $${savings.actual_cost?.toFixed(2) || '0.00'}\\n`;\n text += `Total Requests: ${summary.total_requests || 0}\\n\\n`;\n text += `Savings vs Always-Opus:\\n`;\n text += `- Actual: $${savings.actual_cost?.toFixed(2) || '0.00'}\\n`;\n text += `- Opus-only: $${savings.opus_cost?.toFixed(2) || '0.00'}\\n`;\n text += `- Saved: $${savings.savings?.toFixed(2) || '0.00'} (${savings.savings_percent?.toFixed(1) || '0'}%)\\n`;\n\n return { content: [{ type: \"text\" as const, text }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── semantic_search_codebase ────────────────────────────────\n// Reads local files, extracts their signatures, sends to the\n// Whisper API for embedding-based semantic ranking.\n// No pre-indexing required. Works on any local codebase.\n\nconst SKIP_DIRS = new Set([\"node_modules\", \".git\", \"dist\", \".next\", \"build\", \"__pycache__\", \".turbo\", \"coverage\", \".cache\"]);\nconst CODE_EXTENSIONS = new Set([\"ts\", \"tsx\", \"js\", \"jsx\", \"py\", \"go\", \"rs\", \"java\", \"cpp\", \"c\", \"cs\", \"rb\", \"php\", \"swift\", \"kt\", \"sql\", \"prisma\", \"graphql\", \"json\", \"yaml\", \"yml\", \"toml\", \"env\"]);\n\n/**\n * Extract a semantic \"signature\" from a file:\n * - File path (very informative on its own)\n * - Imports/requires\n * - Exported function/class/const names\n * - First few lines of each function/class body\n * Kept under ~1500 chars to be efficient for embedding\n */\nfunction extractSignature(filePath: string, content: string): string {\n const lines = content.split(\"\\n\");\n const signature: string[] = [`// File: ${filePath}`];\n\n // Take the first 60 lines (captures imports + top-level declarations)\n const head = lines.slice(0, 60);\n\n for (const line of head) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"//\") || trimmed.startsWith(\"*\")) continue;\n\n // Imports / requires\n if (/^(import|from|require|use |pub use )/.test(trimmed)) {\n signature.push(trimmed.slice(0, 120));\n continue;\n }\n\n // Exports, function/class/interface/type declarations\n if (/^(export|async function|function|class|interface|type |const |let |def |pub fn |fn |struct |impl |enum )/.test(trimmed)) {\n signature.push(trimmed.slice(0, 120));\n continue;\n }\n\n // Decorators / annotations\n if (trimmed.startsWith(\"@\") || trimmed.startsWith(\"#[\")) {\n signature.push(trimmed.slice(0, 80));\n }\n }\n\n // Also scan the rest of the file for function/class names (just the declaration line)\n for (const line of lines.slice(60)) {\n const trimmed = line.trim();\n if (/^(export (default |async )?function|export (default )?class|export const|export type|export interface|async function|function |class |def |pub fn |fn )/.test(trimmed)) {\n signature.push(trimmed.slice(0, 120));\n }\n }\n\n return signature.join(\"\\n\").slice(0, 2000);\n}\n\nserver.tool(\n \"semantic_search_codebase\",\n \"Semantically search a local codebase without pre-indexing. Unlike grep/ripgrep, this understands meaning — so 'find authentication logic' finds auth code even if it doesn't literally say 'auth'. Uses vector embeddings via the Whisper API. Perfect for exploring unfamiliar codebases.\",\n {\n query: z.string().describe(\"Natural language description of what you're looking for. E.g. 'authentication and session management', 'database connection pooling', 'error handling middleware'\"),\n path: z.string().optional().describe(\"Absolute path to the codebase root. Defaults to current working directory.\"),\n file_types: z.array(z.string()).optional().describe(\"Limit to specific extensions e.g. ['ts', 'py']. Defaults to all common code files.\"),\n top_k: z.number().optional().default(10).describe(\"Number of most relevant files to return\"),\n threshold: z.number().optional().default(0.2).describe(\"Minimum similarity score 0-1. Lower = more results but less precise.\"),\n max_files: z.number().optional().default(150).describe(\"Max files to scan. For large codebases, narrow with file_types instead of raising this.\"),\n },\n async ({ query, path: searchPath, file_types, top_k, threshold, max_files }) => {\n const rootPath = searchPath || process.cwd();\n\n // Collect files\n const allowedExts = file_types ? new Set(file_types) : CODE_EXTENSIONS;\n const files: string[] = [];\n\n function collect(dir: string) {\n if (files.length >= (max_files ?? 300)) return;\n let entries;\n try { entries = readdirSync(dir, { withFileTypes: true }); } catch { return; }\n for (const entry of entries) {\n if (files.length >= (max_files ?? 300)) break;\n if (SKIP_DIRS.has(entry.name)) continue;\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n collect(full);\n } else if (entry.isFile()) {\n const ext = extname(entry.name).replace(\".\", \"\");\n if (allowedExts.has(ext)) files.push(full);\n }\n }\n }\n\n collect(rootPath);\n\n if (files.length === 0) {\n return { content: [{ type: \"text\" as const, text: `No code files found in ${rootPath}` }] };\n }\n\n // Extract signatures (lightweight representation of each file)\n const documents: Array<{ id: string; content: string }> = [];\n for (const filePath of files) {\n try {\n const stat = statSync(filePath);\n if (stat.size > 500 * 1024) continue; // skip files >500KB\n const content = readFileSync(filePath, \"utf-8\");\n const relPath = relative(rootPath, filePath);\n const signature = extractSignature(relPath, content);\n documents.push({ id: relPath, content: signature });\n } catch { /* skip unreadable */ }\n }\n\n if (documents.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"Could not read any files.\" }] };\n }\n\n // Send to Whisper API for semantic ranking\n let response: any;\n try {\n response = await whisper.semanticSearch({\n query,\n documents,\n top_k: top_k ?? 10,\n threshold: threshold ?? 0.2,\n });\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Semantic search failed: ${error.message}` }] };\n }\n\n if (!response.results || response.results.length === 0) {\n return { content: [{ type: \"text\" as const, text: `No semantically relevant files found for: \"${query}\"\\n\\nSearched ${documents.length} files in ${rootPath}.\\n\\nTry lowering the threshold or rephrasing your query.` }] };\n }\n\n // Format results — for top matches, also read the actual relevant lines\n const lines: string[] = [\n `Semantic search: \"${query}\"`,\n `Searched ${documents.length} files → ${response.results.length} relevant (${response.latency_ms}ms)\\n`,\n ];\n\n for (const result of response.results) {\n lines.push(`📄 ${result.id} (score: ${result.score})`);\n\n // Show the most relevant part of the signature\n if (result.snippet) {\n lines.push(` ${result.snippet}`);\n }\n\n // For high-confidence results, show actual file content excerpt\n if (result.score > 0.5) {\n try {\n const fullPath = join(rootPath, result.id);\n const content = readFileSync(fullPath, \"utf-8\");\n const excerpt = content.split(\"\\n\").slice(0, 30).join(\"\\n\");\n lines.push(`\\n\\`\\`\\`\\n${excerpt}\\n\\`\\`\\``);\n } catch { /* skip */ }\n }\n\n lines.push(\"\");\n }\n\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n }\n);\n\n// ─── search_files ────────────────────────────────────────────\n\nfunction* walkDir(dir: string, fileTypes?: string[]): Generator<string> {\n let entries;\n try { entries = readdirSync(dir, { withFileTypes: true }); } catch { return; }\n for (const entry of entries) {\n if ([\"node_modules\", \".git\", \"dist\", \".next\", \"build\", \"__pycache__\"].includes(entry.name)) continue;\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* walkDir(full, fileTypes);\n } else if (entry.isFile()) {\n if (!fileTypes || fileTypes.length === 0) yield full;\n else if (fileTypes.includes(extname(entry.name).replace(\".\", \"\"))) yield full;\n }\n }\n}\n\nserver.tool(\n \"search_files\",\n \"Search files and content in a local directory without requiring pre-indexing. Uses ripgrep when available, falls back to Node.js. Great for finding files, functions, patterns, or any text across a codebase instantly.\",\n {\n query: z.string().describe(\"What to search for — natural language keyword, function name, pattern, etc.\"),\n path: z.string().optional().describe(\"Absolute path to search in. Defaults to current working directory.\"),\n mode: z.enum([\"content\", \"filename\", \"both\"]).optional().default(\"both\").describe(\"Search file contents, filenames, or both\"),\n file_types: z.array(z.string()).optional().describe(\"Limit to these file extensions e.g. ['ts', 'js', 'py', 'go']\"),\n max_results: z.number().optional().default(20).describe(\"Max number of matching files to return\"),\n context_lines: z.number().optional().default(2).describe(\"Lines of context around each match\"),\n case_sensitive: z.boolean().optional().default(false),\n },\n async ({ query, path: searchPath, mode, file_types, max_results, context_lines, case_sensitive }) => {\n const rootPath = searchPath || process.cwd();\n const results: Array<{ file: string; matches: Array<{ line: number; content: string; context_before: string[]; context_after: string[] }> }> = [];\n\n // Try ripgrep first\n const rgAvailable = spawnSync(\"rg\", [\"--version\"], { stdio: \"ignore\" }).status === 0;\n\n if (rgAvailable && (mode === \"content\" || mode === \"both\")) {\n try {\n const args = [\n \"--json\",\n case_sensitive ? \"\" : \"-i\",\n `-C`, `${context_lines}`,\n `-m`, `${max_results}`,\n \"--max-filesize\", \"1M\",\n \"--glob\", \"!node_modules\",\n \"--glob\", \"!.git\",\n \"--glob\", \"!dist\",\n \"--glob\", \"!.next\",\n \"--glob\", \"!build\",\n ...(file_types && file_types.length > 0 ? [\"--glob\", file_types.length === 1 ? `*.${file_types[0]}` : `*.{${file_types.join(\",\")}}`] : []),\n query,\n rootPath,\n ].filter(Boolean) as string[];\n\n const output = execSync(`rg ${args.join(\" \")}`, {\n maxBuffer: 10 * 1024 * 1024,\n stdio: [\"pipe\", \"pipe\", \"ignore\"],\n }).toString().trim();\n\n const fileMap = new Map<string, typeof results[0][\"matches\"]>();\n for (const line of output.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line);\n if (entry.type === \"match\") {\n const filePath = relative(rootPath, entry.data.path.text);\n if (!fileMap.has(filePath)) fileMap.set(filePath, []);\n fileMap.get(filePath)!.push({\n line: entry.data.line_number,\n content: entry.data.lines.text.trimEnd(),\n context_before: [],\n context_after: [],\n });\n }\n } catch { /* skip */ }\n }\n for (const [file, matches] of fileMap) {\n if (results.length >= (max_results ?? 20)) break;\n results.push({ file, matches });\n }\n } catch (err: any) {\n if (err.status !== 1) { /* ignore no-match exit code */ }\n }\n }\n\n // Filename search (always Node.js — rg --files piped through grep isn't reliable cross-platform)\n if (mode === \"filename\" || mode === \"both\") {\n const queryLower = query.toLowerCase();\n const existingFiles = new Set(results.map(r => r.file));\n for (const filePath of walkDir(rootPath, file_types)) {\n if (results.length >= (max_results ?? 20)) break;\n const relPath = relative(rootPath, filePath);\n const check = case_sensitive ? relPath : relPath.toLowerCase();\n if (check.includes(case_sensitive ? query : queryLower) && !existingFiles.has(relPath)) {\n results.push({ file: relPath, matches: [] });\n existingFiles.add(relPath);\n }\n }\n }\n\n // Node.js content fallback if no ripgrep\n if (!rgAvailable && (mode === \"content\" || mode === \"both\")) {\n const regex = new RegExp(query.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), case_sensitive ? \"g\" : \"gi\");\n for (const filePath of walkDir(rootPath, file_types)) {\n if (results.length >= (max_results ?? 20)) break;\n try {\n const stat = statSync(filePath);\n if (stat.size > 512 * 1024) continue;\n const text = readFileSync(filePath, \"utf-8\");\n const lines = text.split(\"\\n\");\n const matches: typeof results[0][\"matches\"] = [];\n lines.forEach((line, i) => {\n regex.lastIndex = 0;\n if (regex.test(line)) {\n matches.push({\n line: i + 1,\n content: line.trimEnd(),\n context_before: lines.slice(Math.max(0, i - (context_lines ?? 2)), i).map(l => l.trimEnd()),\n context_after: lines.slice(i + 1, i + 1 + (context_lines ?? 2)).map(l => l.trimEnd()),\n });\n regex.lastIndex = 0;\n }\n });\n if (matches.length > 0) results.push({ file: relative(rootPath, filePath), matches });\n } catch { /* skip unreadable */ }\n }\n }\n\n if (results.length === 0) {\n return { content: [{ type: \"text\" as const, text: `No results found for \"${query}\" in ${rootPath}` }] };\n }\n\n const totalMatches = results.reduce((s, r) => s + r.matches.length, 0);\n const lines: string[] = [\n `Found ${results.length} file(s), ${totalMatches} match(es) for \"${query}\" in ${rootPath}\\n`,\n ];\n\n for (const result of results) {\n lines.push(`📄 ${result.file}`);\n for (const match of result.matches.slice(0, 5)) {\n if (match.context_before.length > 0) {\n lines.push(...match.context_before.map(l => ` ${l}`));\n }\n lines.push(`→ L${match.line}: ${match.content}`);\n if (match.context_after.length > 0) {\n lines.push(...match.context_after.map(l => ` ${l}`));\n }\n }\n if (result.matches.length > 5) {\n lines.push(` ... and ${result.matches.length - 5} more matches`);\n }\n lines.push(\"\");\n }\n\n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n }\n);\n\n// ─── Semantic Search ────────────────────────────────────────\n\nserver.tool(\n \"semantic_search\",\n \"Semantic vector search over provided documents. Uses embeddings to find semantically similar content. Perfect for AI code search, finding similar functions, or searching by meaning rather than keywords.\",\n {\n query: z.string().describe(\"What to search for semantically (e.g. 'authentication logic', 'database connection')\"),\n documents: z.array(z.object({\n id: z.string().describe(\"Unique identifier (file path, URL, or any ID)\"),\n content: z.string().describe(\"The text content to search in\"),\n })).describe(\"Documents to search over\"),\n top_k: z.number().optional().default(5).describe(\"Number of results to return\"),\n threshold: z.number().optional().default(0.3).describe(\"Minimum similarity score 0-1\"),\n },\n async ({ query, documents, top_k, threshold }) => {\n try {\n const API_KEY = process.env.WHISPER_API_KEY;\n const BASE_URL = process.env.WHISPER_API_BASE_URL || 'https://context.usewhisper.dev';\n \n const res = await fetch(`${BASE_URL}/v1/search/semantic`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${API_KEY}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ query, documents, top_k, threshold }),\n });\n \n const data = await res.json();\n \n if (data.error) {\n return { content: [{ type: \"text\" as const, text: `Error: ${data.error}` }] };\n }\n \n if (!data.results || data.results.length === 0) {\n return { content: [{ type: \"text\" as const, text: \"No semantically similar results found.\" }] };\n }\n \n const lines = [`Found ${data.results.length} semantically similar results:\\n`];\n for (const r of data.results) {\n lines.push(`📄 ${r.id} (score: ${r.score.toFixed(3)})`);\n lines.push(` ${r.content.slice(0, 200)}${r.content.length > 200 ? '...' : ''}`);\n lines.push(\"\");\n }\n \n return { content: [{ type: \"text\" as const, text: lines.join(\"\\n\") }] };\n } catch (error: any) {\n return { content: [{ type: \"text\" as const, text: `Error: ${error.message}` }] };\n }\n }\n);\n\n// ─── Start ──────────────────────────────────────────────────\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Whisper Context MCP server running on stdio\");\n}\n\nmain().catch(console.error);\n","/**\n * Whisper Context SDK\n * TypeScript SDK for the Whisper Context API\n */\n\nexport interface WhisperConfig {\n apiKey: string;\n baseUrl?: string;\n project?: string;\n orgId?: string;\n timeoutMs?: number;\n retry?: {\n maxAttempts?: number;\n baseDelayMs?: number;\n maxDelayMs?: number;\n };\n}\n\nexport interface QueryParams {\n project?: string;\n query: string;\n top_k?: number;\n threshold?: number;\n chunk_types?: string[];\n source_ids?: string[];\n hybrid?: boolean;\n vector_weight?: number;\n bm25_weight?: number;\n rerank?: boolean;\n include_memories?: boolean;\n user_id?: string;\n session_id?: string;\n agent_id?: string;\n include_graph?: boolean;\n graph_depth?: number;\n max_tokens?: number;\n compress?: boolean;\n compression_strategy?: \"summarize\" | \"extract\" | \"delta\" | \"adaptive\";\n use_cache?: boolean;\n}\n\nexport interface QueryResult {\n results: Array<{\n id: string;\n content: string;\n score: number;\n metadata: Record<string, any>;\n source: string;\n document: string;\n type: string;\n retrieval_source: string;\n }>;\n context: string;\n meta: {\n query: string;\n total: number;\n latency_ms: number;\n cache_hit: boolean;\n tokens_used: number;\n context_hash: string;\n compression?: any;\n };\n}\n\nexport interface Project {\n id: string;\n orgId: string;\n name: string;\n slug: string;\n description?: string;\n settings?: Record<string, any>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface Source {\n id: string;\n projectId: string;\n name: string;\n connectorType: string;\n config: Record<string, any>;\n status: string;\n syncSchedule?: string;\n lastSyncAt?: string;\n syncError?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface Memory {\n id: string;\n projectId: string;\n content: string;\n memoryType: \"factual\" | \"episodic\" | \"semantic\" | \"procedural\";\n userId?: string;\n sessionId?: string;\n agentId?: string;\n importance: number;\n metadata: Record<string, any>;\n accessCount: number;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type WhisperErrorCode =\n | \"INVALID_API_KEY\"\n | \"PROJECT_NOT_FOUND\"\n | \"PROJECT_AMBIGUOUS\"\n | \"RATE_LIMITED\"\n | \"TEMPORARY_UNAVAILABLE\"\n | \"NETWORK_ERROR\"\n | \"TIMEOUT\"\n | \"REQUEST_FAILED\"\n | \"MISSING_PROJECT\";\n\nexport class WhisperError extends Error {\n code: WhisperErrorCode;\n status?: number;\n retryable: boolean;\n details?: unknown;\n\n constructor(args: {\n code: WhisperErrorCode;\n message: string;\n status?: number;\n retryable?: boolean;\n details?: unknown;\n }) {\n super(args.message);\n this.name = \"WhisperError\";\n this.code = args.code;\n this.status = args.status;\n this.retryable = args.retryable ?? false;\n this.details = args.details;\n }\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3;\nconst DEFAULT_BASE_DELAY_MS = 250;\nconst DEFAULT_MAX_DELAY_MS = 2_000;\nconst DEFAULT_TIMEOUT_MS = 15_000;\nconst PROJECT_CACHE_TTL_MS = 30_000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction getBackoffDelay(attempt: number, base: number, max: number): number {\n const jitter = 0.8 + Math.random() * 0.4;\n return Math.min(max, Math.floor(base * Math.pow(2, attempt) * jitter));\n}\n\nfunction isLikelyProjectId(projectRef: string): boolean {\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(projectRef);\n}\n\nexport class WhisperContext {\n private apiKey: string;\n private baseUrl: string;\n private defaultProject?: string;\n private orgId?: string;\n private timeoutMs: number;\n private retryConfig: Required<NonNullable<WhisperConfig[\"retry\"]>>;\n\n private projectRefToId = new Map<string, string>();\n private projectCache: Project[] = [];\n private projectCacheExpiresAt = 0;\n\n constructor(config: WhisperConfig) {\n if (!config.apiKey) {\n throw new WhisperError({\n code: \"INVALID_API_KEY\",\n message: \"API key is required\",\n });\n }\n\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://context.usewhisper.dev\";\n this.defaultProject = config.project;\n this.orgId = config.orgId;\n this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.retryConfig = {\n maxAttempts: config.retry?.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,\n baseDelayMs: config.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS,\n maxDelayMs: config.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,\n };\n }\n\n withProject(project: string): WhisperContext {\n return new WhisperContext({\n apiKey: this.apiKey,\n baseUrl: this.baseUrl,\n project,\n orgId: this.orgId,\n timeoutMs: this.timeoutMs,\n retry: this.retryConfig,\n });\n }\n\n private getRequiredProject(project?: string): string {\n const resolved = project || this.defaultProject;\n if (!resolved) {\n throw new WhisperError({\n code: \"MISSING_PROJECT\",\n message: \"Project is required. Pass project in params or set a default project in WhisperContext config.\",\n });\n }\n return resolved;\n }\n\n private async refreshProjectCache(force = false): Promise<Project[]> {\n if (!force && Date.now() < this.projectCacheExpiresAt && this.projectCache.length > 0) {\n return this.projectCache;\n }\n\n const response = await this.request<{ projects: Project[] }>(\"/v1/projects\", { method: \"GET\" });\n this.projectRefToId.clear();\n this.projectCache = response.projects || [];\n\n for (const p of this.projectCache) {\n this.projectRefToId.set(p.id, p.id);\n this.projectRefToId.set(p.slug, p.id);\n this.projectRefToId.set(p.name, p.id);\n }\n\n this.projectCacheExpiresAt = Date.now() + PROJECT_CACHE_TTL_MS;\n return this.projectCache;\n }\n\n private async resolveProjectId(projectRef: string): Promise<string> {\n if (this.projectRefToId.has(projectRef)) {\n return this.projectRefToId.get(projectRef)!;\n }\n\n const projects = await this.refreshProjectCache(true);\n\n const byDirect = projects.find((p) => p.id === projectRef);\n if (byDirect) return byDirect.id;\n\n const matches = projects.filter((p) => p.slug === projectRef || p.name === projectRef);\n\n if (matches.length === 1) {\n return matches[0].id;\n }\n\n if (matches.length > 1) {\n throw new WhisperError({\n code: \"PROJECT_AMBIGUOUS\",\n message: `Project reference '${projectRef}' matched multiple projects. Use project id instead.`,\n });\n }\n\n if (isLikelyProjectId(projectRef)) {\n return projectRef;\n }\n\n throw new WhisperError({\n code: \"PROJECT_NOT_FOUND\",\n message: `Project '${projectRef}' not found`,\n });\n }\n\n private async getProjectRefCandidates(projectRef: string): Promise<string[]> {\n const candidates = new Set<string>([projectRef]);\n\n try {\n const projects = await this.refreshProjectCache(false);\n const match = projects.find((p) => p.id === projectRef || p.slug === projectRef || p.name === projectRef);\n if (match) {\n candidates.add(match.id);\n candidates.add(match.slug);\n candidates.add(match.name);\n } else if (isLikelyProjectId(projectRef)) {\n const byId = projects.find((p) => p.id === projectRef);\n if (byId) {\n candidates.add(byId.slug);\n candidates.add(byId.name);\n }\n }\n } catch {\n // Keep original project reference if listing projects fails.\n }\n\n return Array.from(candidates).filter(Boolean);\n }\n\n private async withProjectRefFallback<T>(\n projectRef: string,\n execute: (project: string) => Promise<T>\n ): Promise<T> {\n const refs = await this.getProjectRefCandidates(projectRef);\n let lastError: unknown;\n\n for (const ref of refs) {\n try {\n return await execute(ref);\n } catch (error) {\n lastError = error;\n if (error instanceof WhisperError && error.code === \"PROJECT_NOT_FOUND\") {\n continue;\n }\n throw error;\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError;\n }\n\n throw new WhisperError({\n code: \"PROJECT_NOT_FOUND\",\n message: `Project '${projectRef}' not found`,\n });\n }\n\n private classifyError(status: number | undefined, message: string): { code: WhisperErrorCode; retryable: boolean } {\n if (status === 401 || /api key|unauthorized|forbidden/i.test(message)) {\n return { code: \"INVALID_API_KEY\", retryable: false };\n }\n if (status === 404 || /project not found/i.test(message)) {\n return { code: \"PROJECT_NOT_FOUND\", retryable: false };\n }\n if (status === 408) {\n return { code: \"TIMEOUT\", retryable: true };\n }\n if (status === 429) {\n return { code: \"RATE_LIMITED\", retryable: true };\n }\n if (status !== undefined && status >= 500) {\n return { code: \"TEMPORARY_UNAVAILABLE\", retryable: true };\n }\n return { code: \"REQUEST_FAILED\", retryable: false };\n }\n\n private async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {\n const maxAttempts = Math.max(1, this.retryConfig.maxAttempts);\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(`${this.baseUrl}${endpoint}`, {\n ...options,\n signal: controller.signal,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n ...(this.orgId ? { \"X-Whisper-Org-Id\": this.orgId } : {}),\n ...options.headers,\n },\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n let payload: any = null;\n try {\n payload = await response.json();\n } catch {\n payload = await response.text().catch(() => \"\");\n }\n\n const message = typeof payload === \"string\"\n ? payload\n : payload?.error || payload?.message || `HTTP ${response.status}: ${response.statusText}`;\n\n const { code, retryable } = this.classifyError(response.status, message);\n const err = new WhisperError({\n code,\n message,\n status: response.status,\n retryable,\n details: payload,\n });\n\n if (!retryable || attempt === maxAttempts - 1) {\n throw err;\n }\n\n await sleep(getBackoffDelay(attempt, this.retryConfig.baseDelayMs, this.retryConfig.maxDelayMs));\n continue;\n }\n\n return response.json() as Promise<T>;\n } catch (error: any) {\n clearTimeout(timeout);\n\n const isAbort = error?.name === \"AbortError\";\n const mapped = error instanceof WhisperError\n ? error\n : new WhisperError({\n code: isAbort ? \"TIMEOUT\" : \"NETWORK_ERROR\",\n message: isAbort ? \"Request timed out\" : (error?.message || \"Network request failed\"),\n retryable: true,\n details: error,\n });\n\n lastError = mapped;\n\n if (!mapped.retryable || attempt === maxAttempts - 1) {\n throw mapped;\n }\n\n await sleep(getBackoffDelay(attempt, this.retryConfig.baseDelayMs, this.retryConfig.maxDelayMs));\n }\n }\n\n throw (lastError instanceof Error ? lastError : new WhisperError({ code: \"REQUEST_FAILED\", message: \"Request failed\" }));\n }\n\n async query(params: QueryParams): Promise<QueryResult> {\n const projectRef = this.getRequiredProject(params.project);\n return this.withProjectRefFallback(projectRef, (project) => this.request<QueryResult>(\"/v1/context/query\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n }));\n }\n\n async createProject(params: {\n name: string;\n description?: string;\n settings?: Record<string, any>;\n }): Promise<Project> {\n const project = await this.request<Project>(\"/v1/projects\", {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n\n this.projectRefToId.set(project.id, project.id);\n this.projectRefToId.set(project.slug, project.id);\n this.projectRefToId.set(project.name, project.id);\n this.projectCache = [\n ...this.projectCache.filter((p) => p.id !== project.id),\n project,\n ];\n this.projectCacheExpiresAt = Date.now() + PROJECT_CACHE_TTL_MS;\n\n return project;\n }\n\n async listProjects(): Promise<{ projects: Project[] }> {\n const projects = await this.request<{ projects: Project[] }>(\"/v1/projects\", { method: \"GET\" });\n this.projectCache = projects.projects || [];\n for (const p of projects.projects || []) {\n this.projectRefToId.set(p.id, p.id);\n this.projectRefToId.set(p.slug, p.id);\n this.projectRefToId.set(p.name, p.id);\n }\n this.projectCacheExpiresAt = Date.now() + PROJECT_CACHE_TTL_MS;\n return projects;\n }\n\n async getProject(id: string): Promise<Project & { sources: Source[] }> {\n const projectId = await this.resolveProjectId(id);\n return this.request<Project & { sources: Source[] }>(`/v1/projects/${projectId}`);\n }\n\n async deleteProject(id: string): Promise<{ deleted: boolean }> {\n const projectId = await this.resolveProjectId(id);\n return this.request<{ deleted: boolean }>(`/v1/projects/${projectId}`, { method: \"DELETE\" });\n }\n\n async addSource(\n projectId: string,\n params: {\n name: string;\n connector_type: string;\n config: Record<string, any>;\n sync_schedule?: string;\n }\n ): Promise<Source> {\n const resolvedProjectId = await this.resolveProjectId(projectId);\n return this.request<Source>(`/v1/projects/${resolvedProjectId}/sources`, {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n }\n\n async syncSource(sourceId: string): Promise<any> {\n return this.request(`/v1/sources/${sourceId}/sync`, { method: \"POST\" });\n }\n\n async ingest(\n projectId: string,\n documents: Array<{\n id?: string;\n title: string;\n content: string;\n metadata?: Record<string, any>;\n file_path?: string;\n }>\n ): Promise<{ ingested: number }> {\n const resolvedProjectId = await this.resolveProjectId(projectId);\n return this.request<{ ingested: number }>(`/v1/projects/${resolvedProjectId}/ingest`, {\n method: \"POST\",\n body: JSON.stringify({ documents }),\n });\n }\n\n async addContext(params: {\n project?: string;\n content: string;\n title?: string;\n metadata?: Record<string, any>;\n }): Promise<{ ingested: number }> {\n const projectId = await this.resolveProjectId(this.getRequiredProject(params.project));\n return this.ingest(projectId, [\n {\n title: params.title || \"Context\",\n content: params.content,\n metadata: params.metadata || { source: \"addContext\" },\n },\n ]);\n }\n\n async addMemory(params: {\n project?: string;\n content: string;\n memory_type?:\n | \"factual\"\n | \"episodic\"\n | \"semantic\"\n | \"procedural\"\n | \"preference\"\n | \"event\"\n | \"relationship\"\n | \"opinion\"\n | \"goal\"\n | \"instruction\";\n user_id?: string;\n session_id?: string;\n agent_id?: string;\n importance?: number;\n metadata?: Record<string, any>;\n expires_in_seconds?: number;\n allow_legacy_fallback?: boolean;\n }): Promise<{ id: string; success: boolean; path: \"sota\" | \"legacy\"; fallback_used: boolean }> {\n const projectRef = this.getRequiredProject(params.project);\n return this.withProjectRefFallback(projectRef, async (project) => {\n const toSotaType = (\n memoryType: typeof params.memory_type\n ): \"factual\" | \"preference\" | \"event\" | \"relationship\" | \"opinion\" | \"goal\" | \"instruction\" | undefined => {\n switch (memoryType) {\n case \"episodic\":\n return \"event\";\n case \"semantic\":\n return \"factual\";\n case \"procedural\":\n return \"instruction\";\n default:\n return memoryType;\n }\n };\n\n const toLegacyType = (\n memoryType: typeof params.memory_type\n ): \"factual\" | \"episodic\" | \"semantic\" | \"procedural\" | undefined => {\n switch (memoryType) {\n case \"event\":\n return \"episodic\";\n case \"instruction\":\n return \"procedural\";\n case \"preference\":\n case \"relationship\":\n case \"opinion\":\n case \"goal\":\n return \"semantic\";\n default:\n return memoryType as \"factual\" | \"episodic\" | \"semantic\" | \"procedural\" | undefined;\n }\n };\n\n // SOTA is default path.\n try {\n const direct = await this.request<any>(\"/v1/memory\", {\n method: \"POST\",\n body: JSON.stringify({\n project,\n content: params.content,\n memory_type: toSotaType(params.memory_type),\n user_id: params.user_id,\n session_id: params.session_id,\n agent_id: params.agent_id,\n importance: params.importance,\n metadata: params.metadata,\n }),\n });\n\n const id = direct?.memory?.id || direct?.id || direct?.memory_id;\n if (id) {\n return { id, success: true, path: \"sota\", fallback_used: false };\n }\n } catch (error) {\n if (params.allow_legacy_fallback === false) {\n throw error;\n }\n }\n\n // Legacy fallback for compatibility with older deployments.\n const legacy = await this.request<any>(\"/v1/memories\", {\n method: \"POST\",\n body: JSON.stringify({\n project,\n content: params.content,\n memory_type: toLegacyType(params.memory_type),\n user_id: params.user_id,\n session_id: params.session_id,\n agent_id: params.agent_id,\n importance: params.importance,\n metadata: params.metadata,\n expires_in_seconds: params.expires_in_seconds,\n }),\n });\n\n const id = legacy?.memory?.id || legacy?.id || legacy?.memory_id;\n if (!id) {\n throw new WhisperError({\n code: \"REQUEST_FAILED\",\n message: \"Memory create succeeded but no memory id was returned by the API\",\n });\n }\n\n return { id, success: true, path: \"legacy\", fallback_used: true };\n });\n }\n\n async searchMemories(params: {\n project?: string;\n query: string;\n user_id?: string;\n session_id?: string;\n agent_id?: string;\n memory_type?: \"factual\" | \"preference\" | \"event\" | \"relationship\" | \"opinion\" | \"goal\" | \"instruction\";\n top_k?: number;\n }): Promise<any> {\n const projectRef = this.getRequiredProject(params.project);\n return this.withProjectRefFallback(projectRef, (project) => this.request(\"/v1/memory/search\", {\n method: \"POST\",\n body: JSON.stringify({\n query: params.query,\n project,\n user_id: params.user_id,\n session_id: params.session_id,\n memory_types: params.memory_type ? [params.memory_type] : undefined,\n top_k: params.top_k || 10,\n }),\n }));\n }\n\n async createApiKey(params: {\n name: string;\n scopes?: string[];\n rate_limit?: number;\n expires_in_days?: number;\n }): Promise<{ key: string; prefix: string; name: string }> {\n return this.request(\"/v1/keys\", {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n }\n\n async listApiKeys(): Promise<{ keys: any[] }> {\n return this.request<{ keys: any[] }>(\"/v1/keys\");\n }\n\n async getUsage(days = 30): Promise<any> {\n return this.request(`/v1/usage?days=${days}`);\n }\n\n async searchMemoriesSOTA(params: {\n query: string;\n project?: string;\n user_id?: string;\n session_id?: string;\n question_date?: string;\n top_k?: number;\n memory_types?: Array<\"factual\" | \"preference\" | \"event\" | \"relationship\" | \"opinion\" | \"goal\" | \"instruction\">;\n include_inactive?: boolean;\n include_chunks?: boolean;\n include_relations?: boolean;\n }): Promise<any> {\n const projectRef = this.getRequiredProject(params.project);\n return this.withProjectRefFallback(projectRef, (project) => this.request(\"/v1/memory/search\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n }));\n }\n\n async ingestSession(params: {\n project?: string;\n session_id: string;\n user_id?: string;\n messages: Array<{\n role: string;\n content: string;\n timestamp: string;\n }>;\n }): Promise<{\n success: boolean;\n memories_created: number;\n relations_created: number;\n memories_invalidated: number;\n errors?: string[];\n }> {\n const projectRef = this.getRequiredProject(params.project);\n return this.withProjectRefFallback(projectRef, (project) => this.request(\"/v1/memory/ingest/session\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n }));\n }\n\n async getSessionMemories(params: {\n session_id: string;\n project?: string;\n limit?: number;\n since_date?: string;\n }): Promise<{ memories: any[]; count: number }> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n const query = new URLSearchParams({\n project,\n ...(params.limit && { limit: params.limit.toString() }),\n ...(params.since_date && { since_date: params.since_date }),\n });\n return this.request(`/v1/memory/session/${params.session_id}?${query}`);\n }\n\n async getUserProfile(params: {\n user_id: string;\n project?: string;\n memory_types?: string;\n }): Promise<{ user_id: string; memories: any[]; count: number }> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n const query = new URLSearchParams({\n project,\n ...(params.memory_types && { memory_types: params.memory_types }),\n });\n return this.request(`/v1/memory/profile/${params.user_id}?${query}`);\n }\n\n async getMemoryVersions(memoryId: string): Promise<{ memory_id: string; versions: any[]; count: number }> {\n return this.request(`/v1/memory/${memoryId}/versions`);\n }\n\n async updateMemory(\n memoryId: string,\n params: { content: string; reasoning?: string }\n ): Promise<{ success: boolean; new_memory_id: string; old_memory_id: string }> {\n return this.request(`/v1/memory/${memoryId}`, {\n method: \"PUT\",\n body: JSON.stringify(params),\n });\n }\n\n async deleteMemory(memoryId: string): Promise<{ success: boolean; deleted: string }> {\n return this.request(`/v1/memory/${memoryId}`, { method: \"DELETE\" });\n }\n\n async getMemoryRelations(memoryId: string): Promise<{ memory_id: string; relations: any[]; count: number }> {\n return this.request(`/v1/memory/${memoryId}/relations`);\n }\n\n async oracleSearch(params: {\n query: string;\n project?: string;\n max_results?: number;\n mode?: \"search\" | \"research\";\n max_steps?: number;\n }): Promise<any> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n return this.request(\"/v1/oracle/search\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n });\n }\n\n async autosubscribe(params: {\n project?: string;\n source: {\n type: \"github\" | \"local\";\n owner?: string;\n repo?: string;\n path?: string;\n };\n dependency_file?: \"package.json\" | \"requirements.txt\" | \"Cargo.toml\" | \"go.mod\" | \"Gemfile\";\n index_limit?: number;\n auto_sync?: boolean;\n }): Promise<{\n success: boolean;\n discovered: number;\n indexed: number;\n errors: string[];\n dependencies?: any[];\n auto_sync_enabled: boolean;\n }> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n return this.request(\"/v1/autosubscribe\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n });\n }\n\n async createSharedContext(params: {\n session_id: string;\n project?: string;\n title?: string;\n include_memories?: boolean;\n include_chunks?: boolean;\n expiry_days?: number;\n }): Promise<{\n success: boolean;\n share_id: string;\n share_url: string;\n title: string;\n memories_count: number;\n messages_count: number;\n expires_at: string;\n }> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n return this.request(\"/v1/context/share\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n });\n }\n\n async loadSharedContext(shareId: string): Promise<{\n share_id: string;\n title: string;\n created_at: string;\n expires_at: string;\n memories: any[];\n messages: any[];\n chunks?: any[];\n metadata: any;\n }> {\n return this.request(`/v1/context/shared/${shareId}`);\n }\n\n async resumeFromSharedContext(params: {\n share_id: string;\n project?: string;\n new_session_id?: string;\n }): Promise<{\n success: boolean;\n session_id: string;\n memories_restored: number;\n messages_restored: number;\n chunks_restored: number;\n }> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n return this.request(\"/v1/context/resume\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n });\n }\n\n async consolidateMemories(params: {\n project?: string;\n similarity_threshold?: number;\n auto_merge?: boolean;\n dry_run?: boolean;\n }): Promise<any> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n return this.request(\"/v1/memory/consolidate\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n });\n }\n\n async updateImportanceDecay(params: {\n project?: string;\n decay_function?: \"exponential\" | \"linear\" | \"logarithmic\";\n half_life_days?: number;\n access_boost?: number;\n auto_archive?: boolean;\n archive_threshold?: number;\n }): Promise<{\n success: boolean;\n memories_updated: number;\n average_importance: number;\n memories_archived: number;\n config: any;\n }> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n return this.request(\"/v1/memory/decay/update\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n });\n }\n\n async getImportanceStats(project?: string): Promise<{ project_id: string; statistics: any }> {\n const resolvedProject = await this.resolveProjectId(this.getRequiredProject(project));\n return this.request(`/v1/memory/decay/stats?project=${resolvedProject}`);\n }\n\n async getCacheStats(): Promise<{\n cache_type: string;\n hit_rate: number;\n total_requests: number;\n hits: number;\n misses: number;\n size_bytes: number;\n keys_count: number;\n average_latency_ms: number;\n uptime_seconds: number;\n }> {\n return this.request(\"/v1/cache/stats\");\n }\n\n async warmCache(params: {\n project?: string;\n queries: string[];\n ttl_seconds?: number;\n }): Promise<{\n success: boolean;\n queries_warmed: number;\n errors: string[];\n cache_size_increase_bytes: number;\n }> {\n const project = await this.resolveProjectId(this.getRequiredProject(params.project));\n return this.request(\"/v1/cache/warm\", {\n method: \"POST\",\n body: JSON.stringify({ ...params, project }),\n });\n }\n\n async clearCache(params: {\n pattern?: string;\n clear_all?: boolean;\n }): Promise<{ success: boolean; keys_cleared: number; bytes_freed: number }> {\n return this.request(\"/v1/cache/clear\", {\n method: \"DELETE\",\n body: JSON.stringify(params),\n });\n }\n\n async getCostSummary(params: {\n project?: string;\n start_date?: string;\n end_date?: string;\n } = {}): Promise<any> {\n const resolvedProject = params.project ? await this.resolveProjectId(params.project) : undefined;\n const query = new URLSearchParams({\n ...(resolvedProject && { project: resolvedProject }),\n ...(params.start_date && { start_date: params.start_date }),\n ...(params.end_date && { end_date: params.end_date }),\n });\n return this.request(`/v1/cost/summary?${query}`);\n }\n\n async getCostBreakdown(params: {\n project?: string;\n group_by?: \"model\" | \"task\" | \"day\" | \"hour\";\n start_date?: string;\n end_date?: string;\n } = {}): Promise<any> {\n const resolvedProject = params.project ? await this.resolveProjectId(params.project) : undefined;\n const query = new URLSearchParams({\n ...(resolvedProject && { project: resolvedProject }),\n ...(params.group_by && { group_by: params.group_by }),\n ...(params.start_date && { start_date: params.start_date }),\n ...(params.end_date && { end_date: params.end_date }),\n });\n return this.request(`/v1/cost/breakdown?${query}`);\n }\n\n /**\n * Semantic search over raw documents without pre-indexing.\n * Send file contents/summaries directly — the API embeds them in-memory and ranks by similarity.\n * Perfect for AI agents to semantically explore a codebase on-the-fly.\n */\n async semanticSearch(params: {\n query: string;\n documents: Array<{ id: string; content: string }>;\n top_k?: number;\n threshold?: number;\n }): Promise<{\n results: Array<{\n id: string;\n score: number;\n content: string;\n snippet: string;\n }>;\n total_searched: number;\n total_returned: number;\n query: string;\n latency_ms: number;\n }> {\n return this.request(\"/v1/search/semantic\", {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n }\n\n async searchFiles(params: {\n query: string;\n path?: string;\n mode?: \"content\" | \"filename\" | \"both\";\n file_types?: string[];\n max_results?: number;\n context_lines?: number;\n case_sensitive?: boolean;\n }): Promise<{\n results: Array<{\n file: string;\n matches: Array<{\n line: number;\n content: string;\n context_before: string[];\n context_after: string[];\n }>;\n }>;\n total_files: number;\n total_matches: number;\n search_path: string;\n mode: string;\n latency_ms: number;\n engine: \"ripgrep\" | \"node\";\n }> {\n return this.request(\"/v1/search/files\", {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n }\n\n async getCostSavings(params: {\n project?: string;\n start_date?: string;\n end_date?: string;\n } = {}): Promise<any> {\n const resolvedProject = params.project ? await this.resolveProjectId(params.project) : undefined;\n const query = new URLSearchParams({\n ...(resolvedProject && { project: resolvedProject }),\n ...(params.start_date && { start_date: params.start_date }),\n ...(params.end_date && { end_date: params.end_date }),\n });\n return this.request(`/v1/cost/savings?${query}`);\n }\n\n // Backward-compatible grouped namespaces.\n readonly projects = {\n create: (params: { name: string; description?: string; settings?: Record<string, any> }) => this.createProject(params),\n list: () => this.listProjects(),\n get: (id: string) => this.getProject(id),\n delete: (id: string) => this.deleteProject(id),\n };\n\n readonly sources = {\n add: (\n projectId: string,\n params: { name: string; connector_type: string; config: Record<string, any>; sync_schedule?: string }\n ) => this.addSource(projectId, params),\n sync: (sourceId: string) => this.syncSource(sourceId),\n syncSource: (sourceId: string) => this.syncSource(sourceId),\n };\n\n readonly memory = {\n add: (params: Parameters<WhisperContext[\"addMemory\"]>[0]) => this.addMemory(params),\n search: (params: Parameters<WhisperContext[\"searchMemories\"]>[0]) => this.searchMemories(params),\n searchSOTA: (params: Parameters<WhisperContext[\"searchMemoriesSOTA\"]>[0]) => this.searchMemoriesSOTA(params),\n ingestSession: (params: Parameters<WhisperContext[\"ingestSession\"]>[0]) => this.ingestSession(params),\n getSessionMemories: (params: Parameters<WhisperContext[\"getSessionMemories\"]>[0]) => this.getSessionMemories(params),\n getUserProfile: (params: Parameters<WhisperContext[\"getUserProfile\"]>[0]) => this.getUserProfile(params),\n getVersions: (memoryId: string) => this.getMemoryVersions(memoryId),\n update: (memoryId: string, params: Parameters<WhisperContext[\"updateMemory\"]>[1]) => this.updateMemory(memoryId, params),\n delete: (memoryId: string) => this.deleteMemory(memoryId),\n getRelations: (memoryId: string) => this.getMemoryRelations(memoryId),\n consolidate: (params: Parameters<WhisperContext[\"consolidateMemories\"]>[0]) => this.consolidateMemories(params),\n updateDecay: (params: Parameters<WhisperContext[\"updateImportanceDecay\"]>[0]) => this.updateImportanceDecay(params),\n getImportanceStats: (project?: string) => this.getImportanceStats(project),\n };\n\n readonly keys = {\n create: (params: Parameters<WhisperContext[\"createApiKey\"]>[0]) => this.createApiKey(params),\n list: () => this.listApiKeys(),\n getUsage: (days?: number) => this.getUsage(days),\n };\n\n readonly oracle = {\n search: (params: Parameters<WhisperContext[\"oracleSearch\"]>[0]) => this.oracleSearch(params),\n };\n\n readonly context = {\n createShare: (params: Parameters<WhisperContext[\"createSharedContext\"]>[0]) => this.createSharedContext(params),\n loadShare: (shareId: string) => this.loadSharedContext(shareId),\n resumeShare: (params: Parameters<WhisperContext[\"resumeFromSharedContext\"]>[0]) => this.resumeFromSharedContext(params),\n };\n\n readonly optimization = {\n getCacheStats: () => this.getCacheStats(),\n warmCache: (params: Parameters<WhisperContext[\"warmCache\"]>[0]) => this.warmCache(params),\n clearCache: (params: Parameters<WhisperContext[\"clearCache\"]>[0]) => this.clearCache(params),\n getCostSummary: (params?: Parameters<WhisperContext[\"getCostSummary\"]>[0]) => this.getCostSummary(params),\n getCostBreakdown: (params?: Parameters<WhisperContext[\"getCostBreakdown\"]>[0]) => this.getCostBreakdown(params),\n getCostSavings: (params?: Parameters<WhisperContext[\"getCostSavings\"]>[0]) => this.getCostSavings(params),\n };\n}\n\nexport default WhisperContext;\n"],"mappings":"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","names":["id","lines","API_KEY","BASE_URL"]}
package/package.json CHANGED
@@ -1,51 +1,51 @@
1
- {
2
- "name": "@usewhisper/mcp-server",
3
- "version": "0.3.0",
4
- "scripts": {
5
- "build": "tsup ../src/mcp/server.ts --format esm --out-dir dist",
6
- "prepublishOnly": "npm run build"
7
- },
8
- "description": "Model Context Protocol server for Whisper Context API - Connect Claude Desktop to your knowledge base",
9
- "type": "module",
10
- "bin": {
11
- "whisper-context-mcp": "./dist/server.js"
12
- },
13
- "main": "dist/server.js",
14
- "files": [
15
- "dist",
16
- "README.md"
17
- ],
18
- "keywords": [
19
- "whisper",
20
- "context",
21
- "mcp",
22
- "model-context-protocol",
23
- "claude",
24
- "ai",
25
- "llm",
26
- "rag",
27
- "knowledge-base"
28
- ],
29
- "author": "Whisper",
30
- "license": "MIT",
31
- "repository": {
32
- "type": "git",
33
- "url": "https://github.com/Alixus/whisper"
34
- },
35
- "homepage": "https://usewhisper.dev",
36
- "bugs": {
37
- "url": "https://github.com/Alinxus/whisper/issues"
38
- },
39
- "dependencies": {
40
- "@modelcontextprotocol/sdk": "^1.12.0",
41
- "zod": "^3.24.0"
42
- },
43
- "devDependencies": {
44
- "@types/node": "^22.0.0",
45
- "tsup": "^8.3.0",
46
- "typescript": "^5.7.0"
47
- },
48
- "engines": {
49
- "node": ">=18.0.0"
50
- }
51
- }
1
+ {
2
+ "name": "@usewhisper/mcp-server",
3
+ "version": "0.5.0",
4
+ "scripts": {
5
+ "build": "tsup ../src/mcp/server.ts --format esm --out-dir dist",
6
+ "prepublishOnly": "npm run build"
7
+ },
8
+ "description": "Model Context Protocol server for Whisper Context API - Connect Claude Desktop to your knowledge base",
9
+ "type": "module",
10
+ "bin": {
11
+ "whisper-context-mcp": "./dist/server.js"
12
+ },
13
+ "main": "dist/server.js",
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "keywords": [
19
+ "whisper",
20
+ "context",
21
+ "mcp",
22
+ "model-context-protocol",
23
+ "claude",
24
+ "ai",
25
+ "llm",
26
+ "rag",
27
+ "knowledge-base"
28
+ ],
29
+ "author": "Whisper",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/Alixus/whisper"
34
+ },
35
+ "homepage": "https://usewhisper.dev",
36
+ "bugs": {
37
+ "url": "https://github.com/Alinxus/whisper/issues"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.12.0",
41
+ "zod": "^3.24.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.0.0",
45
+ "tsup": "^8.3.0",
46
+ "typescript": "^5.7.0"
47
+ },
48
+ "engines": {
49
+ "node": ">=18.0.0"
50
+ }
51
+ }