mnemos-capture 1.0.6 → 1.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/README.md CHANGED
@@ -4,133 +4,275 @@
4
4
 
5
5
  <h1 align="center">Mnemos</h1>
6
6
 
7
- <p align="center"><strong>Capture knowledge. Apply it through your agents.</strong></p>
7
+ <p align="center">
8
+ <img src="https://img.shields.io/npm/v/mnemos-capture" alt="npm" />
9
+ <img src="https://img.shields.io/badge/license-MIT-blue" alt="License" />
10
+ <img src="https://img.shields.io/badge/MCP-compatible-green" alt="MCP" />
11
+ </p>
12
+
13
+ <p align="center"><strong>A knowledge pipeline for AI agents.<br />Capture anything — your agents retrieve and apply it.</strong></p>
14
+
15
+ Your agents only know what they were trained on. They don't know what you read this morning, what framework you found last week, or what idea you had at midnight.
16
+
17
+ Mnemos bridges that gap. It's a knowledge base that grows in real time and plugs directly into any agent via MCP — so every insight you capture is immediately available to every agent you use.
18
+
19
+
20
+ ## Get started
21
+
22
+ ### 1. Sign up (30 seconds)
23
+
24
+ Go to **[mnemos-capture.vercel.app](https://mnemos-capture.vercel.app)** → **Sign in with GitHub**.
25
+
26
+ During setup, Mnemos will:
8
27
 
9
- Mnemos is a knowledge pipeline for builders who work with AI agents. You learn something — an article, a thread, a transcript, your own notes, an idea on the go — and instead of bookmarking it or letting it rot in a tab, you paste it into Mnemos. An LLM extracts the core insight, tags it by topic, and commits it to a GitHub repo you own.
28
+ - Create a knowledge repo in your GitHub account — plain Markdown files, no proprietary format
29
+ - Ask for your Anthropic API key — your key, stored per-user, Mnemos never pays for your API calls
30
+ - Set a PIN so you can unlock the app quickly on mobile
31
+
32
+ No config files. No repos to clone. No CLI setup required.
33
+
34
+ ### 2. Capture something
10
35
 
11
- That repo becomes your personal knowledge base. Your AI agents — Claude Code, Codex, or any MCP-compatible tool — pull from it directly. The knowledge you captured on your phone during lunch is available to your coding agent by the time you sit down to work.
36
+ Open the app on any device — phone, tablet, or desktop. Paste any content and hit **Capture**.
37
+
38
+ The result is a structured Markdown file, auto-committed to your GitHub knowledge repo and immediately available to your agents.
39
+
40
+ ### 3. Connect to Claude Code
41
+
42
+ After signing up, you get an MCP API key. Run this once on your machine:
43
+
44
+ ```bash
45
+ claude mcp add mnemos -- npx -y mnemos-capture@latest serve-mcp --key <your-api-key>
46
+ ```
47
+
48
+ Your agent confirms the connection and can immediately access your knowledge base.
49
+
50
+ > `npx -y mnemos-capture@latest serve-mcp` runs a lightweight local process that bridges Claude Code to the Mnemos API. The `@latest` tag guarantees you always run the most recently published version. As a safety net, the MCP server also self-upgrades on startup: if a newer version is on npm, it respawns under `npx @latest` automatically — so existing users who registered without `@latest` pick up updates on their next session. No data is stored locally — everything lives in your GitHub repo.
51
+
52
+ **Proactive inbox notifications (automatic).** The first time the MCP server starts, Mnemos silently installs a `SessionStart` hook in `~/.claude/settings.json`. From then on, every new Claude Code session opens with a short reminder:
53
+
54
+ ```
55
+ Mnemos: 3 captures in inbox — run list_inbox to review
56
+ ```
57
+
58
+ Your agent sees this before the conversation begins and can proactively surface pending captures instead of waiting for you to ask. The hook is skipped if one already exists, so rotating keys or upgrading modes is always safe — your configuration is never overwritten silently.
59
+
60
+ **Upgrade to a full session briefing (optional).** If you want more than a count — an LLM-composed briefing grounded in your current git branch, recent commits, and `CLAUDE.md` — run:
61
+
62
+ ```bash
63
+ npx -y mnemos-capture@latest setup-hooks --key <your-api-key> --briefing
64
+ ```
12
65
 
13
- **This is not a note-taking app.** It's a bridge between what you learn and what your agents do.
66
+ Each session now starts with a focused summary: which captures are relevant to what you're working on right now, which synthesized rules apply, and what's waiting in your inbox. Adds ~5s to session start (calls `briefing` on the hosted API, uses your Anthropic key).
14
67
 
15
- ## Why Mnemos exists
68
+ **Where the hook runs.** `SessionStart` hooks fire anywhere Claude Code reads your local settings — CLI, VS Code / JetBrains extensions, and the desktop app. For Claude Code on the web or other MCP clients (Cursor, etc.), the MCP tools (`list_inbox`, `briefing`, `recall`, …) still work — you just won't get the proactive nudge automatically. Add a line to that project's `CLAUDE.md` like `"At session start, call list_inbox to surface pending captures"` for a portable alternative.
16
69
 
17
- Most knowledge tools stop at "save it." Mnemos closes the loop:
70
+ ### 4. Connect to any MCP-compatible agent
18
71
 
19
- 1. **You capture** — paste anything: articles, threads, transcripts, meeting notes, ideas, voice memo transcripts, book highlights
20
- 2. **AI extracts** — an LLM pulls the actual insight (not a summary), tags it by topic, and connects it to what you're building right now
21
- 3. **Your agents apply it** — Claude Code, Codex, or any agentic tool reads your knowledge repo via MCP or Git and uses it in real workflows
72
+ Your knowledge lives in a standard GitHub repo. Any agent that can read Git or speak MCP can access it — no lock-in, no custom integration required.
22
73
 
23
- Every capture includes an **"Applied to"** field — a concrete sentence linking what you learned to what you're building. This is the difference between a saved-for-later graveyard and a knowledge system that compounds.
24
74
 
25
75
  ## How it works
26
76
 
27
77
  ```mermaid
28
- flowchart LR
29
- A["Read an article,\nhear a podcast,\nhave an idea"] -->|paste| B["Mnemos\n(web / mobile)"]
30
- B -->|extract| C["Core idea\nTakeaways\nApplied to"]
31
- C -->|commit| D["Your GitHub repo\n(Markdown)"]
32
- D -->|MCP| E["Claude Code"]
33
- D -->|Git read| F["Codex"]
34
- D -->|API / Git| G["Your agents"]
78
+ flowchart TD
79
+ A["Article / research /\ntranscript / idea"] -->|paste| B["Mnemos\n(web / mobile / CLI)"]
80
+ B -->|extracts insights| C["Structured knowledge\n+ where to apply it"]
81
+ C -->|auto-commit| D["Your GitHub repo\n(Markdown)"]
82
+ D -->|MCP| E["Agent retrieves\n& surfaces to you"]
83
+ E -->|you decide| F{"Apply?"}
84
+ F -->|yes| G["Applied to\nyour workflow"]
85
+ F -->|no| H["Stays in\nknowledge base"]
35
86
 
36
87
  style A fill:#1a1a2e,stroke:#444,color:#fff
37
88
  style B fill:#2A62C6,stroke:#1a4a9e,color:#fff
38
89
  style C fill:#d4a843,stroke:#b8912e,color:#fff
39
90
  style D fill:#2d8a4e,stroke:#1e6b3a,color:#fff
40
91
  style E fill:#1a1a2e,stroke:#444,color:#fff
41
- style F fill:#1a1a2e,stroke:#444,color:#fff
42
- style G fill:#1a1a2e,stroke:#444,color:#fff
92
+ style F fill:#2A62C6,stroke:#1a4a9e,color:#fff
93
+ style G fill:#2d8a4e,stroke:#1e6b3a,color:#fff
94
+ style H fill:#1a1a2e,stroke:#444,color:#fff
43
95
  ```
44
96
 
45
- ## What you can capture
97
+ 1. **You paste content** — an article, a research paper, a thread, a transcript, your own ideas. Anything text-based.
98
+ 2. **Mnemos extracts the insight** — Claude Haiku 4.5 pulls the core idea (not a summary), identifies key takeaways, and tags where it could apply in your work. All automatic.
99
+ 3. **It's committed to your repo** — a structured Markdown file lands in your GitHub knowledge repo, searchable and version-controlled.
100
+ 4. **Your agents retrieve it** — Claude Code or any MCP-compatible agent can search your knowledge base and surface the right insight when it's relevant. You review, you decide what gets applied.
101
+
102
+ ### Example output
103
+
104
+ Paste a research post about multi-agent systems. This is what gets committed to your repo:
105
+
106
+ ```markdown
107
+ ---
108
+ date: 2026-04-01
109
+ source: Why Multi-Agent Systems Outperform Single-Agent Loops
110
+ url: https://example.com/multi-agent-systems
111
+ type: post
112
+ tags: multi-agent, orchestration, agent-design, ai-architecture
113
+ status: inbox
114
+ ---
115
+
116
+ # Why Multi-Agent Systems Outperform Single-Agent Loops
117
+
118
+ ## Core idea
119
+ Decomposing complex tasks across specialized agents reduces error propagation
120
+ and improves output quality — a single orchestrator routing to focused subagents
121
+ consistently outperforms one generalist agent handling everything sequentially.
122
+
123
+ ## Key takeaways
124
+ - Specialized agents outperform generalist agents on tasks requiring depth over breadth
125
+ - Parallel execution across subagents reduces total latency by 40-60% on multi-step tasks
126
+ - Orchestrator-subagent patterns improve error isolation — one agent failing doesn't
127
+ collapse the entire workflow
128
+
129
+ ## Quotes
130
+ > "The bottleneck in complex agentic tasks is not model capability — it's
131
+ > error propagation across sequential steps."
132
+
133
+ ## Applied to
134
+ Evaluate your current single-agent workflows for tasks that could be decomposed
135
+ into parallel subagent calls — prioritize anything with 3+ sequential steps.
136
+ ```
46
137
 
47
- Mnemos handles any text-based input. Paste it, and the LLM figures out the format and extracts accordingly.
138
+ Every field is designed to help your agents find and apply the right knowledge at the right time. The **"Applied to"** field is the most important — it connects the insight to a concrete action in your work.
48
139
 
49
- - **Articles and blog posts** — the insight, not a summary
50
- - **Twitter/X threads** — the argument stitched together
51
- - **Podcast and meeting transcripts** — the signal, not the filler
52
- - **Your own notes and ideas** — raw thoughts turned into structured knowledge
53
- - **Book highlights and excerpts** — the quotes and frameworks worth keeping
54
- - **Newsletter and Substack posts** — the actionable takeaways
55
140
 
56
- Coming soon: voice memos, URL auto-fetch, and browser extension for one-click capture.
141
+ ## What you can feed it
57
142
 
58
- ## Cost
143
+ If it's text, Mnemos can extract insight from it. You don't need to categorize or tag anything yourself — that happens automatically.
59
144
 
60
- Mnemos uses your own Anthropic API key (BYOK — you bring your own key, Mnemos never charges you).
145
+ - **Research papers and preprints** — new models, architectures, evaluation methods
146
+ - **Framework and library docs** — patterns, APIs, integration approaches worth keeping
147
+ - **Optimization techniques** — prompt engineering, caching strategies, latency improvements
148
+ - **Technical threads and writeups** — the argument or finding, not the noise
149
+ - **Your own ideas** — workflow improvements, architecture decisions, things you want your agents to act on later
150
+ - **Transcripts and talks** — the signal extracted, ready to apply
61
151
 
62
- Extraction runs on **Claude Haiku 4.5** with prompt caching and input truncation, optimized for minimal token usage:
63
152
 
64
- | Usage | Estimated monthly cost |
65
- |-------|----------------------|
66
- | 50 captures/month (casual) | ~$0.15 |
67
- | 100 captures/month (regular) | ~$0.30 |
68
- | 200 captures/month (heavy) | ~$0.60 |
153
+ ## Knowledge lifecycle
69
154
 
70
- Less than $1/month for heavy use. For comparison, the same workload on a larger model without optimization would cost 5-6x more.
155
+ Knowledge that sits unreviewed rots. Mnemos forces a decision: apply it, save it for later, or discard it.
71
156
 
72
- ## Get started
157
+ ```
158
+ ┌─────────┐
159
+ │ Capture │
160
+ └────┬─────┘
161
+ ▼
162
+ ┌─────────┐ ┌──────────┐
163
+ │ Inbox │────▶│ Applied │ You used the insight in your workflow
164
+ └────┬─────┘ └──────────┘
165
+ │
166
+ ├──────────▶┌──────────┐
167
+ │ │ Archived │ Reviewed, not actionable right now
168
+ │ └──────────┘
169
+ │
170
+ └──────────▶┌──────────┐
171
+ │ Deleted │ Not useful, permanently removed
172
+ └──────────┘
173
+ ```
73
174
 
74
- ### 1. Sign up (30 seconds)
175
+ **How it works in practice:**
75
176
 
76
- Go to **[mnemos-capture.vercel.app](https://mnemos-capture.vercel.app)** → **Sign in with GitHub**.
177
+ 1. **Capture** — every new capture lands in `inbox/`. After each capture, Mnemos tells you how many items are waiting for review.
178
+ 2. **Review** — use `list_inbox` to see what's in your inbox (with summaries), and `read_capture` to read the full content of any capture.
179
+ 3. **Apply** — when you've used an insight (added it to a project file, changed a workflow, created a rule), use `apply_capture` to move it to `applied/`. This closes the loop — the knowledge is now part of your system.
180
+ 4. **Archive** — reviewed it but it's not actionable right now? Use `archive_capture` to move it to `archived/`. It stays searchable but out of your inbox.
181
+ 5. **Delete** — not useful? Use `delete_capture` to permanently remove it.
77
182
 
78
- During setup, Mnemos will:
183
+ All captures are tracked in `INDEX.md` — a master table your agents use to search across your entire knowledge base.
79
184
 
80
- - Create a knowledge repo in your GitHub account (you own it — just Markdown files in a repo under your name)
81
- - Ask for your Anthropic API key (your key, stored per-user — Mnemos never pays for your API calls)
82
- - Set a PIN so you can unlock the app quickly on mobile
83
185
 
84
- No config files. No CLI setup. No repos to clone.
186
+ ## MCP tools
85
187
 
86
- ### 2. Capture something
188
+ Mnemos exposes 7 tools via MCP, organized by what you're doing:
87
189
 
88
- Open the app on any device — phone, tablet, or desktop. Paste any content and hit **Capture**. That's it.
190
+ ### Capture
89
191
 
90
- The result is auto-committed to your GitHub knowledge repo as a structured Markdown file.
192
+ | Tool | What it does |
193
+ |------|-------------|
194
+ | `capture` | Extracts insight from any pasted content and commits a structured Markdown file to your repo. This is the entry point — everything starts here. |
91
195
 
92
- ### 3. Connect to Claude Code (optional)
196
+ ### Discover
93
197
 
94
- After signing up, you get an API key. This connects Mnemos to Claude Code so your agent can capture and search your knowledge without leaving the terminal.
198
+ | Tool | What it does |
199
+ |------|-------------|
200
+ | `list_inbox` | Shows your unprocessed captures with summaries — title, type, tags, and core idea. Up to 10 at a time. Use this to see what's waiting for your review. |
201
+ | `search_captures` | Searches your knowledge base by keyword or tag. Finds relevant captures across inbox, applied, and archived — so your agent can pull the right knowledge when it's needed. |
202
+ | `read_capture` | Reads the full Markdown of any capture. Use this to see the complete insight, takeaways, and context before deciding what to do with it. |
95
203
 
96
- Run this once:
204
+ ### Manage
205
+
206
+ | Tool | What it does |
207
+ |------|-------------|
208
+ | `apply_capture` | Moves a capture from inbox to applied. Marks it as used — you can add a note about where you applied it (e.g., "Added as a rule in CLAUDE.md"). |
209
+ | `archive_capture` | Moves a capture from inbox to archived. It's been reviewed but isn't actionable right now. Stays searchable, out of your inbox. |
210
+ | `delete_capture` | Permanently removes a capture and its index entry. For mistakes or captures that aren't useful. |
211
+
212
+ The web UI and MCP use the same pipeline. The web UI is for capturing on the go. MCP is for your agents — they retrieve and manage captures without you touching the browser.
97
213
 
98
- ```bash
99
- claude mcp add mnemos -- npx mnemos-capture serve-mcp --key <your-api-key>
100
- ```
101
214
 
102
- Now you can say things like:
215
+ ## Mobile
103
216
 
104
- - *"Capture this article about prompt caching"*
105
- - *"What's in my inbox?"*
106
- - *"Search my captures for evaluation frameworks"*
217
+ Open Mnemos in your phone's browser, tap **Share → Add to Home Screen**. It runs full-screen like a native app.
107
218
 
108
- **Under the hood:** `npx mnemos-capture serve-mcp` runs a lightweight local process that bridges Claude Code's stdio protocol to the Mnemos HTTP API. Your API key authenticates the requests. No data is stored locally — everything goes to your GitHub repo via the hosted app.
219
+ Capture on the go — reading an article on your phone at lunch? Capture it. Your agents have it by the time you sit down to work.
109
220
 
110
- ## Mobile access
221
+ ## Your data, your storage
111
222
 
112
- Mnemos is a PWA. On your phone, open the app URL in your browser → Share → **Add to Home Screen**. Native-app feel, instant capture from anywhere.
223
+ Your knowledge lives in a GitHub repo you own. Plain Markdown files, version-controlled, portable.
113
224
 
114
- ## Why GitHub as storage?
225
+ - **No lock-in** — clone it, search it, move it, delete Mnemos tomorrow and your repo stays exactly where it is
226
+ - **No proprietary format** — every capture is a readable `.md` file
227
+ - **No training on your data** — Mnemos never reads your captures for any purpose other than serving them back to you and your agents
228
+ - **Any tool can access it** — anything that reads Git or speaks MCP works with your knowledge base
229
+
230
+
231
+ ## Cost
232
+
233
+ Mnemos uses your own Anthropic API key (BYOK). You bring your key, Mnemos never charges you for API calls.
234
+
235
+ Extraction runs on **Claude Haiku 4.5** with prompt caching and input truncation, optimized for minimal token usage:
236
+
237
+ | Usage | Estimated monthly cost |
238
+ |-------|----------------------|
239
+ | 50 captures/month | ~$0.15 |
240
+ | 100 captures/month | ~$0.30 |
241
+ | 200 captures/month | ~$0.60 |
242
+
243
+ Less than $1/month for heavy use.
115
244
 
116
- Your knowledge lives in a repo you own. No proprietary database, no vendor lock-in. It's version-controlled, portable, and readable as plain Markdown. Clone it, search it, back it up — it's just files. And because it's a standard Git repo, any MCP-compatible agent or tool can read from it directly.
117
245
 
118
246
  ## Tech stack
119
247
 
120
- Next.js · TypeScript (strict) · Anthropic SDK · GitHub OAuth · Vercel Postgres (Neon) · GitHub API · MCP protocol · Tailwind CSS
248
+ Next.js · TypeScript · Claude Haiku 4.5 · Anthropic SDK · GitHub OAuth · Vercel Postgres · GitHub Content API · MCP protocol · Tailwind CSS
121
249
 
122
250
  ## Roadmap
123
251
 
124
- - [ ] Multi-provider support (OpenAI, Google — schema is ready)
125
- - [ ] Voice memo capture
126
- - [ ] URL auto-fetch (paste a link, Mnemos fetches the content)
127
- - [ ] Batch capture (multiple resources at once)
128
- - [ ] Browser extension for one-click capture
129
- - [ ] Full-text search across knowledge hub
130
- - [ ] Custom user-defined categories
131
- - [ ] Settings page (change API key, repo, regenerate MCP key)
132
- - [ ] Team knowledge hubs (shared captures)
252
+ - Chrome extension for one-click capture from anywhere in the browser
253
+ - URL auto-fetch — paste a link, Mnemos fetches and extracts
254
+ - Multi-provider support (OpenAI, Google — schema is ready)
255
+ - Voice memo capture
256
+
257
+
258
+ ## Built by
259
+
260
+ [Sofía Padrón Valdez](https://github.com/Soph20) — builder, AI systems architect.
261
+
262
+ ## Citation
263
+
264
+ If you use this repository in your agentic workflows, please consider citing as follows:
265
+ ```
266
+ @misc{2026mnemos,
267
+ title = {Mnemos: A Knowledge Pipeline for AI Agents},
268
+ author = {Sofia Padron Valdez},
269
+ year = 2026,
270
+ journal = {GitHub repository},
271
+ publisher = {GitHub},
272
+ howpublished = {\url{https://github.com/Soph20/mnemos-capture}}
273
+ }
274
+ ```
133
275
 
134
276
  ## License
135
277
 
136
- [MIT](LICENSE)
278
+ [MIT License - see LICENSE file for details](./LICENSE)
@@ -0,0 +1,164 @@
1
+ import { homedir } from "os";
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
3
+ import { join } from "path";
4
+ import { execSync } from "child_process";
5
+ const HOSTED_URL = "https://mnemos-capture.vercel.app/api/mcp";
6
+ const CLAUDE_SETTINGS_PATH = join(homedir(), ".claude", "settings.json");
7
+ // Matches both legacy ("mnemos-capture inbox-check") and modern
8
+ // ("mnemos-capture@latest inbox-check") hook command forms.
9
+ function isMnemosHook(cmd) {
10
+ return cmd.includes("mnemos-capture") && cmd.includes("inbox-check");
11
+ }
12
+ function readSettings() {
13
+ if (!existsSync(CLAUDE_SETTINGS_PATH))
14
+ return {};
15
+ try {
16
+ return JSON.parse(readFileSync(CLAUDE_SETTINGS_PATH, "utf-8"));
17
+ }
18
+ catch {
19
+ return {};
20
+ }
21
+ }
22
+ function writeSettings(settings) {
23
+ const dir = join(homedir(), ".claude");
24
+ if (!existsSync(dir))
25
+ mkdirSync(dir, { recursive: true });
26
+ writeFileSync(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2) + "\n");
27
+ }
28
+ export function setupHooks(apiKey, opts = {}) {
29
+ const settings = readSettings();
30
+ const hooks = settings.hooks ?? {};
31
+ const sessionStart = hooks.SessionStart ?? [];
32
+ // Inspect any existing mnemos hook so we can either skip, migrate, or replace
33
+ let existingCmd = null;
34
+ for (const group of sessionStart) {
35
+ for (const h of group.hooks ?? []) {
36
+ if (typeof h.command === "string" && isMnemosHook(h.command)) {
37
+ existingCmd = h.command;
38
+ break;
39
+ }
40
+ }
41
+ if (existingCmd)
42
+ break;
43
+ }
44
+ // skipIfExists (serve-mcp auto-install): preserve user-configured hooks but
45
+ // silently migrate legacy hooks that don't use @latest so they always stay fresh.
46
+ if (existingCmd && opts.skipIfExists) {
47
+ const alreadyLatest = existingCmd.includes("mnemos-capture@latest");
48
+ if (alreadyLatest)
49
+ return;
50
+ // Migration: preserve the existing --briefing flag when upgrading to @latest
51
+ opts = { ...opts, briefing: existingCmd.includes("--briefing") };
52
+ }
53
+ const command = opts.briefing
54
+ ? `npx -y mnemos-capture@latest inbox-check --key ${apiKey} --briefing`
55
+ : `npx -y mnemos-capture@latest inbox-check --key ${apiKey}`;
56
+ // Remove any existing mnemos inbox-check hook (handles key rotation too)
57
+ const filtered = sessionStart
58
+ .map((group) => ({
59
+ ...group,
60
+ hooks: (group.hooks ?? []).filter((h) => !(typeof h.command === "string" && isMnemosHook(h.command))),
61
+ }))
62
+ .filter((group) => (group.hooks ?? []).length > 0);
63
+ filtered.push({ hooks: [{ type: "command", command }] });
64
+ settings.hooks = { ...hooks, SessionStart: filtered };
65
+ writeSettings(settings);
66
+ if (!opts.silent) {
67
+ console.log("Mnemos inbox hook installed.");
68
+ console.log(`Location: ${CLAUDE_SETTINGS_PATH}`);
69
+ if (opts.briefing) {
70
+ console.log("At the start of each Claude Code session you'll see a full project briefing.");
71
+ }
72
+ else {
73
+ console.log("At the start of each Claude Code session you'll see your inbox count.");
74
+ }
75
+ }
76
+ }
77
+ function run(cmd) {
78
+ return execSync(cmd, { timeout: 2000, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
79
+ }
80
+ function detectProjectContext() {
81
+ const parts = [];
82
+ // Repo name
83
+ try {
84
+ const remote = run("git remote get-url origin");
85
+ const match = remote.match(/\/([^/]+?)(?:\.git)?$/);
86
+ const repo = match?.[1] ?? run("git rev-parse --show-toplevel").split("/").pop();
87
+ if (repo)
88
+ parts.push(`Project: ${repo}`);
89
+ }
90
+ catch {
91
+ const dir = process.cwd().split("/").pop();
92
+ if (dir)
93
+ parts.push(`Project: ${dir}`);
94
+ }
95
+ // Current branch
96
+ try {
97
+ const branch = run("git branch --show-current");
98
+ if (branch)
99
+ parts.push(`Branch: ${branch}`);
100
+ }
101
+ catch { }
102
+ // Recent commits (last 5)
103
+ try {
104
+ const log = run("git log --oneline -5");
105
+ if (log)
106
+ parts.push(`Recent commits:\n${log}`);
107
+ }
108
+ catch { }
109
+ // CLAUDE.md — first 800 chars gives the model real project intent
110
+ try {
111
+ const root = run("git rev-parse --show-toplevel");
112
+ const claudeMd = readFileSync(join(root, "CLAUDE.md"), "utf-8").slice(0, 800).trim();
113
+ if (claudeMd)
114
+ parts.push(`Project instructions (CLAUDE.md excerpt):\n${claudeMd}`);
115
+ }
116
+ catch { }
117
+ return parts.length > 0 ? parts.join("\n\n") : "current project";
118
+ }
119
+ async function callMcp(apiKey, toolName, toolArgs) {
120
+ const res = await fetch(HOSTED_URL, {
121
+ method: "POST",
122
+ headers: {
123
+ "Content-Type": "application/json",
124
+ Authorization: `Bearer ${apiKey}`,
125
+ },
126
+ body: JSON.stringify({
127
+ jsonrpc: "2.0",
128
+ method: "tools/call",
129
+ params: { name: toolName, arguments: toolArgs },
130
+ id: 1,
131
+ }),
132
+ signal: AbortSignal.timeout(15000),
133
+ });
134
+ if (!res.ok)
135
+ return null;
136
+ const data = (await res.json());
137
+ return data.result?.content?.[0]?.text ?? null;
138
+ }
139
+ export async function inboxCheck(apiKey, opts = {}) {
140
+ try {
141
+ if (opts.briefing) {
142
+ const projectContext = detectProjectContext();
143
+ const text = await callMcp(apiKey, "briefing", { project_context: projectContext });
144
+ if (text?.trim())
145
+ process.stdout.write(text.trim() + "\n");
146
+ return;
147
+ }
148
+ // Default: fast count via list_inbox (no LLM call)
149
+ const text = await callMcp(apiKey, "list_inbox", {});
150
+ if (!text)
151
+ return;
152
+ // list_inbox returns "N capture(s) in inbox:" or "Inbox is empty."
153
+ const match = text.match(/^(\d+)\s+capture/);
154
+ if (!match)
155
+ return;
156
+ const count = parseInt(match[1], 10);
157
+ if (count > 0) {
158
+ process.stdout.write(`Mnemos: ${count} capture${count === 1 ? "" : "s"} in inbox — run list_inbox to review\n`);
159
+ }
160
+ }
161
+ catch {
162
+ // Silent fail — never interrupt a session startup
163
+ }
164
+ }
package/dist/cli/index.js CHANGED
@@ -8,11 +8,30 @@ async function main() {
8
8
  return;
9
9
  }
10
10
  if (command === "serve-mcp") {
11
- // MCP server mode — proxies to hosted instance
12
11
  const { serveMcp } = await import("./mcp-server.js");
13
12
  await serveMcp();
14
13
  return;
15
14
  }
15
+ if (command === "setup-hooks") {
16
+ const { setupHooks } = await import("./hooks.js");
17
+ const keyIdx = args.indexOf("--key");
18
+ const apiKey = keyIdx !== -1 ? args[keyIdx + 1] : undefined;
19
+ if (!apiKey) {
20
+ console.error("Usage: npx mnemos-capture setup-hooks --key YOUR_API_KEY [--briefing]");
21
+ process.exit(1);
22
+ }
23
+ setupHooks(apiKey, { briefing: args.includes("--briefing") });
24
+ return;
25
+ }
26
+ if (command === "inbox-check") {
27
+ const { inboxCheck } = await import("./hooks.js");
28
+ const keyIdx = args.indexOf("--key");
29
+ const apiKey = keyIdx !== -1 ? args[keyIdx + 1] : undefined;
30
+ if (!apiKey)
31
+ process.exit(0); // silent fail in hook context
32
+ await inboxCheck(apiKey, { briefing: args.includes("--briefing") });
33
+ return;
34
+ }
16
35
  // Default: open the hosted app
17
36
  console.log("");
18
37
  console.log(" Mnemos — Knowledge capture for agentic workflows\n");
@@ -21,7 +40,7 @@ async function main() {
21
40
  console.log(" First time? Sign in with GitHub — setup takes 30 seconds.");
22
41
  console.log("");
23
42
  console.log(" Connect to Claude Code:");
24
- console.log(" claude mcp add mnemos -- npx mnemos-capture serve-mcp --key YOUR_API_KEY");
43
+ console.log(" claude mcp add mnemos -- npx -y mnemos-capture@latest serve-mcp --key YOUR_API_KEY");
25
44
  console.log("");
26
45
  // Try to open the URL in the default browser
27
46
  const { exec } = await import("child_process");
@@ -33,9 +52,11 @@ function printHelp() {
33
52
  Mnemos — Knowledge capture for agentic workflows
34
53
 
35
54
  Usage:
36
- npx mnemos-capture Open Mnemos in your browser
37
- npx mnemos-capture serve-mcp Start the MCP server for Claude Code
38
- npx mnemos-capture help Show this help
55
+ npx mnemos-capture Open Mnemos in your browser
56
+ npx mnemos-capture serve-mcp --key KEY Start the MCP server for Claude Code
57
+ npx mnemos-capture setup-hooks --key KEY Install inbox count hook (fast)
58
+ npx mnemos-capture setup-hooks --key KEY --briefing Install full briefing hook (uses LLM)
59
+ npx mnemos-capture help Show this help
39
60
 
40
61
  Get started:
41
62
  1. Run: npx mnemos-capture
@@ -44,7 +65,15 @@ function printHelp() {
44
65
  4. Start capturing!
45
66
 
46
67
  Connect to Claude Code:
47
- claude mcp add mnemos -- npx mnemos-capture serve-mcp --key YOUR_API_KEY
68
+ claude mcp add mnemos -- npx -y mnemos-capture@latest serve-mcp --key YOUR_API_KEY
69
+
70
+ The @latest tag ensures every Claude Code session uses the most recent
71
+ published version. serve-mcp also self-upgrades on startup as a safety net
72
+ for users who registered without @latest.
73
+
74
+ The hook is installed automatically when you start the MCP server.
75
+ To upgrade to a full project briefing at session start:
76
+ npx mnemos-capture setup-hooks --key YOUR_API_KEY --briefing
48
77
  `);
49
78
  }
50
79
  main().catch((err) => {
@@ -33,10 +33,30 @@ export async function serveMcp() {
33
33
  const apiKey = keyIdx !== -1 ? args[keyIdx + 1] : undefined;
34
34
  if (!apiKey) {
35
35
  process.stderr.write("\nMnemos MCP server requires an API key.\n");
36
- process.stderr.write("Usage: npx mnemos-capture serve-mcp --key <your-api-key>\n\n");
36
+ process.stderr.write("Usage: npx -y mnemos-capture@latest serve-mcp --key <your-api-key>\n\n");
37
37
  process.stderr.write("Get your API key at: https://mnemos-capture.vercel.app/onboard\n\n");
38
38
  process.exit(1);
39
39
  }
40
+ // Self-upgrade: if a newer version exists on npm, respawn via npx @latest.
41
+ // Handled before anything else so stdio isn't yet owned by the MCP loop.
42
+ try {
43
+ const { maybeSelfUpgrade } = await import("./version-check.js");
44
+ const upgrading = await maybeSelfUpgrade();
45
+ if (upgrading)
46
+ return; // child has taken over; parent will exit when child does
47
+ }
48
+ catch {
49
+ // Version check must never block startup
50
+ }
51
+ // Auto-install the inbox hook the first time the MCP server is registered.
52
+ // Uses silent mode so it never prints to stdout (which is reserved for MCP protocol).
53
+ try {
54
+ const { setupHooks } = await import("./hooks.js");
55
+ setupHooks(apiKey, { silent: true, skipIfExists: true });
56
+ }
57
+ catch {
58
+ // Non-fatal — hook setup should never block the MCP server from starting
59
+ }
40
60
  process.stderr.write("Mnemos MCP server starting (proxying to hosted instance)...\n");
41
61
  let buffer = "";
42
62
  process.stdin.setEncoding("utf-8");
@@ -0,0 +1,79 @@
1
+ // Self-update enforcement: ensures users always run the latest mnemos-capture.
2
+ //
3
+ // Strategy: on serve-mcp startup, query npm for the latest published version.
4
+ // If behind, respawn the process via `npx -y mnemos-capture@latest` and proxy
5
+ // stdio. A MNEMOS_UPGRADED=1 env var prevents infinite recursion.
6
+ import { readFileSync } from "fs";
7
+ import { fileURLToPath } from "url";
8
+ import { dirname, join } from "path";
9
+ import { spawn } from "child_process";
10
+ const NPM_REGISTRY = "https://registry.npmjs.org/mnemos-capture/latest";
11
+ const CHECK_TIMEOUT_MS = 2000;
12
+ export function getCurrentVersion() {
13
+ try {
14
+ const here = dirname(fileURLToPath(import.meta.url));
15
+ // dist/cli/version-check.js → ../../package.json
16
+ const pkg = JSON.parse(readFileSync(join(here, "../../package.json"), "utf-8"));
17
+ return pkg.version ?? "0.0.0";
18
+ }
19
+ catch {
20
+ return "0.0.0";
21
+ }
22
+ }
23
+ export function isNewer(latest, current) {
24
+ const l = latest.split(".").map((n) => parseInt(n, 10) || 0);
25
+ const c = current.split(".").map((n) => parseInt(n, 10) || 0);
26
+ for (let i = 0; i < 3; i++) {
27
+ const lv = l[i] ?? 0;
28
+ const cv = c[i] ?? 0;
29
+ if (lv > cv)
30
+ return true;
31
+ if (lv < cv)
32
+ return false;
33
+ }
34
+ return false;
35
+ }
36
+ async function getLatestVersion() {
37
+ try {
38
+ const res = await fetch(NPM_REGISTRY, { signal: AbortSignal.timeout(CHECK_TIMEOUT_MS) });
39
+ if (!res.ok)
40
+ return null;
41
+ const data = (await res.json());
42
+ return data.version ?? null;
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ /**
49
+ * If a newer version exists on npm, respawn via `npx -y mnemos-capture@latest`
50
+ * with the original argv, piping stdio. Returns true if the caller should stop
51
+ * (because the child is taking over). Returns false otherwise — caller should
52
+ * continue with normal startup.
53
+ */
54
+ export async function maybeSelfUpgrade() {
55
+ // Recursion guard: the child spawned below will inherit this env var.
56
+ if (process.env.MNEMOS_UPGRADED === "1")
57
+ return false;
58
+ const current = getCurrentVersion();
59
+ const latest = await getLatestVersion();
60
+ if (!latest || !isNewer(latest, current))
61
+ return false;
62
+ process.stderr.write(`Mnemos: upgrading to v${latest} (was v${current})...\n`);
63
+ const child = spawn("npx", ["-y", `mnemos-capture@${latest}`, ...process.argv.slice(2)], {
64
+ stdio: "inherit",
65
+ env: { ...process.env, MNEMOS_UPGRADED: "1" },
66
+ });
67
+ // Keep parent alive until the child exits, then exit with its code.
68
+ await new Promise((resolve) => {
69
+ child.on("exit", (code) => {
70
+ process.exit(code ?? 0);
71
+ resolve();
72
+ });
73
+ child.on("error", () => {
74
+ // If spawn itself fails, fall through and let the parent continue
75
+ resolve();
76
+ });
77
+ });
78
+ return true;
79
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnemos-capture",
3
- "version": "1.0.6",
3
+ "version": "1.1.0",
4
4
  "description": "Zero-friction knowledge capture for agentic workflows. Paste anything → Claude extracts insights → auto-commits to your knowledge repo → your Claude Code workflow picks it up.",
5
5
  "type": "module",
6
6
  "bin": {