docker-compose.yml mounts `./iii-config.docker.yaml:/app/config.yaml:ro`
but the `files` array in package.json only shipped `iii-config.yaml`.
Docker resolves missing bind sources by silently creating them as empty
directories, so `npx @agentmemory/agentmemory` mounted an empty dir at
/app/config.yaml and iii-engine crashed with:
Error: Failed to read config file '/app/config.yaml':
Is a directory (os error 21)
Fix: add iii-config.docker.yaml to package.json `files`.
Also adds a regression test in test/consistency.test.ts that parses
every `./<path>:<container>` bind mount in docker-compose.yml and
asserts the source file is shipped via the `files` array, so this
class of bug can't reach a release again.
Bumps main package + shim to 0.8.7 and adds CHANGELOG [0.8.7].
0.8.5's publish workflow got blocked on the unscoped `agentmemory-mcp`
name by npm's name-similarity policy (there's an unrelated third-party
package called `agent-memory-mcp`). Publishing the shim under the
`@agentmemory` scope we already own sidesteps the conflict.
Changes:
- Rename packages/agentmemory-mcp → packages/mcp
- Package name: agentmemory-mcp → @agentmemory/mcp (0.8.4 → 0.8.6)
- Keep bin name `agentmemory-mcp` so `npm i -g @agentmemory/mcp`
still installs a binary at `agentmemory-mcp` for muscle memory
- Log prefix [agentmemory-mcp] → [@agentmemory/mcp] in standalone.ts
and in-memory-kv.ts
- README / integrations/openclaw / integrations/hermes / src/cli.ts
all point at `npx -y @agentmemory/mcp`
- .github/workflows/publish.yml working-directory and npm view queries
target packages/mcp and @agentmemory/mcp
- Shim dependency on @agentmemory/agentmemory bumped to ~0.8.6
- Main package 0.8.5 → 0.8.6 across the 8 version files
- CHANGELOG [0.8.6] entry documenting the scope move
Two community contributions on top of 0.8.3 land as a patch release so
they reach users immediately and so `npx agentmemory-mcp` ships to the
npm registry for the first time (closing out #120 on the live release).
- #122 (Jason Landbridge): memory_save persists to disk immediately
after every call, not just on SIGINT/SIGTERM, so memories survive
SIGKILL from agent sessions ending forcefully
- #121 (Jason Landbridge): OpenCode MCP config format corrected —
opencode.json with mcp/type:local/command array instead of the
wrong .opencode/config.json with mcpServers
Version bumped across package.json, src/version.ts, types.ts,
export-import supportedVersions, plugin.json, shim package.json and
its dependency on the main package (~0.8.4). package-lock.json
regenerated. 684 tests passing, clean build.
* fix: retention scoring (#119) + npx agentmemory-mcp 404 (#120), release 0.8.3
Issue #119 — retention score ignored agent-side reads
`mem::retention-score` previously hardcoded `accessCount=0` and
`accessTimestamps=[]` for episodic memories and used only a single-sample
`lastAccessedAt` for semantic memories, so the time-frequency decay
formula was a dead path. All read endpoints now record access events to
a new `mem:access` KV namespace via a keyed-mutex'd access tracker:
- mem::search, mem::smart-search (compact + expand), mem::context,
mem::timeline, mem::file-context, mem::get-related, mem::working-context
- retention.ts pre-fetches the full access log in one kv.list call,
normalizes every row defensively, and builds an O(1) lookup Map
- recordAccessBatch uses Promise.allSettled so a slow keyed-lock on one
id does not block the rest of the batch
- Bounded ring buffer of the last 20 access timestamps per memory
- Backwards-compat fallback: pre-0.8.3 semantic memories with only the
legacy sem.lastAccessedAt still score correctly
- Corrupt lastAccessedAt values are NaN-safe via Date.parse + isFinite
- reinforcementBoost is reported as the raw formula output, not the
clamped residual
Memory deletion sites (retention-evict, evict, auto-forget,
governance-delete, governance-bulk, forget, import replace) now call
deleteAccessLog to prevent mem:access from accumulating zombie entries.
mem::export / mem::import and mem::snapshot-create / mem::snapshot-restore
round-trip the new namespace so backup/restore cycles no longer zero out
reinforcement signals.
Issue #120 — npx agentmemory-mcp returned npm registry 404
The README instructed users to run `npx agentmemory-mcp`, but
`agentmemory-mcp` only existed as a `bin` entry inside
`@agentmemory/agentmemory`, not a real registry package. Two-part fix:
- New sibling package `packages/agentmemory-mcp/` — a thin shim that
depends on `@agentmemory/agentmemory` (~0.8.3, tilde to block 0.9.x
supply-chain drift) and forwards to dist/standalone.mjs via the new
`exports` field on the main package
- Canonical `npx @agentmemory/agentmemory mcp` subcommand on the CLI
for users who already have the main package installed
- Removed the dead `agentmemory-mcp` bin from the main package so the
shim owns the name unambiguously
- publish.yml publishes both packages in order with idempotent
guards and npm-view registry polling (no more fixed sleep)
- All MCP install snippets in README + integrations/openclaw + hermes
+ shim README use `npx -y agentmemory-mcp` to skip install prompts
Release 0.8.3
- 670 tests passing (665 + 11 new: access tracker, retention,
smart-search integration, corrupt-input, kv.list failure path,
Promise.allSettled resilience)
- Version bumped across package.json, src/version.ts, types.ts,
export-import supportedVersions, plugin.json
- package-lock.json regenerated
* fix: address CodeRabbit review feedback on #123
Real issues caught and fixed:
- access-tracker: deleteAccessLog now takes the same mem:access:<id>
keyed mutex used by recordAccess, eliminating the race where a
concurrent delete could drop an in-flight RMW update and leave a
stale access log for an evicted memory
- access-tracker: normalizeAccessLog now coerces count to a
non-negative integer, drops non-finite recent[] entries, truncates
recent[] to the last 20 on read (enforcing the ring-buffer invariant),
and guarantees count >= recent.length so a malformed row can't produce
NaN downstream. count is NOT capped at 20 — it is the lifetime access
counter, while recent[] is the 20-entry window
- export-import: import path now rejects accessLogs arrays above
MAX_ACCESS_LOGS (50_000), normalizes each entry via
normalizeAccessLog, and drops entries whose memoryId is not in the
imported memories set, so a crafted export can't blow up memory or
resurrect zombie access rows for memories that don't exist
- publish.yml: added a post-publish npm view polling loop for
agentmemory-mcp mirroring the one that already guards the main
package, so the workflow only succeeds when `npx agentmemory-mcp` is
actually visible on the registry
- CHANGELOG.md: added the missing [0.8.3] reference-style link target
at the bottom to match the [0.8.2]/[0.8.1]/[0.8.0] pattern
- README.md: standalone MCP inline examples now use `npx -y` to match
the MCP config snippets and skip the install confirmation prompt
Tests: 680/680 (+10 new — deleteAccessLog behavior, normalizeAccessLog
invariants, malformed mem:access row handling in retention scoring).
Findings deliberately not applied:
- auto-forget.ts / remember.ts / evict.ts recordAudit calls: existing
pattern in the codebase only audits governance deletes (user-initiated
admin actions), not automatic eviction. Adding audit everywhere is a
policy change, out of scope for this PR
- evict.ts gating deleteAccessLog on memory delete success: current
order is defensible, deleteAccessLog is already best-effort with its
own try/catch, and calling it after a failed memory delete is harmless
- snapshot.ts fail-fast on kv.list failure: inconsistent with the
existing .catch(() => []) pattern used for observations in the same
function
- retention.ts semantic evict only deletes KV.memories rows: real bug
but pre-existing on main (RetentionScore has no source/type field).
Tracked separately — out of scope for this PR
- bin.mjs fallback command: already present in the existing catch
handler
- Promise.all parallelization of delete+deleteAccessLog: micro
optimization not worth the readability cost
Fixes 6 security issues in agentmemory's default deployment, viewer, mesh sync, export path, and startup flow.
## Findings Addressed
1. **Default REST/stream exposure on 0.0.0.0** — bind default REST and stream services to 127.0.0.1; restrict Docker port publishing to localhost; add dedicated iii-config.docker.yaml for Docker usage.
2. **Stored XSS via inline viewer handlers** — remove inline event handlers from the viewer; replace with delegated data-action event handling; switch to nonce-based CSP for viewer HTML; add script-src-attr 'none'.
3. **Arbitrary path writes in Obsidian export** — confine exports to AGENTMEMORY_EXPORT_ROOT (default ~/.agentmemory); reject vaultDir values outside the allowed root.
4. **Mesh sync without peer auth** — require AGENTMEMORY_SECRET for mesh endpoints and sync operations; send Authorization: Bearer <secret> on mesh push/pull requests.
5. **Secret redaction misses modern token formats** — add coverage for Bearer tokens, sk-proj-*, broader sk/pk/rk/ak variants, GitHub ghs_/ghu_ tokens.
6. **CLI executes remote shell script directly** — remove curl|sh installation pattern; use existing local iii-engine binary if available, otherwise fall back to Docker.
## Validation
- 654 tests passing (8 new security tests)
- npm run build succeeds
- Merged with main and resolved README conflicts to preserve the new benchmark/competitor table layout
Thanks @eng-pf for catching these and submitting the fixes.
Build script now copies src/viewer/index.html to dist/viewer/.
Also added more candidate paths for index.html resolution so
the viewer works from dist/ (npx), src/ (tsx dev), and repo root.
- Update zod from ^3.23.0 to ^4.0.0 (claude-agent-sdk peer dep conflict)
- Mount iii-config.yaml in docker-compose.yml (missing /app/config.yaml)
- Change host binding from 127.0.0.1 to 0.0.0.0 for Docker compatibility
- Switch npm start from index.mjs to cli.mjs (auto-starts iii-engine)
- Fix CLI health check to detect engine via any HTTP response, not just worker route
- Handle EADDRINUSE on viewer port gracefully instead of crashing
- Fix README step numbering and version in health example
- Fix main/bin/start to use .mjs extension (tsdown outputs ESM)
- Remove duplicate shebang banner from standalone build config
- Update integration test: health status "healthy" (v0.4.0), viewer HTML check
- Add POST body to pre-compact hook for claude-bridge sync
* feat: agentmemory v0.4.0 — the memory layer for all AI coding agents
7 new features: Claude Code memory bridge, standalone cross-agent MCP server,
knowledge graph with entity extraction, 4-tier memory consolidation pipeline,
team/shared memory, memory governance with audit trail, git-versioned snapshots.
33 functions, 18 MCP tools, 6 MCP resources, 3 MCP prompts, 49 REST endpoints,
21 KV scopes, 216 tests. All features opt-in via env vars.
* fix: address 28 CodeRabbit findings across v0.4.0 codebase
Critical: Fix bin path mismatch (dist/mcp-standalone.mjs -> dist/standalone.mjs)
Bugs: Fix procedural decay, parseFloat||0.5 for zero values, snapshot restore
missing graphNodes/observations, git catch too broad, N+1 graph query, BFS
duplicate edges, array mutation in audit sort, date validation
Improvements: Lazy readline in transport, JSON-RPC validation, persist error
handling, ID collision prevention, defensive null coalescing for concepts/files,
Windows backslash support in config, direction required for bridge sync tool,
try-catch for audit/governance MCP, team profile fallback teamId, POST body for
bridge sync hook, observations validation for graph-extract endpoint, await in test
* feat: agentmemory v0.4.0 — MCP resources, prompts, enrichment, confidence
Add 4 MCP resources (status, project profile, recent sessions, latest memories),
3 MCP prompts (recall_context, session_handoff, detect_patterns), confidence-scored
memory relations, and a unified enrich endpoint that aggregates file context,
relevant observations, and past bug memories for PreToolUse hook injection.
- Add confidence field to MemoryRelation with auto-scoring from co-occurrence,
recency, and relation type
- Add mem::enrich function aggregating 3 sources with resilient .catch() fallbacks
- Add POST /agentmemory/enrich REST endpoint
- Switch PreToolUse hook from file-context to enrich endpoint with search term extraction
- Add minConfidence filter and confidence-desc sorting to mem::get-related
- 27 new tests (171 total), all passing
* fix: address review findings — input validation, XML escaping, confidence scoring
- enrich.ts: Sort bug memories by recency before slicing top 3; add escapeXml()
for narratives and bug content injected into XML tags
- relations.ts: Use filter+max instead of find() for matchingRelation to pick
highest confidence when multiple edges exist; normalize minConfidence with
Number.isFinite + clamp to [0,1]
- mcp/server.ts: Guard decodeURIComponent with try/catch returning 400 on
malformed percent-encoding; use typeof checks for prompt args instead of
truthy checks; normalize minConfidence/maxHops at MCP layer
- api.ts: Validate files[] and terms[] element types are strings before
calling mem::enrich
- Tests: Add malformed URI and non-string prompt arg test cases (173 total)
New hooks (7):
- PreToolUse: inject file history before edits (Edit/Write/Read/Glob/Grep)
- PostToolUseFailure: capture error patterns for learning
- PreCompact: preserve memory context through compaction
- SubagentStart/SubagentStop: track multi-agent workflows
- Notification: capture permission prompts (tool preferences)
- TaskCompleted: track team task completions
New functions (4):
- mem::file-context: file-centric memory index for PreToolUse
- mem::consolidate: merge observations into long-term memories via LLM
- mem::patterns + mem::generate-rules: detect co-change patterns and recurring errors
- mem::remember + mem::forget: explicit save/delete for long-term memory
MCP server (2 endpoints):
- GET /agentmemory/mcp/tools: list 5 MCP tools (recall, save, file_history, patterns, sessions)
- POST /agentmemory/mcp/call: dispatch tool calls to iii functions
Skills (4):
- /recall [query]: search past observations
- /remember [insight]: save to long-term memory
- /session-history: show past session timeline
- /forget [target]: delete specific memory data
New API endpoints (7):
- POST /agentmemory/file-context
- POST /agentmemory/remember
- POST /agentmemory/forget
- POST /agentmemory/consolidate
- POST /agentmemory/patterns
- POST /agentmemory/generate-rules
- GET/POST /agentmemory/mcp/*
Updated: types (7 new HookTypes, 3 new ObservationTypes), version 0.2.0
- Add integration test suite covering all 11 API endpoints
- Rewrite README for clarity and user-friendliness
- Extract VIEWER_CSP constant, remove dead IndexEntry.terms field
- Consolidate SIGINT/SIGTERM handlers