#!/usr/bin/env node /** * Eddie's Brain MCP Server * * Exposes Eddie's Brain capabilities to AI agents via the Model Context Protocol. * * This module has two concerns, deliberately separated so the same tool * implementations can be served over any transport: * * 1. `createEddieBrainServer(ctx)` — a pure factory that builds an * `McpServer` and registers every tool against a `BrainContext`. It has * no knowledge of transports. The stdio entrypoint below, the local HTTP * test server (`http.ts`), and the Netlify Function all call this exact * factory, so tool behavior is identical everywhere. * * 2. `loadBrainContext()` — resolves where the knowledge graph lives * (EDDIE_ROOT → walk-up from cwd → bundled `dist/graph`) and loads it. * The bundled `dist/graph` fallback is what makes a *hosted, disk-less* * deployment (Netlify Function) possible: the graph JSON is copied into * the build output so the server needs no repo checkout at runtime. * * The stdio entrypoint (Claude Code, Cursor, etc.) is preserved unchanged and * only runs when this file is executed directly (`node dist/mcp/server.js`). */ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { KnowledgeGraph } from '../knowledge-graph/index.js'; import { LearningHistory } from '../knowledge-graph/learning-history.js'; import { ActivityLedger } from '../analyze/activity-ledger.js'; import { type ActivitySource } from '../analyze/activity-source.js'; /** * Everything a tool implementation needs to answer a request. The graph is * mutable so the stdio watch-reload can swap in a freshly-regenerated graph * without re-registering tools (tools read `ctx.graph` at call time). */ export interface BrainContext { /** Loaded knowledge graph, or null if none was found on disk. */ graph: KnowledgeGraph | null; /** Runtime learning/feedback state (the correction flywheel). */ learning: LearningHistory; /** Directory holding the graph JSON files (a live `.eddie-brain` or bundled `dist/graph`). */ brainDir: string; /** Repo root used for health-scorer config. Equals dirname(brainDir) for bundled graphs. */ rootDir: string; /** * True when `brainDir` is a live, on-disk `.eddie-brain` that can be watched * for regeneration. False for the bundled/immutable graph used in hosted * deployments — there is nothing to watch and feedback writes are best-effort. */ watchable: boolean; } /** * Load a BrainContext: resolve the graph directory, load the knowledge graph * and learning history. Never throws — a missing/corrupt graph yields a * context with `graph: null`, and each tool reports the "not initialized" * error itself (identical to the previous behavior). */ export declare function loadBrainContext(opts?: { dir?: string; }): Promise; /** * The real-world-usage block attached to every `eddie_get_component` payload — * the Eddie-reporter feedback loop playing back into the component docs. */ interface ComponentUsage { productCount: number; totalOccurrences: number; products: { id: string; name?: string; occurrences: number; lastSeen: string; }[]; note: string; } /** * Join the activity ledger (`.eddie-brain/activity.json`, fed by the * Eddie-reporter on downstream products) into a per-tag usage summary. This is * how real-world usage bolsters the component docs: an agent looking up a * component sees WHO uses it and how heavily, right next to the guidelines — * heavily-used components deserve extra care; never-reported ones flag either * a coverage gap or a candidate for deprecation. * * The ledger is runtime state and may legitimately be empty (no products have * reported yet). That case reads "unknown", never "unused" — the distinction * matters for anything acting on the signal. */ /** * Resolve the activity ledger for a brain directory. On the hosted function * (NETLIFY set) the flush's snapshot blob may be fresher than the file bundled * at build time, so the store is consulted and the newer wins (#1847). * Everywhere else the file is the truth and no store is opened. */ export declare function activityFor(brainDir: string): Promise; export declare function componentUsage(ledger: ActivityLedger, tagName: string): ComponentUsage; /** * Build an McpServer and register every Eddie's Brain tool against the given * context. Transport-agnostic: call this from stdio, HTTP, or a serverless * function. Safe to call once per request (stateless HTTP) or once per process * (stdio) — it holds no transport state. */ export declare function createEddieBrainServer(ctx: BrainContext): McpServer; /** * Initialize and start the MCP server over stdio (Claude Code, Cursor, etc.). * This is the original, unchanged entrypoint — it just delegates graph loading * and tool registration to the shared factory. */ export declare function main(): Promise; export {}; //# sourceMappingURL=server.d.ts.map