oh-memos-mcp 2.0.0 → 2.1.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.
- package/.env.example +44 -27
- package/CHANGELOG.md +145 -0
- package/README.md +260 -226
- package/dist/api-client.d.ts +0 -0
- package/dist/api-client.js +0 -0
- package/dist/canvas-format.d.ts +101 -0
- package/dist/canvas-format.js +259 -0
- package/dist/canvas-store.d.ts +62 -0
- package/dist/canvas-store.js +187 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +44 -9
- package/dist/cube-manager.d.ts +0 -0
- package/dist/cube-manager.js +11 -0
- package/dist/formatters.d.ts +0 -0
- package/dist/formatters.js +0 -0
- package/dist/graph-provenance.d.ts +34 -0
- package/dist/graph-provenance.js +175 -0
- package/dist/graphify-import.d.ts +72 -0
- package/dist/graphify-import.js +194 -0
- package/dist/handlers/admin.d.ts +1 -0
- package/dist/handlers/admin.js +18 -0
- package/dist/handlers/arg-contract.d.ts +0 -0
- package/dist/handlers/arg-contract.js +0 -0
- package/dist/handlers/calendar.d.ts +0 -0
- package/dist/handlers/calendar.js +0 -0
- package/dist/handlers/canvas.d.ts +40 -0
- package/dist/handlers/canvas.js +334 -0
- package/dist/handlers/graph.d.ts +8 -0
- package/dist/handlers/graph.js +66 -14
- package/dist/handlers/index.d.ts +0 -0
- package/dist/handlers/index.js +28 -5
- package/dist/handlers/memory.d.ts +0 -0
- package/dist/handlers/memory.js +33 -2
- package/dist/handlers/search.d.ts +0 -0
- package/dist/handlers/search.js +56 -15
- package/dist/handlers/skill.d.ts +6 -0
- package/dist/handlers/skill.js +123 -0
- package/dist/handlers/think.d.ts +0 -0
- package/dist/handlers/think.js +0 -0
- package/dist/handlers/utils.d.ts +0 -0
- package/dist/handlers/utils.js +0 -0
- package/dist/handlers/wiki-export.d.ts +0 -0
- package/dist/handlers/wiki-export.js +7 -9
- package/dist/handlers/wiki-import-relations.d.ts +11 -0
- package/dist/handlers/wiki-import-relations.js +32 -0
- package/dist/handlers/wiki-import.d.ts +19 -0
- package/dist/handlers/wiki-import.js +382 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.js +0 -0
- package/dist/keyword-enhancer.d.ts +0 -0
- package/dist/keyword-enhancer.js +0 -0
- package/dist/memory-analysis.d.ts +0 -0
- package/dist/memory-analysis.js +0 -0
- package/dist/memory-quality.d.ts +10 -0
- package/dist/memory-quality.js +57 -0
- package/dist/memory-write-response.d.ts +8 -0
- package/dist/memory-write-response.js +15 -0
- package/dist/models.d.ts +0 -0
- package/dist/models.js +0 -0
- package/dist/policy.d.ts +8 -0
- package/dist/policy.js +9 -0
- package/dist/providers/lite-embedding.d.ts +31 -0
- package/dist/providers/lite-embedding.js +60 -0
- package/dist/providers/local-jsonl-provider.d.ts +28 -0
- package/dist/providers/local-jsonl-provider.js +225 -0
- package/dist/providers/memory-provider.d.ts +21 -0
- package/dist/providers/memory-provider.js +2 -0
- package/dist/providers/provider-factory.d.ts +11 -0
- package/dist/providers/provider-factory.js +27 -0
- package/dist/query-processing.d.ts +0 -0
- package/dist/query-processing.js +0 -0
- package/dist/server.d.ts +0 -0
- package/dist/server.js +13 -3
- package/dist/skill-candidate.d.ts +11 -0
- package/dist/skill-candidate.js +56 -0
- package/dist/skill-lifecycle.d.ts +15 -0
- package/dist/skill-lifecycle.js +51 -0
- package/dist/tools-registry.d.ts +130 -7
- package/dist/tools-registry.js +93 -31
- package/dist/types.d.ts +0 -0
- package/dist/types.js +0 -0
- package/dist/wiki-import-format.d.ts +47 -0
- package/dist/wiki-import-format.js +113 -0
- package/dist/wiki-import-safety.d.ts +25 -0
- package/dist/wiki-import-safety.js +31 -0
- package/dist/wiki-relations.d.ts +44 -0
- package/dist/wiki-relations.js +88 -0
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -1,226 +1,260 @@
|
|
|
1
|
-
# oh-memos-mcp
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/oh-memos-mcp)
|
|
4
|
-
[](https://nodejs.org)
|
|
5
|
-
[](LICENSE)
|
|
6
|
-
|
|
7
|
-
MCP Server for **oh-memos** — Intelligent Persistent Memory for AI Assistants.
|
|
8
|
-
|
|
9
|
-
Pure Node.js. No Python required. Works with `npx` out of the box.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Prerequisites
|
|
14
|
-
|
|
15
|
-
oh-memos backend API must be running before connecting this MCP server:
|
|
16
|
-
|
|
17
|
-
- **oh-memos API** on `http://localhost:18000`
|
|
18
|
-
- **Neo4j** on `localhost:7687` (Knowledge Graph)
|
|
19
|
-
- **Qdrant** on `localhost:6333` (Vector Search)
|
|
20
|
-
|
|
21
|
-
> Start all services: run `scripts\local\start.bat` from the [oh-memos repo](https://github.com/xigou/oh-memos).
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Quick Start
|
|
26
|
-
|
|
27
|
-
Add to your Claude Code `~/.claude/settings.json`:
|
|
28
|
-
|
|
29
|
-
```json
|
|
30
|
-
{
|
|
31
|
-
"mcpServers": {
|
|
32
|
-
"oh-memos": {
|
|
33
|
-
"command": "npx",
|
|
34
|
-
"args": ["-y", "oh-memos-mcp"],
|
|
35
|
-
"env": {
|
|
36
|
-
"MEMOS_URL": "http://localhost:18000",
|
|
37
|
-
"MEMOS_USER": "dev_user",
|
|
38
|
-
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
39
|
-
"MEMOS_CUBES_DIR": "G:/test/oh-memos/data/oh-memos_cubes"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Or use a `.env` file in your working directory (the server auto-discovers it):
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
cp node_modules/oh-memos-mcp/.env.example .env
|
|
50
|
-
# Edit .env with your paths
|
|
51
|
-
npx oh-memos-mcp
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## Configuration Examples
|
|
57
|
-
|
|
58
|
-
### Linux / macOS
|
|
59
|
-
|
|
60
|
-
```json
|
|
61
|
-
{
|
|
62
|
-
"mcpServers": {
|
|
63
|
-
"oh-memos": {
|
|
64
|
-
"command": "npx",
|
|
65
|
-
"args": ["-y", "oh-memos-mcp"],
|
|
66
|
-
"env": {
|
|
67
|
-
"MEMOS_URL": "http://localhost:18000",
|
|
68
|
-
"MEMOS_USER": "dev_user",
|
|
69
|
-
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
70
|
-
"MEMOS_CUBES_DIR": "/home/user/oh-memos/data/oh-memos_cubes"
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Windows
|
|
78
|
-
|
|
79
|
-
```json
|
|
80
|
-
{
|
|
81
|
-
"mcpServers": {
|
|
82
|
-
"oh-memos": {
|
|
83
|
-
"command": "npx",
|
|
84
|
-
"args": ["-y", "oh-memos-mcp"],
|
|
85
|
-
"env": {
|
|
86
|
-
"MEMOS_URL": "http://localhost:18000",
|
|
87
|
-
"MEMOS_USER": "dev_user",
|
|
88
|
-
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
89
|
-
"MEMOS_CUBES_DIR": "G:/test/oh-memos/data/oh-memos_cubes"
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### WSL2
|
|
97
|
-
|
|
98
|
-
```json
|
|
99
|
-
{
|
|
100
|
-
"mcpServers": {
|
|
101
|
-
"oh-memos": {
|
|
102
|
-
"command": "npx",
|
|
103
|
-
"args": ["-y", "oh-memos-mcp"],
|
|
104
|
-
"env": {
|
|
105
|
-
"MEMOS_URL": "http://localhost:18000",
|
|
106
|
-
"MEMOS_USER": "dev_user",
|
|
107
|
-
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
108
|
-
"MEMOS_CUBES_DIR": "/mnt/g/test/oh-memos/data/oh-memos_cubes"
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### With `alwaysAllow` (skip per-tool confirmation)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
"
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"memos_admin
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
| `
|
|
168
|
-
| `
|
|
169
|
-
| `
|
|
170
|
-
| `
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
|
|
175
|
-
> **
|
|
176
|
-
>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
1
|
+
# oh-memos-mcp
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/oh-memos-mcp)
|
|
4
|
+
[](https://nodejs.org)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
MCP Server for **oh-memos** — Intelligent Persistent Memory for AI Assistants.
|
|
8
|
+
|
|
9
|
+
Pure Node.js. No Python required. Works with `npx` out of the box.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
oh-memos backend API must be running before connecting this MCP server:
|
|
16
|
+
|
|
17
|
+
- **oh-memos API** on `http://localhost:18000`
|
|
18
|
+
- **Neo4j** on `localhost:7687` (Knowledge Graph)
|
|
19
|
+
- **Qdrant** on `localhost:6333` (Vector Search)
|
|
20
|
+
|
|
21
|
+
> Start all services: run `scripts\local\start.bat` from the [oh-memos repo](https://github.com/xigou/oh-memos).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
Add to your Claude Code `~/.claude/settings.json`:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"oh-memos": {
|
|
33
|
+
"command": "npx",
|
|
34
|
+
"args": ["-y", "oh-memos-mcp"],
|
|
35
|
+
"env": {
|
|
36
|
+
"MEMOS_URL": "http://localhost:18000",
|
|
37
|
+
"MEMOS_USER": "dev_user",
|
|
38
|
+
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
39
|
+
"MEMOS_CUBES_DIR": "G:/test/oh-memos/data/oh-memos_cubes"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or use a `.env` file in your working directory (the server auto-discovers it):
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cp node_modules/oh-memos-mcp/.env.example .env
|
|
50
|
+
# Edit .env with your paths
|
|
51
|
+
npx oh-memos-mcp
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Configuration Examples
|
|
57
|
+
|
|
58
|
+
### Linux / macOS
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mcpServers": {
|
|
63
|
+
"oh-memos": {
|
|
64
|
+
"command": "npx",
|
|
65
|
+
"args": ["-y", "oh-memos-mcp"],
|
|
66
|
+
"env": {
|
|
67
|
+
"MEMOS_URL": "http://localhost:18000",
|
|
68
|
+
"MEMOS_USER": "dev_user",
|
|
69
|
+
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
70
|
+
"MEMOS_CUBES_DIR": "/home/user/oh-memos/data/oh-memos_cubes"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Windows
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"oh-memos": {
|
|
83
|
+
"command": "npx",
|
|
84
|
+
"args": ["-y", "oh-memos-mcp"],
|
|
85
|
+
"env": {
|
|
86
|
+
"MEMOS_URL": "http://localhost:18000",
|
|
87
|
+
"MEMOS_USER": "dev_user",
|
|
88
|
+
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
89
|
+
"MEMOS_CUBES_DIR": "G:/test/oh-memos/data/oh-memos_cubes"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### WSL2
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"mcpServers": {
|
|
101
|
+
"oh-memos": {
|
|
102
|
+
"command": "npx",
|
|
103
|
+
"args": ["-y", "oh-memos-mcp"],
|
|
104
|
+
"env": {
|
|
105
|
+
"MEMOS_URL": "http://localhost:18000",
|
|
106
|
+
"MEMOS_USER": "dev_user",
|
|
107
|
+
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
108
|
+
"MEMOS_CUBES_DIR": "/mnt/g/test/oh-memos/data/oh-memos_cubes"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### With `alwaysAllow` (skip per-tool confirmation)
|
|
116
|
+
|
|
117
|
+
`alwaysAllow` matches **tool names**, so a call form like
|
|
118
|
+
`memos_admin(action=list_cubes)` matches nothing — list the bare name and every
|
|
119
|
+
action of that tool is auto-approved.
|
|
120
|
+
|
|
121
|
+
`memos_delete` is deliberately absent below. Auto-approving it means memories can
|
|
122
|
+
be deleted without a prompt; add it only if you have decided you want that.
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"mcpServers": {
|
|
127
|
+
"oh-memos": {
|
|
128
|
+
"type": "stdio",
|
|
129
|
+
"command": "npx",
|
|
130
|
+
"args": ["-y", "oh-memos-mcp"],
|
|
131
|
+
"env": {
|
|
132
|
+
"MEMOS_URL": "http://localhost:18000",
|
|
133
|
+
"MEMOS_USER": "dev_user",
|
|
134
|
+
"MEMOS_DEFAULT_CUBE": "dev_cube",
|
|
135
|
+
"MEMOS_CUBES_DIR": "/path/to/oh-memos/data/oh-memos_cubes"
|
|
136
|
+
},
|
|
137
|
+
"alwaysAllow": [
|
|
138
|
+
"memos_context_resume",
|
|
139
|
+
"memos_search",
|
|
140
|
+
"memos_save",
|
|
141
|
+
"memos_list_v2",
|
|
142
|
+
"memos_get",
|
|
143
|
+
"memos_suggest",
|
|
144
|
+
"memos_think",
|
|
145
|
+
"memos_graph",
|
|
146
|
+
"memos_admin",
|
|
147
|
+
"memos_export_wiki",
|
|
148
|
+
"memos_canvas"
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Environment Variables
|
|
158
|
+
|
|
159
|
+
| Variable | Required | Default | Description |
|
|
160
|
+
|----------|----------|---------|-------------|
|
|
161
|
+
| `MEMOS_URL` | Yes | — | oh-memos API base URL |
|
|
162
|
+
| `MEMOS_USER` | Yes | — | Default user ID |
|
|
163
|
+
| `MEMOS_DEFAULT_CUBE` | Yes | — | Default memory cube ID |
|
|
164
|
+
| `MEMOS_CUBES_DIR` | Yes | — | Absolute path to cubes storage directory |
|
|
165
|
+
| `MEMOS_TIMEOUT_TOOL` | No | `300` | Tool call timeout (seconds) |
|
|
166
|
+
| `MEMOS_TIMEOUT_STARTUP` | No | `30` | API startup wait timeout (seconds) |
|
|
167
|
+
| `MEMOS_TIMEOUT_HEALTH` | No | `5` | Health check timeout (seconds) |
|
|
168
|
+
| `MEMOS_API_WAIT_MAX` | No | `60` | Max time to wait for API on startup (seconds) |
|
|
169
|
+
| `MEMOS_ENABLE_DELETE` | No | `false` | Enable `memos_delete` tool |
|
|
170
|
+
| `NEO4J_HTTP_URL` | No | — | Neo4j HTTP endpoint (for direct graph queries) |
|
|
171
|
+
| `NEO4J_USER` | No | — | Neo4j username |
|
|
172
|
+
| `NEO4J_PASSWORD` | No | — | Neo4j password |
|
|
173
|
+
| `MEMOS_ENV_FILE` | No | — | Explicit path to a `.env` file. Highest priority — see below |
|
|
174
|
+
|
|
175
|
+
> **On locating `.env`**: without `MEMOS_ENV_FILE`, the file is found by guessing
|
|
176
|
+
> from position (working directory, two levels above the package, then dotenv's
|
|
177
|
+
> upward search). That works from a checkout and **never works under `npx`**,
|
|
178
|
+
> where the package root sits in the npm cache and every candidate misses — so no
|
|
179
|
+
> variable loads at all. Set `MEMOS_ENV_FILE` (or pass `--memos-env-file`) when the
|
|
180
|
+
> client's working directory and the install location are both outside the project.
|
|
181
|
+
> A path that does not exist warns on stderr rather than failing silently.
|
|
182
|
+
>
|
|
183
|
+
> Copy `.env.example` to get started.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Tools (17)
|
|
188
|
+
|
|
189
|
+
The package defines 17 tool schemas. `memos_delete` is exposed by `tools/list`
|
|
190
|
+
only when `MEMOS_ENABLE_DELETE=true`; the other 16 are available by default.
|
|
191
|
+
|
|
192
|
+
<!-- mcp-tool-inventory:start -->
|
|
193
|
+
| Tool | Description |
|
|
194
|
+
|------|-------------|
|
|
195
|
+
| `memos_context_resume` | Recover project context after compaction (recent 24h + project state) |
|
|
196
|
+
| `memos_search` | Semantic search with keyword reranking. Pass `context` (recent turns) to enable LLM intent analysis and query expansion |
|
|
197
|
+
| `memos_save` | Save memories with explicit type (BUGFIX, DECISION, MILESTONE, SYNTHESIS…) |
|
|
198
|
+
| `memos_list_v2` | List memories with auto-compaction |
|
|
199
|
+
| `memos_get` | Get full memory details by ID |
|
|
200
|
+
| `memos_suggest` | Smart search query suggestions + `memory_type` decision tree |
|
|
201
|
+
| `memos_think` | Evidence pack for a question: retrieval + contradiction/staleness flags + gap analysis. The caller synthesizes the answer and may persist it as `SYNTHESIS` |
|
|
202
|
+
| `memos_graph` | Explainable graph queries plus strict Graphify node-link validation — `mode`: `related` / `path` / `impact` / `schema` / `import` |
|
|
203
|
+
| `memos_admin` | Maintenance — `action`: `list_cubes` / `register_cube` / `create_user` / `validate_cubes` / `stats` / `calendar` |
|
|
204
|
+
| `memos_export_wiki` | Export a cube as an interlinked markdown wiki (page per memory + index + mermaid graph) |
|
|
205
|
+
| `memos_import_wiki` | Import an exported wiki back into a cube; supports dry-run and versioning edited pages, never deletes memories |
|
|
206
|
+
| `memos_canvas` | Symbolic task canvas — short-term task state that survives context compaction. `action`: `open` / `update` / `show` / `list`. Nodes carry greppable ids (`000-N1`) and a `ref` anchoring them to evidence: `mem:<memory_id>` / `file:<path>` / `note:<text>` |
|
|
207
|
+
| `memos_distill_skill` | Create an inert, reviewable Skill candidate under `<project_path>/skill-candidates`; it never installs the candidate automatically |
|
|
208
|
+
| `memos_list_skill_candidates` | List generated Skill candidates without modifying or installing them |
|
|
209
|
+
| `memos_review_skill_candidate` | Approve or reject a candidate with reviewer audit metadata; approval does not install |
|
|
210
|
+
| `memos_install_skill_candidate` | Install an approved candidate only into `.claude/skills/<slug>/SKILL.md`, without overwrite or script execution |
|
|
211
|
+
| `memos_delete` | Delete selected or all memories. Disabled by default and requires explicit user confirmation when enabled |
|
|
212
|
+
<!-- mcp-tool-inventory:end -->
|
|
213
|
+
|
|
214
|
+
### `memos_graph` modes
|
|
215
|
+
|
|
216
|
+
| Mode | Main input | Result |
|
|
217
|
+
|------|------------|--------|
|
|
218
|
+
| `related` | `query` | Related memories and edges, with provenance explanations when available |
|
|
219
|
+
| `path` | `source_id`, `target_id` | A bounded path between two graph nodes, including relationship evidence |
|
|
220
|
+
| `impact` | `memory_id`, optional `max_depth` | Forward blast radius from one memory |
|
|
221
|
+
| `schema` | Optional `sample_size` | Graph structure and statistics |
|
|
222
|
+
| `import` | `graph_json`, optional `project_key` | Deterministic validation and dry-run plan for Graphify NetworkX node-link JSON |
|
|
223
|
+
|
|
224
|
+
`import` accepts at most 5 MB of JSON and rejects duplicate node ids, dangling
|
|
225
|
+
edges, unsafe source paths, invalid confidence values, and oversized graphs. It
|
|
226
|
+
does **not** write Code Graph nodes to Neo4j, Qdrant, or a memory cube.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## How .env Loading Works
|
|
231
|
+
|
|
232
|
+
Priority order for configuration values (highest first):
|
|
233
|
+
|
|
234
|
+
1. **CLI configuration flags** such as `--memos-url`
|
|
235
|
+
2. **Explicit env file** selected by `--memos-env-file` or inherited `MEMOS_ENV_FILE`
|
|
236
|
+
3. **Inherited process environment** — this is where MCP client `env` values belong
|
|
237
|
+
4. **Auto-discovered `process.cwd()/.env`** — provides only missing defaults
|
|
238
|
+
5. **Auto-discovered package-root `.env`** — provides only missing defaults
|
|
239
|
+
6. **dotenv upward fallback**, then built-in defaults
|
|
240
|
+
|
|
241
|
+
The automatic file search never overrides explicit MCP/launcher environment values. Use `MEMOS_ENV_FILE` only when the selected file should deliberately be authoritative; this is also the reliable option for `npx` installs.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Development
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
git clone https://github.com/xigou/oh-memos.git
|
|
249
|
+
cd oh-memos/mcp-server-node
|
|
250
|
+
npm install
|
|
251
|
+
npm run dev # Run with tsx (no build needed)
|
|
252
|
+
npm run build # Compile to dist/
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Requirements
|
|
258
|
+
|
|
259
|
+
- Node.js >= 18.0.0
|
|
260
|
+
- oh-memos backend API running (`scripts\local\start.bat`)
|
package/dist/api-client.d.ts
CHANGED
|
File without changes
|
package/dist/api-client.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbolic task canvas — parse and render.
|
|
3
|
+
*
|
|
4
|
+
* A canvas is one Mermaid file. It is the whole truth: there is no parallel
|
|
5
|
+
* JSON sidecar, because two files describing one task drift apart the first
|
|
6
|
+
* time a write fails halfway. The cost of that choice is that the format has to
|
|
7
|
+
* survive a round trip exactly, which is what the tests pin down.
|
|
8
|
+
*
|
|
9
|
+
* The shape borrows the `NNN-Nn` node id from TencentDB Agent Memory, for the
|
|
10
|
+
* reason that made it work there: it is greppable. An id in a canvas, a commit
|
|
11
|
+
* message or a memory body all lead back to the same node.
|
|
12
|
+
*
|
|
13
|
+
* What is ours is the `ref`: an anchor with a scheme, so a node can point at a
|
|
14
|
+
* memory in the graph (`mem:`), a file the harness already offloaded (`file:`),
|
|
15
|
+
* or an inline remark (`note:`). Their design only ever pointed at local files.
|
|
16
|
+
*/
|
|
17
|
+
export declare const NODE_STATUSES: readonly ["todo", "doing", "done", "blocked"];
|
|
18
|
+
export type NodeStatus = (typeof NODE_STATUSES)[number];
|
|
19
|
+
export interface CanvasNode {
|
|
20
|
+
/** `NNN-Nn`, allocated monotonically and never reused. */
|
|
21
|
+
id: string;
|
|
22
|
+
status: NodeStatus;
|
|
23
|
+
summary: string;
|
|
24
|
+
/** `mem:<uuid>` | `file:<path>` | `note:<text>`, or null. */
|
|
25
|
+
ref: string | null;
|
|
26
|
+
}
|
|
27
|
+
export interface Canvas {
|
|
28
|
+
/** Three-digit canvas prefix; every node id starts with it. */
|
|
29
|
+
prefix: string;
|
|
30
|
+
taskGoal: string;
|
|
31
|
+
createdTime: string | null;
|
|
32
|
+
updatedTime: string | null;
|
|
33
|
+
nodes: CanvasNode[];
|
|
34
|
+
}
|
|
35
|
+
/** Cap on a rendered node summary. Long enough to be useful, short enough that
|
|
36
|
+
* a 20-node canvas still costs a few hundred tokens rather than a few thousand. */
|
|
37
|
+
export declare const SUMMARY_MAX = 120;
|
|
38
|
+
/**
|
|
39
|
+
* Reduce a title to a filename-safe slug.
|
|
40
|
+
*
|
|
41
|
+
* The whitelist is `[a-z0-9-]` and nothing else — not a blacklist of dangerous
|
|
42
|
+
* characters, because that is the kind of list that is always missing one entry.
|
|
43
|
+
* `.` is outside the whitelist, so `..` cannot survive and traversal is
|
|
44
|
+
* structurally impossible rather than merely checked for.
|
|
45
|
+
*
|
|
46
|
+
* Returns "" when nothing usable remains (a purely CJK title, for instance);
|
|
47
|
+
* callers must have a fallback and must not write a file named "".
|
|
48
|
+
*/
|
|
49
|
+
export declare function slugify(input: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Make text safe to sit inside a Mermaid `["..."]` label.
|
|
52
|
+
*
|
|
53
|
+
* Mermaid has no escape syntax inside a quoted label, so the only reliable move
|
|
54
|
+
* is to replace the characters that would terminate it with lookalikes. A
|
|
55
|
+
* summary is prose for a human to skim; swapping `"` for `'` costs nothing a
|
|
56
|
+
* reader will miss, and it makes `x"] --> EVIL["pwned` inert.
|
|
57
|
+
*
|
|
58
|
+
* Arrows are neutralised too: a literal `-->` inside a label does not break
|
|
59
|
+
* Mermaid, but it reads as an edge to anyone scanning the file, and to the
|
|
60
|
+
* regex in `parseCanvas` if it ever loosens.
|
|
61
|
+
*/
|
|
62
|
+
export declare function escapeLabel(text: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* Trim to `max` characters, counting by code point.
|
|
65
|
+
*
|
|
66
|
+
* `String.prototype.slice` counts UTF-16 units, so slicing a string of astral
|
|
67
|
+
* characters mid-pair yields a lone surrogate — which is not a character, and
|
|
68
|
+
* which some JSON consumers reject outright. Spreading into an array iterates
|
|
69
|
+
* code points, so a cut always lands on a boundary.
|
|
70
|
+
*/
|
|
71
|
+
export declare function truncateSummary(text: string, max?: number): string;
|
|
72
|
+
/**
|
|
73
|
+
* Next unused node id for this canvas.
|
|
74
|
+
*
|
|
75
|
+
* Deliberately max+1 rather than filling gaps. A deleted `000-N2` may still be
|
|
76
|
+
* cited by a commit message, a memory body or another node's ref; handing that
|
|
77
|
+
* id to a new node would silently repoint every one of those citations. Ids are
|
|
78
|
+
* cheap, so they are spent rather than recycled.
|
|
79
|
+
*/
|
|
80
|
+
export declare function allocateNodeId(canvas: Canvas): string;
|
|
81
|
+
export declare function renderCanvas(canvas: Canvas): string;
|
|
82
|
+
/**
|
|
83
|
+
* Parse a canvas file.
|
|
84
|
+
*
|
|
85
|
+
* Never throws. A canvas is recovered state — it is read at the moment the
|
|
86
|
+
* model has just lost its context, which is the worst possible moment to hand
|
|
87
|
+
* back an exception. A damaged header costs the goal; a damaged line costs that
|
|
88
|
+
* line; everything still parseable is returned.
|
|
89
|
+
*/
|
|
90
|
+
export declare function parseCanvas(content: string): Canvas;
|
|
91
|
+
export interface CanvasCounts {
|
|
92
|
+
done: number;
|
|
93
|
+
doing: number;
|
|
94
|
+
todo: number;
|
|
95
|
+
blocked: number;
|
|
96
|
+
}
|
|
97
|
+
export declare function countByStatus(canvas: Canvas): CanvasCounts;
|
|
98
|
+
/** One-line digest for the progressive-disclosure index: enough to decide
|
|
99
|
+
* whether to open the canvas, not enough to be worth injecting wholesale. */
|
|
100
|
+
export declare function formatCanvasHeadline(canvas: Canvas): string;
|
|
101
|
+
//# sourceMappingURL=canvas-format.d.ts.map
|