oh-memos-mcp 2.0.1 → 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.
Files changed (88) hide show
  1. package/.env.example +44 -27
  2. package/CHANGELOG.md +133 -0
  3. package/README.md +260 -226
  4. package/dist/api-client.d.ts +0 -0
  5. package/dist/api-client.js +0 -0
  6. package/dist/canvas-format.d.ts +101 -0
  7. package/dist/canvas-format.js +259 -0
  8. package/dist/canvas-store.d.ts +62 -0
  9. package/dist/canvas-store.js +187 -0
  10. package/dist/config.d.ts +3 -0
  11. package/dist/config.js +44 -9
  12. package/dist/cube-manager.d.ts +0 -0
  13. package/dist/cube-manager.js +11 -0
  14. package/dist/formatters.d.ts +0 -0
  15. package/dist/formatters.js +0 -0
  16. package/dist/graph-provenance.d.ts +34 -0
  17. package/dist/graph-provenance.js +175 -0
  18. package/dist/graphify-import.d.ts +72 -0
  19. package/dist/graphify-import.js +194 -0
  20. package/dist/handlers/admin.d.ts +1 -0
  21. package/dist/handlers/admin.js +18 -0
  22. package/dist/handlers/arg-contract.d.ts +0 -0
  23. package/dist/handlers/arg-contract.js +0 -0
  24. package/dist/handlers/calendar.d.ts +0 -0
  25. package/dist/handlers/calendar.js +0 -0
  26. package/dist/handlers/canvas.d.ts +40 -0
  27. package/dist/handlers/canvas.js +334 -0
  28. package/dist/handlers/graph.d.ts +8 -0
  29. package/dist/handlers/graph.js +66 -14
  30. package/dist/handlers/index.d.ts +0 -0
  31. package/dist/handlers/index.js +28 -5
  32. package/dist/handlers/memory.d.ts +0 -0
  33. package/dist/handlers/memory.js +33 -2
  34. package/dist/handlers/search.d.ts +0 -0
  35. package/dist/handlers/search.js +56 -15
  36. package/dist/handlers/skill.d.ts +6 -0
  37. package/dist/handlers/skill.js +123 -0
  38. package/dist/handlers/think.d.ts +0 -0
  39. package/dist/handlers/think.js +0 -0
  40. package/dist/handlers/utils.d.ts +0 -0
  41. package/dist/handlers/utils.js +0 -0
  42. package/dist/handlers/wiki-export.d.ts +0 -0
  43. package/dist/handlers/wiki-export.js +7 -9
  44. package/dist/handlers/wiki-import-relations.d.ts +11 -0
  45. package/dist/handlers/wiki-import-relations.js +32 -0
  46. package/dist/handlers/wiki-import.d.ts +19 -0
  47. package/dist/handlers/wiki-import.js +382 -0
  48. package/dist/index.d.ts +0 -0
  49. package/dist/index.js +0 -0
  50. package/dist/keyword-enhancer.d.ts +0 -0
  51. package/dist/keyword-enhancer.js +0 -0
  52. package/dist/memory-analysis.d.ts +0 -0
  53. package/dist/memory-analysis.js +0 -0
  54. package/dist/memory-quality.d.ts +10 -0
  55. package/dist/memory-quality.js +57 -0
  56. package/dist/memory-write-response.d.ts +8 -0
  57. package/dist/memory-write-response.js +15 -0
  58. package/dist/models.d.ts +0 -0
  59. package/dist/models.js +0 -0
  60. package/dist/policy.d.ts +8 -0
  61. package/dist/policy.js +9 -0
  62. package/dist/providers/lite-embedding.d.ts +31 -0
  63. package/dist/providers/lite-embedding.js +60 -0
  64. package/dist/providers/local-jsonl-provider.d.ts +28 -0
  65. package/dist/providers/local-jsonl-provider.js +225 -0
  66. package/dist/providers/memory-provider.d.ts +21 -0
  67. package/dist/providers/memory-provider.js +2 -0
  68. package/dist/providers/provider-factory.d.ts +11 -0
  69. package/dist/providers/provider-factory.js +27 -0
  70. package/dist/query-processing.d.ts +0 -0
  71. package/dist/query-processing.js +0 -0
  72. package/dist/server.d.ts +0 -0
  73. package/dist/server.js +5 -1
  74. package/dist/skill-candidate.d.ts +11 -0
  75. package/dist/skill-candidate.js +56 -0
  76. package/dist/skill-lifecycle.d.ts +15 -0
  77. package/dist/skill-lifecycle.js +51 -0
  78. package/dist/tools-registry.d.ts +130 -7
  79. package/dist/tools-registry.js +93 -31
  80. package/dist/types.d.ts +0 -0
  81. package/dist/types.js +0 -0
  82. package/dist/wiki-import-format.d.ts +47 -0
  83. package/dist/wiki-import-format.js +113 -0
  84. package/dist/wiki-import-safety.d.ts +25 -0
  85. package/dist/wiki-import-safety.js +31 -0
  86. package/dist/wiki-relations.d.ts +44 -0
  87. package/dist/wiki-relations.js +88 -0
  88. package/package.json +5 -2
