MCP server that builds a semantic graph memory from a project directory — indexing markdown docs, TypeScript/JavaScript source code, and all project files into six interconnected graphs. Exposes 70 MCP tools + REST API + Web UI.
Full documentation: see docs/
npm run build # tsc → dist/ (server + UI)
npm run dev # tsc --watch
npm run cli:dev # tsx src/cli/index.ts (no build needed)Run tests:
npm test # all tests (1809 tests across 45 suites)
npm test -- --testPathPatterns=search # specific test file
npm run test:watch # watch mode
npx tsx src/tests/embedder.test.ts # real model test (slow, excluded from Jest)CLI commands (after build):
node dist/cli/index.js serve # zero-config: cwd as project
node dist/cli/index.js serve --config graph-memory.yaml # multi-project HTTP server
node dist/cli/index.js index --config graph-memory.yaml --project X # index and exit
node dist/cli/index.js serve --config graph-memory.yaml --reindex # force re-index
graphmemory users add --config graph-memory.yaml # add user interactivelyGraphs on Graphology: DocGraph, CodeGraph, KnowledgeGraph, FileIndexGraph, TaskGraph, SkillGraph. Each has a Manager class (unified API for CRUD + search + embedding + events + file mirror). MCP tools and REST routes are thin adapters over managers.
See docs/architecture.md for diagrams and directory structure.
- CommonJS (
module: "CommonJS"in tsconfig) - Graph managers encapsulate everything: embed → CRUD → dirty → emit → file mirror → proxy cleanup
- tree-sitter (web-tree-sitter WASM) for AST parsing — supports TS/JS/TSX/JSX, extensible to other languages
- Hybrid search: BM25 keyword + vector cosine, fused via RRF, with BFS graph expansion
- Three serial queues: docs, code, file index — independent Promise chains, concurrent with each other
- Mutation serialization:
PromiseQueueper project for write operations (MCP + REST) - File mirror:
.notes/,.tasks/,.skills/markdown files with reverse import from IDE - Cross-graph links: phantom proxy nodes (
@docs::,@code::,@files::,@tasks::,@knowledge::,@skills::) - Auth: password login (scrypt + JWT cookies) for UI, API keys (Bearer) for programmatic access
- ACL: graph > project > workspace > server > defaultAccess
All config via graph-memory.yaml. See docs/configuration.md for full reference.
- TypeScript strict mode — no implicit
any, no unused vars/params - Error handling:
.catch()with Pino logger +process.exit(1)for fatal CLI errors - Async errors in indexer queue logged via Pino, don't stop the queue
- Logging: Pino with
createLogger('component')child loggers; pretty by default,LOG_JSON=1for JSON - Tests: Jest + ts-jest; ESM deps mocked via
moduleNameMapper - MCP tests:
InMemoryTransport.createLinkedPair()+ fake embeddings embedder.test.tsloads real model (slow) — excluded from Jest, run withnpx tsx