@agentmemory/agentmemory 0.9.8 → 0.9.10

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
@@ -6,16 +6,30 @@
6
6
  <strong>
7
7
  Your coding agent remembers everything. No more re-explaining.
8
8
  Built on <a href="https://github.com/iii-hq/iii">iii engine</a>
9
- </strong></br>
10
- Persistent memory for Claude Code, Cursor, Gemini CLI, Codex CLI, pi, OpenCode, and any MCP client.
9
+ </strong><br/>
10
+ Persistent memory for Claude Code, Cursor, Gemini CLI, Codex CLI, Hermes, OpenClaw, pi, OpenCode, and any MCP client.
11
11
  </p>
12
12
 
13
13
  <p align="center">
14
- <a href="https://gist.github.com/rohitg00/2067ab416f7bbe447c1977edaaa681e2"><img src="https://img.shields.io/badge/Viral%20GitHub%20Gist-1050%20stars%20%2F%20150%20forks-FF6B35?style=for-the-badge&logo=github&logoColor=white&labelColor=1a1a1a" alt="Design doc: 1050 stars / 150 forks on the gist" /></a>
14
+ <a href="https://trendshift.io/repositories/25123" target="_blank"><img src="https://trendshift.io/api/badge/repositories/25123" alt="rohitg00/agentmemory | Trendshift" width="250" height="55"/></a>
15
15
  </p>
16
16
 
17
17
  <p align="center">
18
- <strong>The gist extends Karpathy's LLM Wiki pattern with confidence scoring, lifecycle, knowledge graphs, and hybrid search.<br/> agentmemory is the implementation.</strong>
18
+ <a href="https://www.star-history.com/?repos=rohitg00%2Fagentmemory&type=date&legend=top-left">
19
+ <picture>
20
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=rohitg00/agentmemory&type=date&theme=dark&legend=top-left" />
21
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=rohitg00/agentmemory&type=date&legend=top-left" />
22
+ <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=rohitg00/agentmemory&type=date&legend=top-left" />
23
+ </picture>
24
+ </a>
25
+ </p>
26
+
27
+ <p align="center">
28
+ <a href="https://gist.github.com/rohitg00/2067ab416f7bbe447c1977edaaa681e2"><img src="https://img.shields.io/badge/Viral%20GitHub%20Gist-1200%20stars%20%2F%20172%20forks-FF6B35?style=for-the-badge&logo=github&logoColor=white&labelColor=1a1a1a" alt="Design doc: 1200 stars / 172 forks on the gist" /></a>
29
+ </p>
30
+
31
+ <p align="center">
32
+ <em>The gist extends Karpathy's LLM Wiki pattern with confidence scoring, lifecycle, knowledge graphs, and hybrid search: agentmemory is the implementation.</em>
19
33
  </p>
20
34
 
21
35
  <p align="center">
@@ -345,13 +359,16 @@ Install agentmemory: run `npx @agentmemory/agentmemory` in a separate terminal t
345
359
  <summary><b>OpenClaw (paste this prompt)</b></summary>
346
360
 
347
361
  ```
348
- Install agentmemory for OpenClaw. Run `npx @agentmemory/agentmemory` in a separate terminal to start the memory server on localhost:3111. Then add this to my OpenClaw MCP config so agentmemory is available with all 43 memory tools:
362
+ Install agentmemory for OpenClaw. Run `npx @agentmemory/agentmemory` in a separate terminal to start the memory server on localhost:3111. Then add this to my OpenClaw MCP config so agentmemory is available with all 51 memory tools:
349
363
 
350
364
  {
351
365
  "mcpServers": {
352
366
  "agentmemory": {
353
367
  "command": "npx",
354
- "args": ["-y", "@agentmemory/mcp"]
368
+ "args": ["-y", "@agentmemory/mcp"],
369
+ "env": {
370
+ "AGENTMEMORY_URL": "http://localhost:3111"
371
+ }
355
372
  }
356
373
  }
357
374
  }
@@ -367,7 +384,7 @@ Full guide: [`integrations/openclaw/`](integrations/openclaw/)
367
384
  <summary><b>Hermes Agent (paste this prompt)</b></summary>
368
385
 
369
386
  ```
