@danielmarbach/mnemonic-mcp 0.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/CHANGELOG.md +37 -0
- package/LICENSE +201 -0
- package/README.md +395 -0
- package/build/config.d.ts +34 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +141 -0
- package/build/config.js.map +1 -0
- package/build/consolidate.d.ts +7 -0
- package/build/consolidate.d.ts.map +1 -0
- package/build/consolidate.js +42 -0
- package/build/consolidate.js.map +1 -0
- package/build/embeddings.d.ts +4 -0
- package/build/embeddings.d.ts.map +1 -0
- package/build/embeddings.js +32 -0
- package/build/embeddings.js.map +1 -0
- package/build/git.d.ts +70 -0
- package/build/git.d.ts.map +1 -0
- package/build/git.js +196 -0
- package/build/git.js.map +1 -0
- package/build/import.d.ts +14 -0
- package/build/import.d.ts.map +1 -0
- package/build/import.js +41 -0
- package/build/import.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +2753 -0
- package/build/index.js.map +1 -0
- package/build/markdown.d.ts +6 -0
- package/build/markdown.d.ts.map +1 -0
- package/build/markdown.js +51 -0
- package/build/markdown.js.map +1 -0
- package/build/migration.d.ts +65 -0
- package/build/migration.d.ts.map +1 -0
- package/build/migration.js +372 -0
- package/build/migration.js.map +1 -0
- package/build/project-introspection.d.ts +5 -0
- package/build/project-introspection.d.ts.map +1 -0
- package/build/project-introspection.js +28 -0
- package/build/project-introspection.js.map +1 -0
- package/build/project-memory-policy.d.ts +17 -0
- package/build/project-memory-policy.d.ts.map +1 -0
- package/build/project-memory-policy.js +16 -0
- package/build/project-memory-policy.js.map +1 -0
- package/build/project.d.ts +32 -0
- package/build/project.d.ts.map +1 -0
- package/build/project.js +125 -0
- package/build/project.js.map +1 -0
- package/build/recall.d.ts +10 -0
- package/build/recall.d.ts.map +1 -0
- package/build/recall.js +18 -0
- package/build/recall.js.map +1 -0
- package/build/storage.d.ts +58 -0
- package/build/storage.d.ts.map +1 -0
- package/build/storage.js +269 -0
- package/build/storage.js.map +1 -0
- package/build/structured-content.d.ts +1818 -0
- package/build/structured-content.d.ts.map +1 -0
- package/build/structured-content.js +267 -0
- package/build/structured-content.js.map +1 -0
- package/build/vault.d.ts +54 -0
- package/build/vault.d.ts.map +1 -0
- package/build/vault.js +144 -0
- package/build/vault.js.map +1 -0
- package/package.json +46 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `mnemonic` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is loosely based on Keep a Changelog and uses semver-style version headings.
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-03-08
|
|
8
|
+
|
|
9
|
+
First public release candidate.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Plain markdown + JSON storage with git-backed main and project vaults.
|
|
14
|
+
- MCP tools for capture, recall, relationships, consolidation, project identity, policies, migrations, and vault operations.
|
|
15
|
+
- Project-scoped memory routing with separate storage location and project association semantics.
|
|
16
|
+
- Structured MCP responses for tool consumers.
|
|
17
|
+
- Migration framework with per-vault schema versioning and `v0.1.0-backfill-memory-versions`.
|
|
18
|
+
- CI-safe MCP integration tests plus unit coverage for storage, vault routing, and migration behavior.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- `move_memory` now rewrites project metadata when moving into a project vault and preserves project association when moving to the main vault.
|
|
23
|
+
- Migration execution now serializes per vault to avoid concurrent atomic-write collisions.
|
|
24
|
+
- Legacy notes normalize missing or invalid `memoryVersion` values to `0` when read.
|
|
25
|
+
- Vault search order now stays focused on the current project vault plus main vault fallback.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Malformed markdown files without frontmatter are no longer treated as valid notes.
|
|
30
|
+
- Explicit migration runs now persist schema version updates correctly.
|
|
31
|
+
- Recent stale migration, storage, and vault tests were reconciled with the actual runtime invariants.
|
|
32
|
+
|
|
33
|
+
### Caveats
|
|
34
|
+
|
|
35
|
+
- This is still an early release. Storage format, migration flow, and some MCP ergonomics may continue to evolve.
|
|
36
|
+
- Existing vaults should be considered migratable rather than permanently stable at this stage.
|
|
37
|
+
- Ollama is required locally for embeddings; CI uses a fake embeddings endpoint for hermetic tests.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# mnemonic
|
|
2
|
+
|
|
3
|
+
A local MCP memory server backed by plain markdown files, synced via git. No database. Project-scoped memory with semantic search.
|
|
4
|
+
|
|
5
|
+
For the high-level system map, see [`ARCHITECTURE.md`](ARCHITECTURE.md). For release notes, see [`CHANGELOG.md`](CHANGELOG.md).
|
|
6
|
+
|
|
7
|
+
## Why mnemonic
|
|
8
|
+
|
|
9
|
+
- 🧠 Your MCP client remembers decisions, fixes, and context across sessions — no re-explaining the same project.
|
|
10
|
+
- 📁 Memories are plain markdown with YAML frontmatter: readable, diffable, mergeable, and easy to back up.
|
|
11
|
+
- 🚫 No database or always-on service: just files, git, and a local Node process.
|
|
12
|
+
- 🎯 Project-scoped recall surfaces the right repo context first while keeping global memories accessible.
|
|
13
|
+
- 🤝 Shared `.mnemonic/` notes travel with the repository, so project knowledge isn't trapped in one person's chat history.
|
|
14
|
+
- 🔒 Embeddings stay local and gitignored — semantic search without committing generated vector data.
|
|
15
|
+
|
|
16
|
+
## Stability
|
|
17
|
+
|
|
18
|
+
mnemonic is at the inception stage. The storage format (frontmatter schema, vault layout, config structure) is still stabilizing and **may change in breaking ways** between releases. Migrations are provided when possible, but treat your vault as something you can afford to rebuild or re-migrate during this period. Keep an eye on the changelog; mnemonic surfaces pending migrations at startup and `list_migrations` shows pending work per vault after each update.
|
|
19
|
+
|
|
20
|
+
**Scale:** Designed for simplicity and portability — not large-scale knowledge bases.
|
|
21
|
+
|
|
22
|
+
- Hundreds to low thousands of notes: excellent fit.
|
|
23
|
+
- Several thousand: often fine, depending on note size, machine speed, and embedding throughput.
|
|
24
|
+
- Very large collections: expect pain points around reindex time, recall latency, and git churn.
|
|
25
|
+
- Many concurrent writers or massive scale: consider a dedicated database and indexing layer instead.
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
[Ollama](https://ollama.com) must be running locally with an embedding model pulled:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
ollama pull nomic-embed-text-v2-moe
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`qwen3-embedding:0.6b` is an alternative with a larger context window for longer notes:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ollama pull qwen3-embedding:0.6b
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
No code changes required — set `EMBED_MODEL=qwen3-embedding:0.6b` in your environment or MCP config.
|
|
42
|
+
|
|
43
|
+
## Setup
|
|
44
|
+
|
|
45
|
+
### Native (Node.js 18+)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install
|
|
49
|
+
npm run build
|
|
50
|
+
npm test
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`npm run build` already runs `typecheck`, but running it explicitly first gives a faster failure loop when iterating on the codebase.
|
|
54
|
+
|
|
55
|
+
For local dogfooding, start the built MCP server with:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm run mcp:local
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This rebuilds first, then launches `build/index.js`, so MCP clients always point at the latest source.
|
|
62
|
+
|
|
63
|
+
### Docker
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
docker compose build
|
|
67
|
+
docker compose up ollama-init # pulls nomic-embed-text-v2-moe into the ollama volume (one-time)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Ollama runs as a container with a named volume (`ollama-data`) so downloaded models persist across restarts. The vault directory (`~/mnemonic-vault` by default) is bind-mounted from the host. Git credentials (`~/.gitconfig` and `~/.ssh`) are mounted read-only so push/pull work inside the container.
|
|
71
|
+
|
|
72
|
+
Override the vault location:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
VAULT_PATH=/path/to/your-vault docker compose run --rm mnemonic
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Installing from GitHub Packages
|
|
79
|
+
|
|
80
|
+
Staging builds are published to GitHub Packages under the `staging` dist-tag. To install outside GitHub Actions, you need a GitHub token with at least the `read:packages` scope.
|
|
81
|
+
|
|
82
|
+
Create an `.npmrc` in the consuming project (or your home directory):
|
|
83
|
+
|
|
84
|
+
```ini
|
|
85
|
+
@danielmarbach:registry=https://npm.pkg.github.com
|
|
86
|
+
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Then install:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Latest staging build
|
|
93
|
+
npm install @danielmarbach/mnemonic-mcp@staging
|
|
94
|
+
|
|
95
|
+
# Specific prerelease
|
|
96
|
+
npm install @danielmarbach/mnemonic-mcp@0.1.0-staging.12
|
|
97
|
+
|
|
98
|
+
# Stable release
|
|
99
|
+
npm install @danielmarbach/mnemonic-mcp@0.1.0
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## MCP client config
|
|
103
|
+
|
|
104
|
+
### Claude Desktop / Cursor (native)
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"mcpServers": {
|
|
109
|
+
"mnemonic": {
|
|
110
|
+
"command": "npx",
|
|
111
|
+
"args": ["@danielmarbach/mnemonic-mcp@staging"],
|
|
112
|
+
"env": {
|
|
113
|
+
"VAULT_PATH": "/Users/you/mnemonic-vault"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
For a fixed installed version, point at the local binary instead:
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"mcpServers": {
|
|
125
|
+
"mnemonic": {
|
|
126
|
+
"command": "/path/to/your/project/node_modules/.bin/mnemonic",
|
|
127
|
+
"env": {
|
|
128
|
+
"VAULT_PATH": "/Users/you/mnemonic-vault"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Claude Desktop / Cursor (Docker)
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"mcpServers": {
|
|
140
|
+
"mnemonic": {
|
|
141
|
+
"command": "docker",
|
|
142
|
+
"args": ["compose", "-f", "/path/to/mnemonic/compose.yaml", "run", "--rm", "mnemonic"],
|
|
143
|
+
"env": {
|
|
144
|
+
"VAULT_PATH": "/Users/you/mnemonic-vault"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
> Ollama must be running before the MCP client invokes mnemonic. Start it once with `docker compose up ollama -d` and it will stay up between calls.
|
|
152
|
+
|
|
153
|
+
For local development against this repository's source tree, use `npm run mcp:local` or point your MCP client at `scripts/mcp-local.sh`.
|
|
154
|
+
|
|
155
|
+
## Configuration
|
|
156
|
+
|
|
157
|
+
| Variable | Default | Description |
|
|
158
|
+
|---------------|---------------------------|----------------------------------|
|
|
159
|
+
| `VAULT_PATH` | `~/mnemonic-vault` | Path to your markdown vault |
|
|
160
|
+
| `OLLAMA_URL` | `http://localhost:11434` | Ollama server URL |
|
|
161
|
+
| `EMBED_MODEL` | `nomic-embed-text-v2-moe` | Ollama embedding model |
|
|
162
|
+
| `DISABLE_GIT` | `false` | Set `true` to skip all git ops |
|
|
163
|
+
|
|
164
|
+
## How it works
|
|
165
|
+
|
|
166
|
+
### Vault layout
|
|
167
|
+
|
|
168
|
+
Two vault types store notes:
|
|
169
|
+
|
|
170
|
+
**Main vault** — private global memories at `~/mnemonic-vault` (its own git repo):
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
~/mnemonic-vault/
|
|
174
|
+
.gitignore ← auto-created, gitignores embeddings/
|
|
175
|
+
notes/
|
|
176
|
+
setup-notes-a1b2c3.md
|
|
177
|
+
embeddings/ ← local only, never committed
|
|
178
|
+
setup-notes-a1b2c3.json
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Project vault** — project-specific memories committed into the project repo:
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
<git-root>/
|
|
185
|
+
.mnemonic/
|
|
186
|
+
.gitignore ← auto-created, gitignores embeddings/
|
|
187
|
+
notes/
|
|
188
|
+
auth-bug-fix-d4e5f6.md
|
|
189
|
+
embeddings/ ← local only, never committed
|
|
190
|
+
auth-bug-fix-d4e5f6.json
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Routing
|
|
194
|
+
|
|
195
|
+
`cwd` sets project context; `scope` picks storage:
|
|
196
|
+
|
|
197
|
+
- `cwd` + `scope: "project"` *(default when `cwd` is present)* → project vault (`.mnemonic/`)
|
|
198
|
+
- `cwd` + `scope: "global"` → main vault, with project association in frontmatter
|
|
199
|
+
- no `cwd` → main vault as a plain global memory
|
|
200
|
+
|
|
201
|
+
Use `set_project_memory_policy` to save a per-project default. Supported values: `project`, `global`, `ask`. When policy is `ask`, `remember` returns a clear choice instead of guessing.
|
|
202
|
+
|
|
203
|
+
### Project identity
|
|
204
|
+
|
|
205
|
+
Project identity derives from the **git remote URL**, normalized to a stable slug (e.g. `github-com-acme-myapp`). The same project is recognized consistently across machines regardless of local clone paths. The default remote is `origin`; use `set_project_identity` to switch to `upstream` for fork workflows. If no remote exists, the git root folder name is used; if not in a git repo, the directory name.
|
|
206
|
+
|
|
207
|
+
### Recall
|
|
208
|
+
|
|
209
|
+
`recall` with `cwd` searches both vaults. Project notes get a **+0.15 similarity boost** — a soft signal, not a hard filter — so global memories remain accessible while project context floats to the top.
|
|
210
|
+
|
|
211
|
+
The `scope` parameter on `recall` narrows results:
|
|
212
|
+
|
|
213
|
+
- `"all"` *(default)* — project memories boosted, then global
|
|
214
|
+
- `"project"` — only memories for the detected project
|
|
215
|
+
- `"global"` — only memories with no project association
|
|
216
|
+
|
|
217
|
+
### Note lifecycle
|
|
218
|
+
|
|
219
|
+
Each note carries a `lifecycle`:
|
|
220
|
+
|
|
221
|
+
- `"permanent"` *(default)* — durable knowledge for future sessions
|
|
222
|
+
- `"temporary"` — working-state scaffolding (plans, WIP checkpoints) that can be cleaned up once consolidated
|
|
223
|
+
|
|
224
|
+
### Note format
|
|
225
|
+
|
|
226
|
+
Notes are standard markdown with YAML frontmatter:
|
|
227
|
+
|
|
228
|
+
```markdown
|
|
229
|
+
---
|
|
230
|
+
title: Auth bug fix approach
|
|
231
|
+
tags: [auth, bugfix]
|
|
232
|
+
project: github-com-acme-myapp
|
|
233
|
+
projectName: myapp
|
|
234
|
+
createdAt: 2026-03-07T10:00:00.000Z
|
|
235
|
+
updatedAt: 2026-03-07T10:00:00.000Z
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
We fixed the JWT expiry issue by switching to RS256 and...
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Content is markdown-linted on `remember`/`update`: fixable issues are auto-corrected before save; non-fixable issues are rejected.
|
|
242
|
+
|
|
243
|
+
### Embeddings and migrations
|
|
244
|
+
|
|
245
|
+
Embeddings are generated by Ollama's `/api/embed` with truncation enabled, stored as local JSON alongside notes, and gitignored. `sync` backfills missing embeddings on every run; `sync { force: true }` rebuilds all.
|
|
246
|
+
|
|
247
|
+
Each vault has its own `config.json` with a `schemaVersion`, so main and project vaults migrate independently:
|
|
248
|
+
|
|
249
|
+
- `list_migrations` reports schema version and pending migrations per vault.
|
|
250
|
+
- Startup warns when a vault is behind schema, but does not auto-migrate.
|
|
251
|
+
- `execute_migration` supports dry-run to preview changes before applying.
|
|
252
|
+
- Failed migration runs roll staged note writes back instead of leaving partial edits.
|
|
253
|
+
- Metadata-only migrations do not re-embed automatically; re-embedding happens on title/content change or during `sync` backfill.
|
|
254
|
+
|
|
255
|
+
The main vault `config.json` also controls mutation push behavior:
|
|
256
|
+
|
|
257
|
+
- `mutationPushMode: "main-only"` *(default)* - auto-push main-vault mutations, but leave project-vault commits local until the user pushes or runs `sync`
|
|
258
|
+
- `mutationPushMode: "all"` - auto-push mutating writes in both vault types
|
|
259
|
+
- `mutationPushMode: "none"` - never auto-push mutating writes; use `sync` or manual git commands instead
|
|
260
|
+
|
|
261
|
+
This keeps unpublished project branches from failing on `remember`/`update`, while still letting the main vault stay in sync by default.
|
|
262
|
+
|
|
263
|
+
## CLI commands
|
|
264
|
+
|
|
265
|
+
mnemonic ships CLI commands in addition to the MCP server.
|
|
266
|
+
|
|
267
|
+
### `mnemonic migrate`
|
|
268
|
+
|
|
269
|
+
Apply pending schema migrations to your vaults. Always preview with `--dry-run` first.
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
# Preview what would change
|
|
273
|
+
mnemonic migrate --dry-run
|
|
274
|
+
|
|
275
|
+
# Apply and auto-commit
|
|
276
|
+
mnemonic migrate
|
|
277
|
+
|
|
278
|
+
# Limit to one project vault
|
|
279
|
+
mnemonic migrate --dry-run --cwd=/path/to/project
|
|
280
|
+
mnemonic migrate --cwd=/path/to/project
|
|
281
|
+
|
|
282
|
+
# List available migrations and pending count
|
|
283
|
+
mnemonic migrate --list
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### `mnemonic import-claude-memory`
|
|
287
|
+
|
|
288
|
+
Import [Claude Code auto-memory](https://docs.anthropic.com/en/docs/claude-code/memory) into your vault. Claude Code stores per-project auto-memory at `~/.claude/projects/<encoded-path>/memory/*.md`. Each `##` heading becomes a separate mnemonic note tagged with `claude-memory` and `imported`. Notes whose titles already exist in the vault are skipped, so the command is safe to re-run.
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# Preview what would be imported
|
|
292
|
+
mnemonic import-claude-memory --dry-run
|
|
293
|
+
|
|
294
|
+
# Import from the current directory's Claude memory
|
|
295
|
+
mnemonic import-claude-memory
|
|
296
|
+
|
|
297
|
+
# Import for a specific project path
|
|
298
|
+
mnemonic import-claude-memory --cwd=/path/to/project
|
|
299
|
+
|
|
300
|
+
# Use a non-default Claude home
|
|
301
|
+
mnemonic import-claude-memory --claude-home=/custom/.claude
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Imported notes are written to the main vault with `lifecycle: permanent` and `scope: global`. After importing, run `sync` to embed them and push to your remote.
|
|
305
|
+
|
|
306
|
+
## Tools
|
|
307
|
+
|
|
308
|
+
| Tool | Description |
|
|
309
|
+
|-----------------------------|--------------------------------------------------------------------------|
|
|
310
|
+
| `consolidate` | Merge multiple notes into one with relationship to sources |
|
|
311
|
+
| `detect_project` | Resolve `cwd` to stable project id via git remote URL |
|
|
312
|
+
| `execute_migration` | Execute a named migration (supports dry-run) |
|
|
313
|
+
| `forget` | Delete note + embedding, git commit + push, cleanup relationships |
|
|
314
|
+
| `get` | Fetch one or more notes by exact id |
|
|
315
|
+
| `get_project_identity` | Show effective project identity and remote override |
|
|
316
|
+
| `get_project_memory_policy` | Show saved default write scope |
|
|
317
|
+
| `list` | List notes filtered by scope/tags/storage |
|
|
318
|
+
| `list_migrations` | List available migrations and pending count |
|
|
319
|
+
| `memory_graph` | Show compact adjacency list of relationships |
|
|
320
|
+
| `move_memory` | Move note between vaults without changing id |
|
|
321
|
+
| `project_memory_summary` | Summarize what mnemonic knows about a project |
|
|
322
|
+
| `recall` | Semantic search with optional project boost |
|
|
323
|
+
| `recent_memories` | Show most recently updated notes for scope |
|
|
324
|
+
| `remember` | Write note + embedding; `cwd` sets context, `scope` picks storage, `lifecycle` picks temporary vs permanent |
|
|
325
|
+
| `relate` | Create typed relationship between notes (bidirectional) |
|
|
326
|
+
| `set_project_identity` | Save which git remote defines project identity |
|
|
327
|
+
| `set_project_memory_policy` | Save default write scope for project (`project`, `global`, `ask`) |
|
|
328
|
+
| `sync` | Git sync when remote exists plus embedding backfill always; `force=true` rebuilds all embeddings |
|
|
329
|
+
| `unrelate` | Remove relationship between notes |
|
|
330
|
+
| `update` | Update note content/title/tags/lifecycle, re-embeds always |
|
|
331
|
+
| `where_is_memory` | Show note's project association and storage location |
|
|
332
|
+
|
|
333
|
+
### Relationships
|
|
334
|
+
|
|
335
|
+
Notes can be linked with typed edges stored in frontmatter:
|
|
336
|
+
|
|
337
|
+
```yaml
|
|
338
|
+
relatedTo:
|
|
339
|
+
- id: auth-bug-fix-a1b2c3d4
|
|
340
|
+
type: related-to
|
|
341
|
+
- id: security-policy-b5c6d7e8
|
|
342
|
+
type: explains
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
| Type | Meaning |
|
|
346
|
+
|--------------|------------------------------------------|
|
|
347
|
+
| `related-to` | Generic association (default) |
|
|
348
|
+
| `explains` | `fromId` explains `toId` |
|
|
349
|
+
| `example-of` | `fromId` is a concrete example of `toId` |
|
|
350
|
+
| `supersedes` | `fromId` is the newer version of `toId` |
|
|
351
|
+
|
|
352
|
+
`relate` is bidirectional by default. `forget` automatically removes any edges pointing at the deleted note.
|
|
353
|
+
|
|
354
|
+
## Multi-machine workflow
|
|
355
|
+
|
|
356
|
+
**Main vault:**
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
# First time on a new machine:
|
|
360
|
+
git clone git@github.com:you/mnemonic-vault.git ~/mnemonic-vault
|
|
361
|
+
# Then ask Claude to run `sync` — it pulls, pushes, and backfills embeddings in one step.
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**Project vault:**
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
# Already in the project repo — clone the project as normal.
|
|
368
|
+
# The .mnemonic/ directory comes along with it.
|
|
369
|
+
# Ask Claude to run `sync` with the project cwd to pull/push and backfill embeddings.
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
After the first sync, call `sync` (with `cwd` for project vaults) whenever you switch machines. It handles pull, push, and embeddings in one shot.
|
|
373
|
+
|
|
374
|
+
## FAQ
|
|
375
|
+
|
|
376
|
+
**Are mnemonic's embeddings the same as what Claude uses?**
|
|
377
|
+
|
|
378
|
+
No. The embeddings here are **local vector representations** generated by Ollama on your machine — nothing is sent to Anthropic or any cloud service. They are produced by a small embedding model (`nomic-embed-text-v2-moe` by default) and stored as plain JSON files. This is the same idea as retrieval-augmented generation (RAG): each note is converted to a dense numeric vector so `recall` can find semantically related notes even when you don't remember the exact words you used. It has nothing to do with how Claude processes tokens internally.
|
|
379
|
+
|
|
380
|
+
**Why do project memories appear first in `recall` results even when global memories are more similar?**
|
|
381
|
+
|
|
382
|
+
When you call `recall` with `cwd`, mnemonic adds a fixed **+0.15 boost** to the cosine similarity score of every note belonging to the detected project. This is a soft boost, not a hard filter — global memories are still included when relevant. The boost ensures project-specific context floats to the top when you're working inside a repo while cross-project knowledge remains accessible further down the list.
|
|
383
|
+
|
|
384
|
+
## Repository layout
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
src/ TypeScript runtime code
|
|
388
|
+
tests/ Vitest test files
|
|
389
|
+
build/ Compiled JavaScript output
|
|
390
|
+
.mnemonic/ Project-scoped memories for this repo
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Agent instructions
|
|
394
|
+
|
|
395
|
+
See [`SYSTEM_PROMPT.md`](SYSTEM_PROMPT.md) for the system prompt to use with your MCP client.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ProjectMemoryPolicy } from "./project-memory-policy.js";
|
|
2
|
+
import type { ProjectIdentityOverride } from "./project.js";
|
|
3
|
+
export type MutationPushMode = "all" | "main-only" | "none";
|
|
4
|
+
export interface MnemonicConfig {
|
|
5
|
+
schemaVersion: string;
|
|
6
|
+
reindexEmbedConcurrency: number;
|
|
7
|
+
mutationPushMode: MutationPushMode;
|
|
8
|
+
projectMemoryPolicies: Record<string, ProjectMemoryPolicy>;
|
|
9
|
+
projectIdentityOverrides: Record<string, ProjectIdentityOverride>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Read the schema version from a vault's config.json.
|
|
13
|
+
* Works for both main vault and project vaults.
|
|
14
|
+
* Returns the default schema version if no config exists.
|
|
15
|
+
*/
|
|
16
|
+
export declare function readVaultSchemaVersion(vaultPath: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Write the schema version to a vault's config.json.
|
|
19
|
+
* Preserves any existing fields in the file.
|
|
20
|
+
*/
|
|
21
|
+
export declare function writeVaultSchemaVersion(vaultPath: string, schemaVersion: string): Promise<void>;
|
|
22
|
+
export declare class MnemonicConfigStore {
|
|
23
|
+
readonly filePath: string;
|
|
24
|
+
constructor(mainVaultPath: string);
|
|
25
|
+
load(): Promise<MnemonicConfig>;
|
|
26
|
+
getProjectPolicy(projectId: string): Promise<ProjectMemoryPolicy | undefined>;
|
|
27
|
+
getProjectIdentityOverride(projectId: string): Promise<ProjectIdentityOverride | undefined>;
|
|
28
|
+
setProjectPolicy(policy: ProjectMemoryPolicy): Promise<void>;
|
|
29
|
+
setProjectIdentityOverride(projectId: string, override: ProjectIdentityOverride): Promise<void>;
|
|
30
|
+
setSchemaVersion(schemaVersion: string): Promise<void>;
|
|
31
|
+
private readAll;
|
|
32
|
+
private writeAll;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAE5D,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,WAAW,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC3D,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;CACnE;AAmED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS/E;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrG;AAED,qBAAa,mBAAmB;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,aAAa,EAAE,MAAM;IAI3B,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC;IAI/B,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAK7E,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC;IAK3F,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5D,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/F,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAM9C,OAAO;YAgBP,QAAQ;CAGvB"}
|