package/.env.example CHANGED
@@ -1,27 +1,44 @@
1
- # ============================================================================
2
- # oh-memos-mcp Environment Configuration
3
- # ============================================================================
4
- # Copy this file to .env in your project root and adjust values.
5
- # Priority: CLI args > environment variables > defaults
6
- # ============================================================================
7
-
8
- # --- Required ---
9
- MEMOS_URL=http://localhost:18000 # oh-memos API address
10
- MEMOS_USER=dev_user # Default user ID
11
- MEMOS_DEFAULT_CUBE=dev_cube # Default memory cube ID
12
- MEMOS_CUBES_DIR=/path/to/cubes # Absolute path to cubes directory
13
-
14
- # --- Timeouts (seconds) ---
15
- # MEMOS_TIMEOUT_TOOL=300 # Tool call timeout (default: 300)
16
- # MEMOS_TIMEOUT_STARTUP=30 # Startup timeout (default: 30)
17
- # MEMOS_TIMEOUT_HEALTH=5 # Health check timeout (default: 5)
18
- # MEMOS_API_WAIT_MAX=60 # Max API wait time (default: 60)
19
-
20
- # --- Feature Flags ---
21
- # MEMOS_ENABLE_DELETE=false # Enable memory deletion (default: false)
22
- # MEMOS_LOG_LEVEL=WARNING # DEBUG | INFO | WARNING | ERROR
23
-
24
- # --- Neo4j (optional, for direct graph queries) ---
25
- # NEO4J_HTTP_URL=http://localhost:7474
26
- # NEO4J_USER=neo4j
27
- # NEO4J_PASSWORD=your_password
1
+ # ============================================================================
2
+ # oh-memos-mcp Environment Configuration
3
+ # ============================================================================
4
+ # Copy this file to .env in your project root and adjust values.
5
+ # Priority: CLI flags > explicit env file > inherited environment > discovered .env > defaults
6
+ # A discovered .env only fills gaps; it never overrides MCP client env values.
7
+ # Set MEMOS_ENV_FILE when a specific file must be authoritative (recommended for npx).
8
+ # ============================================================================
9
+
10
+ # --- Required (Full/API mode) ---
11
+ MEMOS_URL=http://localhost:18000 # oh-memos API address (may be empty in local mode)
12
+ MEMOS_USER=dev_user # Default user ID
13
+ MEMOS_DEFAULT_CUBE=dev_cube # Default memory cube ID
14
+ MEMOS_CUBES_DIR=/path/to/cubes # Absolute path to cubes directory
15
+
16
+ # --- Provider selection ---
17
+ # MEMOS_PROVIDER=api # api = Full backend via Python API (default)
18
+ # MEMOS_PROVIDER=local # local = Lite JSONL store, no Python API needed
19
+ # MEMOS_MODE=lite # Shorthand: implies MEMOS_PROVIDER=local
20
+
21
+ # --- Lite local embeddings (optional, only for MEMOS_PROVIDER=local) ---
22
+ # Semantic ranking for the Lite store talks to an Ollama-compatible endpoint.
23
+ # It expects the Ollama /api/embeddings protocol, so point it at an Ollama
24
+ # host (local or self-hosted remote) — cloud OpenAI-compatible embedding
25
+ # endpoints belong to the Full backend instead (see docker/.env.docker.example,
26
+ # MOS_EMBEDDER_*). Defaults below need no configuration at all.
27
+ # MEMOS_LITE_EMBED_URL=http://127.0.0.1:11434 # Ollama endpoint
28
+ # MEMOS_LITE_EMBED_MODEL=bge-m3 # any embedding model you pulled
29
+ # MEMOS_LITE_EMBED=off # pin lexical-only ranking explicitly
30
+
31
+ # --- Timeouts (seconds) ---
32
+ # MEMOS_TIMEOUT_TOOL=300 # Tool call timeout (default: 300)
33
+ # MEMOS_TIMEOUT_STARTUP=30 # Startup timeout (default: 30)
34
+ # MEMOS_TIMEOUT_HEALTH=5 # Health check timeout (default: 5)
35
+ # MEMOS_API_WAIT_MAX=60 # Max API wait time (default: 60)
36
+
37
+ # --- Feature Flags ---
38
+ # MEMOS_ENABLE_DELETE=false # Enable memory deletion (default: false)
39
+ # MEMOS_LOG_LEVEL=WARNING # DEBUG | INFO | WARNING | ERROR
40
+
41
+ # --- Neo4j (optional, for direct graph queries) ---
42
+ # NEO4J_HTTP_URL=http://localhost:7474
43
+ # NEO4J_USER=neo4j
44
+ # NEO4J_PASSWORD=your_password
package/CHANGELOG.md CHANGED
@@ -6,6 +6,139 @@ This project follows [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ---
8
8
 
9
+ ## [2.1.0] - 2026-08-16
10
+
11
+ ### Fixed
12
+
13
+ - **Auto-discovered `.env` no longer overrides launcher environment.** A `.env`
14
+ found in the working directory or package root now only fills missing values,
15
+ so MCP client `env` blocks and shell exports such as `MEMOS_PROVIDER=local`
16
+ stay in effect. A file selected explicitly through `MEMOS_ENV_FILE` or
17
+ `--memos-env-file` remains authoritative.
18
+
19
+ ### Added
20
+
21
+ - **Local Lite provider.** `MEMOS_PROVIDER=local` (implied by `MEMOS_MODE=lite`)
22
+ serves `memos_save`, `memos_get`, `memos_list_v2`, `memos_search`, and
23
+ `memos_context_resume` from a per-cube `memories.jsonl` with deterministic
24
+ lexical ranking, durable appends, and a cross-process lock. Graph, Think,
25
+ Wiki, and admin tools report `LOCAL_PROVIDER_UNSUPPORTED` rather than
26
+ pretending a graph backend exists.
27
+
28
+ - **Skill candidate lifecycle.** `memos_review_skill_candidate` records
29
+ approve/reject with reviewer audit metadata, and
30
+ `memos_install_skill_candidate` installs only approved candidates into
31
+ `.claude/skills/<slug>/SKILL.md` without overwriting, following symlinks, or
32
+ executing anything.
33
+
34
+ - **Explainable graph provenance.** `memos_graph(mode="related"|"path"|"impact")`
35
+ now reports normalized evidence categories (`EXTRACTED`, `INFERRED`,
36
+ `AMBIGUOUS`, or `UNKNOWN`) and includes confidence, evidence references,
37
+ source file/location, extractor version and verification time when those
38
+ fields exist. Legacy graph data without provenance remains readable and is
39
+ reported as `UNKNOWN` rather than assigned invented evidence.
40
+
41
+ - **`memos_graph(mode="import")` Graphify boundary.** Accepts up to 5 MB of
42
+ Graphify/NetworkX node-link JSON through `graph_json`, validates `nodes` plus
43
+ `links` (or the `edges` alias), and produces a deterministic import plan with
44
+ portable stable Code Graph ids. Duplicate ids, dangling edges, unsafe source
45
+ paths, invalid confidence values and oversized graphs are rejected before
46
+ any persistence boundary. This mode is intentionally **dry-run only**: it
47
+ never writes to Neo4j, Qdrant or a memory cube.
48
+
49
+ - **`memos_canvas`** — a symbolic task canvas: short-term task state that survives
50
+ context compaction. One Mermaid file per task under
51
+ `{MEMOS_CUBES_DIR}/{cube_id}/canvas/`, whose nodes carry a greppable id
52
+ (`000-N1`) and an optional `ref` anchoring them to evidence:
53
+ `mem:<memory_id>` (a memory in the graph), `file:<path>` (any file, including
54
+ the large tool results the harness already offloads), or `note:<text>`.
55
+
56
+ `action`: `open` (needs `goal`) · `update` (appends a node; `node_id` edits one
57
+ in place) · `show` · `list`.
58
+
59
+ Canvases are deliberately **not** written to Neo4j or Qdrant. A canvas changes
60
+ several times an hour, and paying an embedding round trip for a `doing→done`
61
+ flip would be absurd. Durable facts still go through `memos_save`; the canvas
62
+ points at them with a `mem:` ref.
63
+
64
+ This is **not** a token-saving feature. The design it borrows from
65
+ ([TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory))
66
+ achieves its reduction by intercepting and replacing tool output before the
67
+ model sees it, which a Claude Code hook cannot do — `PreToolUse` can rewrite a
68
+ tool's *input* via `updatedInput`, but no hook can rewrite its *output*. What
69
+ this offers instead is task state that survives compaction, and a path from a
70
+ summary back to the evidence behind it.
71
+
72
+ Node ids and canvas prefixes are allocated as max+1 and **never reuse a gap**:
73
+ a deleted `000-N2` may still be cited from a commit message, a memory body or
74
+ another node's ref, and handing that id to a new node would silently repoint
75
+ every one of those citations.
76
+
77
+ - `memos_context_resume` now lists **unfinished** canvases first — headlines and
78
+ counts only, a few dozen tokens — so the first thing visible after a compaction
79
+ is the open work rather than a memory feed. Injecting canvas bodies here would
80
+ rebuild the very context bloat the canvas exists to avoid; the model opens what
81
+ it needs with `show`.
82
+
83
+ - **Test infrastructure.** This package previously had none: no test script, no
84
+ `*.test.ts`. Adds vitest and `npm test`, with 65 unit tests covering the
85
+ parse/render round trip, node-id allocation, Mermaid label injection, path
86
+ traversal refusal and atomic writes. `scripts/canvas-e2e.mjs` adds 18 checks
87
+ driven over real MCP stdio rather than mocks.
88
+
89
+ - `MEMOS_ENV_FILE` env var and `--memos-env-file` flag, to point the server at an
90
+ explicit `.env`. Previously the file was located only by guessing from position
91
+ (cwd, two levels above the package, dotenv's upward search) — which works from
92
+ a checkout and never works under `npx`, where the package root sits in the npm
93
+ cache and every candidate misses, loading not one variable. A path that does
94
+ not exist now warns on stderr rather than falling through silently.
95
+
96
+ ### Fixed
97
+
98
+ - `toLocalPath()` rewrote Windows cube paths to `/mnt/...` unconditionally. That
99
+ mapping only resolves inside WSL; under native Windows Node the result is not
100
+ absolute, so it resolved against the current drive and every cube write landed
101
+ in a phantom tree while the API kept reading the real path. Registration
102
+ reported success, then `/search` and `/memories` failed 400 — the loaded cube
103
+ had no memory backend.
104
+
105
+ ### Security
106
+
107
+ - `canvasPath` is the one place caller text becomes a filesystem path. It uses a
108
+ **whitelist** (`[a-z0-9-]`) rather than a blacklist of dangerous characters,
109
+ because a blacklist is always missing an entry. `.` is outside the whitelist,
110
+ so `..` cannot survive it — traversal is structurally impossible rather than
111
+ merely checked for — and a post-resolve containment check backs that up
112
+ independently. `cube_id` is treated as untrusted too, since it is derived from
113
+ a caller-supplied `project_path`.
114
+
115
+ ### Documentation
116
+
117
+ - The `alwaysAllow` example carried two defects. `memos_search` appeared twice,
118
+ and several entries were **call forms** — `memos_admin(action=list_cubes)` and
119
+ the like. `alwaysAllow` matches tool names, so those entries matched nothing:
120
+ a reader would believe those calls were pre-approved and still be prompted for
121
+ every one. Replaced with bare tool names, which auto-approve every action of
122
+ the tool.
123
+ - `memos_delete` was dropped from that example, which also set
124
+ `MEMOS_ENABLE_DELETE: "true"` — together they auto-approve deleting memories
125
+ with no prompt. Enabling that is a decision worth making deliberately.
126
+ - The `.env` note claimed the working directory's file loads "automatically with
127
+ highest priority". Under `npx` no file loads at all. Documented `MEMOS_ENV_FILE`
128
+ and what actually happens.
129
+
130
+ ### Notes
131
+
132
+ - Tool surface grew 12488 B → 13680 B (+9.5%), past the +5% drift budget, and the
133
+ baseline was re-frozen. This is the cost of a new tool rather than description
134
+ drift; the description was trimmed from 1333 B to 1192 B first, moving detail
135
+ into `show`'s output (the same move `memos_suggest` made with the memory-type
136
+ decision tree).
137
+ - `tsconfig.json` now excludes `src/**/*.test.ts`. Without it the test files
138
+ compile into `dist` and ship with `npm publish`.
139
+
140
+ ---
141
+
9
142
  ## [2.0.1] — 2026-08-02
10
143
 
11
144
  ### Fixed