370
- Install agentmemory for Hermes. Run `npx @agentmemory/agentmemory` in a separate terminal to start the memory server on localhost:3111. Then add this to ~/.hermes/config.yaml so Hermes can use agentmemory as an MCP server with all 43 memory tools:
387
+ Install agentmemory for Hermes. Run `npx @agentmemory/agentmemory` in a separate terminal to start the memory server on localhost:3111. Then add this to ~/.hermes/config.yaml so Hermes can use agentmemory as an MCP server with all 51 memory tools:
371
388
 
372
389
  mcp_servers:
373
390
  agentmemory:
@@ -388,21 +405,37 @@ Full guide: [`integrations/hermes/`](integrations/hermes/)
388
405
 
389
406
  Start the memory server: `npx @agentmemory/agentmemory`
390
407
 
391
- Then add the MCP config for your agent:
408
+ The agentmemory entry is the **same MCP server block** across every host that uses the `mcpServers` shape (Cursor, Claude Desktop, Cline, Roo Code, Windsurf, Gemini CLI, OpenClaw):
392
409
 
393
- | Agent | Setup |
394
- |---|---|
395
- | **Cursor** | Add to `~/.cursor/mcp.json`: `{"mcpServers": {"agentmemory": {"command": "npx", "args": ["-y", "@agentmemory/mcp"]}}}` |
396
- | **OpenClaw** | Add to MCP config: `{"mcpServers": {"agentmemory": {"command": "npx", "args": ["-y", "@agentmemory/mcp"]}}}` or use the [memory plugin](integrations/openclaw/) |
397
- | **Gemini CLI** | `gemini mcp add agentmemory npx -y @agentmemory/mcp --scope user` |
398
- | **Codex CLI** | `codex mcp add agentmemory -- npx -y @agentmemory/mcp` or add `[mcp_servers.agentmemory]` to `.codex/config.toml` |
399
- | **pi** | Copy [`integrations/pi`](integrations/pi/) to `~/.pi/agent/extensions/agentmemory` and restart pi |
400
- | **OpenCode** | Add to `opencode.json`: `{"mcp": {"agentmemory": {"type": "local", "command": ["npx", "-y", "@agentmemory/mcp"], "enabled": true}}}` |
401
- | **Hermes Agent** | Add to `~/.hermes/config.yaml` with `memory.provider: agentmemory` or use the [memory provider plugin](integrations/hermes/) |
402
- | **Cline / Goose / Kilo Code** | Add MCP server in settings |
403
- | **Claude Desktop** | Add to `claude_desktop_config.json`: `{"mcpServers": {"agentmemory": {"command": "npx", "args": ["-y", "@agentmemory/mcp"]}}}` |
404
- | **Aider** | REST API: `curl -X POST http://localhost:3111/agentmemory/smart-search -d '{"query": "auth"}'` |
405
- | **Any agent (32+)** | `npx skillkit install agentmemory` |
410
+ ```json
411
+ "agentmemory": {
412
+ "command": "npx",
413
+ "args": ["-y", "@agentmemory/mcp"],
414
+ "env": {
415
+ "AGENTMEMORY_URL": "http://localhost:3111"
416
+ }
417
+ }
418
+ ```
419
+
420
+ **Merge this entry into the existing `mcpServers` object** in the host's config file — don't replace the file. If the file already has other servers, add `agentmemory` next to them as another key inside `mcpServers`. If `mcpServers` is missing entirely, paste the block inside `{ "mcpServers": { ... } }`.
421
+
422
+ | Agent | Config file | Notes |
423
+ |---|---|---|
424
+ | **Cursor** | `~/.cursor/mcp.json` | Merge into `mcpServers`. One-click deeplink also available on the website. |
425
+ | **Claude Desktop** | `claude_desktop_config.json` (Application Support) | Merge into `mcpServers`. Restart Claude Desktop after editing. |
426
+ | **Cline / Roo Code / Kilo Code** | Cline MCP settings (Settings UI → MCP Servers → Edit) | Same `mcpServers` block. |
427
+ | **Windsurf** | `~/.codeium/windsurf/mcp_config.json` | Same `mcpServers` block. |
428
+ | **Gemini CLI** | `~/.gemini/settings.json` | `gemini mcp add agentmemory npx -y @agentmemory/mcp --scope user` (auto-merges). |
429
+ | **OpenClaw** | OpenClaw MCP config | Same `mcpServers` block, or use the deeper [memory plugin](integrations/openclaw/). |
430
+ | **Codex CLI** | `.codex/config.toml` | TOML shape: `codex mcp add agentmemory -- npx -y @agentmemory/mcp`, or add `[mcp_servers.agentmemory]` manually. |
431
+ | **OpenCode** | `opencode.json` | Different shape — top-level `mcp` key, command as array: `{"mcp": {"agentmemory": {"type": "local", "command": ["npx", "-y", "@agentmemory/mcp"], "enabled": true}}}`. |
432
+ | **pi** | `~/.pi/agent/extensions/agentmemory` | Copy [`integrations/pi`](integrations/pi/) and restart pi. |
433
+ | **Hermes Agent** | `~/.hermes/config.yaml` | Use the deeper [memory provider plugin](integrations/hermes/) with `memory.provider: agentmemory`. |
434
+ | **Goose** | Goose MCP settings UI | Same `mcpServers` block. |
435
+ | **Aider** | n/a | Talk to the REST API directly: `curl -X POST http://localhost:3111/agentmemory/smart-search -d '{"query": "auth"}'`. |
436
+ | **Any agent (32+)** | n/a | `npx skillkit install agentmemory` auto-detects the host and merges. |
437
+
438
+ **Sandboxed MCP clients** (Flatpak / Snap / restrictive containers) that can't reach the host's `localhost`: also set `"AGENTMEMORY_FORCE_PROXY": "1"` in the `env` block, and point `AGENTMEMORY_URL` at a route the sandbox can actually reach (e.g. your LAN IP). See [#234](https://github.com/rohitg00/agentmemory/issues/234) for the diagnostic walkthrough.
406
439
 
407
440
  ### From source
408
441
 
@@ -701,18 +734,23 @@ npx -y @agentmemory/mcp # shim package alias
701
734
 
702
735
  Or add to your agent's MCP config:
703
736
 
704
- Most agents (Cursor, Claude Desktop, Cline, etc.):
737
+ Most agents (Cursor, Claude Desktop, Cline, Roo Code, Windsurf, Gemini CLI):
705
738
  ```json
706
739
  {
707
740
  "mcpServers": {
708
741
  "agentmemory": {
709
742
  "command": "npx",
710
- "args": ["-y", "@agentmemory/mcp"]
743
+ "args": ["-y", "@agentmemory/mcp"],
744
+ "env": {
745
+ "AGENTMEMORY_URL": "http://localhost:3111"
746
+ }
711
747
  }
712
748
  }
713
749
  }
714
750
  ```
715
751
 
752
+ Merge the `agentmemory` entry into your host's existing `mcpServers` object rather than replacing the file. For sandboxed clients that can't reach the host's `localhost`, add `"AGENTMEMORY_FORCE_PROXY": "1"` to the env block and set `AGENTMEMORY_URL` to a route the sandbox can reach.
753
+
716
754
  OpenCode (`opencode.json`):
717
755
  ```json
718
756
  {
package/dist/cli.mjs CHANGED
@@ -361,12 +361,12 @@ async function main() {
361
361
  p.intro("agentmemory");
362
362
  if (skipEngine) {
363
363
  p.log.info("Skipping engine check (--no-engine)");
364
- await import("./src-CMt8D9OY.mjs");
364
+ await import("./src-d1vwmuPU.mjs");
365
365
  return;
366
366
  }
367
367
  if (await isEngineRunning()) {
368
368
  p.log.success("iii-engine is running");
369
- await import("./src-CMt8D9OY.mjs");
369
+ await import("./src-d1vwmuPU.mjs");
370
370
  return;
371
371
  }
372
372
  if (!await startEngine()) {
@@ -410,7 +410,7 @@ async function main() {
410
410
  process.exit(1);
411
411
  }
412
412
  s.stop("iii-engine is ready");
413
- await import("./src-CMt8D9OY.mjs");
413
+ await import("./src-d1vwmuPU.mjs");
414
414
  }
415
415
  async function apiFetch(base, path, timeoutMs = 5e3) {
416
416
  try {
@@ -872,7 +872,7 @@ async function runUpgrade() {
872
872
  ].join("\n"), "agentmemory upgrade");
873
873
  }
874
874
  async function runMcp() {
875
- await import("./standalone-Ddgv2rHv.mjs");
875
+ await import("./standalone-DQrqCL0s.mjs");
876
876
  }
877
877
  async function runImportJsonl() {
878
878
  const VALUE_FLAGS = new Set(["--port", "--tools"]);
@@ -1,4 +1,18 @@
1
1
  services:
2
+ # One-shot init container: docker creates named volumes root:root mode
3
+ # 755, but the iii-engine image is distroless and runs as UID 65532
4
+ # with no `chown` of its own. Without this, /data is unwritable, the
5
+ # engine silently buffers in RAM, and state evaporates on every
6
+ # restart — the exact symptom v0.9.7's working-directory fix set out
7
+ # to solve. Runs once at compose-up and exits.
8
+ iii-init:
9
+ image: busybox:1.36
10
+ user: "0:0"
11
+ volumes:
12
+ - iii-data:/data
13
+ entrypoint: ["sh", "-c", "chown -R 65532:65532 /data && chmod 755 /data"]
14
+ restart: "no"
15
+
2
16
  iii-engine:
3
17
  # Pinned to v0.11.2 — the last engine that runs agentmemory's current
4
18
  # worker model cleanly. v0.11.6 introduces a new sandbox-everything-
@@ -10,6 +24,10 @@ services:
10
24
  # Override per-shell or via .env file:
11
25
  # AGENTMEMORY_III_VERSION=0.11.7 docker compose up
12
26
  image: iiidev/iii:${AGENTMEMORY_III_VERSION:-0.11.2}
27
+ user: "65532:65532"
28
+ depends_on:
29
+ iii-init:
30
+ condition: service_completed_successfully
13
31
  ports:
14
32
  - "127.0.0.1:49134:49134"
15
33
  - "127.0.0.1:3111:3111"
@@ -0,0 +1,3 @@
1
+ import { n as getImageRefCount, r as incrementImageRef, t as decrementImageRef } from "./src-d1vwmuPU.mjs";
2
+
3
+ export { decrementImageRef, incrementImageRef };
@@ -1,3 +1,3 @@
1
- import { a as deleteImage, c as saveImageToDisk, i as IMAGES_DIR, l as touchImage, o as getMaxBytes, s as isManagedImagePath } from "./src-CMt8D9OY.mjs";
1
+ import { a as deleteImage, c as saveImageToDisk, i as IMAGES_DIR, l as touchImage, o as getMaxBytes, s as isManagedImagePath } from "./src-d1vwmuPU.mjs";
2
2
 
3
3
  export { deleteImage, saveImageToDisk };
package/dist/index.mjs CHANGED
@@ -325,13 +325,13 @@ var AnthropicProvider = class {
325
325
  * The Anthropic SDK automatically injects `x-stainless-*` headers that MiniMax
326
326
  * rejects with 403. This provider bypasses the SDK and calls the API directly.
327
327
  *
328
- * Required env vars:
328
+ * Required env vars (loaded from ~/.agentmemory/.env or process.env):
329
329
  * MINIMAX_API_KEY — your MiniMax API key
330
330
  * MINIMAX_MODEL — model name (default: MiniMax-M2.7)
331
331
  * MAX_TOKENS — max output tokens (default: 800; MiniMax-M2.7 needs ≤800)
332
332
  *
333
333
  * Optional:
334
- * MINIMAX_BASE_URL — base URL without path (default: https://api.minimaxi.com/anthropic)
334
+ * MINIMAX_BASE_URL — base URL without path (default: https://api.minimax.io/anthropic)
335
335
  */
336
336
  var MinimaxProvider = class {
337
337
  name = "minimax";
@@ -343,7 +343,7 @@ var MinimaxProvider = class {
343
343
  this.apiKey = apiKey;
344
344
  this.model = model;
345
345
  this.maxTokens = maxTokens;
346
- this.baseUrl = process.env["MINIMAX_BASE_URL"] || "https://api.minimaxi.com/anthropic";
346
+ this.baseUrl = getEnvVar("MINIMAX_BASE_URL") || "https://api.minimax.io/anthropic";
347
347
  }
348
348
  async compress(systemPrompt, userPrompt) {
349
349
  return this.call(systemPrompt, userPrompt);
@@ -3409,6 +3409,23 @@ async function seedDefaults(kv) {
3409
3409
  await kv.set(target, tmpl.label, slot);
3410
3410
  }
3411
3411
  }
3412
+ async function listPinnedSlots(kv) {
3413
+ const [project, global] = await Promise.all([kv.list(KV.slots), kv.list(KV.globalSlots)]);
3414
+ const merged = /* @__PURE__ */ new Map();
3415
+ for (const s of global) merged.set(s.label, s);
3416
+ for (const s of project) merged.set(s.label, s);
3417
+ return Array.from(merged.values()).filter((s) => s.pinned && s.content.trim().length > 0).sort((a, b) => a.label.localeCompare(b.label));
3418
+ }
3419
+ function renderPinnedContext(slots) {
3420
+ if (slots.length === 0) return "";
3421
+ const lines = ["# agentmemory pinned slots", ""];
3422
+ for (const slot of slots) {
3423
+ lines.push(`## ${slot.label}`);
3424
+ lines.push(slot.content.trim());
3425
+ lines.push("");
3426
+ }
3427
+ return lines.join("\n");
3428
+ }
3412
3429
  function registerSlotsFunctions(sdk, kv) {
3413
3430
  seedDefaults(kv).catch((err) => {
3414
3431
  logger.warn("slot defaults seed failed", { error: err instanceof Error ? err.message : String(err) });
@@ -4175,7 +4192,14 @@ function registerContextFunction(sdk, kv, tokenBudget) {
4175
4192
  sdk.registerFunction("mem::context", async (data) => {
4176
4193
  const budget = data.budget || tokenBudget;
4177
4194
  const blocks = [];
4178
- const profile = await kv.get(KV.profiles, data.project).catch(() => null);
4195
+ const [pinnedSlots, profile] = await Promise.all([isSlotsEnabled() ? listPinnedSlots(kv).catch(() => []) : Promise.resolve([]), kv.get(KV.profiles, data.project).catch(() => null)]);
4196
+ const slotContent = renderPinnedContext(pinnedSlots);
4197
+ if (slotContent) blocks.push({
4198
+ type: "memory",
4199
+ content: slotContent,
4200
+ tokens: estimateTokens$1(slotContent),
4201
+ recency: Date.now()
4202
+ });
4179
4203
  if (profile) {
4180
4204
  const profileParts = [];
4181
4205
  if (profile.topConcepts.length > 0) profileParts.push(`Concepts: ${profile.topConcepts.slice(0, 8).map((c) => c.concept).join(", ")}`);
@@ -4232,7 +4256,7 @@ function registerContextFunction(sdk, kv, tokenBudget) {
4232
4256
  const footer = `</agentmemory-context>`;
4233
4257
  usedTokens += estimateTokens$1(header) + estimateTokens$1(footer);
4234
4258
  for (const block of blocks) {
4235
- if (usedTokens + block.tokens > budget) break;
4259
+ if (usedTokens + block.tokens > budget) continue;
4236
4260
  selected.push(block.content);
4237
4261
  usedTokens += block.tokens;
4238
4262
  if (block.sourceIds && block.sourceIds.length > 0) accessedIds.push(...block.sourceIds);
@@ -5731,7 +5755,7 @@ function registerAutoForgetFunction(sdk, kv) {
5731
5755
 
5732
5756
  //#endregion
5733
5757
  //#region src/version.ts
5734
- const VERSION = "0.9.8";
5758
+ const VERSION = "0.9.10";
5735
5759
 
5736
5760
  //#endregion
5737
5761
  //#region src/functions/export-import.ts
@@ -5857,7 +5881,9 @@ function registerExportImportFunction(sdk, kv) {
5857
5881
  "0.9.5",
5858
5882
  "0.9.6",
5859
5883
  "0.9.7",
5860
- "0.9.8"
5884
+ "0.9.8",
5885
+ "0.9.9",
5886
+ "0.9.10"
5861
5887
  ]).has(importData.version)) return {
5862
5888
  success: false,
5863
5889
  error: `Unsupported export version: ${importData.version}`