@graphmemory/server 1.1.0 → 1.3.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 (104) hide show
  1. package/LICENSE +84 -12
  2. package/README.md +66 -101
  3. package/dist/api/index.js +279 -169
  4. package/dist/api/rest/index.js +36 -16
  5. package/dist/api/rest/tools.js +8 -1
  6. package/dist/api/rest/websocket.js +22 -1
  7. package/dist/api/tools/code/search-code.js +12 -9
  8. package/dist/api/tools/code/search-files.js +1 -1
  9. package/dist/api/tools/docs/cross-references.js +3 -2
  10. package/dist/api/tools/docs/explain-symbol.js +2 -1
  11. package/dist/api/tools/docs/find-examples.js +2 -1
  12. package/dist/api/tools/docs/search-files.js +1 -1
  13. package/dist/api/tools/docs/search-snippets.js +1 -1
  14. package/dist/api/tools/docs/search.js +5 -4
  15. package/dist/api/tools/file-index/search-all-files.js +1 -1
  16. package/dist/api/tools/knowledge/add-attachment.js +14 -3
  17. package/dist/api/tools/knowledge/create-relation.js +2 -2
  18. package/dist/api/tools/knowledge/delete-relation.js +2 -2
  19. package/dist/api/tools/knowledge/find-linked-notes.js +1 -1
  20. package/dist/api/tools/knowledge/remove-attachment.js +5 -1
  21. package/dist/api/tools/knowledge/search-notes.js +5 -4
  22. package/dist/api/tools/skills/add-attachment.js +14 -3
  23. package/dist/api/tools/skills/recall-skills.js +1 -1
  24. package/dist/api/tools/skills/remove-attachment.js +5 -1
  25. package/dist/api/tools/skills/search-skills.js +6 -5
  26. package/dist/api/tools/tasks/add-attachment.js +14 -3
  27. package/dist/api/tools/tasks/create-task-link.js +1 -1
  28. package/dist/api/tools/tasks/delete-task-link.js +1 -1
  29. package/dist/api/tools/tasks/find-linked-tasks.js +1 -1
  30. package/dist/api/tools/tasks/remove-attachment.js +5 -1
  31. package/dist/api/tools/tasks/search-tasks.js +5 -4
  32. package/dist/cli/index.js +69 -311
  33. package/dist/cli/indexer.js +61 -29
  34. package/dist/graphs/code.js +70 -7
  35. package/dist/graphs/docs.js +15 -2
  36. package/dist/graphs/file-index.js +20 -6
  37. package/dist/graphs/file-lang.js +1 -1
  38. package/dist/graphs/knowledge.js +20 -3
  39. package/dist/graphs/manager-types.js +1 -1
  40. package/dist/graphs/skill.js +23 -4
  41. package/dist/graphs/task.js +23 -4
  42. package/dist/lib/embedding-codec.js +65 -0
  43. package/dist/lib/file-mirror.js +7 -7
  44. package/dist/lib/frontmatter.js +3 -2
  45. package/dist/lib/jwt.js +4 -4
  46. package/dist/lib/mirror-watcher.js +5 -4
  47. package/dist/lib/multi-config.js +60 -1
  48. package/dist/lib/parsers/code.js +158 -31
  49. package/dist/lib/parsers/codeblock.js +11 -6
  50. package/dist/lib/parsers/docs.js +59 -31
  51. package/dist/lib/parsers/languages/registry.js +10 -4
  52. package/dist/lib/parsers/languages/typescript.js +195 -48
  53. package/dist/lib/project-manager.js +14 -10
  54. package/dist/lib/search/bm25.js +18 -1
  55. package/dist/lib/search/code.js +12 -3
  56. package/dist/lib/watcher.js +17 -9
  57. package/dist/ui/assets/NoteForm-aZX9f6-3.js +1 -0
  58. package/dist/ui/assets/SkillForm-KYa3o92l.js +1 -0
  59. package/dist/ui/assets/TaskForm-Bl5nkybO.js +1 -0
  60. package/dist/ui/assets/_articleId_-DjbCByxM.js +1 -0
  61. package/dist/ui/assets/_docId_-hdCDjclV.js +1 -0
  62. package/dist/ui/assets/_filePath_-CpG836v4.js +1 -0
  63. package/dist/ui/assets/_noteId_-C1enaQd1.js +1 -0
  64. package/dist/ui/assets/_skillId_-hPoCet7J.js +1 -0
  65. package/dist/ui/assets/_taskId_-DSB3dLVz.js +1 -0
  66. package/dist/ui/assets/_toolName_-3SmCfxZy.js +2 -0
  67. package/dist/ui/assets/api-BMnBjMMf.js +1 -0
  68. package/dist/ui/assets/api-BlFF6gX-.js +1 -0
  69. package/dist/ui/assets/api-CrGJOcaN.js +1 -0
  70. package/dist/ui/assets/api-DuX-0a_X.js +1 -0
  71. package/dist/ui/assets/attachments-CEQ-2nMo.js +1 -0
  72. package/dist/ui/assets/client-Bq88u7gN.js +1 -0
  73. package/dist/ui/assets/docs-CrXsRcOG.js +1 -0
  74. package/dist/ui/assets/edit-BYiy1FZy.js +1 -0
  75. package/dist/ui/assets/edit-TUIIpUMF.js +1 -0
  76. package/dist/ui/assets/edit-hc-ZWz3y.js +1 -0
  77. package/dist/ui/assets/esm-BWiKNcBW.js +1 -0
  78. package/dist/ui/assets/files-0bPg6NH9.js +1 -0
  79. package/dist/ui/assets/graph-DXGud_wF.js +1 -0
  80. package/dist/ui/assets/help-CEMQqZUR.js +891 -0
  81. package/dist/ui/assets/help-DJ52_fxN.js +1 -0
  82. package/dist/ui/assets/index-BCZDAYZi.js +2 -0
  83. package/dist/ui/assets/index-D6zSNtzo.css +1 -0
  84. package/dist/ui/assets/knowledge-DeygeGGH.js +1 -0
  85. package/dist/ui/assets/new-CpD7hOBA.js +1 -0
  86. package/dist/ui/assets/new-DHTg3Dqq.js +1 -0
  87. package/dist/ui/assets/new-s8c0M75X.js +1 -0
  88. package/dist/ui/assets/prompts-BgOmdxgM.js +295 -0
  89. package/dist/ui/assets/rolldown-runtime-Dw2cE7zH.js +1 -0
  90. package/dist/ui/assets/search-EpJhdP2a.js +1 -0
  91. package/dist/ui/assets/skill-y9pizyqE.js +1 -0
  92. package/dist/ui/assets/skills-Cga9iUZN.js +1 -0
  93. package/dist/ui/assets/tasks-CobouTKV.js +1 -0
  94. package/dist/ui/assets/tools-JxKH5BDF.js +1 -0
  95. package/dist/ui/assets/vendor-graph-BWpSgpMe.js +321 -0
  96. package/dist/ui/assets/vendor-markdown-CT8ZVEPu.js +50 -0
  97. package/dist/ui/assets/vendor-md-editor-DmWafJvr.js +44 -0
  98. package/dist/ui/assets/{index-kKd4mVrh.css → vendor-md-editor-HrwGbQou.css} +1 -1
  99. package/dist/ui/assets/vendor-mui-BPj7d3Sw.js +139 -0
  100. package/dist/ui/assets/vendor-mui-icons-B196sG3f.js +1 -0
  101. package/dist/ui/assets/vendor-react-CHUjhoxh.js +11 -0
  102. package/dist/ui/index.html +11 -3
  103. package/package.json +2 -2
  104. package/dist/ui/assets/index-D6oxrVF7.js +0 -1759
