memento-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/.env.example ADDED
@@ -0,0 +1,3 @@
1
+ MEMENTO_API_KEY=mp_live_your_key_here
2
+ MEMENTO_API_URL=https://memento-api.myrakrusemark.workers.dev
3
+ MEMENTO_WORKSPACE=my-project
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Myra Krusemark
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.
package/README.md ADDED
@@ -0,0 +1,206 @@
1
+ # The Memento Protocol
2
+
3
+ Persistent memory for AI agents.
4
+
5
+ AI agents have anterograde amnesia — every session starts blank. The Memento Protocol gives agents a structured way to remember, not by recording everything, but by writing **instructions to their future selves**. Memories decay, consolidate, and evolve — like biological memory, not a log file.
6
+
7
+ ## Get Started
8
+
9
+ ```bash
10
+ git clone https://github.com/myrakrusemark/memento-protocol.git
11
+ cd memento-protocol && npm install
12
+ ```
13
+
14
+ Verify the install:
15
+
16
+ ```bash
17
+ npm run test:smoke
18
+ ```
19
+
20
+ You should see all tools listed and "All smoke tests passed."
21
+
22
+ ### Step 1: Sign up
23
+
24
+ ```bash
25
+ curl -X POST https://memento-api.myrakrusemark.workers.dev/v1/auth/signup \
26
+ -H "Content-Type: application/json" \
27
+ -d '{"workspace": "my-project"}'
28
+ ```
29
+
30
+ No email, no password, no OAuth. One curl, one key. Optionally include `"email"` for account recovery later.
31
+
32
+ Save the `api_key` from the response — you'll need it next.
33
+
34
+ ### Step 2: Configure your MCP client
35
+
36
+ **Claude Code (project-level):** Create `.mcp.json` in your project root.
37
+
38
+ **Claude Code (global):** Add to `~/.claude.json` under `"mcpServers"`.
39
+
40
+ **Claude Desktop:** Add to your `claude_desktop_config.json`.
41
+
42
+ ```json
43
+ {
44
+ "mcpServers": {
45
+ "memento": {
46
+ "command": "node",
47
+ "args": ["/home/you/memento-protocol/src/index.js"],
48
+ "env": {
49
+ "MEMENTO_API_KEY": "mp_live_your_key_here",
50
+ "MEMENTO_API_URL": "https://memento-api.myrakrusemark.workers.dev",
51
+ "MEMENTO_WORKSPACE": "my-project"
52
+ }
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ > **Tip:** Replace the path with the actual absolute path to `src/index.js` in your clone. Run `echo "$(pwd)/src/index.js"` from inside the repo to get it.
59
+
60
+ ### Step 3: Restart your client
61
+
62
+ The MCP server connects at startup. Restart so it picks up the new config.
63
+
64
+ ### Step 4: First session
65
+
66
+ ```
67
+ > memento_health() # verify connection
68
+ > memento_store( # store your first memory
69
+ content: "API uses /v2 endpoints. Auth is Bearer token in header.",
70
+ type: "instruction",
71
+ tags: ["api", "auth"]
72
+ )
73
+ > memento_recall(query: "api auth") # find it again
74
+ ```
75
+
76
+ That's it. The agent reads memory at session start, updates it as it works, and writes instructions for next time.
77
+
78
+ ---
79
+
80
+ ## Add to Your CLAUDE.md
81
+
82
+ Paste this block into your project's `CLAUDE.md` to teach your agent memory discipline:
83
+
84
+ ```markdown
85
+ ## Memory (Memento Protocol)
86
+
87
+ On session start:
88
+ 1. `memento_health` — verify connection
89
+ 2. `memento_item_list` — check active work items and their next actions
90
+ 3. `memento_recall` with current task context — find relevant past memories
91
+
92
+ Writing memories:
93
+ - Instructions, not logs: "API moved to /v2 — update all calls" not "checked API, got 404"
94
+ - Tag generously — tags power recall and consolidation
95
+ - Set expiration on time-sensitive facts
96
+ - Use `memento_skip_add` for things to actively avoid (with expiry)
97
+ - Use `memento_item_create` for structured work tracking with next actions
98
+
99
+ Before session ends:
100
+ - `memento_item_update` with progress on active work (include what was done AND what comes next)
101
+ - `memento_store` for new decisions and discoveries
102
+ - `memento_skip_add` for things to skip next time
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Hooks
108
+
109
+ Hooks automate memory at session boundaries — the agent doesn't need to remember to recall or save. Two production-ready scripts are included in `scripts/`.
110
+
111
+ ### Setup
112
+
113
+ 1. **Create a `.env` file** in the repo root (copy from the example):
114
+
115
+ ```bash
116
+ cp .env.example .env
117
+ # Then edit .env with your actual API key and workspace name
118
+ ```
119
+
120
+ The `.env` file is gitignored. It needs three variables:
121
+
122
+ ```bash
123
+ MEMENTO_API_KEY=mp_live_your_key_here
124
+ MEMENTO_API_URL=https://memento-api.myrakrusemark.workers.dev
125
+ MEMENTO_WORKSPACE=my-project
126
+ ```
127
+
128
+ 2. **Make scripts executable** (they should already be, but just in case):
129
+
130
+ ```bash
131
+ chmod +x scripts/*.sh
132
+ ```
133
+
134
+ 3. **Register in Claude Code settings** — add to `.claude/settings.json` (project-level) or `~/.claude/settings.json` (global):
135
+
136
+ ```json
137
+ {
138
+ "hooks": {
139
+ "UserPromptSubmit": [
140
+ {
141
+ "command": "/path/to/memento-protocol/scripts/memento-memory-recall.sh",
142
+ "timeout": 5000
143
+ }
144
+ ],
145
+ "PreCompact": [
146
+ {
147
+ "command": "/path/to/memento-protocol/scripts/memento-precompact-distill.sh",
148
+ "timeout": 30000
149
+ }
150
+ ]
151
+ }
152
+ }
153
+ ```
154
+
155
+ Replace `/path/to/memento-protocol` with the actual absolute path to your clone.
156
+
157
+ ### `memento-memory-recall.sh` (UserPromptSubmit)
158
+
159
+ Fires before every agent response. Sends the user's message to the `/v1/context` endpoint, which returns relevant memories and skip list warnings.
160
+
161
+ - **Timeout:** 5 seconds (3s API call + overhead)
162
+ - **User sees:** "Memento Recall: N memories" in their terminal
163
+ - **Model sees:** Full memory details and skip list warnings as injected context (via `additionalContext`)
164
+ - **Short messages:** Messages under 10 characters are skipped (greetings, "yes", etc.)
165
+
166
+ ### `memento-precompact-distill.sh` (PreCompact)
167
+
168
+ Fires before Claude Code compresses the conversation. Parses the full JSONL transcript into readable text, then sends it to `/v1/distill` which extracts key memories, decisions, and observations — so nothing important is lost to compaction.
169
+
170
+ - **Timeout:** 30 seconds (transcript processing is heavier)
171
+ - **User sees:** "Memento Distill: extracted N memories" in their terminal
172
+ - **Transcript parsing:** Uses a dedicated parser script if available at `/data/Dropbox/Work/fathom/infrastructure/fathom-mcp/scripts/parse-transcript.sh`. Falls back to direct JSONL extraction (works everywhere, just less polished formatting).
173
+ - **Minimum threshold:** Transcripts under 200 characters are skipped.
174
+
175
+ ---
176
+
177
+ ## Dashboard
178
+
179
+ Browse and manage memories visually at [hifathom.com/dashboard](https://hifathom.com/dashboard). Paste your API key and workspace name to connect.
180
+
181
+ ---
182
+
183
+ ## Documentation
184
+
185
+ Full reference docs at [hifathom.com/projects/memento](https://hifathom.com/projects/memento):
186
+
187
+ - **[Quick Start](https://hifathom.com/projects/memento/quick-start)** — 5-minute setup guide
188
+ - **[Core Concepts](https://hifathom.com/projects/memento/concepts)** — memories, working memory, skip lists, identity crystals
189
+ - **[MCP Tools](https://hifathom.com/projects/memento/mcp-tools)** — full tool reference with parameters and examples
190
+ - **[API Reference](https://hifathom.com/projects/memento/api)** — REST endpoints, request/response schemas, authentication
191
+ - **[Self-Hosting](docs/self-hosting.md)** — deploy your own instance with Cloudflare Workers + Turso
192
+
193
+ ---
194
+
195
+ ## Development
196
+
197
+ ```bash
198
+ npm test # Run unit + integration tests
199
+ npm run lint # Lint with ESLint
200
+ npm run format:check # Check formatting with Prettier
201
+ npm run test:smoke # Quick smoke test of all tools
202
+ ```
203
+
204
+ ## License
205
+
206
+ MIT
@@ -0,0 +1,86 @@
1
+ # Self-Hosting
2
+
3
+ The Memento Protocol API runs on Cloudflare Workers with Turso edge databases. The full source is in `saas/`.
4
+
5
+ For most users, the [hosted service](https://memento-api.myrakrusemark.workers.dev) is the fastest path — free tier, no infrastructure to manage. Self-hosting makes sense if you need data sovereignty or want to modify the API.
6
+
7
+ ## Prerequisites
8
+
9
+ - [Cloudflare account](https://dash.cloudflare.com/sign-up) (Workers free tier works)
10
+ - [Turso account](https://turso.tech) (free tier: 500 databases, 9GB storage)
11
+ - Node.js 18+
12
+ - [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/): `npm i -g wrangler`
13
+
14
+ ## Setup
15
+
16
+ ### 1. Create the control plane database
17
+
18
+ ```bash
19
+ turso db create memento-control
20
+ turso db tokens create memento-control
21
+ turso db show memento-control --url
22
+ ```
23
+
24
+ Save the URL and token — you'll need them as secrets.
25
+
26
+ ### 2. Create the Vectorize index
27
+
28
+ ```bash
29
+ wrangler vectorize create memento-memories --dimensions=384 --metric=cosine
30
+ ```
31
+
32
+ This powers semantic search. The API degrades gracefully without it (keyword-only recall), but you'll want it.
33
+
34
+ ### 3. Set secrets
35
+
36
+ ```bash
37
+ cd saas
38
+ wrangler secret put MEMENTO_DB_URL # Turso control plane URL
39
+ wrangler secret put MEMENTO_DB_TOKEN # Turso control plane token
40
+ wrangler secret put TURSO_API_TOKEN # Turso Platform API token (for creating workspace DBs)
41
+ wrangler secret put TURSO_ORG # Your Turso organization slug
42
+ ```
43
+
44
+ The Turso Platform API token is needed because the API auto-creates a separate database per workspace. Get it from [Turso dashboard > Settings > Platform API Tokens](https://turso.tech/app).
45
+
46
+ ### 4. Deploy
47
+
48
+ ```bash
49
+ cd saas
50
+ npm install
51
+ wrangler deploy
52
+ ```
53
+
54
+ Your API is now live at `https://memento-api.<your-subdomain>.workers.dev`.
55
+
56
+ ### 5. Point the MCP server at your instance
57
+
58
+ In your MCP client config, set the environment variables to your instance:
59
+
60
+ ```json
61
+ {
62
+ "env": {
63
+ "MEMENTO_API_KEY": "mp_live_your_key",
64
+ "MEMENTO_API_URL": "https://memento-api.your-subdomain.workers.dev",
65
+ "MEMENTO_WORKSPACE": "my-project"
66
+ }
67
+ }
68
+ ```
69
+
70
+ ## What you get
71
+
72
+ | Feature | Requires |
73
+ |---------|----------|
74
+ | Core memory (store, recall, working memory, skip list) | Workers + Turso |
75
+ | Semantic search (vector embeddings) | + Vectorize + Workers AI |
76
+ | AI consolidation summaries | + Workers AI |
77
+ | Scheduled decay + consolidation | Cron triggers (auto-configured in `wrangler.toml`) |
78
+
79
+ Workers AI and Vectorize are included in the Cloudflare Workers free tier.
80
+
81
+ ## What's different from hosted
82
+
83
+ - You manage your own Turso databases and Cloudflare account
84
+ - You handle upgrades by pulling from the repo and redeploying
85
+ - No usage dashboard at hifathom.com (you'd use Cloudflare's dashboard)
86
+ - Signup endpoint creates keys in your control plane database
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "memento-mcp",
3
+ "version": "0.1.0",
4
+ "description": "The Memento Protocol — persistent memory for AI agents",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "memento-server": "src/index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node src/index.js",
12
+ "test": "node --test test/*.test.js",
13
+ "test:smoke": "node test-smoke.js",
14
+ "lint": "eslint .",
15
+ "lint:fix": "eslint --fix .",
16
+ "format": "prettier --write .",
17
+ "format:check": "prettier --check ."
18
+ },
19
+ "dependencies": {
20
+ "@modelcontextprotocol/sdk": "^1.12.1",
21
+ "zod": "^3.24.2"
22
+ },
23
+ "files": [
24
+ "src/",
25
+ "scripts/",
26
+ "docs/",
27
+ "LICENSE",
28
+ "README.md",
29
+ ".env.example"
30
+ ],
31
+ "keywords": [
32
+ "mcp",
33
+ "memory",
34
+ "ai-agent",
35
+ "persistent",
36
+ "memento"
37
+ ],
38
+ "license": "MIT",
39
+ "devDependencies": {
40
+ "@eslint/js": "^10.0.1",
41
+ "eslint": "^10.0.0",
42
+ "globals": "^17.3.0",
43
+ "prettier": "^3.8.1"
44
+ }
45
+ }
@@ -0,0 +1,101 @@
1
+ #!/bin/bash
2
+ # Memento SaaS recall — context retrieval from Memento Protocol on every user message.
3
+ # JSON output: systemMessage (user sees count) + additionalContext (model sees details).
4
+ #
5
+ # Calls /v1/context endpoint for memories + skip list matches.
6
+
7
+ set -o pipefail
8
+
9
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
10
+
11
+ # Source credentials from .env (gitignored)
12
+ if [ -f "$SCRIPT_DIR/../.env" ]; then
13
+ set -a
14
+ source "$SCRIPT_DIR/../.env"
15
+ set +a
16
+ fi
17
+
18
+ MEMENTO_API="${MEMENTO_API_URL:-https://memento-api.myrakrusemark.workers.dev}"
19
+ MEMENTO_KEY="${MEMENTO_API_KEY:?MEMENTO_API_KEY not set — check memento-protocol/.env}"
20
+ MEMENTO_WS="${MEMENTO_WORKSPACE:-fathom}"
21
+
22
+ INPUT=$(cat)
23
+ USER_MESSAGE=$(echo "$INPUT" | jq -r '.prompt // empty' 2>/dev/null)
24
+
25
+ if [ -z "$USER_MESSAGE" ] || [ ${#USER_MESSAGE} -lt 10 ]; then
26
+ exit 0
27
+ fi
28
+
29
+ QUERY="${USER_MESSAGE:0:500}"
30
+
31
+ # Call Memento SaaS /v1/context
32
+ SAAS_OUTPUT=$(curl -s --max-time 3 \
33
+ -X POST \
34
+ -H "Authorization: Bearer $MEMENTO_KEY" \
35
+ -H "X-Memento-Workspace: $MEMENTO_WS" \
36
+ -H "Content-Type: application/json" \
37
+ -d "{\"message\": $(echo "$QUERY" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))'), \"include\": [\"memories\", \"skip_list\"]}" \
38
+ "$MEMENTO_API/v1/context" 2>/dev/null \
39
+ | python3 -c "
40
+ import json, sys
41
+ try:
42
+ data = json.load(sys.stdin)
43
+ lines = []
44
+ count = 0
45
+
46
+ # Memory matches
47
+ memories = data.get('memories', {}).get('matches', [])
48
+ if memories:
49
+ for m in memories[:5]:
50
+ tags = m.get('tags', [])
51
+ tag_str = f' [{\", \".join(tags)}]' if tags else ''
52
+ content = m['content'][:120]
53
+ score = m.get('score', '?')
54
+ lines.append(f' {m[\"id\"]} ({m[\"type\"]}, {score}){tag_str} — {content}')
55
+ count += 1
56
+
57
+ # Skip matches (WARNING format)
58
+ skip_matches = data.get('skip_matches', [])
59
+ if skip_matches:
60
+ lines.append('')
61
+ lines.append('SKIP LIST WARNINGS:')
62
+ for s in skip_matches:
63
+ lines.append(f' ⚠ SKIP: {s[\"item\"]} — {s[\"reason\"]} (expires: {s[\"expires\"]})')
64
+
65
+ # Output count and detail as tab-separated on first line, rest follows
66
+ detail = '\n'.join(lines)
67
+ print(f'{count}\t{detail}')
68
+ except Exception:
69
+ print('0\t')
70
+ " 2>/dev/null)
71
+
72
+ # Parse count and detail
73
+ SAAS_COUNT=$(echo "$SAAS_OUTPUT" | head -1 | cut -f1)
74
+ SAAS_DETAIL=$(echo "$SAAS_OUTPUT" | head -1 | cut -f2-)
75
+ # Append any remaining lines (skip warnings etc.)
76
+ REMAINING=$(echo "$SAAS_OUTPUT" | tail -n +2)
77
+ if [ -n "$REMAINING" ]; then
78
+ SAAS_DETAIL="$SAAS_DETAIL"$'\n'"$REMAINING"
79
+ fi
80
+
81
+ if [ -z "$SAAS_COUNT" ] || [ "$SAAS_COUNT" = "0" ]; then
82
+ exit 0
83
+ fi
84
+
85
+ DETAIL_TEXT="Memento Recall: ${SAAS_COUNT} memories"
86
+ DETAIL_TEXT="$DETAIL_TEXT"$'\n'"$SAAS_DETAIL"
87
+ DETAIL_TEXT="$DETAIL_TEXT"$'\n'$'\n'"REMINDER: If Memento MCP tools are not loaded, run: ToolSearch query=\"+memento\" max_results=20"
88
+
89
+ SUMMARY="Memento Recall: ${SAAS_COUNT} memories"
90
+ python3 -c "
91
+ import json, sys
92
+ summary = sys.argv[1]
93
+ detail = sys.argv[2]
94
+ print(json.dumps({
95
+ 'systemMessage': summary,
96
+ 'hookSpecificOutput': {
97
+ 'hookEventName': 'UserPromptSubmit',
98
+ 'additionalContext': detail
99
+ }
100
+ }))
101
+ " "$SUMMARY" "$DETAIL_TEXT"
@@ -0,0 +1,82 @@
1
+ #!/bin/bash
2
+ # PreCompact hook (Memento) — Distill memories from conversation transcript before context compression.
3
+ # Parses JSONL transcript into readable text, then sends it to Memento SaaS /v1/distill endpoint,
4
+ # which extracts key memories, decisions, and observations.
5
+ #
6
+ # Independent of other PreCompact hooks — reads the raw JSONL transcript directly.
7
+
8
+ set -o pipefail
9
+
10
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
11
+ INPUT=$(cat)
12
+
13
+ TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path' | sed "s|~|$HOME|")
14
+
15
+ # Only distill if transcript exists and has content
16
+ if [ ! -f "$TRANSCRIPT_PATH" ]; then
17
+ exit 0
18
+ fi
19
+
20
+ LINE_COUNT=$(wc -l < "$TRANSCRIPT_PATH")
21
+ if [ "$LINE_COUNT" -lt 2 ]; then
22
+ exit 0
23
+ fi
24
+
25
+ # Source credentials from .env (gitignored)
26
+ if [ -f "$SCRIPT_DIR/../.env" ]; then
27
+ set -a
28
+ source "$SCRIPT_DIR/../.env"
29
+ set +a
30
+ fi
31
+
32
+ MEMENTO_API="${MEMENTO_API_URL:-https://memento-api.myrakrusemark.workers.dev}"
33
+ MEMENTO_KEY="${MEMENTO_API_KEY:?MEMENTO_API_KEY not set — check memento-protocol/.env}"
34
+ MEMENTO_WS="${MEMENTO_WORKSPACE:-fathom}"
35
+
36
+ # Parse transcript to readable text (use fathom's parser if available, else raw)
37
+ FATHOM_PARSER="/data/Dropbox/Work/fathom/infrastructure/fathom-mcp/scripts/parse-transcript.sh"
38
+ if [ -x "$FATHOM_PARSER" ]; then
39
+ TRANSCRIPT_TEXT=$("$FATHOM_PARSER" "$TRANSCRIPT_PATH")
40
+ else
41
+ # Fallback: extract text content directly from JSONL
42
+ TRANSCRIPT_TEXT=$(jq -r 'select(.type == "user" or .type == "assistant") | .message.content | if type == "string" then . elif type == "array" then [.[] | select(.type == "text") | .text] | join("\n") else empty end' "$TRANSCRIPT_PATH" 2>/dev/null)
43
+ fi
44
+
45
+ if [ ${#TRANSCRIPT_TEXT} -lt 200 ]; then
46
+ exit 0 # Too short to distill anything useful
47
+ fi
48
+
49
+ # Send to Memento SaaS /v1/distill
50
+ RESPONSE=$(curl -s --max-time 30 \
51
+ -X POST \
52
+ -H "Authorization: Bearer $MEMENTO_KEY" \
53
+ -H "X-Memento-Workspace: $MEMENTO_WS" \
54
+ -H "Content-Type: application/json" \
55
+ -d "{\"transcript\": $(echo "$TRANSCRIPT_TEXT" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')}" \
56
+ "$MEMENTO_API/v1/distill" 2>/dev/null)
57
+
58
+ # Report results
59
+ MEMORY_COUNT=$(echo "$RESPONSE" | python3 -c "
60
+ import json, sys
61
+ try:
62
+ data = json.load(sys.stdin)
63
+ print(len(data.get('memories', [])))
64
+ except Exception:
65
+ print('0')
66
+ " 2>/dev/null)
67
+
68
+ if [ "$MEMORY_COUNT" -gt 0 ] 2>/dev/null; then
69
+ python3 -c "
70
+ import json, sys
71
+ msg = sys.argv[1]
72
+ print(json.dumps({'systemMessage': msg}))
73
+ " "Memento Distill: extracted ${MEMORY_COUNT} memories"
74
+ else
75
+ python3 -c "
76
+ import json, sys
77
+ msg = sys.argv[1]
78
+ print(json.dumps({'systemMessage': msg}))
79
+ " "Memento Distill: no memories extracted"
80
+ fi
81
+
82
+ exit 0