@prih/mcp-graph-memory 1.0.3

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 (111) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +512 -0
  3. package/dist/api/index.js +473 -0
  4. package/dist/api/rest/code.js +78 -0
  5. package/dist/api/rest/docs.js +80 -0
  6. package/dist/api/rest/files.js +64 -0
  7. package/dist/api/rest/graph.js +56 -0
  8. package/dist/api/rest/index.js +117 -0
  9. package/dist/api/rest/knowledge.js +238 -0
  10. package/dist/api/rest/skills.js +284 -0
  11. package/dist/api/rest/tasks.js +272 -0
  12. package/dist/api/rest/tools.js +126 -0
  13. package/dist/api/rest/validation.js +191 -0
  14. package/dist/api/rest/websocket.js +65 -0
  15. package/dist/api/tools/code/get-file-symbols.js +30 -0
  16. package/dist/api/tools/code/get-symbol.js +22 -0
  17. package/dist/api/tools/code/list-files.js +18 -0
  18. package/dist/api/tools/code/search-code.js +27 -0
  19. package/dist/api/tools/code/search-files.js +22 -0
  20. package/dist/api/tools/context/get-context.js +19 -0
  21. package/dist/api/tools/docs/cross-references.js +76 -0
  22. package/dist/api/tools/docs/explain-symbol.js +55 -0
  23. package/dist/api/tools/docs/find-examples.js +52 -0
  24. package/dist/api/tools/docs/get-node.js +24 -0
  25. package/dist/api/tools/docs/get-toc.js +22 -0
  26. package/dist/api/tools/docs/list-snippets.js +46 -0
  27. package/dist/api/tools/docs/list-topics.js +18 -0
  28. package/dist/api/tools/docs/search-files.js +22 -0
  29. package/dist/api/tools/docs/search-snippets.js +43 -0
  30. package/dist/api/tools/docs/search.js +27 -0
  31. package/dist/api/tools/file-index/get-file-info.js +21 -0
  32. package/dist/api/tools/file-index/list-all-files.js +28 -0
  33. package/dist/api/tools/file-index/search-all-files.js +24 -0
  34. package/dist/api/tools/knowledge/add-attachment.js +31 -0
  35. package/dist/api/tools/knowledge/create-note.js +20 -0
  36. package/dist/api/tools/knowledge/create-relation.js +29 -0
  37. package/dist/api/tools/knowledge/delete-note.js +19 -0
  38. package/dist/api/tools/knowledge/delete-relation.js +23 -0
  39. package/dist/api/tools/knowledge/find-linked-notes.js +25 -0
  40. package/dist/api/tools/knowledge/get-note.js +20 -0
  41. package/dist/api/tools/knowledge/list-notes.js +18 -0
  42. package/dist/api/tools/knowledge/list-relations.js +17 -0
  43. package/dist/api/tools/knowledge/remove-attachment.js +19 -0
  44. package/dist/api/tools/knowledge/search-notes.js +25 -0
  45. package/dist/api/tools/knowledge/update-note.js +34 -0
  46. package/dist/api/tools/skills/add-attachment.js +31 -0
  47. package/dist/api/tools/skills/bump-usage.js +19 -0
  48. package/dist/api/tools/skills/create-skill-link.js +25 -0
  49. package/dist/api/tools/skills/create-skill.js +26 -0
  50. package/dist/api/tools/skills/delete-skill-link.js +23 -0
  51. package/dist/api/tools/skills/delete-skill.js +20 -0
  52. package/dist/api/tools/skills/find-linked-skills.js +25 -0
  53. package/dist/api/tools/skills/get-skill.js +21 -0
  54. package/dist/api/tools/skills/link-skill.js +23 -0
  55. package/dist/api/tools/skills/list-skills.js +20 -0
  56. package/dist/api/tools/skills/recall-skills.js +18 -0
  57. package/dist/api/tools/skills/remove-attachment.js +19 -0
  58. package/dist/api/tools/skills/search-skills.js +25 -0
  59. package/dist/api/tools/skills/update-skill.js +58 -0
  60. package/dist/api/tools/tasks/add-attachment.js +31 -0
  61. package/dist/api/tools/tasks/create-task-link.js +25 -0
  62. package/dist/api/tools/tasks/create-task.js +25 -0
  63. package/dist/api/tools/tasks/delete-task-link.js +23 -0
  64. package/dist/api/tools/tasks/delete-task.js +20 -0
  65. package/dist/api/tools/tasks/find-linked-tasks.js +25 -0
  66. package/dist/api/tools/tasks/get-task.js +20 -0
  67. package/dist/api/tools/tasks/link-task.js +23 -0
  68. package/dist/api/tools/tasks/list-tasks.js +24 -0
  69. package/dist/api/tools/tasks/move-task.js +38 -0
  70. package/dist/api/tools/tasks/remove-attachment.js +19 -0
  71. package/dist/api/tools/tasks/search-tasks.js +25 -0
  72. package/dist/api/tools/tasks/update-task.js +55 -0
  73. package/dist/cli/index.js +451 -0
  74. package/dist/cli/indexer.js +277 -0
  75. package/dist/graphs/attachment-types.js +74 -0
  76. package/dist/graphs/code-types.js +10 -0
  77. package/dist/graphs/code.js +172 -0
  78. package/dist/graphs/docs.js +198 -0
  79. package/dist/graphs/file-index-types.js +10 -0
  80. package/dist/graphs/file-index.js +310 -0
  81. package/dist/graphs/file-lang.js +119 -0
  82. package/dist/graphs/knowledge-types.js +32 -0
  83. package/dist/graphs/knowledge.js +764 -0
  84. package/dist/graphs/manager-types.js +87 -0
  85. package/dist/graphs/skill-types.js +10 -0
  86. package/dist/graphs/skill.js +1013 -0
  87. package/dist/graphs/task-types.js +17 -0
  88. package/dist/graphs/task.js +960 -0
  89. package/dist/lib/embedder.js +101 -0
  90. package/dist/lib/events-log.js +400 -0
  91. package/dist/lib/file-import.js +327 -0
  92. package/dist/lib/file-mirror.js +446 -0
  93. package/dist/lib/frontmatter.js +17 -0
  94. package/dist/lib/mirror-watcher.js +637 -0
  95. package/dist/lib/multi-config.js +254 -0
  96. package/dist/lib/parsers/code.js +246 -0
  97. package/dist/lib/parsers/codeblock.js +66 -0
  98. package/dist/lib/parsers/docs.js +196 -0
  99. package/dist/lib/project-manager.js +418 -0
  100. package/dist/lib/promise-queue.js +22 -0
  101. package/dist/lib/search/bm25.js +167 -0
  102. package/dist/lib/search/code.js +103 -0
  103. package/dist/lib/search/docs.js +108 -0
  104. package/dist/lib/search/file-index.js +31 -0
  105. package/dist/lib/search/files.js +61 -0
  106. package/dist/lib/search/knowledge.js +101 -0
  107. package/dist/lib/search/skills.js +104 -0
  108. package/dist/lib/search/tasks.js +103 -0
  109. package/dist/lib/watcher.js +67 -0
  110. package/package.json +83 -0
  111. package/ui/README.md +54 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 prih
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,512 @@
1
+ # mcp-graph-memory
2
+
3
+ An MCP server that builds a **semantic graph memory** from a project directory.
4
+ It indexes markdown documentation and TypeScript/JavaScript source code into graph structures,
5
+ then exposes them as MCP tools that any AI assistant can use to navigate and search the project.
6
+
7
+ ## Quick start with Docker
8
+
9
+ ### 1. Create a config file
10
+
11
+ Create `graph-memory.yaml` — paths must be relative to the container filesystem:
12
+
13
+ ```yaml
14
+ server:
15
+ host: "0.0.0.0"
16
+ port: 3000
17
+ modelsDir: "/data/models"
18
+
19
+ projects:
20
+ my-app:
21
+ projectDir: "/data/projects/my-app"
22
+ docsPattern: "docs/**/*.md"
23
+ codePattern: "src/**/*.{ts,tsx}"
24
+ excludePattern: "node_modules/**,dist/**"
25
+ ```
26
+
27
+ ### 2. Run with Docker
28
+
29
+ ```bash
30
+ docker run -d \
31
+ --name graph-memory \
32
+ -p 3000:3000 \
33
+ -v $(pwd)/graph-memory.yaml:/data/config/graph-memory.yaml:ro \
34
+ -v /path/to/my-app:/data/projects/my-app:ro \
35
+ -v graph-memory-models:/data/models \
36
+ ghcr.io/prih/mcp-graph-memory
37
+ ```
38
+
39
+ Three mounts:
40
+ | Mount | Container path | Description |
41
+ |-------|---------------|-------------|
42
+ | **Config** | `/data/config/graph-memory.yaml` | Your config file (read-only) |
43
+ | **Projects** | `/data/projects/` | Project directories to index (read-only, unless you use knowledge/tasks/skills — then remove `:ro`) |
44
+ | **Models** | `/data/models/` | Embedding model cache — use a named volume so models persist across container restarts |
45
+
46
+ The embedding model (`Xenova/bge-m3`, ~560MB) is downloaded on first startup. Subsequent starts use the cached model from the volume.
47
+
48
+ ### 3. Run with Docker Compose
49
+
50
+ ```yaml
51
+ # docker-compose.yaml
52
+ services:
53
+ graph-memory:
54
+ image: ghcr.io/prih/mcp-graph-memory
55
+ ports:
56
+ - "3000:3000"
57
+ volumes:
58
+ - ./graph-memory.yaml:/data/config/graph-memory.yaml:ro
59
+ - /path/to/my-app:/data/projects/my-app
60
+ - models:/data/models
61
+ restart: unless-stopped
62
+
63
+ volumes:
64
+ models:
65
+ ```
66
+
67
+ ```bash
68
+ docker compose up -d
69
+ ```
70
+
71
+ ### 4. Connect
72
+
73
+ - **Web UI**: `http://localhost:3000`
74
+ - **MCP (Streamable HTTP)**: `http://localhost:3000/mcp/my-app`
75
+ - **REST API**: `http://localhost:3000/api/projects`
76
+
77
+ To force re-index all projects from scratch:
78
+
79
+ ```bash
80
+ docker run --rm \
81
+ -v $(pwd)/graph-memory.yaml:/data/config/graph-memory.yaml:ro \
82
+ -v /path/to/my-app:/data/projects/my-app \
83
+ -v graph-memory-models:/data/models \
84
+ ghcr.io/prih/mcp-graph-memory serve --config /data/config/graph-memory.yaml --reindex
85
+ ```
86
+
87
+ To index once and exit (useful in CI or as a pre-start step):
88
+
89
+ ```bash
90
+ # Docker
91
+ docker run --rm \
92
+ -v $(pwd)/graph-memory.yaml:/data/config/graph-memory.yaml:ro \
93
+ -v /path/to/my-app:/data/projects/my-app \
94
+ -v graph-memory-models:/data/models \
95
+ ghcr.io/prih/mcp-graph-memory index --config /data/config/graph-memory.yaml
96
+
97
+ # Docker Compose (uses volumes defined in your compose file)
98
+ docker compose run --rm graph-memory index --config /data/config/graph-memory.yaml
99
+ ```
100
+
101
+ > **Multiple projects**: mount each project directory separately and add entries to `graph-memory.yaml`. The config file is watched for changes — add or remove projects without restarting the container.
102
+
103
+ ## What it does
104
+
105
+ - Parses **markdown files** into heading-based chunks, links related files via graph edges
106
+ - Extracts **fenced code blocks** from markdown — parses TS/JS blocks with ts-morph for symbol extraction
107
+ - Parses **TypeScript/JavaScript source** via ts-morph — extracts functions, classes, interfaces,
108
+ types, enums, and their relationships (`contains`, `imports`, `extends`, `implements`)
109
+ - Indexes **all project files** into a file index graph with directory hierarchy, language/MIME detection
110
+ - Stores **facts and notes** in a dedicated knowledge graph with typed relations, file attachments, and cross-graph links; mirrors to `.notes/{id}/` directories
111
+ - Tracks **tasks** in a task graph with status (kanban), priority, due dates, estimates, file attachments, and cross-graph links; mirrors to `.tasks/{id}/` directories
112
+ - Manages **skills** (recipes/procedures) in a skill graph with steps, triggers, usage tracking, file attachments, and cross-graph links; mirrors to `.skills/{id}/` directories
113
+ - Embeds every node locally using `Xenova/bge-m3` by default (no external API calls); supports per-graph models with configurable pooling, normalization, dtype, and query/document prefixes
114
+ - Answers search queries via **hybrid search** (BM25 keyword + vector cosine similarity) with BFS graph expansion
115
+ - Watches for file changes and re-indexes incrementally
116
+
117
+ ## MCP tools (58)
118
+
119
+ ### Context tool (always enabled)
120
+
121
+ | Tool | Description |
122
+ |--------------------|----------------------------------------------------------------|
123
+ | `get_context` | Returns current project and workspace context (project ID, workspace ID, workspace projects, available graphs) |
124
+
125
+ ### Docs tools (enabled when `--docs-pattern` is set)
126
+
127
+ | Tool | Description |
128
+ |--------------------|----------------------------------------------------------------|
129
+ | `list_topics` | List all indexed markdown files with title and chunk count |
130
+ | `get_toc` | Return the table of contents for a specific file |
131
+ | `search` | Hybrid search over docs (BM25 + vector) with BFS expansion |
132
+ | `get_node` | Fetch full content of a specific doc chunk by ID |
133
+ | `search_topic_files` | Semantic file-level search over docs (by file path + title) |
134
+
135
+ ### Code block tools (enabled when `--docs-pattern` is set)
136
+
137
+ | Tool | Description |
138
+ |--------------------|----------------------------------------------------------------|
139
+ | `find_examples` | Find code blocks in docs containing a specific symbol |
140
+ | `search_snippets` | Semantic search over code blocks extracted from docs |
141
+ | `list_snippets` | List code blocks with filters (file, language, content) |
142
+ | `explain_symbol` | Find code example + surrounding text explanation for a symbol |
143
+
144
+ ### Cross-graph tools (requires both docs + code)
145
+
146
+ | Tool | Description |
147
+ |--------------------|----------------------------------------------------------------|
148
+ | `cross_references` | Full picture: definitions (code) + examples + docs for a symbol |
149
+
150
+ ### Code tools (enabled when `--code-pattern` is set)
151
+
152
+ | Tool | Description |
153
+ |--------------------|----------------------------------------------------------------|
154
+ | `list_files` | List all indexed source files with symbol counts |
155
+ | `get_file_symbols` | List all symbols in a file (sorted by line) |
156
+ | `search_code` | Hybrid search over code (BM25 + vector) with BFS expansion |
157
+ | `get_symbol` | Fetch full source body of a specific symbol by ID |
158
+ | `search_files` | Semantic file-level search over code (by file path) |
159
+
160
+ ### File index tools (always enabled)
161
+
162
+ | Tool | Description |
163
+ |--------------------|----------------------------------------------------------------|
164
+ | `list_all_files` | List all project files/dirs with filters (directory, extension, language) |
165
+ | `search_all_files` | Semantic search over files by path |
166
+ | `get_file_info` | Get full metadata for a file or directory |
167
+
168
+ ### Knowledge tools (always enabled)
169
+
170
+ | Tool | Description |
171
+ |--------------------|----------------------------------------------------------------|
172
+ | `create_note` | Create a note with title, content, and tags |
173
+ | `update_note` | Update an existing note's title, content, or tags |
174
+ | `delete_note` | Delete a note and its relations |
175
+ | `get_note` | Fetch a note by ID |
176
+ | `list_notes` | List notes with optional filter and tag |
177
+ | `search_notes` | Hybrid search over notes (BM25 + vector) with BFS expansion |
178
+ | `create_relation` | Create a relation between notes or to doc/code/files/task nodes |
179
+ | `delete_relation` | Delete a relation (note-to-note or cross-graph) |
180
+ | `list_relations` | List all relations for a note (includes cross-graph links) |
181
+ | `find_linked_notes`| Reverse lookup: find all notes that link to a doc/code/file/task node |
182
+ | `add_note_attachment` | Attach a file to a note (by absolute path) |
183
+ | `remove_note_attachment` | Remove an attachment from a note |
184
+
185
+ ### Task tools (always enabled)
186
+
187
+ | Tool | Description |
188
+ |--------------------|----------------------------------------------------------------|
189
+ | `create_task` | Create a task with title, description, priority, tags, status, dueDate, estimate |
190
+ | `update_task` | Update any task fields (partial update) |
191
+ | `delete_task` | Delete a task and its relations |
192
+ | `get_task` | Fetch a task with subtasks, blockedBy, blocks, and related |
193
+ | `list_tasks` | List tasks with filters (status, priority, tag, filter text) |
194
+ | `search_tasks` | Hybrid search over tasks (BM25 + vector) with BFS expansion |
195
+ | `move_task` | Change task status with auto completedAt management |
196
+ | `link_task` | Create task↔task relations (subtask_of, blocks, related_to) |
197
+ | `create_task_link` | Link a task to a doc/code/file/knowledge node |
198
+ | `delete_task_link` | Remove a cross-graph link from a task |
199
+ | `find_linked_tasks`| Reverse lookup: find all tasks that link to a target node |
200
+ | `add_task_attachment` | Attach a file to a task (by absolute path) |
201
+ | `remove_task_attachment` | Remove an attachment from a task |
202
+
203
+ ### Skill tools (always enabled)
204
+
205
+ | Tool | Description |
206
+ |--------------------|----------------------------------------------------------------|
207
+ | `create_skill` | Create a skill (recipe/procedure) with steps, triggers, and metadata |
208
+ | `update_skill` | Update any skill fields (partial update) |
209
+ | `delete_skill` | Delete a skill and its relations |
210
+ | `get_skill` | Fetch a skill with dependsOn/dependedBy/related/variants + cross-links |
211
+ | `list_skills` | List skills with filters (source, tag, filter text) |
212
+ | `search_skills` | Hybrid search over skills (BM25 + vector) with BFS expansion |
213
+ | `link_skill` | Create skill↔skill relations (depends_on, related_to, variant_of) |
214
+ | `create_skill_link`| Link a skill to a doc/code/file/knowledge/task node |
215
+ | `delete_skill_link`| Remove a cross-graph link from a skill |
216
+ | `find_linked_skills`| Reverse lookup: find all skills that link to a target node |
217
+ | `add_skill_attachment` | Attach a file to a skill (by absolute path) |
218
+ | `remove_skill_attachment` | Remove an attachment from a skill |
219
+ | `recall_skills` | Recall relevant skills for a task context (lower minScore for higher recall) |
220
+ | `bump_skill_usage` | Increment skill usage counter + set lastUsedAt |
221
+
222
+ ## Installation (from source)
223
+
224
+ ```bash
225
+ npm install
226
+ npm run build
227
+ ```
228
+
229
+ ## Usage
230
+
231
+ ### 1. Create `graph-memory.yaml`
232
+
233
+ ```yaml
234
+ server:
235
+ host: "127.0.0.1"
236
+ port: 3000
237
+ sessionTimeout: 1800
238
+ embedding:
239
+ model: "Xenova/bge-m3" # default for all graphs
240
+
241
+ projects:
242
+ my-app:
243
+ projectDir: "/path/to/my-app"
244
+ docsPattern: "docs/**/*.md"
245
+ codePattern: "src/**/*.{ts,tsx}"
246
+ excludePattern: "node_modules/**,dist/**"
247
+ tsconfig: "./tsconfig.json"
248
+ # Per-graph embedding overrides (optional):
249
+ graphs:
250
+ code:
251
+ model: "Xenova/bge-base-en-v1.5"
252
+ pooling: "cls"
253
+ queryPrefix: "Represent this sentence for searching relevant passages: "
254
+ ```
255
+
256
+ Embedding config uses inheritance: `graphs.<name>` → `project.embedding` → `server.embedding` → defaults. The same model is loaded only once (deduplication). See [`graph-memory.yaml.example`](graph-memory.yaml.example) for all options and model examples.
257
+
258
+ All fields are optional except `projectDir` — see [`graph-memory.yaml.example`](graph-memory.yaml.example) for the full list.
259
+
260
+ ### 2. Run
261
+
262
+ ```bash
263
+ # Multi-project HTTP server (primary mode — serves all projects)
264
+ node /path/to/mcp-graph-memory/dist/cli/index.js serve --config graph-memory.yaml
265
+
266
+ # Single-project stdio (for MCP clients like Claude Desktop)
267
+ node /path/to/mcp-graph-memory/dist/cli/index.js mcp --config graph-memory.yaml --project my-app
268
+
269
+ # Index one project and exit
270
+ node /path/to/mcp-graph-memory/dist/cli/index.js index --config graph-memory.yaml --project my-app
271
+
272
+ # Force re-index from scratch (discard persisted graphs)
273
+ node /path/to/mcp-graph-memory/dist/cli/index.js serve --config graph-memory.yaml --reindex
274
+ ```
275
+
276
+ All three commands (`serve`, `mcp`, `index`) support `--reindex` to discard persisted graph JSON files and re-create graphs from scratch.
277
+
278
+ ### Claude Desktop / MCP client configuration
279
+
280
+ **Stdio transport** (one project per process):
281
+
282
+ ```json
283
+ {
284
+ "mcpServers": {
285
+ "project-memory": {
286
+ "command": "node",
287
+ "args": [
288
+ "/path/to/mcp-graph-memory/dist/cli/index.js",
289
+ "mcp",
290
+ "--config", "/path/to/graph-memory.yaml",
291
+ "--project", "my-app"
292
+ ]
293
+ }
294
+ }
295
+ }
296
+ ```
297
+
298
+ **HTTP transport** (multi-project, multiple clients share one server):
299
+
300
+ Start the server:
301
+ ```bash
302
+ node /path/to/mcp-graph-memory/dist/cli/index.js serve --config graph-memory.yaml
303
+ ```
304
+
305
+ Then connect your MCP client to `http://localhost:3000/mcp/{projectId}` using the Streamable HTTP transport.
306
+
307
+ For Claude Desktop with HTTP transport:
308
+ ```json
309
+ {
310
+ "mcpServers": {
311
+ "project-memory": {
312
+ "type": "streamable-http",
313
+ "url": "http://localhost:3000/mcp/my-app"
314
+ }
315
+ }
316
+ }
317
+ ```
318
+
319
+ For Cursor, Windsurf, or other MCP clients — use the Streamable HTTP URL:
320
+ ```
321
+ http://localhost:3000/mcp/{projectId}
322
+ ```
323
+
324
+ Each project configured in `graph-memory.yaml` gets its own MCP endpoint at `/mcp/{projectId}`. Multiple clients can connect to the same server simultaneously — each session gets its own MCP instance but shares graph data.
325
+
326
+ The server watches `graph-memory.yaml` for changes — add, remove, or update projects without restarting.
327
+
328
+ ## Configuration
329
+
330
+ ### `graph-memory.yaml`
331
+
332
+ YAML config file. All fields optional except `projects.*.projectDir`:
333
+
334
+ **Server settings** (`server:`):
335
+
336
+ | Field | Type | Default | Description |
337
+ |---|---|---|---|
338
+ | `host` | `string` | `127.0.0.1` | HTTP server bind address |
339
+ | `port` | `number` | `3000` | HTTP server port |
340
+ | `sessionTimeout` | `number` | `1800` | Idle session timeout in seconds |
341
+ | `modelsDir` | `string` | `~/.graph-memory/models` | Local model cache directory |
342
+ | `embedding` | `object` | (see below) | Default embedding config (fallback for all graphs) |
343
+
344
+ **Embedding config** (`server.embedding`, `projects.<id>.embedding`, `projects.<id>.graphs.<name>`):
345
+
346
+ | Field | Type | Default | Description |
347
+ |---|---|---|---|
348
+ | `model` | `string` | `Xenova/bge-m3` | Embedding model from HuggingFace |
349
+ | `pooling` | `string` | `cls` | Pooling strategy: `mean` or `cls` |
350
+ | `normalize` | `boolean` | `true` | L2-normalize output vectors |
351
+ | `dtype` | `string` | — | Quantization: `fp32`, `fp16`, `q8`, `q4` |
352
+ | `queryPrefix` | `string` | `""` | Prefix prepended to search queries |
353
+ | `documentPrefix` | `string` | `""` | Prefix prepended to documents during indexing |
354
+
355
+ Config inheritance: `graphs.<name>` → `project.embedding` → `server.embedding` → defaults.
356
+
357
+ **Per-project settings** (`projects.<id>:`):
358
+
359
+ | Field | Type | Default | Description |
360
+ |---|---|---|---|
361
+ | `projectDir` | `string` | **(required)** | Root directory to index |
362
+ | `graphMemory` | `string` | `{projectDir}/.graph-memory` | Where to store graph JSON files |
363
+ | `docsPattern` | `string` | `**/*.md` | Glob for markdown files |
364
+ | `codePattern` | `string` | `**/*.{js,ts,jsx,tsx}` | Glob for source files |
365
+ | `excludePattern` | `string` | `node_modules/**` | Glob to exclude from indexing |
366
+ | `tsconfig` | `string` | — | Path to tsconfig.json |
367
+ | `embedding` | `object` | (server default) | Project-level embedding config |
368
+ | `graphs` | `object` | — | Per-graph embedding overrides (`docs`, `code`, `knowledge`, `tasks`, `files`, `skills`) |
369
+ | `chunkDepth` | `number` | `4` | Max heading depth to chunk at |
370
+ | `maxTokensDefault` | `number` | `4000` | Default max tokens for responses |
371
+ | `embedMaxChars` | `number` | `2000` | Max chars fed to embedder per node |
372
+
373
+ ## How graph IDs work
374
+
375
+ **Doc nodes**: `"docs/auth.md"` (file root), `"docs/auth.md::JWT Tokens"` (section),
376
+ `"docs/auth.md::Notes::2"` (duplicate heading)
377
+
378
+ **Code block nodes**: `"docs/auth.md::JWT Tokens::code-1"` (first code block in section)
379
+
380
+ **Code nodes**: `"src/lib/graph.ts"` (file), `"src/lib/graph.ts::updateFile"` (function),
381
+ `"src/lib/graph.ts::GraphStore::set"` (method)
382
+
383
+ **Knowledge nodes**: `"auth-uses-jwt"` (slug from title), `"auth-uses-jwt::2"` (dedup)
384
+
385
+ **File index nodes**: `"src/lib/config.ts"` (file), `"src/lib"` (directory), `"."` (root)
386
+
387
+ **Task nodes**: `"implement-auth"` (slug from title), `"implement-auth::2"` (dedup)
388
+
389
+ **Skill nodes**: `"add-rest-endpoint"` (slug from title), `"add-rest-endpoint::2"` (dedup)
390
+
391
+ **Cross-graph proxy nodes**: `"@docs::docs/auth.md::JWT Tokens"`, `"@code::src/auth.ts::Foo"`, `"@files::src/config.ts"`, `"@tasks::implement-auth"`, `"@knowledge::my-note"`, `"@skills::add-rest-endpoint"` (internal — resolved transparently in `list_relations`)
392
+
393
+ Pass these IDs to `get_node`, `get_symbol`, or `get_note` to fetch full content.
394
+
395
+ ## Web UI
396
+
397
+ The `serve` command starts a web UI at `http://localhost:3000` with:
398
+
399
+ - **Dashboard** — project stats (notes, tasks, skills, docs, code, files) + recent activity
400
+ - **Knowledge** — notes CRUD, semantic search, relations, cross-graph links
401
+ - **Tasks** — kanban board with configurable columns, drag-drop with drop-zone highlights, inline task creation, filter bar (search/priority/tags), due date and estimate badges, quick actions on hover, scrollable columns
402
+ - **Skills** — skill/recipe management with triggers, steps, and usage tracking
403
+ - **Docs** — browse and search indexed markdown documentation
404
+ - **Files** — file browser with directory navigation, metadata, search
405
+ - **Prompts** — AI prompt generator with scenario presets, role/style/graph selection, live preview, copy & export as skill
406
+ - **Search** — unified semantic search across all 6 graphs
407
+ - **Graph** — interactive force-directed graph visualization (Cytoscape.js)
408
+ - **Tools** — MCP tools explorer with live execution from the browser
409
+ - **Help** — built-in searchable documentation on all tools and concepts
410
+
411
+ Light/dark theme toggle. Real-time updates via WebSocket.
412
+
413
+ ### REST API
414
+
415
+ The HTTP server also exposes a REST API at `/api/*`:
416
+
417
+ ```
418
+ GET /api/projects → list projects with stats
419
+ GET /api/projects/:id/stats → per-graph node/edge counts
420
+
421
+ GET /api/projects/:id/knowledge/notes → list notes
422
+ POST /api/projects/:id/knowledge/notes → create note
423
+ GET /api/projects/:id/knowledge/notes/:noteId → get note
424
+ PUT /api/projects/:id/knowledge/notes/:noteId → update note
425
+ DELETE /api/projects/:id/knowledge/notes/:noteId → delete note
426
+ GET /api/projects/:id/knowledge/search?q=... → search notes
427
+ POST /api/projects/:id/knowledge/relations → create relation
428
+ DELETE /api/projects/:id/knowledge/relations → delete relation
429
+ GET /api/projects/:id/knowledge/notes/:noteId/relations → list note relations
430
+ GET /api/projects/:id/knowledge/linked?targetGraph=...&targetNodeId=... → find linked notes
431
+ POST /api/projects/:id/knowledge/notes/:noteId/attachments → upload attachment
432
+ GET /api/projects/:id/knowledge/notes/:noteId/attachments → list attachments
433
+ GET /api/projects/:id/knowledge/notes/:noteId/attachments/:filename → download attachment
434
+ DELETE /api/projects/:id/knowledge/notes/:noteId/attachments/:filename → delete attachment
435
+
436
+ GET /api/projects/:id/tasks → list tasks
437
+ POST /api/projects/:id/tasks → create task
438
+ GET /api/projects/:id/tasks/:taskId → get task
439
+ PUT /api/projects/:id/tasks/:taskId → update task
440
+ DELETE /api/projects/:id/tasks/:taskId → delete task
441
+ POST /api/projects/:id/tasks/:taskId/move → move task status
442
+ GET /api/projects/:id/tasks/search?q=... → search tasks
443
+ POST /api/projects/:id/tasks/links → create task link
444
+ DELETE /api/projects/:id/tasks/links → delete task link
445
+ GET /api/projects/:id/tasks/:taskId/relations → list task relations
446
+ GET /api/projects/:id/tasks/linked?targetGraph=...&targetNodeId=... → find linked tasks
447
+ POST /api/projects/:id/tasks/:taskId/attachments → upload attachment
448
+ GET /api/projects/:id/tasks/:taskId/attachments → list attachments
449
+ GET /api/projects/:id/tasks/:taskId/attachments/:filename → download attachment
450
+ DELETE /api/projects/:id/tasks/:taskId/attachments/:filename → delete attachment
451
+
452
+ GET /api/projects/:id/skills → list skills
453
+ POST /api/projects/:id/skills → create skill
454
+ GET /api/projects/:id/skills/:skillId → get skill
455
+ PUT /api/projects/:id/skills/:skillId → update skill
456
+ DELETE /api/projects/:id/skills/:skillId → delete skill
457
+ GET /api/projects/:id/skills/search?q=... → search skills
458
+ GET /api/projects/:id/skills/recall?q=... → recall skills (lower minScore)
459
+ POST /api/projects/:id/skills/links → create skill link
460
+ DELETE /api/projects/:id/skills/links → delete skill link
461
+ GET /api/projects/:id/skills/:skillId/relations → list skill relations
462
+ GET /api/projects/:id/skills/linked?targetGraph=...&targetNodeId=... → find linked skills
463
+ POST /api/projects/:id/skills/:skillId/attachments → upload attachment
464
+ GET /api/projects/:id/skills/:skillId/attachments → list attachments
465
+ GET /api/projects/:id/skills/:skillId/attachments/:filename → download attachment
466
+ DELETE /api/projects/:id/skills/:skillId/attachments/:filename → delete attachment
467
+
468
+ GET /api/projects/:id/docs/search?q=... → search docs
469
+ GET /api/projects/:id/code/search?q=... → search code
470
+ GET /api/projects/:id/files → list files
471
+ GET /api/projects/:id/files/search?q=... → search files
472
+ GET /api/projects/:id/graph?scope=... → graph export
473
+
474
+ GET /api/projects/:id/tools → list MCP tools
475
+ GET /api/projects/:id/tools/:toolName → tool details + schema
476
+ POST /api/projects/:id/tools/:toolName/call → call a tool
477
+ ```
478
+
479
+ ## Demo Project
480
+
481
+ A demo project (`demo-project/`) is included — a fictional "TaskFlow" project management API with:
482
+
483
+ - **18 TypeScript files** — models, services, controllers, middleware, utilities
484
+ - **11 markdown docs** — architecture, API reference, guides, changelog
485
+ - **Seed script** — creates 15 notes + 20 tasks + 10 skills + relations + cross-graph links via REST API
486
+
487
+ To try it:
488
+
489
+ ```bash
490
+ # 1. Start the server (indexes code + docs automatically)
491
+ npm run build
492
+ node dist/cli/index.js serve --config graph-memory.yaml
493
+
494
+ # 2. Seed notes, tasks, and relations
495
+ ./demo-project/scripts/seed.sh
496
+ ```
497
+
498
+ The `demo-taskflow` project is pre-configured in `graph-memory.yaml`. Open `http://localhost:3000` to explore the data.
499
+
500
+ ## Development
501
+
502
+ ```bash
503
+ npm run dev # watch mode (backend)
504
+ cd ui && npm run dev # Vite dev server on :5173, proxies /api → :3000
505
+ ```
506
+
507
+ Run tests:
508
+ ```bash
509
+ npm test # all tests (1178 tests across 26 suites)
510
+ npm test -- --testPathPatterns=search # run a specific test file
511
+ npm run test:watch # watch mode
512
+ ```