mnueron 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/ARCHITECTURE.md +161 -0
- package/INSTALL.md +262 -0
- package/LICENSE +21 -0
- package/README.md +305 -0
- package/dashboard/index.html +838 -0
- package/dist/cli.js +685 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/server.js +234 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/detectors/claude_code.js +72 -0
- package/dist/detectors/claude_code.js.map +1 -0
- package/dist/detectors/claude_desktop.js +37 -0
- package/dist/detectors/claude_desktop.js.map +1 -0
- package/dist/detectors/cursor.js +36 -0
- package/dist/detectors/cursor.js.map +1 -0
- package/dist/detectors/extra.js +59 -0
- package/dist/detectors/extra.js.map +1 -0
- package/dist/detectors/index.js +14 -0
- package/dist/detectors/index.js.map +1 -0
- package/dist/detectors/json_detector.js +95 -0
- package/dist/detectors/json_detector.js.map +1 -0
- package/dist/detectors/types.js +13 -0
- package/dist/detectors/types.js.map +1 -0
- package/dist/import/claude.js +82 -0
- package/dist/import/claude.js.map +1 -0
- package/dist/import/openai.js +102 -0
- package/dist/import/openai.js.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/loader.js +175 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/types.js +24 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/setup.js +123 -0
- package/dist/setup.js.map +1 -0
- package/dist/store/chunking.js +150 -0
- package/dist/store/chunking.js.map +1 -0
- package/dist/store/embeddings.js +126 -0
- package/dist/store/embeddings.js.map +1 -0
- package/dist/store/local.js +720 -0
- package/dist/store/local.js.map +1 -0
- package/dist/store/provider.js +7 -0
- package/dist/store/provider.js.map +1 -0
- package/dist/store/redactor.js +114 -0
- package/dist/store/redactor.js.map +1 -0
- package/dist/store/remote.js +62 -0
- package/dist/store/remote.js.map +1 -0
- package/dist/tools.js +312 -0
- package/dist/tools.js.map +1 -0
- package/package.json +55 -0
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# mnueron architecture
|
|
2
|
+
|
|
3
|
+
## The two-mode design
|
|
4
|
+
|
|
5
|
+
The MCP server is **storage-agnostic**. It depends on a `Provider` interface
|
|
6
|
+
with five methods (`save`, `search`, `list`, `delete`, `namespaces`). Two
|
|
7
|
+
implementations satisfy it:
|
|
8
|
+
|
|
9
|
+
| Provider | When | Storage | Cost |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| `LocalProvider` | Default | SQLite + FTS5 in `~/.mnueron/memories.db` | $0 |
|
|
12
|
+
| `RemoteProvider` | When `MNUERON_API_URL` + `MNUERON_API_TOKEN` are set | HTTPS → hosted Postgres + pgvector | Whatever you charge |
|
|
13
|
+
|
|
14
|
+
Flipping modes is **one env-var change** on the client. The MCP tool surface
|
|
15
|
+
and behavior stay identical. This is the property that makes the local repo
|
|
16
|
+
both a free OSS giveaway *and* the on-ramp to the hosted product.
|
|
17
|
+
|
|
18
|
+
## Tenancy model (hosted mode)
|
|
19
|
+
|
|
20
|
+
The hosted backend is multi-tenant by design. The unit of isolation is `org`:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
┌────────────────────────────────────────┐
|
|
24
|
+
│ org (a company) │
|
|
25
|
+
│ ┌──────────────┐ ┌──────────────┐ │
|
|
26
|
+
│ │ namespace A │ │ namespace B │ │ ← e.g. one per app
|
|
27
|
+
│ │ memories… │ │ memories… │ │
|
|
28
|
+
│ └──────────────┘ └──────────────┘ │
|
|
29
|
+
│ │
|
|
30
|
+
│ users (1..N belong via org_members) │
|
|
31
|
+
│ api_tokens (each bound to user+org) │
|
|
32
|
+
└────────────────────────────────────────┘
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- **Users** can belong to multiple orgs (personal + work, multiple clients,
|
|
36
|
+
contractors). The `org_members` table holds the M:N relation with a role
|
|
37
|
+
per (org, user).
|
|
38
|
+
- **API tokens** are bound to `(user, org)`. The token itself decides which
|
|
39
|
+
org's memories you see. A user with three orgs has three different tokens.
|
|
40
|
+
- **Namespaces** are sub-buckets inside an org. The two apps you mentioned —
|
|
41
|
+
Claude-app and OpenAI-app under the same company — get two namespaces
|
|
42
|
+
under one org. Same billing, separate memory pools.
|
|
43
|
+
- **Memories** are scoped to one `(org_id, namespace_id)`. The `org_id` is
|
|
44
|
+
the load-bearing isolation column.
|
|
45
|
+
|
|
46
|
+
## Three layers of isolation (defense in depth)
|
|
47
|
+
|
|
48
|
+
Even if app code has a bug, cross-org leaks should not be possible.
|
|
49
|
+
|
|
50
|
+
### 1. Token resolution
|
|
51
|
+
|
|
52
|
+
Every request carries `Authorization: Bearer mn_…`. The middleware hashes the
|
|
53
|
+
token, looks it up in `api_tokens`, and gets back `(user_id, org_id, token_id)`.
|
|
54
|
+
That triple is stored on the request object and is the only source of truth
|
|
55
|
+
for "which org are we acting as." Headers, query params, and request bodies
|
|
56
|
+
are never trusted to specify the org.
|
|
57
|
+
|
|
58
|
+
### 2. Postgres Row-Level Security
|
|
59
|
+
|
|
60
|
+
After resolving the token, the backend runs:
|
|
61
|
+
|
|
62
|
+
```sql
|
|
63
|
+
SELECT set_config('app.current_org_id', '<the resolved org_id>', false);
|
|
64
|
+
SET ROLE mnueron_app;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then it runs the actual query. The `mnueron_app` role has RLS policies that
|
|
68
|
+
make every read/write `WHERE org_id = current_setting('app.current_org_id')`.
|
|
69
|
+
A `SELECT * FROM memories` from within that role returns only this org's
|
|
70
|
+
rows. If `app.current_org_id` isn't set, the policy returns zero rows by
|
|
71
|
+
default — fail-closed, not fail-open.
|
|
72
|
+
|
|
73
|
+
```sql
|
|
74
|
+
CREATE POLICY p_memories_isolation ON memories
|
|
75
|
+
USING (org_id::text = current_setting('app.current_org_id', true));
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
This means the **database** enforces the boundary, not the application. A
|
|
79
|
+
forgotten `WHERE org_id = ?` in app code can't leak data.
|
|
80
|
+
|
|
81
|
+
### 3. Audit log
|
|
82
|
+
|
|
83
|
+
Every mutation writes a row to `audit_log` with `(org_id, user_id, token_id,
|
|
84
|
+
action, target_id, metadata)`. Companies that ask "who touched our data
|
|
85
|
+
when" can be answered from one table. Cheap to write, expensive not to have
|
|
86
|
+
when an enterprise customer asks for it.
|
|
87
|
+
|
|
88
|
+
## Multi-app, multi-LLM
|
|
89
|
+
|
|
90
|
+
The storage layer is provider-agnostic and LLM-agnostic. Three concrete
|
|
91
|
+
patterns:
|
|
92
|
+
|
|
93
|
+
**Two apps under one company.** One org, two API tokens (one per app), each
|
|
94
|
+
defaulting to its own namespace. Memories tagged by app are separate but
|
|
95
|
+
queryable across both if you ever want a cross-app view.
|
|
96
|
+
|
|
97
|
+
**Claude-app and OpenAI-app sharing memory.** Both apps hit the same
|
|
98
|
+
`/v1/memories/search` endpoint. The HTTP API is the contract; the agent
|
|
99
|
+
framework on top doesn't matter. Use the Anthropic SDK for one, OpenAI SDK
|
|
100
|
+
for the other, but they both pull from the same memory pool.
|
|
101
|
+
|
|
102
|
+
**Different companies (multi-tenant SaaS).** Each company gets an `org`.
|
|
103
|
+
Their users sign up under it. Token-bound-to-org guarantees one company's
|
|
104
|
+
memories never reach another's tools or eyes.
|
|
105
|
+
|
|
106
|
+
## What's open-core
|
|
107
|
+
|
|
108
|
+
| | OSS (MIT, free forever) | Hosted (paid) |
|
|
109
|
+
| --- | --- | --- |
|
|
110
|
+
| Local MCP server | ✓ | (uses same client) |
|
|
111
|
+
| SQLite local store | ✓ | — |
|
|
112
|
+
| Importers (Claude, OpenAI) | ✓ | ✓ |
|
|
113
|
+
| CLI | ✓ | ✓ |
|
|
114
|
+
| Hosted Postgres backend | — | ✓ |
|
|
115
|
+
| Multi-device sync | — | ✓ |
|
|
116
|
+
| Web dashboard | — | ✓ |
|
|
117
|
+
| Team sharing | — | ✓ |
|
|
118
|
+
| SSO + audit | — | Enterprise tier |
|
|
119
|
+
| BAAs / compliance posture | — | Enterprise tier |
|
|
120
|
+
|
|
121
|
+
The `server/` directory in this repo is the hosted backend reference
|
|
122
|
+
implementation. It's yours; the open-core licensing convention is to keep
|
|
123
|
+
the server source-available but not OSI-OSS, so competitors can't repackage
|
|
124
|
+
your hosting as their own product. (See PostHog, Sentry, Mattermost for
|
|
125
|
+
established versions of this.)
|
|
126
|
+
|
|
127
|
+
## Performance notes
|
|
128
|
+
|
|
129
|
+
- **Recall latency target: <300ms p95.** The hosted server's hybrid search
|
|
130
|
+
uses BM25 (tsvector) + cosine (pgvector HNSW) and fuses with reciprocal
|
|
131
|
+
rank. Both indexes are HNSW/GIN, so 10K-row scans aren't a problem until
|
|
132
|
+
~10M rows per org. Past that, partition by org_id.
|
|
133
|
+
- **Embeddings on the write path are blocking in the current skeleton.** In
|
|
134
|
+
production, move them to a worker queue: respond 200 immediately, queue the
|
|
135
|
+
embedding job, fill `embedding` async. Recall still works on tsvector while
|
|
136
|
+
embedding is pending.
|
|
137
|
+
- **Summarization (LLM compression) is always async.** Run nightly via the
|
|
138
|
+
Anthropic Batch API for 50% off list price. Users don't notice.
|
|
139
|
+
|
|
140
|
+
## Cost at scale (recap)
|
|
141
|
+
|
|
142
|
+
| Users | Monthly infra | Monthly LLM (Haiku batch) | Total | Revenue @ $12/mo | Margin |
|
|
143
|
+
| ---: | ---: | ---: | ---: | ---: | ---: |
|
|
144
|
+
| 100 | $130 | $20 | $150 | $1,200 | 88% |
|
|
145
|
+
| 1,000 | $640 | $115 | $760 | $12,000 | 94% |
|
|
146
|
+
| 10,000 | $4,200 | $1,100 | $5,300 | $120,000 | 96% |
|
|
147
|
+
|
|
148
|
+
The dominant variable cost is LLM compression (session summarization). Use
|
|
149
|
+
prompt caching for repeated context and the Batch API for non-realtime
|
|
150
|
+
summarization to cut that ~50–60%.
|
|
151
|
+
|
|
152
|
+
## Threat model (one paragraph)
|
|
153
|
+
|
|
154
|
+
The realistic threats are: (a) token theft via compromised dev machine, (b)
|
|
155
|
+
cross-tenant leak via app-layer bug, (c) malicious memory content trying to
|
|
156
|
+
prompt-inject downstream agents. Mitigations: short-lived tokens with
|
|
157
|
+
rotation + last-used tracking; RLS at the DB layer (covered above); strip
|
|
158
|
+
control sequences and tag user-provided memory clearly when returning to
|
|
159
|
+
agents so prompt-injection at recall time is contained, not silent. Secret
|
|
160
|
+
redaction at write time (regex + entropy scanner) before content hits storage
|
|
161
|
+
catches the most common "agent accidentally captured an AWS key" failure.
|
package/INSTALL.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Installing MNUERON
|
|
2
|
+
|
|
3
|
+
Three install paths depending on what you want to do.
|
|
4
|
+
|
|
5
|
+
| You want to… | Use this section |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| Use it with Claude Desktop / Cursor / etc. on one machine (free, local) | [Path A](#path-a-local-mode-free-1-machine) |
|
|
8
|
+
| Use it across multiple machines / share with a team / build it into a SaaS | [Path B](#path-b-hosted-mode-multi-machine) |
|
|
9
|
+
| Use it from your own Python or .NET app | [Path C](#path-c-app-sdk) |
|
|
10
|
+
|
|
11
|
+
You can do A first, then add B and C later. Nothing locks you in.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
| Need | Version | How to check |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| Node.js | 20+ | `node --version` |
|
|
20
|
+
| npm | 10+ | `npm --version` |
|
|
21
|
+
| (For Path C, Python) Python | 3.9+ | `python --version` |
|
|
22
|
+
| (For Path C, .NET) .NET SDK | 6.0+ | `dotnet --version` |
|
|
23
|
+
| (For Path B) Supabase account or any Postgres 15+ with pgvector | — | Free tier at supabase.com |
|
|
24
|
+
|
|
25
|
+
If you don't have Node.js: install from https://nodejs.org/ (LTS version).
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Path A: Local mode (free, 1 machine)
|
|
30
|
+
|
|
31
|
+
This is the fastest path. Everything runs on your computer; nothing leaves it.
|
|
32
|
+
Memories live in `~/.mnueron/memories.db` (or `%USERPROFILE%\.mnueron\` on Windows).
|
|
33
|
+
|
|
34
|
+
### Step 1 — Install from source
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/yourorg/mnueron.git
|
|
38
|
+
cd mnueron
|
|
39
|
+
npm install
|
|
40
|
+
npm run build
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
(Once we publish to npm, this becomes `npm install -g mnueron` and skip the rest.)
|
|
44
|
+
|
|
45
|
+
### Step 2 — Run the setup wizard
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
node dist/cli.js setup
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The wizard scans for installed AI tools and configures each one. Expected output:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
🧠 mnueron — persistent memory for AI dev tools
|
|
55
|
+
mode: local SQLite
|
|
56
|
+
|
|
57
|
+
Configured:
|
|
58
|
+
✓ Claude Desktop added
|
|
59
|
+
✓ Cursor added
|
|
60
|
+
|
|
61
|
+
Not detected:
|
|
62
|
+
Claude Code
|
|
63
|
+
Windsurf
|
|
64
|
+
Cline (VS Code)
|
|
65
|
+
|
|
66
|
+
✨ Done. Restart any running AI tool to load the memory plugin.
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Step 3 — Verify it works
|
|
70
|
+
|
|
71
|
+
Restart Claude Desktop (or any AI tool that was configured). In a new chat,
|
|
72
|
+
ask:
|
|
73
|
+
|
|
74
|
+
> "What memory tools do you have available?"
|
|
75
|
+
|
|
76
|
+
The AI should list `memory_save`, `memory_recall`, `memory_list`, `memory_delete`,
|
|
77
|
+
`memory_namespaces`, and `memory_import_chat`. If it doesn't, see [Troubleshooting](#troubleshooting).
|
|
78
|
+
|
|
79
|
+
### Step 4 — (Optional) Import your past chat history
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# claude.ai → Settings → Privacy → Export data → wait for email
|
|
83
|
+
# Unzip the archive, find conversations.json
|
|
84
|
+
|
|
85
|
+
node dist/cli.js import ~/Downloads/conversations.json --ns personal
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Each past Claude conversation becomes one searchable memory. Same command
|
|
89
|
+
works for ChatGPT exports — auto-detects format.
|
|
90
|
+
|
|
91
|
+
You're done with Path A.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Path B: Hosted mode (multi-machine)
|
|
96
|
+
|
|
97
|
+
For when you want the same memories on your laptop, desktop, and work box —
|
|
98
|
+
or you're going to offer this as a service. The backend is multi-tenant by
|
|
99
|
+
design with row-level security per organization.
|
|
100
|
+
|
|
101
|
+
### Step 1 — Provision the database
|
|
102
|
+
|
|
103
|
+
Easiest path is Supabase free tier. **See `server/SUPABASE_SETUP.md` for the
|
|
104
|
+
full 15-minute walkthrough** — it covers:
|
|
105
|
+
|
|
106
|
+
- Creating the Supabase project
|
|
107
|
+
- Enabling the `vector` extension
|
|
108
|
+
- Applying the schema (`server/supabase_schema.sql`)
|
|
109
|
+
- Generating your first API token via the included `mnueron_signup()` function
|
|
110
|
+
- Getting the connection string
|
|
111
|
+
|
|
112
|
+
Skip ahead to Step 2 below when your database is ready.
|
|
113
|
+
|
|
114
|
+
### Step 2 — Run the backend
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
cd server
|
|
118
|
+
npm install express pg dotenv @types/pg @types/express
|
|
119
|
+
|
|
120
|
+
# Create server/.env with your connection string
|
|
121
|
+
cat > .env <<EOF
|
|
122
|
+
DATABASE_URL=postgresql://postgres.xxx:password@aws-0-region.pooler.supabase.com:6543/postgres
|
|
123
|
+
OPENAI_API_KEY=sk-... # optional, omit to fall back to BM25-only search
|
|
124
|
+
PORT=3111
|
|
125
|
+
EOF
|
|
126
|
+
|
|
127
|
+
# Run it
|
|
128
|
+
npx tsx index.ts
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
You should see `mnueron-server listening on :3111`.
|
|
132
|
+
|
|
133
|
+
### Step 3 — Make the server publicly reachable
|
|
134
|
+
|
|
135
|
+
For "any computer, anywhere" access, the API needs a public HTTPS URL. Cheapest options:
|
|
136
|
+
|
|
137
|
+
- **Railway** — push the `server/` folder to GitHub, link to Railway, set env vars, done. ~$5/mo.
|
|
138
|
+
- **Lightsail** — $5/mo container, same shape as a Node app you'd deploy normally.
|
|
139
|
+
- **Fly.io** — $1.94/mo for a small VM.
|
|
140
|
+
- **Render** — $7/mo for always-on.
|
|
141
|
+
|
|
142
|
+
Whichever you pick, the result is a URL like `https://api.your-mnueron.com`.
|
|
143
|
+
|
|
144
|
+
### Step 4 — Point your local client at the hosted backend
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
node dist/cli.js setup --hosted https://api.your-mnueron.com --token mnu_xxxxxxxxxxxx
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Repeat on every machine you want to use the hosted memory from. Same token = same memories everywhere.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Path C: App SDK
|
|
155
|
+
|
|
156
|
+
For when you want your own Python or C# app to read and write memories. You
|
|
157
|
+
need a hosted backend (Path B) or you can hit the local server on
|
|
158
|
+
`http://localhost:3111` for development.
|
|
159
|
+
|
|
160
|
+
### Python
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cd sdks/python
|
|
164
|
+
pip install -e .
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Then in your app:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from mnueron import Mnueron
|
|
171
|
+
|
|
172
|
+
with Mnueron(api_key="mnu_xxx", base_url="https://api.your-mnueron.com") as mem:
|
|
173
|
+
mem.save("User prefers concise replies", namespace=f"user-{user_id}")
|
|
174
|
+
results = mem.search("how does user like responses?", namespace=f"user-{user_id}")
|
|
175
|
+
for r in results:
|
|
176
|
+
print(r.content, r.score)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Or use the async version (`AsyncMnueron`) for `asyncio`-based apps.
|
|
180
|
+
|
|
181
|
+
### .NET / C#
|
|
182
|
+
|
|
183
|
+
Drop `sdks/csharp/MnueronClient.cs` into any .NET 6+ project. No NuGet package needed.
|
|
184
|
+
|
|
185
|
+
```csharp
|
|
186
|
+
using Mnueron;
|
|
187
|
+
|
|
188
|
+
using var mem = new MnueronClient("mnu_xxx", "https://api.your-mnueron.com");
|
|
189
|
+
await mem.SaveAsync("User prefers concise replies", $"user-{userId}");
|
|
190
|
+
var results = await mem.SearchAsync("how does user like responses?", $"user-{userId}");
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Configuration reference
|
|
196
|
+
|
|
197
|
+
| Variable | Used by | Purpose |
|
|
198
|
+
| --- | --- | --- |
|
|
199
|
+
| `MNUERON_API_URL` | CLI, MCP server | Hosted backend base URL. If unset, falls back to local SQLite. |
|
|
200
|
+
| `MNUERON_API_TOKEN` | CLI, MCP server | Bearer token for hosted mode. Required if `MNUERON_API_URL` is set. |
|
|
201
|
+
| `MNUERON_API_KEY` | Python SDK | Same as `MNUERON_API_TOKEN`. Both names work. |
|
|
202
|
+
| `MNUERON_DB_PATH` | CLI, MCP server (local mode) | Override the SQLite path. Default: `~/.mnueron/memories.db`. |
|
|
203
|
+
| `MNUERON_NAMESPACE` | CLI, MCP server | Default namespace when one isn't specified. Default: `default`. |
|
|
204
|
+
| `DATABASE_URL` | Backend (Path B) | Postgres connection string. |
|
|
205
|
+
| `OPENAI_API_KEY` | Backend (Path B) | Embedding provider. Optional — falls back to BM25-only search. |
|
|
206
|
+
| `PORT` | Backend (Path B) | Default 3111. |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Uninstall
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
node dist/cli.js setup --uninstall
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Removes mnueron from every tool's MCP config. Your local memories at
|
|
217
|
+
`~/.mnueron/` are preserved unless you delete the folder yourself.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Troubleshooting
|
|
222
|
+
|
|
223
|
+
**Claude Desktop doesn't see the memory tools after setup.**
|
|
224
|
+
- Make sure you fully quit and restarted Claude Desktop (not just closed the window — quit the app).
|
|
225
|
+
- Check that the config file exists and is valid JSON:
|
|
226
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
227
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
228
|
+
- Look for a `mcpServers.mnueron` entry. If missing, re-run `setup`.
|
|
229
|
+
|
|
230
|
+
**`mnueron setup` says "tool not detected" but the tool is installed.**
|
|
231
|
+
- Run the tool once before setup so it creates its config directory.
|
|
232
|
+
- For Cursor, the detector looks for `~/.cursor/` — open Cursor once if it's a fresh install.
|
|
233
|
+
|
|
234
|
+
**Hosted mode: server returns 401 unauthorized.**
|
|
235
|
+
- Token mismatch. Check that `MNUERON_API_TOKEN` is set to the **raw** token (starts with `mnu_`), not the hash stored in the database.
|
|
236
|
+
- If you've lost the raw token, generate a new one and update the database `api_tokens.token_hash`.
|
|
237
|
+
|
|
238
|
+
**Hosted mode: server returns empty results for everything.**
|
|
239
|
+
- RLS is blocking. Check that `app.current_org_id` is being set per request. Look in `server/index.ts` for the `withTenantScope` helper.
|
|
240
|
+
|
|
241
|
+
**`pgvector` errors when applying the schema.**
|
|
242
|
+
- Extension not enabled. On Supabase: Dashboard → Database → Extensions → toggle `vector` on.
|
|
243
|
+
- On RDS or self-hosted Postgres: `sudo apt install postgresql-15-pgvector` then `CREATE EXTENSION vector;`.
|
|
244
|
+
|
|
245
|
+
**`bcrypt` or `better-sqlite3` errors during `npm install` on Windows.**
|
|
246
|
+
- These packages need a C++ build chain. Install `windows-build-tools` via npm or just use a Node version with prebuilt binaries (recent LTS works out of the box).
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Next steps after install
|
|
251
|
+
|
|
252
|
+
Once mnueron is working, the highest-value memories to save first:
|
|
253
|
+
|
|
254
|
+
1. **Project conventions** — `memory_save` with content like `"In this project: TypeScript strict mode, prettier with 2-space indent, no default exports, file names kebab-case"`.
|
|
255
|
+
2. **Tech stack facts** — `"Backend is FastAPI + Postgres + Redis. Frontend is Next.js 14 app router."`.
|
|
256
|
+
3. **Decisions and their rationale** — `"We chose pgvector over Pinecone for cost and self-host reasons (Mar 2026)."`.
|
|
257
|
+
|
|
258
|
+
The "click" moment — when mnueron feels indispensable — usually arrives about
|
|
259
|
+
two weeks in, when a new chat starts and the AI orients itself without you
|
|
260
|
+
re-explaining anything.
|
|
261
|
+
|
|
262
|
+
Anything else, file an issue or open a PR.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MNUERON contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|