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