@@ -0,0 +1,891 @@
1
+ var e=[{id:`getting-started`,title:`Getting Started`,summary:`What Graph Memory does, how the six graphs work, and how to get started.`,category:`overview`,relatedTools:[],content:`# Getting Started with Graph Memory
2
+
3
+ Graph Memory is an MCP server that builds a **semantic graph** from your project directory. It indexes markdown documentation, TypeScript/JavaScript source code, and all project files — then exposes 58 tools for searching, navigating, and enriching that knowledge.
4
+
5
+ ## What does it do?
6
+
7
+ Imagine having a smart assistant that has read every file in your project and can instantly:
8
+
9
+ - **Find relevant documentation** by meaning, not just keywords
10
+ - **Look up any code symbol** — functions, classes, interfaces — with full context
11
+ - **Track knowledge and decisions** in a persistent note graph
12
+ - **Manage tasks** with a full kanban workflow
13
+ - **Store reusable skills** — recipes, procedures, and troubleshooting guides
14
+ - **Cross-reference** code definitions with documentation examples
15
+
16
+ ## The Six Graphs
17
+
18
+ Graph Memory maintains six separate but interconnected graphs:
19
+
20
+ | Graph | What it indexes | Created from |
21
+ |-------|----------------|--------------|
22
+ | **DocGraph** | Markdown sections, headings, code blocks | Files matching \`graphs.docs.include\` |
23
+ | **CodeGraph** | Functions, classes, methods, imports | Files matching \`graphs.code.include\` |
24
+ | **FileIndexGraph** | All files and directories with metadata | Entire project directory |
25
+ | **KnowledgeGraph** | User-created notes, facts, decisions | Manual creation via tools |
26
+ | **TaskGraph** | Tasks with status, priority, dependencies | Manual creation via tools |
27
+ | **SkillGraph** | Reusable recipes, procedures, triggers | Manual creation via tools |
28
+
29
+ ## How search works
30
+
31
+ All search tools use **semantic search** — you describe what you're looking for in natural language, and the system finds the most relevant results by meaning.
32
+
33
+ Under the hood:
34
+ 1. Your query is converted to a **vector embedding** (a list of numbers representing meaning)
35
+ 2. This vector is compared against all indexed items using **cosine similarity**
36
+ 3. Top matches are expanded via **BFS graph walk** — following links to find related content
37
+ 4. Results are scored and ranked by relevance
38
+
39
+ This means \`"how to authenticate users"\` will find documentation about auth even if it never contains that exact phrase.
40
+
41
+ ## Quick start workflow
42
+
43
+ 1. **Start** the server: \`graphmemory serve\` (uses current directory as project, or \`--config graph-memory.yaml\` for custom config)
44
+ 3. **Browse** your indexed content in the UI
45
+ 4. **Search** across all graphs using natural language
46
+ 5. **Create notes** to capture knowledge and decisions
47
+ 6. **Link** notes to code, docs, files, and tasks for a connected knowledge base
48
+ `},{id:`how-search-works`,title:`How Semantic Search Works`,summary:`Vector embeddings, cosine similarity, and BFS graph expansion explained.`,category:`concept`,relatedTools:[`search`,`search_code`,`search_notes`,`search_tasks`,`search_skills`,`search_all_files`,`search_topic_files`,`search_files`,`search_snippets`],content:`# How Search Works
49
+
50
+ Graph Memory uses **hybrid search** — combining BM25 keyword matching with vector similarity, fused via Reciprocal Rank Fusion (RRF). This gives you the best of both worlds: precise keyword matching for exact terms and semantic understanding for natural language queries.
51
+
52
+ ## Vector embeddings
53
+
54
+ When content is indexed, each chunk (doc section, code symbol, file path, note, task, skill) is converted to a **vector embedding** — a list of ~1024 numbers that represent semantic meaning.
55
+
56
+ The default model is \`bge-m3\`, a multilingual transformer that runs locally. No API calls, no data leaves your machine.
57
+
58
+ Similar concepts produce similar vectors:
59
+ - "authentication" and "login" will have high similarity
60
+ - "authentication" and "database schema" will have low similarity
61
+
62
+ ### What gets embedded
63
+
64
+ | Graph | What's embedded | Embedding input |
65
+ |-------|-----------------|-----------------|
66
+ | DocGraph | Each section/heading | Section title + content text |
67
+ | DocGraph (file-level) | Each file root | File path + h1 title |
68
+ | CodeGraph | Each symbol | Symbol name + signature + docComment |
69
+ | CodeGraph (file-level) | Each file root | File path only |
70
+ | FileIndexGraph | Each file | File path |
71
+ | KnowledgeGraph | Each note | Note title + content |
72
+ | TaskGraph | Each task | Task title + description |
73
+ | SkillGraph | Each skill | Skill title + description |
74
+
75
+ ### Per-graph models
76
+
77
+ Each graph can use a different embedding model, configured in \`graph-memory.yaml\`:
78
+
79
+ \`\`\`yaml
80
+ projects:
81
+ my-app:
82
+ model:
83
+ name: Xenova/bge-m3 # default for all graphs
84
+ graphs:
85
+ docs:
86
+ model:
87
+ name: Xenova/bge-m3 # override for docs (whole object, no merge)
88
+ code:
89
+ model:
90
+ name: Xenova/bge-base-en-v1.5
91
+ # knowledge, tasks, files, skills inherit project.model
92
+ \`\`\`
93
+
94
+ Model resolution: \`graph.model → project.model → server.model → defaults\`. Each level is a complete config block — no field-by-field merge. Embedding config (\`batchSize\`, \`maxChars\`, etc.) is separate and merges field-by-field.
95
+
96
+ ## Cosine similarity
97
+
98
+ To compare a search query against indexed content, both are converted to vectors, then compared using **cosine similarity** (dot product of L2-normalized vectors).
99
+
100
+ Score ranges from 0 to 1:
101
+ - **> 0.7** — very relevant
102
+ - **0.5 - 0.7** — probably relevant
103
+ - **< 0.5** — weak match
104
+
105
+ The default \`minScore\` threshold is **0.5** for node search and **0.3** for file-level search.
106
+
107
+ ## BFS graph expansion
108
+
109
+ After finding the top-K most similar nodes, the search expands outward through the graph using **breadth-first search** (BFS):
110
+
111
+ 1. Start with the top-K seed nodes
112
+ 2. Follow edges to neighboring nodes (linked sections, related code symbols, connected notes)
113
+ 3. Each hop applies a **decay factor** (default 0.8) — relevance decreases with distance
114
+ 4. Continue up to \`bfsDepth\` hops (default 1)
115
+
116
+ This is powerful because relevant content is often **near** other relevant content in the graph.
117
+
118
+ ### What edges are followed
119
+
120
+ | Graph | Edge types followed during BFS |
121
+ |-------|-------------------------------|
122
+ | DocGraph | \`sibling\` (next section), \`cross-file link\` (markdown links) |
123
+ | CodeGraph | \`contains\` (file→symbol), \`imports\`, \`extends\`, \`implements\` |
124
+ | KnowledgeGraph | All relation edges between notes |
125
+ | TaskGraph | \`subtask_of\`, \`blocks\`, \`related_to\` |
126
+ | SkillGraph | \`depends_on\`, \`related_to\`, \`variant_of\` |
127
+
128
+ ## Hybrid scoring: BM25 + Vector
129
+
130
+ Each search combines two ranking methods:
131
+
132
+ 1. **Vector search** — cosine similarity between query embedding and node embedding (finds semantically similar content)
133
+ 2. **BM25 keyword search** — classic TF-IDF term matching (finds exact keyword matches)
134
+
135
+ Results are fused using **Reciprocal Rank Fusion (RRF)**:
136
+ \`\`\`
137
+ score(d) = 1/(k + rank_vector) + 1/(k + rank_bm25)
138
+ \`\`\`
139
+
140
+ This means a document ranked highly by both methods gets the highest fused score. A document ranked highly by only one method still appears, but lower.
141
+
142
+ ### BM25 tokenizer
143
+
144
+ The BM25 tokenizer splits text on whitespace, punctuation, and **camelCase boundaries**:
145
+ - \`getUserById\` → \`[get, user, by, id]\`
146
+ - \`AuthService\` → \`[auth, service]\`
147
+ - \`XMLParser\` → \`[xml, parser]\`
148
+
149
+ This makes it effective for searching code symbols by partial name.
150
+
151
+ ### Search mode
152
+
153
+ All search tools accept a \`searchMode\` parameter:
154
+
155
+ | Mode | Description |
156
+ |------|-------------|
157
+ | \`hybrid\` (default) | BM25 + vector, fused with RRF |
158
+ | \`vector\` | Embedding similarity only (original behavior) |
159
+ | \`keyword\` | BM25 keyword matching only |
160
+
161
+ Use \`vector\` mode when you want pure semantic search. Use \`keyword\` when you know the exact term.
162
+
163
+ ## Two types of search
164
+
165
+ ### Node search (hybrid + BFS)
166
+
167
+ Used by: \`search\`, \`search_code\`, \`search_notes\`, \`search_tasks\`, \`search_skills\`
168
+
169
+ Full parameter set:
170
+
171
+ | Parameter | Default | Description |
172
+ |-----------|---------|-------------|
173
+ | \`query\` | (required) | Natural language search query |
174
+ | \`topK\` | 5 | Number of seed nodes from hybrid scoring |
175
+ | \`bfsDepth\` | 1 | Hops to follow in graph expansion (0 = no expansion) |
176
+ | \`maxResults\` | 20 | Maximum results to return |
177
+ | \`minScore\` | 0.5 | Minimum relevance score (0–1) |
178
+ | \`bfsDecay\` | 0.8 | Score multiplier per hop |
179
+ | \`searchMode\` | \`hybrid\` | \`hybrid\`, \`vector\`, or \`keyword\` |
180
+
181
+ ### File-level search (cosine only)
182
+
183
+ Used by: \`search_topic_files\`, \`search_files\`, \`search_all_files\`, \`search_snippets\`
184
+
185
+ Simpler — no BFS expansion, just vector similarity:
186
+
187
+ | Parameter | Default | Description |
188
+ |-----------|---------|-------------|
189
+ | \`query\` | (required) | Search query |
190
+ | \`topK\` | 10 | Maximum results |
191
+ | \`minScore\` | 0.3 | Minimum relevance score (0–1) |
192
+
193
+ Lower \`minScore\` default because file path and code snippet embeddings are less semantically rich than full content.
194
+
195
+ ## All search tools at a glance
196
+
197
+ | Tool | Graph | Search type | What it searches |
198
+ |------|-------|-------------|-----------------|
199
+ | \`search\` | DocGraph | Node (BFS) | Documentation sections |
200
+ | \`search_topic_files\` | DocGraph | File-level | Documentation files |
201
+ | \`search_snippets\` | DocGraph | File-level | Code blocks in docs (+ language filter) |
202
+ | \`search_code\` | CodeGraph | Node (BFS) | Code symbols |
203
+ | \`search_files\` | CodeGraph | File-level | Source code files |
204
+ | \`search_all_files\` | FileIndexGraph | File-level | All project files |
205
+ | \`search_notes\` | KnowledgeGraph | Node (BFS) | Knowledge notes |
206
+ | \`search_tasks\` | TaskGraph | Node (BFS) | Tasks |
207
+ | \`search_skills\` | SkillGraph | Node (BFS) | Skills |
208
+
209
+ ## Tips
210
+
211
+ - Lower \`minScore\` (e.g., 0.3) to get more results when you're exploring
212
+ - Increase \`bfsDepth\` to 2 when you want to discover loosely related content
213
+ - Set \`bfsDepth: 0\` for pure vector search without graph expansion
214
+ - Use \`searchMode: 'keyword'\` when searching for exact symbol names like \`AuthService\`
215
+ - Use \`searchMode: 'vector'\` for pure semantic queries like "how does authentication work"
216
+ - File-level searches are faster — use them as a first pass before diving into node-level search
217
+ - The search query is embedded the same way as the content — so descriptive natural language works best
218
+ - All models run locally — first search after startup may be slow while the model loads
219
+ `},{id:`graph-structure`,title:`Graph Structure`,summary:`The six graphs: DocGraph, CodeGraph, FileIndexGraph, KnowledgeGraph, TaskGraph, SkillGraph.`,category:`concept`,relatedTools:[`list_topics`,`get_toc`,`get_node`,`list_files`,`get_file_symbols`,`get_symbol`,`list_all_files`,`get_file_info`,`list_notes`,`get_note`,`list_tasks`,`get_task`,`list_skills`,`get_skill`],content:`# Graph Structure
220
+
221
+ Graph Memory organizes project knowledge into six interconnected graphs. Each graph is a set of **nodes** (entities) connected by **edges** (relationships).
222
+
223
+ ## DocGraph
224
+
225
+ Indexes markdown documentation by parsing files into a hierarchy of sections.
226
+
227
+ **Nodes:**
228
+ - **File root** (level 1) — represents the markdown file itself
229
+ - **Sections** (level 2+) — headings and their content (\`# Title\`, \`## Subtitle\`)
230
+ - **Code blocks** — fenced code snippets extracted as child nodes with \`language\` and \`symbols\` fields
231
+
232
+ **Edges:**
233
+ - \`sibling\` — links consecutive sections within the same file
234
+ - \`cross-file link\` — when markdown contains \`[text](./other.md)\`, links to the target file
235
+
236
+ **Node IDs:** \`"guide.md"\` for file root, \`"guide.md::Setup"\` for sections, \`"guide.md::Setup::code-1"\` for code blocks.
237
+
238
+ ## CodeGraph
239
+
240
+ Indexes TypeScript/JavaScript source code using tree-sitter AST parsing.
241
+
242
+ **Nodes:**
243
+ - **File** — represents the source file
244
+ - **Symbols** — functions, classes, interfaces, types, variables, enums, methods
245
+
246
+ **Edges:**
247
+ - \`contains\` — file → symbol, class → method
248
+ - \`imports\` — file → imported file (resolved by import resolver)
249
+ - \`extends\` — class → base class
250
+ - \`implements\` — class → interface
251
+
252
+ **Node IDs:** \`"auth.ts"\` for file, \`"auth.ts::createUser"\` for top-level symbols, \`"auth.ts::AuthService::login"\` for methods.
253
+
254
+ ## FileIndexGraph
255
+
256
+ Indexes **every file and directory** in the project, regardless of docs/code patterns.
257
+
258
+ **Nodes:**
259
+ - **Files** — with size, language, MIME type, modification date
260
+ - **Directories** — with aggregate size and file count
261
+
262
+ **Edges:**
263
+ - \`contains\` — directory → child file or subdirectory
264
+
265
+ ## KnowledgeGraph
266
+
267
+ A manually curated graph for notes, facts, and decisions. Not populated by indexing — created through tools or the UI.
268
+
269
+ **Nodes:**
270
+ - **Notes** — title, content, tags, embedding
271
+
272
+ **Edges:**
273
+ - Free-form typed relations: \`relates_to\`, \`depends_on\`, \`contradicts\`, etc.
274
+ - **Cross-graph links** — can link to nodes in DocGraph, CodeGraph, FileIndexGraph, or TaskGraph via proxy nodes
275
+
276
+ ## TaskGraph
277
+
278
+ Task management with kanban workflow. Also manually curated.
279
+
280
+ **Nodes:**
281
+ - **Tasks** — title, description, status, priority, tags, dueDate, estimate, assignee
282
+
283
+ **Edges:**
284
+ - \`subtask_of\` — parent-child tasks
285
+ - \`blocks\` — dependency ordering
286
+ - \`related_to\` — loose associations
287
+ - **Cross-graph links** — can link to any other graph
288
+
289
+ ## SkillGraph
290
+
291
+ Stores reusable recipes and procedures. Also manually curated.
292
+
293
+ **Nodes:**
294
+ - **Skills** — title, description, steps[], triggers[], source (\`user\`|\`learned\`), tags, usageCount, lastUsedAt, confidence, embedding
295
+
296
+ **Edges:**
297
+ - \`depends_on\` — skill requires another skill
298
+ - \`related_to\` — loose associations
299
+ - \`variant_of\` — alternative approaches to the same goal
300
+ - **Cross-graph links** — can link to docs, code, files, knowledge, or tasks via proxy nodes
301
+
302
+ **Node IDs:** slug from title (\`"add-rest-endpoint"\`), dedup with suffix (\`"add-rest-endpoint::2"\`).
303
+
304
+ **Persistence:** \`skills.json\` in the graphMemory directory, mirrored to \`.skills/{id}/skill.md\`.
305
+
306
+ ## Cross-graph links
307
+
308
+ KnowledgeGraph, TaskGraph, and SkillGraph can create edges to nodes in other graphs using **proxy nodes**. A proxy is a lightweight placeholder node (e.g., \`@docs::guide.md::Setup\`) that represents an external entity.
309
+
310
+ This lets you create connections like:
311
+ - Note "Auth architecture" → links to \`auth.ts::AuthService\` in CodeGraph
312
+ - Task "Update auth docs" → links to \`guide.md\` in DocGraph
313
+ - Note "Config format" → links to \`src/config.ts\` in FileIndexGraph
314
+ - Skill "Add REST endpoint" → links to \`auth.ts::AuthService\` in CodeGraph
315
+ `},{id:`cross-graph`,title:`Cross-Graph Links`,summary:`How to link notes and tasks to code, docs, and files via proxy nodes.`,category:`concept`,relatedTools:[`create_relation`,`delete_relation`,`list_relations`,`create_task_link`,`delete_task_link`,`create_skill_link`,`delete_skill_link`,`find_linked_notes`,`find_linked_tasks`,`find_linked_skills`],content:'# Cross-Graph Links\n\nOne of Graph Memory\'s most powerful features is the ability to **link knowledge across different graphs**. A note can reference a code symbol, a task can link to documentation, and everything stays connected.\n\n## How it works\n\nWhen you create a cross-graph link (via `create_relation`, `create_task_link`, or `create_skill_link`), the system creates a **proxy node** — a lightweight placeholder in the source graph that represents a node from another graph.\n\nProxy node IDs follow the format `@{graph}::{nodeId}`:\n- `@docs::guide.md::Setup` — a doc section\n- `@code::auth.ts::AuthService` — a code symbol\n- `@files::src/config.ts` — a file\n- `@tasks::fix-auth-bug` — a task\n- `@knowledge::auth-architecture` — a note\n- `@skills::add-rest-endpoint` — a skill\n\n## Creating cross-graph links\n\n### From Knowledge (notes)\n\nUse `create_relation` with the `targetGraph` parameter:\n\n```\ncreate_relation({\n fromId: "auth-architecture",\n toId: "auth.ts::AuthService",\n kind: "documents",\n targetGraph: "code"\n})\n```\n\nSupported target graphs: `docs`, `code`, `files`, `tasks`, `skills`\n\n### From Tasks\n\nUse `create_task_link` with the `targetGraph` parameter:\n\n```\ncreate_task_link({\n taskId: "update-auth-docs",\n targetId: "guide.md::Authentication",\n kind: "relates_to",\n targetGraph: "docs"\n})\n```\n\nSupported target graphs: `docs`, `code`, `files`, `knowledge`, `skills`\n\n### From Skills\n\nUse `create_skill_link` with the `targetGraph` parameter:\n\n```\ncreate_skill_link({\n skillId: "add-rest-endpoint",\n targetId: "api-guide.md::REST",\n kind: "relates_to",\n targetGraph: "docs"\n})\n```\n\nSupported target graphs: `docs`, `code`, `files`, `knowledge`, `tasks`\n\n## Discovering cross-graph links\n\n- `find_linked_notes` — find all notes linked to a specific external node\n- `find_linked_tasks` — find all tasks linked to a specific external node\n- `find_linked_skills` — find all skills linked to a specific external node\n- `list_relations` — list all relations for a note (including cross-graph)\n- `get_task` — returns enriched task data including all cross-graph links\n- `get_skill` — returns enriched skill data including all cross-graph links\n\n## Proxy cleanup\n\nProxy nodes are automatically cleaned up when:\n- The source note, task, or skill is deleted (orphaned proxies removed)\n- The relation/link is explicitly deleted\n- During indexing, if the target file no longer exists\n\n## Use cases\n\n- **Architecture decisions**: Create notes documenting why code is structured a certain way, link to the actual code symbols\n- **Task context**: Link tasks to the files and docs they affect for quick navigation\n- **Knowledge mapping**: Build a web of connections between concepts, implementations, and documentation\n- **Reusable skills**: Link skills to the code, docs, and tasks they relate to so they can be recalled in context\n'},{id:`mcp-setup`,title:`Connecting MCP Clients`,summary:`How to connect Claude Desktop, Cursor, Windsurf, and other MCP clients via HTTP.`,category:`guide`,relatedTools:[`get_context`],content:`# Connecting MCP Clients
316
+
317
+ Graph Memory uses HTTP transport for MCP clients. Start the server, then connect your client to the MCP endpoint.
318
+
319
+ ## Setup
320
+
321
+ Start the server first:
322
+
323
+ \`\`\`bash
324
+ graphmemory serve --config graph-memory.yaml
325
+ \`\`\`
326
+
327
+ Each project gets its own MCP endpoint at \`http://localhost:3000/mcp/{projectId}\`.
328
+
329
+ ### Claude Desktop
330
+
331
+ Add via **Settings > Connectors** in the Claude Desktop app, enter the URL:
332
+
333
+ \`\`\`
334
+ http://localhost:3000/mcp/my-app
335
+ \`\`\`
336
+
337
+ ### Claude Code
338
+
339
+ Run in your project directory:
340
+
341
+ \`\`\`bash
342
+ claude mcp add --transport http --scope project graph-memory http://localhost:3000/mcp/my-app
343
+ \`\`\`
344
+
345
+ Or add to \`.mcp.json\` manually:
346
+
347
+ \`\`\`json
348
+ {
349
+ "mcpServers": {
350
+ "graph-memory": {
351
+ "type": "http",
352
+ "url": "http://localhost:3000/mcp/my-app"
353
+ }
354
+ }
355
+ }
356
+ \`\`\`
357
+
358
+ ### Cursor / Windsurf / Other clients
359
+
360
+ Enter the MCP URL directly in your client's server configuration:
361
+
362
+ \`\`\`
363
+ http://localhost:3000/mcp/{projectId}
364
+ \`\`\`
365
+
366
+ ## Docker
367
+
368
+ \`\`\`bash
369
+ docker run -d \\
370
+ --name graph-memory \\
371
+ -p 3000:3000 \\
372
+ -v $(pwd)/graph-memory.yaml:/data/config/graph-memory.yaml:ro \\
373
+ -v /path/to/my-app:/data/projects/my-app \\
374
+ -v graph-memory-models:/data/models \\
375
+ ghcr.io/graph-memory/graphmemory-server
376
+ \`\`\`
377
+
378
+ Then connect your MCP client to \`http://localhost:3000/mcp/my-app\`.
379
+
380
+ To index once and exit without starting the server:
381
+
382
+ \`\`\`bash
383
+ # Docker
384
+ docker run --rm \\
385
+ -v $(pwd)/graph-memory.yaml:/data/config/graph-memory.yaml:ro \\
386
+ -v /path/to/my-app:/data/projects/my-app \\
387
+ -v graph-memory-models:/data/models \\
388
+ ghcr.io/graph-memory/graphmemory-server index --config /data/config/graph-memory.yaml
389
+
390
+ # Docker Compose (uses volumes defined in your compose file)
391
+ docker compose run --rm graph-memory index --config /data/config/graph-memory.yaml
392
+ \`\`\`
393
+
394
+ ## Troubleshooting
395
+
396
+ **Model loading is slow on first start**: The embedding model (\`Xenova/bge-m3\`, ~560MB) is downloaded on first use. Subsequent starts use the cached model from \`~/.graph-memory/models/\` (or the configured \`modelsDir\`).
397
+
398
+ **Port already in use**: Change the port in \`graph-memory.yaml\` under \`server.port\`, or stop the existing process.
399
+
400
+ **Tools not showing up**: Make sure \`graphs.docs.include\` and/or \`graphs.code.include\` are set in your config (defaults: \`**/*.md\` and \`**/*.{js,ts,jsx,tsx}\`). If a graph is \`enabled: false\`, its tools won't be registered.
401
+
402
+ **Config changes not taking effect**: Restart the server process to apply changes to \`graph-memory.yaml\`.
403
+ `},{id:`configuration`,title:`Configuration Guide`,summary:`All graph-memory.yaml settings: server, projects, workspaces, embedding models, and patterns.`,category:`guide`,relatedTools:[],content:`# Configuration Guide
404
+
405
+ All configuration is done via a single \`graph-memory.yaml\` file. This guide covers every setting and common patterns.
406
+
407
+ ## Basic structure
408
+
409
+ \`\`\`yaml
410
+ author:
411
+ name: "Your Name"
412
+ email: "you@example.com"
413
+
414
+ server:
415
+ port: 3000
416
+
417
+ projects:
418
+ my-app:
419
+ projectDir: "/path/to/my-app"
420
+ \`\`\`
421
+
422
+ The only required field is \`projects.*.projectDir\`. Everything else has sensible defaults (docs indexes \`**/*.md\`, code indexes \`**/*.{js,ts,jsx,tsx}\`).
423
+
424
+ ## Author settings
425
+
426
+ The \`author\` block sets who is recorded as the creator/updater of notes, tasks, and skills. Written in git-style format (\`"Name <email>"\`) in mirror files.
427
+
428
+ \`\`\`yaml
429
+ author:
430
+ name: "Your Name"
431
+ email: "you@example.com"
432
+ \`\`\`
433
+
434
+ Can be overridden per project or per workspace.
435
+
436
+ ## Server settings
437
+
438
+ | Field | Default | Description |
439
+ |---|---|---|
440
+ | \`host\` | \`127.0.0.1\` | Bind address. Use \`0.0.0.0\` for Docker or remote access |
441
+ | \`port\` | \`3000\` | HTTP server port |
442
+ | \`sessionTimeout\` | \`1800\` | Idle MCP session timeout in seconds (30 min) |
443
+ | \`modelsDir\` | \`~/.graph-memory/models\` | Where embedding models are cached locally |
444
+ | \`corsOrigins\` | — | Allowed CORS origins (array of strings) |
445
+ | \`defaultAccess\` | \`rw\` | Default access for unknown users: \`deny\`, \`r\`, \`rw\` |
446
+ | \`embedding.model\` | \`Xenova/bge-m3\` | Default model for all graphs |
447
+ | \`embedding.remote\` | — | Remote embedding API URL (delegates instead of local model) |
448
+ | \`embedding.remoteApiKey\` | — | API key for remote embedding |
449
+ | \`embeddingApi.enabled\` | \`false\` | Expose local model via \`POST /api/embed\` |
450
+ | \`embeddingApi.apiKey\` | — | API key for the embedding endpoint |
451
+
452
+ ## Project settings
453
+
454
+ Each project needs at least \`projectDir\`:
455
+
456
+ | Field | Default | Description |
457
+ |---|---|---|
458
+ | \`projectDir\` | **(required)** | Root directory to index |
459
+ | \`graphMemory\` | \`.graph-memory\` | Where graph JSON files are stored (relative to projectDir) |
460
+ | \`exclude\` | — | Additional glob to exclude (merged with server default \`**/node_modules/**,**/dist/**\`) |
461
+ | \`chunkDepth\` | \`4\` | Max heading depth for markdown chunking |
462
+ | \`embedding.maxChars\` | \`8000\` | Max characters fed to the embedding model per node (inherits: graph → project → workspace → server) |
463
+ | \`access\` | — | Per-user access overrides for this project |
464
+
465
+ > **Legacy fields:** \`docsPattern\` and \`codePattern\` have been removed. Use \`graphs.docs.include\` and \`graphs.code.include\` instead.
466
+
467
+ ### Per-graph configuration
468
+
469
+ Each graph can be individually configured with \`enabled\`, \`include\`, \`exclude\`, \`embedding\`, and \`access\`:
470
+
471
+ \`\`\`yaml
472
+ projects:
473
+ my-app:
474
+ projectDir: "/path/to/my-app"
475
+ graphs:
476
+ docs:
477
+ enabled: true # Set false to disable this graph
478
+ include: "**/*.md" # Default — indexes all markdown files
479
+ exclude: "**/archive/**" # Glob to exclude
480
+ model: # Full model config (whole object, no merge with parent)
481
+ name: "Xenova/bge-m3"
482
+ pooling: "cls"
483
+ normalize: true
484
+ access: # Per-graph access control
485
+ bob: rw
486
+ code:
487
+ enabled: true
488
+ include: "**/*.{js,ts,jsx,tsx}" # Default — indexes all JS/TS files
489
+ model:
490
+ name: "Xenova/bge-base-en-v1.5"
491
+ knowledge:
492
+ access:
493
+ bob: rw # bob gets rw on knowledge
494
+ tasks:
495
+ enabled: true
496
+ files:
497
+ enabled: true
498
+ skills:
499
+ enabled: true
500
+ \`\`\`
501
+
502
+ Graphs without a specific \`embedding\` block use the project-level \`embedding\`, then the server-level \`embedding\`. The same model string is loaded only once, even if used by multiple graphs.
503
+
504
+ Graph-level \`embedding\` is a complete block (first-defined-wins, no field-by-field merge with parent).
505
+
506
+ ## Workspaces
507
+
508
+ Workspaces let multiple projects share the same knowledge, task, and skill graphs. Each project keeps its own docs, code, and file index graphs.
509
+
510
+ \`\`\`yaml
511
+ projects:
512
+ api-gateway:
513
+ projectDir: "./api-gateway"
514
+
515
+ catalog-service:
516
+ projectDir: "./catalog-service"
517
+
518
+ workspaces:
519
+ backend:
520
+ projects: [api-gateway, catalog-service]
521
+ graphMemory: "./.workspace-backend"
522
+ mirrorDir: "./.workspace-backend"
523
+ author:
524
+ name: "Backend Team"
525
+ email: "backend@example.com"
526
+ \`\`\`
527
+
528
+ | Field | Description |
529
+ |---|---|
530
+ | \`projects\` | List of project IDs that share this workspace |
531
+ | \`graphMemory\` | Where shared graph JSON files are stored |
532
+ | \`mirrorDir\` | Where shared \`.notes/\`, \`.tasks/\`, \`.skills/\` mirror files are written |
533
+ | \`author\` | Author for shared notes/tasks/skills (overrides root author) |
534
+ | \`access\` | Per-user access for shared graphs (overrides \`server.access\`) |
535
+ | \`embedding\` | Embedding config for shared graphs (overrides \`server.embedding\`) |
536
+
537
+ ## Users & authentication
538
+
539
+ Define users for REST API and UI authentication.
540
+
541
+ \`\`\`yaml
542
+ users:
543
+ alice:
544
+ name: "Alice"
545
+ email: "alice@example.com"
546
+ apiKey: "mgm-key-abc123"
547
+ passwordHash: "$scrypt$16384$8$1$salt$hash" # generated by: graphmemory users add
548
+
549
+ server:
550
+ jwtSecret: "your-secret-key-here" # required when users are defined
551
+ accessTokenTtl: "15m" # JWT access token lifetime (default: 15m)
552
+ refreshTokenTtl: "7d" # JWT refresh token lifetime (default: 7d)
553
+ \`\`\`
554
+
555
+ | Field | Description |
556
+ |---|---|
557
+ | \`name\` | Display name (used as createdBy/updatedBy in notes/tasks/skills) |
558
+ | \`email\` | Email address (for UI login and mirror files) |
559
+ | \`apiKey\` | Bearer token for programmatic API/MCP access |
560
+ | \`passwordHash\` | Scrypt hash for UI password login (generate with \`graphmemory users add\`) |
561
+
562
+ Two authentication methods:
563
+ - **UI login**: email + password → JWT cookies (httpOnly, SameSite=Strict)
564
+ - **API access**: \`Authorization: Bearer <apiKey>\` header
565
+
566
+ When a user authenticates, their \`name\` and \`email\` are used as the author for mutations, overriding the root \`author\` config.
567
+
568
+ ## Access control
569
+
570
+ Access control restricts who can read or write to projects, workspaces, and individual graphs. Access levels are \`deny\`, \`r\` (read-only), or \`rw\` (read-write).
571
+
572
+ ### Server-level defaults
573
+
574
+ \`\`\`yaml
575
+ server:
576
+ defaultAccess: rw # Access for users not listed in access maps
577
+ access: # Server-level per-user access
578
+ alice: rw
579
+ bob: r
580
+ \`\`\`
581
+
582
+ \`defaultAccess\` applies to any authenticated user not explicitly listed. Default is \`rw\`.
583
+
584
+ ### Per-project access
585
+
586
+ \`\`\`yaml
587
+ projects:
588
+ my-app:
589
+ projectDir: "/path/to/my-app"
590
+ access:
591
+ bob: rw # bob gets rw on this project (overrides server.access)
592
+ \`\`\`
593
+
594
+ ### Per-workspace access
595
+
596
+ \`\`\`yaml
597
+ workspaces:
598
+ backend:
599
+ projects: [api-gateway, catalog-service]
600
+ access:
601
+ alice: rw
602
+ bob: r # bob gets read-only on shared graphs
603
+ \`\`\`
604
+
605
+ ### Per-graph access
606
+
607
+ \`\`\`yaml
608
+ projects:
609
+ my-app:
610
+ projectDir: "/path/to/my-app"
611
+ access:
612
+ bob: r # bob is read-only on this project...
613
+ graphs:
614
+ knowledge:
615
+ access:
616
+ bob: rw # ...but gets rw on knowledge specifically
617
+ \`\`\`
618
+
619
+ ### Resolution order
620
+
621
+ Access is resolved from most specific to least specific:
622
+
623
+ 1. **Graph-level** \`access\` (e.g., \`graphs.knowledge.access.bob\`)
624
+ 2. **Project-level** \`access\` (e.g., \`projects.my-app.access.bob\`)
625
+ 3. **Workspace-level** \`access\` (for shared graphs)
626
+ 4. **Server-level** \`access\` (e.g., \`server.access.bob\`)
627
+ 5. **\`server.defaultAccess\`** (fallback, default \`rw\`)
628
+
629
+ ## Team directory setup
630
+
631
+ For team environments, combine \`users\` with access control to give each team member appropriate permissions:
632
+
633
+ \`\`\`yaml
634
+ users:
635
+ alice:
636
+ name: "Alice (Tech Lead)"
637
+ email: "alice@company.com"
638
+ apiKey: "mgm-key-alice-secret"
639
+ bob:
640
+ name: "Bob (Developer)"
641
+ email: "bob@company.com"
642
+ apiKey: "mgm-key-bob-secret"
643
+ ci:
644
+ name: "CI Bot"
645
+ email: "ci@company.com"
646
+ apiKey: "mgm-key-ci-secret"
647
+
648
+ server:
649
+ defaultAccess: deny # Deny unknown users
650
+ access:
651
+ alice: rw
652
+ bob: rw
653
+ ci: r # CI can only read
654
+
655
+ projects:
656
+ production-app:
657
+ projectDir: "/path/to/app"
658
+ access:
659
+ ci: r # CI can read project data
660
+ \`\`\`
661
+
662
+ ## Embedding API configuration
663
+
664
+ Expose the server's local embedding model as an HTTP API for other services or Graph Memory instances to use:
665
+
666
+ \`\`\`yaml
667
+ server:
668
+ embeddingApi:
669
+ enabled: true # Enable POST /api/embed endpoint
670
+ apiKey: "emb-secret-key" # API key for embedding requests (separate from user apiKeys)
671
+ \`\`\`
672
+
673
+ When enabled, \`POST /api/embed\` accepts \`{ text: "..." }\` or \`{ texts: ["..."] }\` and returns embeddings from the server's configured model. Authenticate with \`Authorization: Bearer <apiKey>\` using the \`embeddingApi.apiKey\`.
674
+
675
+ ## Remote embedding setup
676
+
677
+ Instead of running the embedding model locally, delegate to a remote embedding API (e.g., another Graph Memory instance with \`embeddingApi\` enabled, or any compatible service):
678
+
679
+ \`\`\`yaml
680
+ server:
681
+ model:
682
+ name: "Xenova/bge-m3"
683
+ embedding:
684
+ remote: "http://gpu-server:3000/api/embed"
685
+ remoteApiKey: "emb-secret-key"
686
+ \`\`\`
687
+
688
+ When \`remote\` is set, the server sends embedding requests to the remote URL instead of loading the model locally. This is useful for:
689
+ - Running on machines without GPU/enough RAM for the model
690
+ - Sharing a single model instance across multiple Graph Memory servers
691
+ - Using a dedicated embedding service
692
+
693
+ The \`remote\` and \`remoteApiKey\` fields can be set at server, project, or graph level following the same embedding resolution order.
694
+
695
+ ## CORS origins
696
+
697
+ Configure allowed origins for Cross-Origin Resource Sharing when the UI or API is accessed from a different domain:
698
+
699
+ \`\`\`yaml
700
+ server:
701
+ corsOrigins:
702
+ - "http://localhost:5173" # Vite dev server
703
+ - "https://my-app.example.com" # Production frontend
704
+ \`\`\`
705
+
706
+ When \`corsOrigins\` is not set, CORS headers are not added. Set this when the web UI or REST API is accessed from a different origin than the server.
707
+
708
+ ## Common patterns
709
+
710
+ ### Docs-only project (no code indexing)
711
+
712
+ \`\`\`yaml
713
+ projects:
714
+ wiki:
715
+ projectDir: "/path/to/wiki"
716
+ graphs:
717
+ docs:
718
+ include: "**/*.md"
719
+ code:
720
+ enabled: false
721
+ \`\`\`
722
+
723
+ ### Code-only project (no docs)
724
+
725
+ \`\`\`yaml
726
+ projects:
727
+ library:
728
+ projectDir: "/path/to/library"
729
+ graphs:
730
+ docs:
731
+ enabled: false
732
+ code:
733
+ include: "src/**/*.ts"
734
+ \`\`\`
735
+
736
+ ### Multiple exclude patterns
737
+
738
+ \`\`\`yaml
739
+ projects:
740
+ my-app:
741
+ projectDir: "/path/to/my-app"
742
+ exclude: "**/coverage/**,**/.git/**"
743
+ \`\`\`
744
+
745
+ ### Docker deployment
746
+
747
+ \`\`\`yaml
748
+ server:
749
+ host: "0.0.0.0"
750
+ port: 3000
751
+ modelsDir: "/data/models"
752
+
753
+ projects:
754
+ my-app:
755
+ projectDir: "/data/projects/my-app"
756
+ \`\`\`
757
+
758
+ ## Applying config changes
759
+
760
+ Restart the server process to apply changes to \`graph-memory.yaml\`.
761
+
762
+ ## Automatic re-indexing
763
+
764
+ Each graph stores which embedding model was used. If you change the model in config, the graph is automatically discarded and re-indexed on next startup — no \`--reindex\` flag needed.
765
+ `},{id:`docs-tools`,title:`Documentation Tools`,summary:`Search, browse, and navigate indexed markdown documentation.`,category:`guide`,relatedTools:[`list_topics`,`get_toc`,`search`,`get_node`,`search_topic_files`,`find_examples`,`search_snippets`,`list_snippets`,`explain_symbol`],content:'# Documentation Tools\n\nThe docs tools let you search, browse, and navigate your indexed markdown documentation. They\'re available when `graphs.docs.include` is configured in your project (default: `**/*.md`).\n\n## Tool overview\n\n| Tool | Purpose | When to use |\n|------|---------|-------------|\n| `list_topics` | List all indexed files | Get an overview of available documentation |\n| `get_toc` | Get table of contents for a file | Understand the structure of a specific document |\n| `search` | Semantic search across all docs | Find information without knowing which file has it |\n| `get_node` | Get full content of a section | Read the actual content after finding it via search |\n| `search_topic_files` | Search at file level | Find which files are most relevant to a topic |\n| `find_examples` | Find code blocks containing a specific symbol | Look up usage examples of a known function/class |\n| `search_snippets` | Semantic search across code blocks | Find code examples by description |\n| `list_snippets` | List code blocks in a file | Discover what code examples exist in docs |\n| `explain_symbol` | Get symbol\'s code block + surrounding docs context | Understand what a symbol does via documentation |\n| `cross_references` | Find symbol across code AND docs | Most comprehensive symbol lookup (see dedicated guide) |\n\n## Typical workflow\n\n### 1. Discover what\'s documented\n\nStart with `list_topics` to see all indexed markdown files. This gives you file IDs and titles.\n\n### 2. Search by meaning\n\nUse `search` with a natural language query. For example:\n- `"how to set up authentication"` — finds auth-related sections\n- `"database migration process"` — finds migration docs\n\nThe search returns scored results with `id`, `title`, `content` preview, and `score`.\n\n### 3. Read full content\n\nTake the `id` from search results and pass it to `get_node` to read the full section content, including any code blocks.\n\n### 4. Navigate structure\n\nUse `get_toc` with a file ID to see the full heading hierarchy. This helps when you want to explore a specific document top-to-bottom.\n\n## Code block tools\n\nWhen markdown is indexed, fenced code blocks (` ```lang ... ``` `) are extracted as child nodes. TypeScript/JavaScript blocks are additionally parsed with tree-sitter to extract top-level symbol names into the `symbols` field. This enables powerful code example discovery.\n\n### find_examples\n\nSearches the `symbols` array of code blocks for an exact symbol name match. Use this when you know the function/class name and want to find documentation examples.\n\nReturns: `{ id, fileId, language, symbols, content, parentId, parentTitle }`\n\n### search_snippets\n\nSemantic search across code block nodes only. Unlike `find_examples` (exact name), this works with natural language descriptions like "authentication example" or "database query".\n\nSupports a `language` filter to narrow results (e.g., `"typescript"`, `"python"`).\n\nReturns: `{ id, fileId, language, symbols, content, score }`\n\n### list_snippets\n\nLists code blocks with optional filters. Useful for exploring what examples exist in a specific file.\n\nFilters: `fileId` (specific file), `language` (e.g., "typescript"), `filter` (substring match on content).\n\nReturns: `{ id, fileId, language, symbols, preview }`\n\n### explain_symbol\n\nThe most context-rich symbol lookup in docs. For each match, returns both the **code block** and the **parent text section** that provides narrative context/explanation around the example.\n\nReturns: `{ codeBlock: { id, language, symbols, content }, explanation: { id, title, content } | null, fileId }`\n\n## Tool reference\n\n### list_topics\n\nList indexed documentation files with optional filtering.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `filter` | string | No | — | Case-insensitive substring to match against file paths |\n| `limit` | number | No | 20 | Maximum number of results |\n\n**Returns:** `[{ fileId, title, chunks }]`\n\n### get_toc\n\nReturn the table of contents (heading hierarchy) for a specific file.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fileId` | string | Yes | File path relative to docs dir, e.g. `"docs/auth.md"` |\n\n**Returns:** `[{ id, title, level }]` — `id` can be passed to `get_node`\n\n### search\n\nSemantic search over all indexed documentation sections.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | — | Natural language search query |\n| `topK` | number | No | 5 | Number of seed nodes (1–500) |\n| `bfsDepth` | number | No | 1 | Hops to follow cross-document links (0–10) |\n| `maxResults` | number | No | 20 | Maximum results (1–500) |\n| `minScore` | number | No | 0.5 | Minimum relevance score (0–1) |\n| `bfsDecay` | number | No | 0.8 | Score multiplier per graph hop (0–1) |\n| `searchMode` | string | No | `hybrid` | `hybrid`, `vector`, or `keyword` |\n\n**Returns:** `[{ id, fileId, title, content, level, score }]`\n\n### get_node\n\nReturn the full content of a specific doc node (file root or section).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `nodeId` | string | Yes | Node ID, e.g. `"docs/auth.md"` or `"docs/auth.md::Overview"` |\n\n**Returns:** `{ id, fileId, title, content, level, links, mtime }`\n\nNode IDs have two forms:\n- `"docs/auth.md"` — file root (intro text before first heading)\n- `"docs/auth.md::Overview"` — named section\n- `"docs/auth.md::Overview::code-1"` — code block within a section\n\n### search_topic_files\n\nSemantic search at file level (not section level). Faster than `search` when you just need to identify relevant files.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | — | Natural language search query |\n| `topK` | number | No | 10 | Maximum results |\n| `minScore` | number | No | 0.3 | Minimum relevance score (0–1) |\n\n**Returns:** `[{ fileId, title, chunks, score }]`\n\n### find_examples\n\nFind code blocks containing a specific symbol by exact name match.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `symbol` | string | Yes | — | Symbol name, e.g. `"createUser"`, `"UserService"` |\n| `limit` | number | No | 20 | Max results |\n\n**Returns:** `[{ id, fileId, language, symbols, content, parentId, parentTitle }]`\n\n### search_snippets\n\nSemantic search over code block nodes only.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | — | Natural language search query |\n| `topK` | number | No | 10 | Max results |\n| `minScore` | number | No | 0.3 | Minimum relevance score (0–1) |\n| `language` | string | No | — | Filter by language (e.g., `"typescript"`, `"python"`) |\n\n**Returns:** `[{ id, fileId, language, symbols, content, score }]`\n\n### list_snippets\n\nList code blocks with optional filters.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `fileId` | string | No | — | Filter by file |\n| `filter` | string | No | — | Substring match on content (case-insensitive) |\n| `language` | string | No | — | Filter by language |\n| `limit` | number | No | 20 | Max results |\n\n**Returns:** `[{ id, fileId, language, symbols, preview }]`\n\n### explain_symbol\n\nFind documentation that explains a symbol — returns both code example and surrounding text.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `symbol` | string | Yes | — | Symbol name, e.g. `"createUser"` |\n| `limit` | number | No | 10 | Max results |\n\n**Returns:** `[{ codeBlock: { id, language, symbols, content }, explanation: { id, title, content } | null, fileId }]`\n\n## Tips\n\n- Use `search` for broad exploration, `get_node` for targeted reading\n- `search_topic_files` is faster than `search` when you just need to know which file covers a topic\n- `find_examples` is for exact symbol name lookup; `search_snippets` is for natural language queries\n- `explain_symbol` gives the richest context — both the code example and the documentation around it\n- Lower `minScore` to 0.3 when exploring unfamiliar codebases\n- Set `bfsDepth: 0` in `search` for pure vector search without graph expansion\n- Set `bfsDepth: 2` to discover more loosely related content\n'},{id:`code-tools`,title:`Code Tools`,summary:`Search and navigate TypeScript/JavaScript source code symbols.`,category:`guide`,relatedTools:[`list_files`,`get_file_symbols`,`search_code`,`get_symbol`,`search_files`],content:'# Code Tools\n\nThe code tools let you search and navigate your indexed TypeScript/JavaScript source code. They\'re available when `graphs.code.include` is configured in your project (default: `**/*.{js,ts,jsx,tsx}`).\n\n## Tool overview\n\n| Tool | Purpose | When to use |\n|------|---------|-------------|\n| `list_files` | List all indexed source files | Get an overview of the codebase |\n| `get_file_symbols` | List symbols in a file | Explore a file\'s exports and structure |\n| `search_code` | Semantic search across code symbols | Find functions/classes by what they do |\n| `get_symbol` | Get full details of a symbol | Read signature, JSDoc, body, line numbers |\n| `search_files` | Search at file level | Find which files are relevant to a topic |\n\n## What gets indexed\n\nThe code parser uses tree-sitter to extract:\n- **Functions** — declarations, arrow functions, function expressions, ambient (`declare function`)\n- **Classes** — concrete and abstract, with constructors, methods, and fields as children\n- **Interfaces** — with method signatures and property signatures as children\n- **Types** and **Enums** — name, signature\n- **Variables** — exported and non-exported (`const`, `let`)\n- **Constructors** — extracted as `kind: \'constructor\'` (distinct from methods)\n- **Nested functions** — named functions inside function bodies (1 level deep)\n- **Generic types** — `Foo<T>` extracts base name `"Foo"` for extends/implements edges\n\nEdges capture structural relationships:\n- `contains` — file → symbol, class → method\n- `imports` — file → imported file (resolved by import resolver)\n- `extends` — class → base class\n- `implements` — class → interface\n\n## Node ID format\n\nCode graph node IDs follow a hierarchical pattern:\n- `"src/auth.ts"` — file node\n- `"src/auth.ts::createUser"` — top-level symbol in file\n- `"src/auth.ts::AuthService::login"` — method within a class\n\n## Typical workflow\n\n### 1. Find code by meaning\n\nUse `search_code` with a description of what you\'re looking for:\n- `"user authentication"` — finds auth-related functions and classes\n- `"parse markdown into sections"` — finds parsing logic\n\nUnlike grep, this finds code by **what it does**, not by exact text matches.\n\n### 2. Explore a symbol\n\nUse `get_symbol` with the symbol ID from search results. This returns the full picture: signature, JSDoc comment, body text, file location, line numbers, export status.\n\n### 3. Understand file structure\n\nUse `get_file_symbols` to see all symbols in a file — helpful for understanding module organization. The result includes `isExported` flag to distinguish public API from internal helpers.\n\n### 4. Discover relevant files\n\nUse `search_files` for a quick file-level search before diving into symbols. Lighter than `search_code` when you just need to identify which files to explore.\n\n### 5. Cross-reference with docs\n\nUse `cross_references` (requires both `graphs.docs.include` and `graphs.code.include`) to find everywhere a symbol appears — in both code definitions and documentation examples. See the dedicated guide for details.\n\n## Tool reference\n\n### list_files\n\nList indexed source files with optional filtering.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `filter` | string | No | — | Case-insensitive substring to match against file paths, e.g. `"graph"` or `"src/lib"` |\n| `limit` | number | No | 20 | Maximum number of results |\n\n**Returns:** `[{ fileId, symbolCount }]`\n\n### get_file_symbols\n\nReturn all symbols declared in a specific file.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fileId` | string | Yes | File path, e.g. `"src/lib/graph.ts"` |\n\n**Returns:** `[{ id, kind, name, signature, startLine, endLine, isExported }]`\n\nSymbol kinds: `function`, `class`, `interface`, `type`, `enum`, `variable`, `method`, `constructor`.\n\n### search_code\n\nSemantic search over code symbols. Matches against signatures and doc comments using vector similarity, then expands through graph edges.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | — | Natural language or code search query |\n| `topK` | number | No | 5 | Number of seed nodes (1–500) |\n| `bfsDepth` | number | No | 1 | Hops to follow graph edges (0–10). 0 = no expansion |\n| `maxResults` | number | No | 20 | Maximum results to return (1–500) |\n| `minScore` | number | No | 0.3 | Minimum relevance score (0–1) |\n| `bfsDecay` | number | No | 0.8 | Score multiplier per graph hop (0–1) |\n| `searchMode` | string | No | `hybrid` | `hybrid`, `vector`, or `keyword` |\n| `includeBody` | boolean | No | `false` | Include full body text in results |\n\n**Returns:** `[{ id, fileId, kind, name, signature, docComment, startLine, endLine, score, body? }]`\n\n### get_symbol\n\nReturn full details of a specific code symbol.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `nodeId` | string | Yes | Symbol ID, e.g. `"src/lib/graph.ts::updateFile"` or `"src/auth.ts::AuthService::login"` |\n\n**Returns:** `{ id, fileId, kind, name, signature, docComment, body, startLine, endLine, isExported }`\n\nThe `body` field contains the full implementation text. `docComment` contains the JSDoc comment if present.\n\n### search_files\n\nSemantic search at file level using file path embeddings.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | — | Natural language or path search query |\n| `topK` | number | No | 10 | Maximum results |\n| `minScore` | number | No | 0.3 | Minimum relevance score (0–1) |\n\n**Returns:** `[{ fileId, symbolCount, score }]`\n\n## Tips\n\n- `search_code` works best with descriptive queries about **what the code does**, not exact symbol names\n- For exact name lookup, use `get_symbol` directly with the node ID\n- `get_file_symbols` shows `isExported` — useful for distinguishing public API from internals\n- `search_files` is useful as a first step when exploring unfamiliar codebases\n- The `cross_references` tool (see dedicated guide) is the most comprehensive way to understand a symbol\n- BFS expansion in `search_code` follows `imports`, `contains`, and `extends` edges — set `bfsDepth: 2` to discover related modules\n- Code graph edges track `imports` for relative imports and tsconfig path aliases (`@/lib/foo`); external packages are skipped\n- BFS in `search_code` excludes reverse `imports` edges — popular utility files won\'t flood results\n'},{id:`knowledge-tools`,title:`Knowledge Tools`,summary:`Create and manage notes, facts, and decisions in a persistent knowledge graph.`,category:`guide`,relatedTools:[`create_note`,`update_note`,`delete_note`,`get_note`,`list_notes`,`search_notes`,`create_relation`,`delete_relation`,`list_relations`,`find_linked_notes`,`add_note_attachment`,`remove_note_attachment`],content:'# Knowledge Tools\n\nThe knowledge tools manage a persistent graph of **notes, facts, and decisions**. Unlike docs and code tools that index existing files, the knowledge graph is built manually — capturing information that lives in people\'s heads.\n\n## Why use a knowledge graph?\n\nCode and docs tell you **what** exists. The knowledge graph captures **why** — architectural decisions, domain knowledge, gotchas, context that doesn\'t belong in code comments.\n\nExamples:\n- "We use JWT instead of sessions because the mobile app needs stateless auth"\n- "The billing service has a 30-second timeout — don\'t chain more than 3 API calls"\n- "Users in the \'legacy\' tier have different rate limits, check `isLegacy` flag"\n\n## Tool overview\n\n| Tool | Purpose | Type |\n|------|---------|------|\n| `create_note` | Create a new note with title, content, tags | Mutation |\n| `update_note` | Update an existing note | Mutation |\n| `delete_note` | Remove a note and all its relations | Mutation |\n| `get_note` | Read a single note by ID | Read |\n| `list_notes` | List notes with optional filters | Read |\n| `search_notes` | Semantic search across notes | Read |\n| `create_relation` | Link a note to another note or external node | Mutation |\n| `delete_relation` | Remove a link | Mutation |\n| `list_relations` | List all relations for a note | Read |\n| `find_linked_notes` | Reverse lookup: find notes that link to an external node | Read |\n| `add_note_attachment` | Attach a file to a note | Mutation |\n| `remove_note_attachment` | Remove an attachment from a note | Mutation |\n\n> **Mutation tools** are serialized through a queue to prevent concurrent graph modifications.\n\n## Note ID generation\n\nNote IDs are slugified from the title:\n- "Auth Architecture" → `auth-architecture`\n- "JWT Token Format" → `jwt-token-format`\n\nDuplicate titles get a suffix: `auth-architecture::2`, `auth-architecture::3`.\n\n## Tool reference\n\n### create_note\n\nCreate a new note. Automatically embedded for semantic search.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `title` | string | Yes | Short title, e.g. `"Auth uses JWT tokens"` |\n| `content` | string | Yes | Full text content |\n| `tags` | string[] | No | Tags for filtering, e.g. `["architecture", "decision"]` |\n\n**Returns:** `{ noteId }` — the generated slug ID\n\n### update_note\n\nUpdate an existing note. Only provided fields change. Re-embeds automatically if title or content changes.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `noteId` | string | Yes | ID of the note to update |\n| `title` | string | No | New title |\n| `content` | string | No | New content |\n| `tags` | string[] | No | New tags (replaces existing array entirely) |\n\n**Returns:** `{ noteId, updated: true }`\n\n### delete_note\n\nDelete a note and all its connected edges (relations, cross-graph links). Orphaned proxy nodes are cleaned up automatically.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `noteId` | string | Yes | ID of the note to delete |\n\n**Returns:** `{ noteId, deleted: true }`\n\n### get_note\n\nReturn the full content of a note.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `noteId` | string | Yes | Note ID, e.g. `"auth-uses-jwt-tokens"` |\n\n**Returns:** `{ id, title, content, tags, createdAt, updatedAt }`\n\n### list_notes\n\nList notes with optional filtering. Sorted by most recently updated.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `filter` | string | No | — | Case-insensitive substring match on title or ID |\n| `tag` | string | No | — | Filter by tag (exact match, case-insensitive) |\n| `limit` | number | No | 20 | Maximum results |\n\n**Returns:** `[{ id, title, tags, updatedAt }]`\n\n### search_notes\n\nSemantic search over the knowledge graph with BFS expansion through note relations.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | — | Natural language search query |\n| `topK` | number | No | 5 | Number of seed nodes (1–500) |\n| `bfsDepth` | number | No | 1 | Hops to follow relations (0–10) |\n| `maxResults` | number | No | 20 | Maximum results (1–500) |\n| `minScore` | number | No | 0.5 | Minimum relevance score (0–1) |\n| `bfsDecay` | number | No | 0.8 | Score multiplier per hop (0–1) |\n| `searchMode` | string | No | `hybrid` | `hybrid`, `vector`, or `keyword` |\n\n**Returns:** `[{ id, title, content, tags, score }]`\n\n### create_relation\n\nCreate a directed edge from a note to another note or to an external graph node.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fromId` | string | Yes | Source note ID |\n| `toId` | string | Yes | Target note ID, or target node ID in external graph |\n| `kind` | string | Yes | Relation type: `"relates_to"`, `"depends_on"`, `"contradicts"`, `"supports"`, `"part_of"`, `"references"`, etc. |\n| `targetGraph` | `"docs"` \\| `"code"` \\| `"files"` \\| `"tasks"` \\| `"skills"` | No | Set to create a cross-graph link instead of note-to-note |\n\n**Returns:** `{ fromId, toId, kind, targetGraph, created: true }`\n\n**Cross-graph examples:**\n```\ncreate_relation({ fromId: "auth-arch", toId: "auth.ts::AuthService", kind: "documents", targetGraph: "code" })\ncreate_relation({ fromId: "config-note", toId: "src/config.ts", kind: "references", targetGraph: "files" })\ncreate_relation({ fromId: "api-decision", toId: "api-guide.md::Endpoints", kind: "explains", targetGraph: "docs" })\ncreate_relation({ fromId: "my-note", toId: "fix-auth-bug", kind: "tracks", targetGraph: "tasks" })\n```\n\n### delete_relation\n\nRemove a directed edge.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fromId` | string | Yes | Source note ID |\n| `toId` | string | Yes | Target note ID or external node ID |\n| `targetGraph` | `"docs"` \\| `"code"` \\| `"files"` \\| `"tasks"` \\| `"skills"` | No | Set when deleting a cross-graph link |\n\n**Returns:** `{ fromId, toId, targetGraph, deleted: true }`\n\n### list_relations\n\nList all relations (both incoming and outgoing) for a note. Cross-graph links include `targetGraph` field and resolve the real node ID (not the proxy ID).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `noteId` | string | Yes | Note ID to list relations for |\n\n**Returns:** `[{ fromId, toId, kind, targetGraph? }]`\n\n### find_linked_notes\n\nReverse lookup: given a node in an external graph, find all notes that link to it.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `targetId` | string | Yes | Target node ID in the external graph, e.g. `"src/config.ts"`, `"auth.ts::login"`, `"api.md::Setup"` |\n| `targetGraph` | `"docs"` \\| `"code"` \\| `"files"` \\| `"tasks"` \\| `"skills"` | Yes | Which graph the target belongs to |\n| `kind` | string | No | Filter by relation kind. If omitted, returns all relations |\n\n**Returns:** `[{ noteId, title, kind, tags }]`\n\n**Use case:** When working on a code file, call `find_linked_notes({ targetId: "src/auth.ts", targetGraph: "code" })` to discover what knowledge notes reference that file.\n\n### add_note_attachment\n\nAttach a file to a note. The file is copied into the note\'s directory (`.notes/{noteId}/`).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `noteId` | string | Yes | Note ID to attach the file to |\n| `filePath` | string | Yes | Absolute path to the file on disk |\n\n**Returns:** `{ noteId, attachment: { filename, mimeType, size } }`\n\n### remove_note_attachment\n\nRemove an attachment from a note. Deletes the file from disk.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `noteId` | string | Yes | Note ID |\n| `filename` | string | Yes | Filename of the attachment to remove |\n\n**Returns:** `{ noteId, filename, deleted: true }`\n\n## Tips\n\n- Use tags consistently for easy filtering (e.g., `decision`, `gotcha`, `todo`, `architecture`)\n- Link notes to the code they describe — this creates a navigable knowledge web\n- `find_linked_notes` is useful to discover what knowledge exists about a specific code symbol or file\n- Notes persist across server restarts (saved as `knowledge.json`)\n- The `kind` field on relations is free-form — use whatever makes sense for your domain\n- `update_note` with `tags` replaces the entire array — include all tags you want to keep\n- `search_notes` with `bfsDepth: 2` will traverse through related notes to find loosely connected knowledge\n- Notes support file attachments — attach images, logs, or any file via `add_note_attachment`\n- Attachments are stored in `.notes/{noteId}/` alongside the note\'s markdown file\n- When the knowledge graph is configured as `readonly: true`, mutation tools (create, update, delete) are hidden from MCP clients and REST mutation endpoints return 403. The UI hides write buttons accordingly.\n'},{id:`task-tools`,title:`Task Tools`,summary:`Kanban task management with priorities, dependencies, and cross-graph links.`,category:`guide`,relatedTools:[`create_task`,`update_task`,`delete_task`,`get_task`,`list_tasks`,`search_tasks`,`move_task`,`link_task`,`create_task_link`,`delete_task_link`,`find_linked_tasks`,`add_task_attachment`,`remove_task_attachment`],content:'# Task Tools\n\nThe task tools provide a full **kanban-style task management** system within Graph Memory. Tasks have status, priority, due dates, estimates, and can link to any other graph.\n\n## Why tasks in Graph Memory?\n\nTasks here are tightly integrated with your project\'s knowledge graph:\n- Link a task to the code files it affects\n- Link a task to documentation that needs updating\n- Link a task to knowledge notes for context\n- Track dependencies between tasks (subtasks, blockers)\n\n## Tool overview\n\n| Tool | Purpose | Type |\n|------|---------|------|\n| `create_task` | Create a task | Mutation |\n| `update_task` | Modify task fields | Mutation |\n| `delete_task` | Remove a task and all its edges | Mutation |\n| `get_task` | Read a task with all relations | Read |\n| `list_tasks` | List tasks with filters | Read |\n| `search_tasks` | Semantic search across tasks | Read |\n| `move_task` | Change task status (kanban move) | Mutation |\n| `link_task` | Create task-to-task relation | Mutation |\n| `create_task_link` | Link task to external graph node | Mutation |\n| `delete_task_link` | Remove cross-graph link | Mutation |\n| `find_linked_tasks` | Reverse lookup: find tasks linked to an external node | Read |\n| `add_task_attachment` | Attach a file to a task | Mutation |\n| `remove_task_attachment` | Remove an attachment from a task | Mutation |\n\n> **Mutation tools** are serialized through a queue to prevent concurrent graph modifications.\n\n## Task properties\n\n| Property | Type | Values / Format | Notes |\n|----------|------|-----------------|-------|\n| `title` | string | Free text | Becomes slug ID |\n| `description` | string | Markdown | Full task description |\n| `status` | enum | `backlog`, `todo`, `in_progress`, `review`, `done`, `cancelled` | Use `move_task` to change |\n| `priority` | enum | `critical`, `high`, `medium`, `low` | Affects sort order |\n| `tags` | string[] | Free-form | For filtering |\n| `dueDate` | number | Unix timestamp in milliseconds | Optional deadline |\n| `estimate` | number | Hours | Optional effort estimate |\n| `assignee` | string \\| null | Team member ID | Optional assignee from `users:` config |\n| `completedAt` | number | Unix timestamp (auto-managed) | Set on done/cancelled, cleared on reopen |\n| `createdAt` | number | Unix timestamp (auto) | Set at creation |\n| `updatedAt` | number | Unix timestamp (auto) | Updated on every change |\n\n## Task ID generation\n\nLike notes, task IDs are slugified from the title:\n- "Fix auth redirect loop" → `fix-auth-redirect-loop`\n- Duplicates get suffixes: `fix-auth-redirect-loop::2`\n\n## Tool reference\n\n### create_task\n\nCreate a new task. Automatically embedded for semantic search.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `title` | string | Yes | — | Short title, e.g. `"Fix auth redirect loop"` |\n| `description` | string | Yes | — | Full description (markdown) |\n| `priority` | enum | Yes | — | `"critical"`, `"high"`, `"medium"`, `"low"` |\n| `status` | enum | No | `"backlog"` | `"backlog"`, `"todo"`, `"in_progress"`, `"review"`, `"done"`, `"cancelled"` |\n| `tags` | string[] | No | `[]` | Tags for filtering |\n| `dueDate` | number | No | — | Due date as Unix timestamp in milliseconds |\n| `estimate` | number | No | — | Estimated effort in hours |\n| `assignee` | string | No | — | Team member ID to assign the task to |\n\n**Returns:** `{ taskId }`\n\n### update_task\n\nUpdate an existing task. Only provided fields change. Re-embeds if title or description changes. Status changes auto-manage `completedAt`.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `taskId` | string | Yes | Task ID to update |\n| `title` | string | No | New title |\n| `description` | string | No | New description |\n| `status` | enum | No | New status |\n| `priority` | enum | No | New priority |\n| `tags` | string[] | No | Replace tags array (include all you want to keep) |\n| `dueDate` | number \\| null | No | New due date (ms timestamp), or `null` to clear |\n| `estimate` | number \\| null | No | New estimate (hours), or `null` to clear |\n| `assignee` | string \\| null | No | Team member ID to assign, or `null` to unassign |\n\n**Returns:** `{ taskId, updated: true }`\n\n> Use `move_task` for a simpler status-only change — it\'s more explicit about `completedAt` management.\n\n### delete_task\n\nDelete a task and all its edges (relations + cross-graph links). Orphaned proxy nodes cleaned up automatically. **Irreversible.**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `taskId` | string | Yes | Task ID to delete |\n\n**Returns:** `{ taskId, deleted: true }`\n\n### get_task\n\nReturn full task details including all relations. This is the most complete view of a task.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `taskId` | string | Yes | Task ID to retrieve |\n\n**Returns:**\n```\n{\n id, title, description, status, priority, tags, assignee,\n dueDate, estimate, completedAt, createdAt, updatedAt,\n subtasks: [{ id, title, status }],\n blockedBy: [{ id, title, status }],\n blocks: [{ id, title, status }],\n related: [{ id, title, status }]\n}\n```\n\nThe `subtasks`, `blockedBy`, `blocks`, and `related` arrays are automatically populated from task-to-task edges.\n\n### list_tasks\n\nList tasks with optional filters. Sorted by priority (critical → low) then due date (earliest first, nulls last).\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `status` | enum | No | — | Filter by status |\n| `priority` | enum | No | — | Filter by priority |\n| `tag` | string | No | — | Filter by tag (exact match, case-insensitive) |\n| `filter` | string | No | — | Substring match on title or ID |\n| `assignee` | string | No | — | Filter by assignee (team member ID) |\n| `limit` | number | No | 50 | Maximum results |\n\n**Returns:** `[{ id, title, description, status, priority, tags, dueDate, estimate, assignee, completedAt, createdAt, updatedAt }]`\n\n### search_tasks\n\nSemantic search over the task graph with BFS expansion.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | — | Natural language search query |\n| `topK` | number | No | 5 | Seed nodes (1–500) |\n| `bfsDepth` | number | No | 1 | Hops to follow relations (0–10) |\n| `maxResults` | number | No | 20 | Maximum results (1–500) |\n| `minScore` | number | No | 0.5 | Minimum relevance score (0–1) |\n| `bfsDecay` | number | No | 0.8 | Score multiplier per hop (0–1) |\n| `searchMode` | string | No | `hybrid` | `hybrid`, `vector`, or `keyword` |\n\n**Returns:** `[{ id, title, description, status, priority, tags, score }]`\n\n### move_task\n\nChange task status. The preferred way to move tasks through the kanban workflow.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `taskId` | string | Yes | Task ID to move |\n| `status` | enum | Yes | New status: `"backlog"`, `"todo"`, `"in_progress"`, `"review"`, `"done"`, `"cancelled"` |\n\n**Returns:** `{ taskId, status, completedAt }`\n\n**Automatic behavior:**\n- Moving to `done` or `cancelled` → sets `completedAt` to current time\n- Moving from `done`/`cancelled` to any other status → clears `completedAt`\n\n### link_task\n\nCreate a directed relation between two tasks.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fromId` | string | Yes | Source task ID |\n| `toId` | string | Yes | Target task ID |\n| `kind` | enum | Yes | `"subtask_of"`, `"blocks"`, `"related_to"` |\n\n**Returns:** `{ fromId, toId, kind, created: true }`\n\n**Semantics:**\n- `subtask_of` — `fromId` is a subtask of `toId` (child → parent)\n- `blocks` — `fromId` blocks `toId` (blocker → blocked task)\n- `related_to` — free association between tasks\n\n### create_task_link\n\nLink a task to a node in another graph (docs, code, files, or knowledge).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `taskId` | string | Yes | Source task ID |\n| `targetId` | string | Yes | Target node ID in the external graph |\n| `targetGraph` | enum | Yes | `"docs"`, `"code"`, `"files"`, `"knowledge"`, `"skills"` |\n| `kind` | string | Yes | Relation type: `"references"`, `"fixes"`, `"implements"`, `"documents"`, etc. |\n\n**Returns:** `{ taskId, targetId, targetGraph, kind, created: true }`\n\n**Examples:**\n```\ncreate_task_link({ taskId: "fix-auth", targetId: "src/auth.ts::login", targetGraph: "code", kind: "fixes" })\ncreate_task_link({ taskId: "update-docs", targetId: "guide.md::Authentication", targetGraph: "docs", kind: "updates" })\ncreate_task_link({ taskId: "review-config", targetId: "src/config.ts", targetGraph: "files", kind: "references" })\ncreate_task_link({ taskId: "implement-arch", targetId: "auth-architecture", targetGraph: "knowledge", kind: "implements" })\n```\n\n### delete_task_link\n\nRemove a cross-graph link from a task. Orphaned proxy nodes cleaned up automatically.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `taskId` | string | Yes | Source task ID |\n| `targetId` | string | Yes | Target node ID in the external graph |\n| `targetGraph` | enum | Yes | `"docs"`, `"code"`, `"files"`, `"knowledge"`, `"skills"` |\n\n**Returns:** `{ taskId, targetId, targetGraph, deleted: true }`\n\n### find_linked_tasks\n\nReverse lookup: given a node in an external graph, find all tasks that link to it.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `targetId` | string | Yes | Target node ID, e.g. `"src/auth.ts"`, `"guide.md::Setup"`, `"my-note"` |\n| `targetGraph` | enum | Yes | `"docs"`, `"code"`, `"files"`, `"knowledge"`, `"skills"` |\n| `kind` | string | No | Filter by relation kind. Omit for all relations |\n\n**Returns:** `[{ taskId, title, kind, status, priority, tags }]`\n\n**Use case:** When working on a file, call `find_linked_tasks({ targetId: "src/auth.ts", targetGraph: "code" })` to see all tasks related to that file.\n\n### add_task_attachment\n\nAttach a file to a task. The file is copied into the task\'s directory (`.tasks/{taskId}/`).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `taskId` | string | Yes | Task ID to attach the file to |\n| `filePath` | string | Yes | Absolute path to the file on disk |\n\n**Returns:** `{ taskId, attachment: { filename, mimeType, size } }`\n\n### remove_task_attachment\n\nRemove an attachment from a task. Deletes the file from disk.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `taskId` | string | Yes | Task ID |\n| `filename` | string | Yes | Filename of the attachment to remove |\n\n**Returns:** `{ taskId, filename, deleted: true }`\n\n## Kanban board UI\n\nThe Tasks page provides a visual kanban board with these features:\n\n- **Column visibility** — toggle which status columns are shown via the column icon in the top bar; saved in localStorage\n- **Drag-and-drop** — drag task cards between columns to change status; drop-zone highlights on hover\n- **Inline task creation** — click "+" in a column header to quickly create a task in that status\n- **Filter bar** — search tasks by text, filter by priority or tag\n- **Due date indicators** — overdue tasks show a red badge, approaching deadlines (≤3 days) show yellow\n- **Estimate badges** — tasks with estimates show hours on the card\n- **Quick actions** — hover a card to see edit and delete buttons\n- **Scrollable columns** — columns scroll independently when content overflows\n\n## Tips\n\n- Use `move_task` instead of `update_task` for status changes — it explicitly handles `completedAt`\n- `get_task` returns the richest data — includes subtasks, blockers, and related tasks\n- `list_tasks` is sorted by priority then due date — critical overdue tasks appear first\n- Link tasks to code files they affect — makes it easy to find related tasks when working on code\n- Use `search_tasks` to find tasks by meaning, not just title keywords\n- `update_task` with `dueDate: null` or `estimate: null` clears those fields\n- `update_task` with `tags` replaces the entire array — include all tags you want to keep\n- Task-to-task `kind` values are a fixed enum (`subtask_of`, `blocks`, `related_to`), unlike knowledge relations which are free-form\n- Tasks support file attachments — attach screenshots, logs, or any file via `add_task_attachment`\n- Attachments are stored in `.tasks/{taskId}/` alongside the task\'s markdown file\n- When the task graph is configured as `readonly: true`, mutation tools (create, update, delete, move) are hidden from MCP clients and REST mutation endpoints return 403. The UI hides write buttons and disables drag-and-drop on the kanban board.\n'},{id:`skill-tools`,title:`Skill Tools`,summary:`Create and manage reusable skills, recipes, and procedures with triggers and usage tracking.`,category:`guide`,relatedTools:[`create_skill`,`update_skill`,`delete_skill`,`get_skill`,`list_skills`,`search_skills`,`link_skill`,`create_skill_link`,`delete_skill_link`,`find_linked_skills`,`add_skill_attachment`,`remove_skill_attachment`,`recall_skills`,`bump_skill_usage`],content:'# Skill Tools\n\nThe skill tools provide a **recipe/procedure management** system within Graph Memory. Skills capture reusable knowledge — step-by-step procedures, patterns, and best practices — with triggers, usage tracking, and cross-graph links.\n\n## Why skills in Graph Memory?\n\nSkills here are tightly integrated with your project\'s knowledge graph:\n- Link a skill to the code files it applies to\n- Link a skill to documentation that describes the pattern\n- Link a skill to knowledge notes for context\n- Link a skill to tasks that use the procedure\n- Track dependencies and variants between skills\n\n## Tool overview\n\n| Tool | Purpose | Type |\n|------|---------|------|\n| `create_skill` | Create a skill with steps, triggers, and metadata | Mutation |\n| `update_skill` | Modify skill fields (partial update) | Mutation |\n| `delete_skill` | Remove a skill and all its edges | Mutation |\n| `get_skill` | Read a skill with all relations | Read |\n| `list_skills` | List skills with filters | Read |\n| `search_skills` | Semantic search across skills | Read |\n| `link_skill` | Create skill-to-skill relation | Mutation |\n| `create_skill_link` | Link skill to external graph node | Mutation |\n| `delete_skill_link` | Remove cross-graph link | Mutation |\n| `find_linked_skills` | Reverse lookup: find skills linked to an external node | Read |\n| `add_skill_attachment` | Attach a file to a skill | Mutation |\n| `remove_skill_attachment` | Remove an attachment from a skill | Mutation |\n| `recall_skills` | Recall relevant skills for a task context | Read |\n| `bump_skill_usage` | Increment usage counter + set lastUsedAt | Mutation |\n\n> **Mutation tools** are serialized through a queue to prevent concurrent graph modifications.\n\n## Skill properties\n\n| Property | Type | Values / Format | Notes |\n|----------|------|-----------------|-------|\n| `title` | string | Free text | Becomes slug ID |\n| `description` | string | Markdown | Full skill description |\n| `steps` | string[] | Ordered list | Step-by-step procedure |\n| `triggers` | string[] | Free-form | When to apply this skill |\n| `source` | enum | `user`, `learned` | How the skill was created |\n| `tags` | string[] | Free-form | For filtering |\n| `usageCount` | number | Auto-managed | Incremented by `bump_skill_usage` |\n| `lastUsedAt` | number | Unix timestamp (auto) | Set by `bump_skill_usage` |\n| `createdAt` | number | Unix timestamp (auto) | Set at creation |\n| `updatedAt` | number | Unix timestamp (auto) | Updated on every change |\n\n## Skill ID generation\n\nLike notes and tasks, skill IDs are slugified from the title:\n- "Add REST Endpoint" -> `add-rest-endpoint`\n- Duplicates get suffixes: `add-rest-endpoint::2`\n\n## Tool reference\n\n### create_skill\n\nCreate a new skill. Automatically embedded for semantic search.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `title` | string | Yes | -- | Short title, e.g. `"Add REST Endpoint"` |\n| `description` | string | Yes | -- | Full description (markdown) |\n| `steps` | string[] | No | `[]` | Ordered steps of the procedure |\n| `triggers` | string[] | No | `[]` | When this skill should be applied |\n| `source` | enum | No | `"user"` | `"user"`, `"learned"` |\n| `tags` | string[] | No | `[]` | Tags for filtering |\n\n**Returns:** `{ skillId }`\n\n### update_skill\n\nUpdate an existing skill. Only provided fields change. Re-embeds if title, description, or triggers change.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `skillId` | string | Yes | Skill ID to update |\n| `title` | string | No | New title |\n| `description` | string | No | New description |\n| `steps` | string[] | No | Replace steps array |\n| `triggers` | string[] | No | Replace triggers array |\n| `source` | enum | No | New source |\n| `tags` | string[] | No | Replace tags array (include all you want to keep) |\n\n**Returns:** `{ skillId, updated: true }`\n\n### delete_skill\n\nDelete a skill and all its edges (relations + cross-graph links). Orphaned proxy nodes cleaned up automatically. **Irreversible.**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `skillId` | string | Yes | Skill ID to delete |\n\n**Returns:** `{ skillId, deleted: true }`\n\n### get_skill\n\nReturn full skill details including all relations. This is the most complete view of a skill.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `skillId` | string | Yes | Skill ID to retrieve |\n\n**Returns:**\n```\n{\n id, title, description, steps, triggers, source, tags,\n usageCount, lastUsedAt, createdAt, updatedAt,\n dependsOn: [{ id, title }],\n dependedBy: [{ id, title }],\n related: [{ id, title }],\n variants: [{ id, title }]\n}\n```\n\nThe `dependsOn`, `dependedBy`, `related`, and `variants` arrays are automatically populated from skill-to-skill edges.\n\n### list_skills\n\nList skills with optional filters. Sorted by usage count (most used first).\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `source` | enum | No | -- | Filter by source (`user`, `learned`) |\n| `tag` | string | No | -- | Filter by tag (exact match, case-insensitive) |\n| `filter` | string | No | -- | Substring match on title or ID |\n| `limit` | number | No | 50 | Maximum results |\n\n**Returns:** `[{ id, title, description, steps, triggers, source, tags, usageCount, lastUsedAt, createdAt, updatedAt }]`\n\n### search_skills\n\nSemantic search over the skill graph with BFS expansion.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | -- | Natural language search query |\n| `topK` | number | No | 5 | Seed nodes (1–500) |\n| `bfsDepth` | number | No | 1 | Hops to follow relations (0–10) |\n| `maxResults` | number | No | 20 | Maximum results (1–500) |\n| `minScore` | number | No | 0.5 | Minimum relevance score (0–1) |\n| `bfsDecay` | number | No | 0.8 | Score multiplier per hop (0–1) |\n| `searchMode` | string | No | `hybrid` | `hybrid`, `vector`, or `keyword` |\n\n**Returns:** `[{ id, title, description, steps, triggers, source, tags, score }]`\n\n### recall_skills\n\nRecall relevant skills for a task context. Uses a lower default `minScore` (0.3) for higher recall.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `context` | string | Yes | -- | Description of the current task or context to match skills against |\n| `topK` | number | No | 5 | How many top similar skills to use as seeds |\n| `minScore` | number | No | 0.3 | Minimum relevance score (0-1) |\n\n**Returns:** `[{ id, title, description, steps, triggers, source, tags, score, usageCount }]`\n\n### bump_skill_usage\n\nRecord that a skill was used. Increments `usageCount` and sets `lastUsedAt` to the current time.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `skillId` | string | Yes | Skill ID to bump |\n\n**Returns:** `{ skillId, usageCount, lastUsedAt }`\n\n### link_skill\n\nCreate a directed relation between two skills.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `fromId` | string | Yes | Source skill ID |\n| `toId` | string | Yes | Target skill ID |\n| `kind` | enum | Yes | `"depends_on"`, `"related_to"`, `"variant_of"` |\n\n**Returns:** `{ fromId, toId, kind, created: true }`\n\n**Semantics:**\n- `depends_on` -- `fromId` depends on `toId` (prerequisite)\n- `related_to` -- free association between skills\n- `variant_of` -- `fromId` is a variation of `toId`\n\n### create_skill_link\n\nLink a skill to a node in another graph (docs, code, files, knowledge, or tasks).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `skillId` | string | Yes | Source skill ID |\n| `targetId` | string | Yes | Target node ID in the external graph |\n| `targetGraph` | enum | Yes | `"docs"`, `"code"`, `"files"`, `"knowledge"`, `"tasks"` |\n| `kind` | string | Yes | Relation type: `"applies_to"`, `"documented_in"`, `"used_by"`, etc. |\n\n**Returns:** `{ skillId, targetId, targetGraph, kind, created: true }`\n\n**Examples:**\n```\ncreate_skill_link({ skillId: "add-rest-endpoint", targetId: "src/routes/index.ts", targetGraph: "code", kind: "applies_to" })\ncreate_skill_link({ skillId: "add-rest-endpoint", targetId: "guide.md::REST API", targetGraph: "docs", kind: "documented_in" })\ncreate_skill_link({ skillId: "add-rest-endpoint", targetId: "implement-api", targetGraph: "tasks", kind: "used_by" })\n```\n\n### delete_skill_link\n\nRemove a cross-graph link from a skill. Orphaned proxy nodes cleaned up automatically.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `skillId` | string | Yes | Source skill ID |\n| `targetId` | string | Yes | Target node ID in the external graph |\n| `targetGraph` | enum | Yes | `"docs"`, `"code"`, `"files"`, `"knowledge"`, `"tasks"` |\n\n**Returns:** `{ skillId, targetId, targetGraph, deleted: true }`\n\n### find_linked_skills\n\nReverse lookup: given a node in an external graph, find all skills that link to it.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `targetId` | string | Yes | Target node ID, e.g. `"src/auth.ts"`, `"guide.md::Setup"`, `"my-task"` |\n| `targetGraph` | enum | Yes | `"docs"`, `"code"`, `"files"`, `"knowledge"`, `"tasks"` |\n| `kind` | string | No | Filter by relation kind. Omit for all relations |\n\n**Returns:** `[{ skillId, title, kind, source, tags }]`\n\n**Use case:** When working on a file, call `find_linked_skills({ targetId: "src/routes/index.ts", targetGraph: "code" })` to see all skills related to that file.\n\n### add_skill_attachment\n\nAttach a file to a skill. The file is copied into the skill\'s directory (`.skills/{skillId}/`).\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `skillId` | string | Yes | Skill ID to attach the file to |\n| `filePath` | string | Yes | Absolute path to the file on disk |\n\n**Returns:** `{ skillId, attachment: { filename, mimeType, size } }`\n\n### remove_skill_attachment\n\nRemove an attachment from a skill. Deletes the file from disk.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `skillId` | string | Yes | Skill ID |\n| `filename` | string | Yes | Filename of the attachment to remove |\n\n**Returns:** `{ skillId, filename, deleted: true }`\n\n## Tips\n\n- Use `recall_skills` when starting a task to find relevant procedures -- it uses a lower threshold for better recall\n- Call `bump_skill_usage` after applying a skill to track which skills are most useful\n- Skills with `source: "learned"` are typically created by AI agents that discover patterns\n- Skills with `source: "user"` are created by humans documenting their procedures\n- Link skills to code files they apply to -- makes it easy to find relevant skills when working on code\n- Use `search_skills` to find skills by meaning, not just title keywords\n- `update_skill` with `tags` replaces the entire array -- include all tags you want to keep\n- Skill-to-skill `kind` values are a fixed enum (`depends_on`, `related_to`, `variant_of`)\n- Skills support file attachments -- attach templates, examples, or reference files via `add_skill_attachment`\n- Attachments are stored in `.skills/{skillId}/` alongside the skill\'s markdown file\n- When the skill graph is configured as `readonly: true`, mutation tools (create, update, delete) are hidden from MCP clients and REST mutation endpoints return 403. The UI hides write buttons accordingly.\n'},{id:`files-tools`,title:`File Index Tools`,summary:`Browse and search metadata for every file and directory in your project.`,category:`guide`,relatedTools:[`list_all_files`,`search_all_files`,`get_file_info`],content:'# File Index Tools\n\nThe file index tools provide access to metadata about **every file and directory** in your project. Unlike docs and code tools which only index pattern-matched files, the file index covers the entire project tree.\n\n## Tool overview\n\n| Tool | Purpose | When to use |\n|------|---------|-------------|\n| `list_all_files` | List files/directories with filters | Browse project structure, filter by extension/language |\n| `search_all_files` | Semantic search by file path | Find files by what they might contain |\n| `get_file_info` | Get metadata for a specific path | Check size, language, modification date |\n\n## What gets indexed\n\nFor every file in the project directory:\n- **Path** (relative to project root)\n- **File name** and **extension**\n- **Size** in bytes\n- **Language** (detected from extension: `.ts` → TypeScript, `.md` → Markdown, `.json` → JSON, etc.)\n- **MIME type** (e.g., `application/json`, `text/markdown`, `image/png`)\n- **Modification time** (`mtime`)\n\nFor directories:\n- **Aggregate size** (sum of all contained files)\n- **File count** (total files in subtree)\n- Directory → child edges (`contains`)\n\n## Browsing vs searching\n\n### Directory browsing\n\n`list_all_files` with the `directory` parameter returns **immediate children** (files + subdirectories) of that directory. This is how you browse the project tree:\n\n```\nlist_all_files({ directory: "." }) → root contents\nlist_all_files({ directory: "src" }) → src/ contents\nlist_all_files({ directory: "src/api" }) → src/api/ contents\n```\n\nWithout `directory`, it returns all files matching filters (flat list, no directories).\n\n### File search\n\n`search_all_files` embeds file paths for semantic search. You can search by:\n- Partial paths: `"config"` finds configuration files\n- Concepts: `"authentication"` finds files in auth-related directories\n- File types: `"typescript source"` finds `.ts` files\n\nThe `minScore` default is **0.3** (lower than node search) because file path embeddings are less semantically rich than content embeddings.\n\n## Tool reference\n\n### list_all_files\n\nList project files and directories with optional filters.\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `directory` | string | No | — | List immediate children of this directory (e.g. `"."`, `"src/lib"`). Without this, returns all files matching filters |\n| `extension` | string | No | — | Filter by extension (e.g. `".ts"`, `".md"`, `".png"`) |\n| `language` | string | No | — | Filter by detected language (e.g. `"typescript"`, `"markdown"`, `"json"`) |\n| `filter` | string | No | — | Substring match on file path (case-insensitive) |\n| `limit` | number | No | 50 | Maximum results |\n\n**Returns:** `[{ filePath, kind, fileName, extension, language, mimeType, size, fileCount }]`\n\n- `kind` is `"file"` or `"directory"`\n- `fileCount` is present for directories (number of files in subtree)\n- `language` and `mimeType` are present for files\n\n**Behavior differences:**\n- With `directory` set: returns both files and subdirectories (immediate children only)\n- Without `directory`: returns only files (no directories), across the entire project\n\n### search_all_files\n\nSemantic search over file nodes by path embedding. Searches files only (not directories).\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `query` | string | Yes | — | Search query (natural language or path fragment) |\n| `topK` | number | No | 10 | Maximum results |\n| `minScore` | number | No | 0.3 | Minimum cosine similarity score (0–1) |\n\n**Returns:** `[{ filePath, fileName, extension, language, size, score }]`\n\n### get_file_info\n\nGet full metadata for a specific file or directory. Use `"."` for the project root.\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `filePath` | string | Yes | Relative file or directory path (e.g. `"src/lib/config.ts"`, `"src/lib"`, `"."`) |\n\n**Returns for files:**\n```\n{ filePath, kind: "file", fileName, directory, extension, language, mimeType, size, mtime }\n```\n\n**Returns for directories:**\n```\n{ filePath, kind: "directory", fileName, directory, fileCount, size }\n```\n\n- `size` for directories is the total size of all direct children\n- `fileCount` for directories is the total number of files in the subtree\n- `mtime` is the last modification timestamp (files only)\n\n## Cross-graph links\n\nFiles can be linked from notes and tasks:\n\n```\n// From a knowledge note\ncreate_relation({ fromId: "config-format", toId: "src/config.ts", kind: "documents", targetGraph: "files" })\n\n// From a task\ncreate_task_link({ taskId: "refactor-config", targetId: "src/config.ts", targetGraph: "files", kind: "affects" })\n```\n\nUse `find_linked_notes` or `find_linked_tasks` with `targetGraph: "files"` to discover what knowledge or tasks reference a specific file:\n\n```\nfind_linked_notes({ targetId: "src/auth.ts", targetGraph: "files" })\nfind_linked_tasks({ targetId: "src/auth.ts", targetGraph: "files" })\n```\n\n## Tips\n\n- Use `list_all_files` with `directory` to browse top-down through the project tree\n- Use `list_all_files` with `extension: ".ts"` or `language: "typescript"` to find all files of a type\n- `get_file_info` on `"."` gives project-level stats (total size, file count)\n- `search_all_files` works better with path-like queries than abstract concepts\n- File index is always active — no `graphs.docs.include` or `graphs.code.include` configuration needed\n- The `language` filter in `list_all_files` uses detected language names like `"typescript"`, `"javascript"`, `"markdown"`, `"json"`, `"yaml"`, `"css"`, `"html"`, `"python"`, etc.\n'},{id:`cross-references`,title:`Cross References Tool`,summary:`Bridge code definitions and documentation examples for any symbol.`,category:`guide`,relatedTools:[`cross_references`],content:`# Cross References Tool
766
+
767
+ \`cross_references\` is the only tool that works across **both** the CodeGraph and DocGraph simultaneously. It's the most comprehensive way to understand a symbol — combining source code definitions, documentation context, and usage examples.
768
+
769
+ ## When to use it
770
+
771
+ Use \`cross_references\` when you want to fully understand a symbol:
772
+ - "Where is \`createUser\` defined, and where is it documented?"
773
+ - "Show me all examples of \`AuthService\` in the docs"
774
+ - "What does \`parseConfig\` do, and how is it used?"
775
+
776
+ ## Requirements
777
+
778
+ This tool is **only available** when both \`graphs.docs.include\` and \`graphs.code.include\` are configured in the project. It needs both graphs to bridge definitions and documentation.
779
+
780
+ ## Tool reference
781
+
782
+ ### cross_references
783
+
784
+ Find all references to a symbol across both code and documentation graphs.
785
+
786
+ | Parameter | Type | Required | Description |
787
+ |-----------|------|----------|-------------|
788
+ | \`symbol\` | string | Yes | Symbol name to look up, e.g. \`"createUser"\`, \`"AuthService"\` |
789
+
790
+ **Returns:**
791
+ \`\`\`
792
+ {
793
+ definitions: [{
794
+ id, // CodeGraph node ID, e.g. "src/auth.ts::createUser"
795
+ fileId, // Source file path
796
+ kind, // Symbol kind: function, class, method, interface, etc.
797
+ name, // Symbol name
798
+ signature, // Full type signature
799
+ docComment, // JSDoc comment text
800
+ startLine, // First line number
801
+ endLine // Last line number
802
+ }],
803
+ documentation: [{
804
+ id, // DocGraph node ID of parent text section
805
+ fileId, // Documentation file path
806
+ title, // Section heading
807
+ content // Full section text (narrative context)
808
+ }],
809
+ examples: [{
810
+ id, // DocGraph node ID of code block
811
+ fileId, // Documentation file path
812
+ language, // Code block language (e.g. "typescript")
813
+ symbols, // All symbols found in this code block
814
+ content // Full code block text
815
+ }]
816
+ }
817
+ \`\`\`
818
+
819
+ ## How it works in detail
820
+
821
+ ### Step 1: Find definitions in CodeGraph
822
+
823
+ The tool iterates over all nodes in the CodeGraph, looking for exact \`name\` matches. This finds where the symbol is **defined** — the source code declarations.
824
+
825
+ A single symbol name can have multiple definitions (e.g., overloaded functions, or the same name in different files).
826
+
827
+ ### Step 2: Find examples in DocGraph
828
+
829
+ The tool iterates over all nodes in the DocGraph, checking the \`symbols\` array of code block nodes. When markdown is indexed, fenced code blocks are parsed:
830
+
831
+ 1. The code block's language is detected from the fence tag (\` \`\`\`ts \`, \` \`\`\`javascript \`, etc.)
832
+ 2. TypeScript/JavaScript blocks are parsed with \`tree-sitter\` using a virtual in-memory file
833
+ 3. Top-level symbol names are extracted: function declarations, class declarations, variable declarations
834
+ 4. These are stored in the \`symbols\` field
835
+
836
+ So \`cross_references\` can find a code block like:
837
+
838
+ \`\`\`typescript
839
+ const user = createUser({ name: 'Alice', role: 'admin' });
840
+ await sendWelcomeEmail(user);
841
+ \`\`\`
842
+
843
+ This block would have \`symbols: ["user"]\` (the top-level variable declaration), but **not** \`symbols: ["createUser"]\` — because \`createUser\` is a function **call**, not a declaration. Only top-level declarations are extracted.
844
+
845
+ > **Important:** Symbol extraction captures **declarations**, not **usages**. A code block that calls \`createUser()\` won't match unless it also declares something named \`createUser\`.
846
+
847
+ For the symbol to match, the code block must contain a **declaration** of that name. For example:
848
+
849
+ \`\`\`typescript
850
+ function createUser(data: UserInput): User {
851
+ return db.insert(data);
852
+ }
853
+ \`\`\`
854
+
855
+ This block **would** match because \`createUser\` is declared as a top-level function.
856
+
857
+ ### Step 3: Find documentation context
858
+
859
+ For each matching code block example, the tool looks at its **parent text section** — the in-neighbors in the doc graph that are in the same file with a lower heading level and no language tag (i.e., text content, not another code block).
860
+
861
+ This gives you the narrative context around the example: the explanation, the motivation, the caveats.
862
+
863
+ ## Example scenario
864
+
865
+ Project structure:
866
+ - \`src/auth.ts\` contains \`export function createUser(data: UserInput): User { ... }\`
867
+ - \`docs/guide.md\` has a section "## Creating Users" with an example code block that declares/uses \`createUser\`
868
+
869
+ Calling \`cross_references({ symbol: "createUser" })\` returns:
870
+ - **definitions**: \`[{ id: "src/auth.ts::createUser", kind: "function", signature: "function createUser(data: UserInput): User", ... }]\`
871
+ - **examples**: \`[{ id: "docs/guide.md::Creating Users::code-1", language: "typescript", symbols: ["createUser"], content: "..." }]\`
872
+ - **documentation**: \`[{ id: "docs/guide.md::Creating Users", title: "Creating Users", content: "To create a new user, call..." }]\`
873
+
874
+ ## Comparison with other symbol tools
875
+
876
+ | Tool | Graph | Finds | Best for |
877
+ |------|-------|-------|----------|
878
+ | \`get_symbol\` | CodeGraph only | One specific symbol by ID | Reading full implementation |
879
+ | \`search_code\` | CodeGraph only | Symbols by semantic similarity | Finding code by description |
880
+ | \`find_examples\` | DocGraph only | Code blocks by symbol name | Finding doc examples |
881
+ | \`explain_symbol\` | DocGraph only | Code blocks + parent text | Understanding via docs |
882
+ | \`cross_references\` | Both graphs | Definitions + examples + docs | Complete understanding |
883
+
884
+ ## Tips
885
+
886
+ - Use exact symbol names (case-sensitive match)
887
+ - If you get no results, check that both \`graphs.docs.include\` and \`graphs.code.include\` are configured
888
+ - Empty \`definitions\` + non-empty \`examples\` means the symbol is documented but not in your indexed code
889
+ - Empty \`examples\` + non-empty \`definitions\` means the symbol exists in code but isn't documented with examples
890
+ - Combine with \`get_symbol\` to read the full implementation body (which \`cross_references\` doesn't include)
891
+ `}];function t(t){return e.find(e=>e.id===t)}function n(t){return e.filter(e=>e.relatedTools.includes(t))}export{n,e as r,t};