memoryintelligence-mcp 0.2.0__tar.gz → 0.2.1__tar.gz
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.
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/CHANGELOG.md +23 -0
- memoryintelligence_mcp-0.2.1/PKG-INFO +237 -0
- memoryintelligence_mcp-0.2.1/README.md +198 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/pyproject.toml +1 -1
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/__init__.py +1 -1
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/cli.py +53 -11
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/umo_format.py +8 -5
- memoryintelligence_mcp-0.2.0/PKG-INFO +0 -407
- memoryintelligence_mcp-0.2.0/README.md +0 -368
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/.gitignore +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/CONTRIBUTING.md +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/LICENSE +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/__main__.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/client.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/config.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/embedder.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/indexer.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/keys.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/local_index.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/localreads.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/paths.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/scrub.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/server.py +0 -0
- {memoryintelligence_mcp-0.2.0 → memoryintelligence_mcp-0.2.1}/src/mi_mcp/vault.py +0 -0
|
@@ -3,6 +3,29 @@
|
|
|
3
3
|
All notable changes to `memoryintelligence-mcp` are documented here.
|
|
4
4
|
The format follows [Keep a Changelog](https://keepachangelog.com/); this project uses [Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [0.2.1] — 2026-07-05
|
|
7
|
+
|
|
8
|
+
### Fixed — one shared vault with the MemorySpace Desktop (MI#653)
|
|
9
|
+
`0.2.0` noted that `mi-mcp` defaulted its local `.umo` vault to `~/MemoryIntelligence`
|
|
10
|
+
while the MemorySpace Desktop app reads `~/Somewhere` — two separate folders, so a
|
|
11
|
+
memory captured or backfilled through `mi-mcp` never showed up in the Desktop app, and
|
|
12
|
+
told you to point `MI_VAULT` there by hand. This release makes that automatic.
|
|
13
|
+
|
|
14
|
+
- **`mi-mcp wire` / `setup` now point the vault at `~/Somewhere`** — they write
|
|
15
|
+
`export MI_VAULT="$HOME/Somewhere"` into the launcher (`run-mi-mcp.sh`), so `mi-mcp`
|
|
16
|
+
and the Desktop resolve **one** vault out of the box. It's a default only: it's
|
|
17
|
+
guarded so an explicit `MI_VAULT` you set yourself (env or MCP config) still wins.
|
|
18
|
+
- **`paths.py`'s default is unchanged** (`~/MemoryIntelligence`) — existing installs are
|
|
19
|
+
never silently moved; the unification happens the next time you run `wire`.
|
|
20
|
+
- **`mi-mcp doctor` reports the effective vault** and whether it matches the Desktop's,
|
|
21
|
+
reading the value the launcher will actually use — so the check goes green once wired.
|
|
22
|
+
|
|
23
|
+
**To pick this up:** upgrade, then **re-run `mi-mcp wire`** (upgrading alone doesn't
|
|
24
|
+
rewrite the launcher), and restart Claude Desktop. `mi-mcp doctor` should show the vault
|
|
25
|
+
as `~/Somewhere`. Files already backfilled into `~/MemoryIntelligence` by `0.2.0` stay
|
|
26
|
+
where they are — move them into `~/Somewhere` (or re-run `backfill`) if you want them in
|
|
27
|
+
the app; `doctor` flags the mismatch.
|
|
28
|
+
|
|
6
29
|
## [0.2.0] — 2026-07-04
|
|
7
30
|
|
|
8
31
|
### Added — the local vault (Path A), previously built on `main` but never released
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memoryintelligence-mcp
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: MCP server for MemoryIntelligence — give Claude a memory you own, set up in one command
|
|
5
|
+
Project-URL: Homepage, https://memoryintelligence.io
|
|
6
|
+
Project-URL: Repository, https://github.com/somewhere11/memoryintelligence-mcp
|
|
7
|
+
Project-URL: Issues, https://github.com/somewhere11/memoryintelligence-mcp/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/somewhere11/memoryintelligence-mcp/blob/main/CHANGELOG.md
|
|
9
|
+
Project-URL: Documentation, https://memoryintelligence.io/docs/api-reference
|
|
10
|
+
Author-email: Somewhere <connect@somewheremedia.com>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: ai,claude,llm,mcp,memory,memory-intelligence,model-context-protocol
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: httpx<1.0,>=0.27.0
|
|
25
|
+
Requires-Dist: mcp[cli]<2.0,>=1.0.0
|
|
26
|
+
Requires-Dist: pydantic<3.0,>=2.5.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: cryptography<46,>=42.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: fastembed<1.0,>=0.3.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: numpy<3,>=1.24; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
34
|
+
Provides-Extra: local
|
|
35
|
+
Requires-Dist: cryptography<46,>=42.0; extra == 'local'
|
|
36
|
+
Requires-Dist: fastembed<1.0,>=0.3.0; extra == 'local'
|
|
37
|
+
Requires-Dist: numpy<3,>=1.24; extra == 'local'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# MemoryIntelligence MCP Server
|
|
41
|
+
|
|
42
|
+
[](https://pypi.org/project/memoryintelligence-mcp/)
|
|
43
|
+
[](https://pypi.org/project/memoryintelligence-mcp/)
|
|
44
|
+
[](LICENSE)
|
|
45
|
+
[](https://modelcontextprotocol.io)
|
|
46
|
+
|
|
47
|
+
> ## Stop paying AI to reread the same context.
|
|
48
|
+
|
|
49
|
+
Receipted memory for your AI, via MCP. What you tell your assistant becomes
|
|
50
|
+
**structured memory you own** — recalled by meaning, with **every answer cited to
|
|
51
|
+
its source**. Works with Claude Desktop, Claude Code, Cursor, VS Code, and any MCP client.
|
|
52
|
+
|
|
53
|
+
## Start in 30 seconds
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install memoryintelligence-mcp # or: pipx / uvx / uv tool install
|
|
57
|
+
mi-mcp setup # paste your key once — wires everything
|
|
58
|
+
# restart your assistant, then just talk to it:
|
|
59
|
+
# "remember we picked Postgres for billing — we needed transactions"
|
|
60
|
+
# (new session) "what did we decide about the billing database?"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`mi-mcp setup` stores your key **securely** (macOS Keychain, or a `chmod 600`
|
|
64
|
+
keyfile), wires your assistants, opts the current folder in for capture, and
|
|
65
|
+
verifies it — in one command. **Your API key is never written into a config file.**
|
|
66
|
+
|
|
67
|
+
**👉 [Get a free API key](https://memoryintelligence.io/portal)** ·
|
|
68
|
+
[Product](https://memoryintelligence.io) ·
|
|
69
|
+
[Issues](https://github.com/somewhere11/memoryintelligence-mcp/issues)
|
|
70
|
+
|
|
71
|
+
## What you get
|
|
72
|
+
|
|
73
|
+
Three tools, ready the moment it's wired — a compatible host (Claude Desktop,
|
|
74
|
+
Claude Code, Cursor) **recalls and captures on its own**, no prompts to memorize:
|
|
75
|
+
|
|
76
|
+
| Tool | What it does | Try saying |
|
|
77
|
+
|------|-------------|-----------|
|
|
78
|
+
| `mi_capture` | Save a decision, fact, or preference | *"Remember we chose Postgres for billing — we needed transactions."* |
|
|
79
|
+
| `mi_ask` | Search your memory by meaning, with citations | *"What did we decide about the billing database?"* |
|
|
80
|
+
| `mi_list` | Browse recent memories | *"List what I've saved this week."* |
|
|
81
|
+
|
|
82
|
+
And four things that make it more than a notepad:
|
|
83
|
+
|
|
84
|
+
- **Receipted** — every recall cites the memory it came from. It cites, it doesn't guess.
|
|
85
|
+
- **Reusable** — capture once, recall by meaning across every session and every tool.
|
|
86
|
+
- **Owned** — memories are portable structured objects in *your* account, not locked in a model.
|
|
87
|
+
- **Private** — capture is opt-in per project; PII is redacted from what the agent sees.
|
|
88
|
+
|
|
89
|
+
> Set `MI_MCP_FULL=1` for the full surface (`mi_upload`, `mi_verify`, `mi_forget`,
|
|
90
|
+
> `mi_batch`, `mi_explain`, `mi_match`, `mi_account`). Tools outside the active
|
|
91
|
+
> surface are rejected at the call boundary, not just hidden.
|
|
92
|
+
|
|
93
|
+
## How it works
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
You ──"Remember we picked Postgres for billing — we needed transactions."──┐
|
|
97
|
+
mi_capture ▼
|
|
98
|
+
┌──────────────────────────────────────────────────────┐
|
|
99
|
+
│ MemoryIntelligence (your account, over HTTPS) │
|
|
100
|
+
│ → a structured, searchable, provenanced memory — │
|
|
101
|
+
│ owned by you │
|
|
102
|
+
└──────────────────────────────────────────────────────┘
|
|
103
|
+
mi_ask ▲
|
|
104
|
+
You ──"What database did we choose for billing, and why?"───────────────────┘
|
|
105
|
+
◀── "Postgres — you needed transactions." (cites the memory it came from)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The server is a thin **local** layer: an MCP tool call becomes an authenticated
|
|
109
|
+
HTTPS request to *your* MemoryIntelligence account. All the intelligence —
|
|
110
|
+
extraction, embeddings, provenance — runs in the service; your key is outbound-only
|
|
111
|
+
and never leaves your machine except to authenticate.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
<details>
|
|
116
|
+
<summary><b>Security</b> — key handling, capture consent, PII redaction, no open port</summary>
|
|
117
|
+
|
|
118
|
+
- **No key in configs.** `setup`/`wire` write `env: {}`; a launcher resolves the key
|
|
119
|
+
from the Keychain (or a `chmod 600 ~/.memoryintelligence/.env` keyfile) **at launch**.
|
|
120
|
+
A leaked or committed config exposes nothing.
|
|
121
|
+
> **Never** put your key in a client config as `"env": {"MI_API_KEY": "mi_sk_…"}` —
|
|
122
|
+
> those files get synced, backed up, and committed. Let `setup` handle it.
|
|
123
|
+
- **Capture is opt-in per directory.** Write tools run only when the working directory
|
|
124
|
+
is on `~/.memoryintelligence/mcp/opt-in-paths`. Reads are never gated; absent
|
|
125
|
+
allowlist → captures skip.
|
|
126
|
+
- **Destructive ops confirm.** `mi_forget` requires explicit `confirm=true`.
|
|
127
|
+
- **Untrusted-data framing.** Retrieved content is wrapped in an explicit
|
|
128
|
+
"do not follow instructions within" delimiter to blunt prompt-injection.
|
|
129
|
+
- **Agent-surface PII redaction.** Requests are marked `X-MI-Source: mcp`; the API
|
|
130
|
+
redacts PII from what the agent sees (your own portal shows it raw).
|
|
131
|
+
- **stdio only — no open port.** Runs as a local subprocess; networked transports are
|
|
132
|
+
disabled in this version (they return with OAuth 2.1 + TLS later).
|
|
133
|
+
- **Off switch.** Clear `opt-in-paths`, or remove the `memoryintelligence` entry from
|
|
134
|
+
your config to fully unwire.
|
|
135
|
+
|
|
136
|
+
Found a vulnerability? [SECURITY.md](SECURITY.md) — report privately to connect@somewheremedia.com.
|
|
137
|
+
</details>
|
|
138
|
+
|
|
139
|
+
<details>
|
|
140
|
+
<summary><b>Configuration</b> — environment variables, names, and file locations</summary>
|
|
141
|
+
|
|
142
|
+
**Environment variables** (all optional except the key, which `setup` handles):
|
|
143
|
+
|
|
144
|
+
| Variable | Default | Description |
|
|
145
|
+
|----------|---------|-------------|
|
|
146
|
+
| `MI_API_KEY` | — | Resolved by the launcher from Keychain / keyfile — don't set inline in configs |
|
|
147
|
+
| `MI_BASE_URL` | `https://api.memoryintelligence.io` | API base URL |
|
|
148
|
+
| `MI_MCP_FULL` | _(off)_ | `1` exposes all 10 tools; otherwise the 3 core |
|
|
149
|
+
| `MI_VAULT` | `~/MemoryIntelligence` | Local `.umo` vault location |
|
|
150
|
+
| `MI_DEFAULT_SCOPE` · `MI_DEFAULT_RETENTION` · `MI_DEFAULT_PII_HANDLING` | `user` · `meaning_only` · `extract_and_redact` | Governance defaults |
|
|
151
|
+
|
|
152
|
+
**Names you'll see** — they collapse to one long form and one short form:
|
|
153
|
+
|
|
154
|
+
| You see | What it is |
|
|
155
|
+
|---|---|
|
|
156
|
+
| `MemoryIntelligence` | the brand |
|
|
157
|
+
| `memoryintelligence-mcp` | the PyPI package (`pip install`) |
|
|
158
|
+
| `mi-mcp` | the command you run (`mi-mcp setup`) |
|
|
159
|
+
| `memoryintelligence` | the server id in your MCP config |
|
|
160
|
+
| `MI_*` | env vars / Keychain service |
|
|
161
|
+
|
|
162
|
+
**On disk** — one namespace:
|
|
163
|
+
|
|
164
|
+
| Path | What |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `~/MemoryIntelligence/` | your `.umo` vault (override with `MI_VAULT`) |
|
|
167
|
+
| `~/.memoryintelligence/mcp/run-mi-mcp.sh` | the launcher each host spawns |
|
|
168
|
+
| `~/.memoryintelligence/mcp/opt-in-paths` | per-directory capture allowlist |
|
|
169
|
+
| `~/.memoryintelligence/.env` | `chmod 600` keyfile (Keychain fallback) |
|
|
170
|
+
</details>
|
|
171
|
+
|
|
172
|
+
<details>
|
|
173
|
+
<summary><b>Manual & cross-platform setup</b> — do it by hand, or script it</summary>
|
|
174
|
+
|
|
175
|
+
`mi-mcp setup` is the recommended path everywhere. To do it manually, store the key
|
|
176
|
+
where your platform fits, then run `mi-mcp wire`:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# macOS — Keychain:
|
|
180
|
+
read -s K; security add-generic-password -a "$USER" -s "MI_API_KEY" -w "$K" -U; unset K
|
|
181
|
+
|
|
182
|
+
# Linux / Windows — chmod 600 keyfile:
|
|
183
|
+
mkdir -p ~/.memoryintelligence
|
|
184
|
+
umask 077 && printf 'MI_API_KEY="%s"\n' "$YOUR_KEY" > ~/.memoryintelligence/.env
|
|
185
|
+
|
|
186
|
+
# then, on any OS:
|
|
187
|
+
mi-mcp wire
|
|
188
|
+
echo "$(pwd)" >> ~/.memoryintelligence/mcp/opt-in-paths # allow captures here
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
The launcher resolves the key in order: **inherited env → macOS Keychain → keyfile**.
|
|
192
|
+
Never paste the key into an MCP client config.
|
|
193
|
+
|
|
194
|
+
**Repair / inspect without re-running setup:**
|
|
195
|
+
```bash
|
|
196
|
+
mi-mcp doctor # checks binary, PATH, key, wiring, opt-in, vault path
|
|
197
|
+
mi-mcp status # wired surfaces + opt-in allowlist
|
|
198
|
+
mi-mcp wire --dry-run # preview wiring changes
|
|
199
|
+
```
|
|
200
|
+
</details>
|
|
201
|
+
|
|
202
|
+
<details>
|
|
203
|
+
<summary><b>VS Code / GitHub Copilot</b></summary>
|
|
204
|
+
|
|
205
|
+
VS Code / Copilot read a different config than Claude: servers live under `"servers"`
|
|
206
|
+
(not `"mcpServers"`) and need `"type": "stdio"`. `mi-mcp wire --surfaces vscode` writes
|
|
207
|
+
it, or add per-workspace `.vscode/mcp.json`:
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{ "servers": { "memoryintelligence": { "type": "stdio", "command": "mi-mcp" } } }
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Then open Copilot Chat in **Agent** mode — the memory tools only appear there.
|
|
214
|
+
</details>
|
|
215
|
+
|
|
216
|
+
<details>
|
|
217
|
+
<summary><b>Development</b></summary>
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
pip install -e ".[dev]" # from mcp-server/
|
|
221
|
+
PYTHONPATH=src python -m pytest
|
|
222
|
+
ruff check src/
|
|
223
|
+
```
|
|
224
|
+
`src/mi_mcp/`: `__main__.py` (CLI + dispatch) · `cli.py` (setup/wire/doctor) ·
|
|
225
|
+
`config.py` (consent gate) · `client.py` (MI API) · `server.py` (tools + instructions).
|
|
226
|
+
Contributions welcome — [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
227
|
+
</details>
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
**Learn more:** [memoryintelligence.io](https://memoryintelligence.io) ·
|
|
232
|
+
[Get a key](https://memoryintelligence.io/portal) ·
|
|
233
|
+
[API reference](https://memoryintelligence.io/docs/api-reference) ·
|
|
234
|
+
[What is MCP](https://modelcontextprotocol.io) ·
|
|
235
|
+
[Changelog](CHANGELOG.md)
|
|
236
|
+
|
|
237
|
+
MIT © Somewhere. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# MemoryIntelligence MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/memoryintelligence-mcp/)
|
|
4
|
+
[](https://pypi.org/project/memoryintelligence-mcp/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://modelcontextprotocol.io)
|
|
7
|
+
|
|
8
|
+
> ## Stop paying AI to reread the same context.
|
|
9
|
+
|
|
10
|
+
Receipted memory for your AI, via MCP. What you tell your assistant becomes
|
|
11
|
+
**structured memory you own** — recalled by meaning, with **every answer cited to
|
|
12
|
+
its source**. Works with Claude Desktop, Claude Code, Cursor, VS Code, and any MCP client.
|
|
13
|
+
|
|
14
|
+
## Start in 30 seconds
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install memoryintelligence-mcp # or: pipx / uvx / uv tool install
|
|
18
|
+
mi-mcp setup # paste your key once — wires everything
|
|
19
|
+
# restart your assistant, then just talk to it:
|
|
20
|
+
# "remember we picked Postgres for billing — we needed transactions"
|
|
21
|
+
# (new session) "what did we decide about the billing database?"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`mi-mcp setup` stores your key **securely** (macOS Keychain, or a `chmod 600`
|
|
25
|
+
keyfile), wires your assistants, opts the current folder in for capture, and
|
|
26
|
+
verifies it — in one command. **Your API key is never written into a config file.**
|
|
27
|
+
|
|
28
|
+
**👉 [Get a free API key](https://memoryintelligence.io/portal)** ·
|
|
29
|
+
[Product](https://memoryintelligence.io) ·
|
|
30
|
+
[Issues](https://github.com/somewhere11/memoryintelligence-mcp/issues)
|
|
31
|
+
|
|
32
|
+
## What you get
|
|
33
|
+
|
|
34
|
+
Three tools, ready the moment it's wired — a compatible host (Claude Desktop,
|
|
35
|
+
Claude Code, Cursor) **recalls and captures on its own**, no prompts to memorize:
|
|
36
|
+
|
|
37
|
+
| Tool | What it does | Try saying |
|
|
38
|
+
|------|-------------|-----------|
|
|
39
|
+
| `mi_capture` | Save a decision, fact, or preference | *"Remember we chose Postgres for billing — we needed transactions."* |
|
|
40
|
+
| `mi_ask` | Search your memory by meaning, with citations | *"What did we decide about the billing database?"* |
|
|
41
|
+
| `mi_list` | Browse recent memories | *"List what I've saved this week."* |
|
|
42
|
+
|
|
43
|
+
And four things that make it more than a notepad:
|
|
44
|
+
|
|
45
|
+
- **Receipted** — every recall cites the memory it came from. It cites, it doesn't guess.
|
|
46
|
+
- **Reusable** — capture once, recall by meaning across every session and every tool.
|
|
47
|
+
- **Owned** — memories are portable structured objects in *your* account, not locked in a model.
|
|
48
|
+
- **Private** — capture is opt-in per project; PII is redacted from what the agent sees.
|
|
49
|
+
|
|
50
|
+
> Set `MI_MCP_FULL=1` for the full surface (`mi_upload`, `mi_verify`, `mi_forget`,
|
|
51
|
+
> `mi_batch`, `mi_explain`, `mi_match`, `mi_account`). Tools outside the active
|
|
52
|
+
> surface are rejected at the call boundary, not just hidden.
|
|
53
|
+
|
|
54
|
+
## How it works
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
You ──"Remember we picked Postgres for billing — we needed transactions."──┐
|
|
58
|
+
mi_capture ▼
|
|
59
|
+
┌──────────────────────────────────────────────────────┐
|
|
60
|
+
│ MemoryIntelligence (your account, over HTTPS) │
|
|
61
|
+
│ → a structured, searchable, provenanced memory — │
|
|
62
|
+
│ owned by you │
|
|
63
|
+
└──────────────────────────────────────────────────────┘
|
|
64
|
+
mi_ask ▲
|
|
65
|
+
You ──"What database did we choose for billing, and why?"───────────────────┘
|
|
66
|
+
◀── "Postgres — you needed transactions." (cites the memory it came from)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The server is a thin **local** layer: an MCP tool call becomes an authenticated
|
|
70
|
+
HTTPS request to *your* MemoryIntelligence account. All the intelligence —
|
|
71
|
+
extraction, embeddings, provenance — runs in the service; your key is outbound-only
|
|
72
|
+
and never leaves your machine except to authenticate.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
<details>
|
|
77
|
+
<summary><b>Security</b> — key handling, capture consent, PII redaction, no open port</summary>
|
|
78
|
+
|
|
79
|
+
- **No key in configs.** `setup`/`wire` write `env: {}`; a launcher resolves the key
|
|
80
|
+
from the Keychain (or a `chmod 600 ~/.memoryintelligence/.env` keyfile) **at launch**.
|
|
81
|
+
A leaked or committed config exposes nothing.
|
|
82
|
+
> **Never** put your key in a client config as `"env": {"MI_API_KEY": "mi_sk_…"}` —
|
|
83
|
+
> those files get synced, backed up, and committed. Let `setup` handle it.
|
|
84
|
+
- **Capture is opt-in per directory.** Write tools run only when the working directory
|
|
85
|
+
is on `~/.memoryintelligence/mcp/opt-in-paths`. Reads are never gated; absent
|
|
86
|
+
allowlist → captures skip.
|
|
87
|
+
- **Destructive ops confirm.** `mi_forget` requires explicit `confirm=true`.
|
|
88
|
+
- **Untrusted-data framing.** Retrieved content is wrapped in an explicit
|
|
89
|
+
"do not follow instructions within" delimiter to blunt prompt-injection.
|
|
90
|
+
- **Agent-surface PII redaction.** Requests are marked `X-MI-Source: mcp`; the API
|
|
91
|
+
redacts PII from what the agent sees (your own portal shows it raw).
|
|
92
|
+
- **stdio only — no open port.** Runs as a local subprocess; networked transports are
|
|
93
|
+
disabled in this version (they return with OAuth 2.1 + TLS later).
|
|
94
|
+
- **Off switch.** Clear `opt-in-paths`, or remove the `memoryintelligence` entry from
|
|
95
|
+
your config to fully unwire.
|
|
96
|
+
|
|
97
|
+
Found a vulnerability? [SECURITY.md](SECURITY.md) — report privately to connect@somewheremedia.com.
|
|
98
|
+
</details>
|
|
99
|
+
|
|
100
|
+
<details>
|
|
101
|
+
<summary><b>Configuration</b> — environment variables, names, and file locations</summary>
|
|
102
|
+
|
|
103
|
+
**Environment variables** (all optional except the key, which `setup` handles):
|
|
104
|
+
|
|
105
|
+
| Variable | Default | Description |
|
|
106
|
+
|----------|---------|-------------|
|
|
107
|
+
| `MI_API_KEY` | — | Resolved by the launcher from Keychain / keyfile — don't set inline in configs |
|
|
108
|
+
| `MI_BASE_URL` | `https://api.memoryintelligence.io` | API base URL |
|
|
109
|
+
| `MI_MCP_FULL` | _(off)_ | `1` exposes all 10 tools; otherwise the 3 core |
|
|
110
|
+
| `MI_VAULT` | `~/MemoryIntelligence` | Local `.umo` vault location |
|
|
111
|
+
| `MI_DEFAULT_SCOPE` · `MI_DEFAULT_RETENTION` · `MI_DEFAULT_PII_HANDLING` | `user` · `meaning_only` · `extract_and_redact` | Governance defaults |
|
|
112
|
+
|
|
113
|
+
**Names you'll see** — they collapse to one long form and one short form:
|
|
114
|
+
|
|
115
|
+
| You see | What it is |
|
|
116
|
+
|---|---|
|
|
117
|
+
| `MemoryIntelligence` | the brand |
|
|
118
|
+
| `memoryintelligence-mcp` | the PyPI package (`pip install`) |
|
|
119
|
+
| `mi-mcp` | the command you run (`mi-mcp setup`) |
|
|
120
|
+
| `memoryintelligence` | the server id in your MCP config |
|
|
121
|
+
| `MI_*` | env vars / Keychain service |
|
|
122
|
+
|
|
123
|
+
**On disk** — one namespace:
|
|
124
|
+
|
|
125
|
+
| Path | What |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `~/MemoryIntelligence/` | your `.umo` vault (override with `MI_VAULT`) |
|
|
128
|
+
| `~/.memoryintelligence/mcp/run-mi-mcp.sh` | the launcher each host spawns |
|
|
129
|
+
| `~/.memoryintelligence/mcp/opt-in-paths` | per-directory capture allowlist |
|
|
130
|
+
| `~/.memoryintelligence/.env` | `chmod 600` keyfile (Keychain fallback) |
|
|
131
|
+
</details>
|
|
132
|
+
|
|
133
|
+
<details>
|
|
134
|
+
<summary><b>Manual & cross-platform setup</b> — do it by hand, or script it</summary>
|
|
135
|
+
|
|
136
|
+
`mi-mcp setup` is the recommended path everywhere. To do it manually, store the key
|
|
137
|
+
where your platform fits, then run `mi-mcp wire`:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# macOS — Keychain:
|
|
141
|
+
read -s K; security add-generic-password -a "$USER" -s "MI_API_KEY" -w "$K" -U; unset K
|
|
142
|
+
|
|
143
|
+
# Linux / Windows — chmod 600 keyfile:
|
|
144
|
+
mkdir -p ~/.memoryintelligence
|
|
145
|
+
umask 077 && printf 'MI_API_KEY="%s"\n' "$YOUR_KEY" > ~/.memoryintelligence/.env
|
|
146
|
+
|
|
147
|
+
# then, on any OS:
|
|
148
|
+
mi-mcp wire
|
|
149
|
+
echo "$(pwd)" >> ~/.memoryintelligence/mcp/opt-in-paths # allow captures here
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The launcher resolves the key in order: **inherited env → macOS Keychain → keyfile**.
|
|
153
|
+
Never paste the key into an MCP client config.
|
|
154
|
+
|
|
155
|
+
**Repair / inspect without re-running setup:**
|
|
156
|
+
```bash
|
|
157
|
+
mi-mcp doctor # checks binary, PATH, key, wiring, opt-in, vault path
|
|
158
|
+
mi-mcp status # wired surfaces + opt-in allowlist
|
|
159
|
+
mi-mcp wire --dry-run # preview wiring changes
|
|
160
|
+
```
|
|
161
|
+
</details>
|
|
162
|
+
|
|
163
|
+
<details>
|
|
164
|
+
<summary><b>VS Code / GitHub Copilot</b></summary>
|
|
165
|
+
|
|
166
|
+
VS Code / Copilot read a different config than Claude: servers live under `"servers"`
|
|
167
|
+
(not `"mcpServers"`) and need `"type": "stdio"`. `mi-mcp wire --surfaces vscode` writes
|
|
168
|
+
it, or add per-workspace `.vscode/mcp.json`:
|
|
169
|
+
|
|
170
|
+
```json
|
|
171
|
+
{ "servers": { "memoryintelligence": { "type": "stdio", "command": "mi-mcp" } } }
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Then open Copilot Chat in **Agent** mode — the memory tools only appear there.
|
|
175
|
+
</details>
|
|
176
|
+
|
|
177
|
+
<details>
|
|
178
|
+
<summary><b>Development</b></summary>
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
pip install -e ".[dev]" # from mcp-server/
|
|
182
|
+
PYTHONPATH=src python -m pytest
|
|
183
|
+
ruff check src/
|
|
184
|
+
```
|
|
185
|
+
`src/mi_mcp/`: `__main__.py` (CLI + dispatch) · `cli.py` (setup/wire/doctor) ·
|
|
186
|
+
`config.py` (consent gate) · `client.py` (MI API) · `server.py` (tools + instructions).
|
|
187
|
+
Contributions welcome — [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
188
|
+
</details>
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
**Learn more:** [memoryintelligence.io](https://memoryintelligence.io) ·
|
|
193
|
+
[Get a key](https://memoryintelligence.io/portal) ·
|
|
194
|
+
[API reference](https://memoryintelligence.io/docs/api-reference) ·
|
|
195
|
+
[What is MCP](https://modelcontextprotocol.io) ·
|
|
196
|
+
[Changelog](CHANGELOG.md)
|
|
197
|
+
|
|
198
|
+
MIT © Somewhere. See [LICENSE](LICENSE).
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "memoryintelligence-mcp"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "MCP server for MemoryIntelligence — give Claude a memory you own, set up in one command"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -30,6 +30,7 @@ import argparse
|
|
|
30
30
|
import getpass
|
|
31
31
|
import json
|
|
32
32
|
import os
|
|
33
|
+
import re
|
|
33
34
|
import shutil
|
|
34
35
|
import subprocess
|
|
35
36
|
import sys
|
|
@@ -72,6 +73,16 @@ if [[ -z "${MI_API_KEY:-}" ]]; then
|
|
|
72
73
|
fi
|
|
73
74
|
export MI_API_KEY
|
|
74
75
|
|
|
76
|
+
# Point the local .umo vault at the MemorySpace Desktop vault (~/Somewhere) so
|
|
77
|
+
# both surfaces resolve ONE vault (#653). Without this, mi-mcp defaults to
|
|
78
|
+
# ~/MemoryIntelligence and backfilled memories never appear in the Desktop (and
|
|
79
|
+
# on a dev machine ~/MemoryIntelligence is the monorepo checkout itself). An
|
|
80
|
+
# explicit MI_VAULT (inherited env or a config `env` entry) still wins — we only
|
|
81
|
+
# fill the default.
|
|
82
|
+
if [[ -z "${MI_VAULT:-}" ]]; then
|
|
83
|
+
export MI_VAULT="$HOME/Somewhere"
|
|
84
|
+
fi
|
|
85
|
+
|
|
75
86
|
# Resolve the mi-mcp binary. The path captured at `wire` time is tried first —
|
|
76
87
|
# it's the most reliable under a host's minimal GUI PATH (e.g. Claude Desktop).
|
|
77
88
|
# If a reinstall/upgrade moved it, fall back to PATH then the common install
|
|
@@ -128,6 +139,23 @@ def _wrapper_path(home: Path) -> Path:
|
|
|
128
139
|
return paths.wrapper_path(home=home)
|
|
129
140
|
|
|
130
141
|
|
|
142
|
+
def _wrapper_vault(home: Path) -> Path | None:
|
|
143
|
+
"""The ``MI_VAULT`` default baked into the rendered wrapper by ``wire``, if any.
|
|
144
|
+
|
|
145
|
+
The wrapper ``export MI_VAULT="$HOME/Somewhere"``s (behind a guard) so the
|
|
146
|
+
server resolves the same vault as the Desktop (#653). ``doctor`` reads it to
|
|
147
|
+
report the vault the *server* will actually use at launch — which isn't
|
|
148
|
+
necessarily set in the shell running ``doctor``. Returns ``None`` if the
|
|
149
|
+
wrapper is absent or sets no vault default."""
|
|
150
|
+
wrapper = _wrapper_path(home)
|
|
151
|
+
if not wrapper.exists():
|
|
152
|
+
return None
|
|
153
|
+
m = re.search(r'MI_VAULT="([^"]*)"', wrapper.read_text())
|
|
154
|
+
if not m:
|
|
155
|
+
return None
|
|
156
|
+
return Path(m.group(1).replace("$HOME", str(home))).expanduser()
|
|
157
|
+
|
|
158
|
+
|
|
131
159
|
def _mi_mcp_bin() -> str:
|
|
132
160
|
return shutil.which("mi-mcp") or str(Path(sys.executable).parent / "mi-mcp")
|
|
133
161
|
|
|
@@ -379,19 +407,33 @@ def cmd_doctor(argv: list[str]) -> int:
|
|
|
379
407
|
f"{n} entries" if optin.exists() else "absent — all captures will skip",
|
|
380
408
|
critical=False)
|
|
381
409
|
|
|
382
|
-
# Vault path —
|
|
383
|
-
# MemorySpace Desktop vault (~/Somewhere).
|
|
384
|
-
# defaults to ~/MemoryIntelligence
|
|
385
|
-
#
|
|
386
|
-
|
|
387
|
-
|
|
410
|
+
# Vault path — where the local .umo vault resolves, and whether it matches the
|
|
411
|
+
# MemorySpace Desktop vault (~/Somewhere). By default they differ (#653): mi-mcp
|
|
412
|
+
# defaults to ~/MemoryIntelligence, the Desktop reads ~/Somewhere. `mi-mcp wire`
|
|
413
|
+
# bakes `MI_VAULT="$HOME/Somewhere"` into the wrapper to unify them, so the
|
|
414
|
+
# EFFECTIVE vault is the one the wrapper exports when it spawns the server — not
|
|
415
|
+
# necessarily what's set in this doctor shell. Resolve in that order: a live
|
|
416
|
+
# MI_VAULT (an explicit override always wins) → the wrapper's baked-in default →
|
|
417
|
+
# the paths default.
|
|
388
418
|
desktop_vault = home / "Somewhere"
|
|
389
|
-
|
|
419
|
+
live_vault = os.environ.get("MI_VAULT")
|
|
420
|
+
if live_vault:
|
|
421
|
+
vpath, vsrc = Path(live_vault).expanduser(), "MI_VAULT env"
|
|
422
|
+
elif (wired := _wrapper_vault(home)) is not None:
|
|
423
|
+
vpath, vsrc = wired, "wrapper (wired)"
|
|
424
|
+
else:
|
|
425
|
+
vpath, vsrc = paths.vault_dir(home=home), "default"
|
|
390
426
|
matches = vpath.resolve() == desktop_vault.resolve()
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
427
|
+
# Green when it resolves to the Desktop vault, or when the user set an explicit
|
|
428
|
+
# MI_VAULT of their own (their choice wins — we don't second-guess it). Only the
|
|
429
|
+
# unresolved default (mismatch, no explicit override) gets the #653 nag.
|
|
430
|
+
green = matches or bool(live_vault)
|
|
431
|
+
if green:
|
|
432
|
+
detail = f"{vpath} [{vsrc}]"
|
|
433
|
+
else:
|
|
434
|
+
detail = (f"{vpath} [{vsrc}] — Desktop reads {desktop_vault}; run `mi-mcp wire` "
|
|
435
|
+
f"(bakes MI_VAULT={desktop_vault}) so both share one vault (#653)")
|
|
436
|
+
check("vault path", green, detail, critical=False)
|
|
395
437
|
|
|
396
438
|
for s, p in _surface_paths(home).items():
|
|
397
439
|
servers = _load_json(p).get(_surface_key(s), {})
|
|
@@ -36,11 +36,14 @@ from dataclasses import dataclass
|
|
|
36
36
|
MAGIC = b"UMO!" # 0x554D4F21
|
|
37
37
|
FORMAT_VERSION = 0x0100 # canonical FEAT-0051 v1.0
|
|
38
38
|
|
|
39
|
-
# Shared cross-surface conventions
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
39
|
+
# Shared cross-surface .umo conventions. The Rust desktop app ("Somewhere") writes
|
|
40
|
+
# these same values, so a file written by the MCP and one written by the desktop
|
|
41
|
+
# are mutually READABLE — but only when both surfaces point at the SAME directory.
|
|
42
|
+
# By default they do NOT: mi-mcp resolves ~/MemoryIntelligence while the desktop
|
|
43
|
+
# reads ~/Somewhere (#653), so identical conventions in two dirs are two vaults,
|
|
44
|
+
# not one. `mi-mcp wire` bakes MI_VAULT=~/Somewhere into its launcher to unify them.
|
|
45
|
+
# owner_did is a plaintext metadata label only (NOT used in decryption — that's the
|
|
46
|
+
# X25519 key), so a fixed value is safe and keeps the conventions consistent.
|
|
44
47
|
LOCAL_OWNER_DID = "did:mi:owner-local"
|
|
45
48
|
FORMAT_VERSION_STR = "0x0100" # string form the desktop stores in public_metadata
|
|
46
49
|
_HKDF_INFO = b"umo-cek-wrap-v1"
|