Agentmemory Deployment Lessons¶
Komodo Periphery + Bind Mounts¶
Bind mounts in compose.yaml resolve on the host, not inside the periphery container.
/etc/komodo/repos/docker-compose/only exists inside periphery — cannot use in compose volumes/mnt/user/appdata/is mounted from host into periphery — works in both contexts- Pre_deploy runs inside periphery → can access
/etc/komodo/repos/paths - Solution: pre_deploy copies files from repo path to
/mnt/user/appdata/, then compose mounts from/mnt/user/appdata/
Missing compose.env Causes Silent Failure¶
If TOML declares additional_env_files = ["compose.env"] but file doesn't exist, deploy fails with no useful error.
Fix: Only declare env files that exist. Remove the line if not needed.
iii-engine UID is 65532¶
iii-engine image runs as UID 65532 (nonroot), not 99:100 (nobody/Unraid standard).
- Wrong ownership →
Permission deniedon/data/state_store.dband/data/stream_store - Use init container (busybox) to chown, matching official docker-compose.yml pattern
- Set
user: "65532:65532"explicitly on iii-engine service
Storage is File-Based Only¶
iii-engine only has kv (SQLite file_based) and redis state adapters. No PostgreSQL adapter.
- agentmemory uses iii-engine KV state for all storage
iii-databaseworker is for SQL queries, NOT a state store replacement- Embeddings use in-memory vector index (BM25 + vector), not pgvector
Viewer UI is Static HTML¶
Viewer HTML served at /agentmemory/viewer on iii-engine REST port 3111. The built-in viewer server binds to 127.0.0.1:3113 inside container — cannot be accessed externally via Docker port mapping. VIEWER_HOST=0.0.0.0 is not recognized.
- Solution: nginx:alpine container proxying port 3113 → iii-engine:3111
- nginx.conf:
location /→/agentmemory/viewer,location /agentmemory/→ iii-engine:3111 (with WebSocket upgrade) - Pre_deploy must copy nginx.conf to
/mnt/user/appdata/agentmemory/ - Beware stale directories: if nginx.conf exists as a directory (from failed sync),
cpsilently fails. Remove directory first.
MCP Config¶
- MCP servers go in project
.mcp.json(not~/.claude/settings.local.json) - Add
.mcp.jsonto.gitignore(contains API keys) - Client-side env vars (GRAPH_EXTRACTION_ENABLED, EMBEDDING_PROVIDER, etc.) go in MCP env block, not server TOML
- MUST set
AGENTMEMORY_FORCE_PROXY=1to use remote server — without it, MCP starts local iii-engine - MUST set
AGENTMEMORY_SECRETin MCP env for auth with remote server
iii-engine REST API¶
All endpoints under /agentmemory/ prefix. Root returns 404.
- Health:
GET /agentmemory/livez(public),GET /agentmemory/health(auth) - Memory:
POST /agentmemory/remember,/search,/forget - Auth:
Authorization: Bearer <AGENTMEMORY_SECRET>
External Access: Bind 0.0.0.0¶
iii-config defaults to host: 127.0.0.1. Change to host: 0.0.0.0 for external access.
- iptables DNAT in pre_deploy silently fails (Komodo periphery context)
- socat on host network creates infinite loops
host: 0.0.0.0+ Tailscale is the correct solution
iii-engine Version Pin¶
Pinned to v0.11.2. v0.11.6+ introduces new sandbox worker model incompatible with agentmemory. Server binary auto-detects and refuses to start if version mismatch.
Semantic Search (BM25-Only)¶
Search works without vector embeddings. BM25-only mode returns conceptually-related results.
POST /agentmemory/search— finds related memories with different wordsPOST /agentmemory/smart-search— hybrid semantic+keyword- MCP
memory_recalluses smart-search under the hood
CLI Demo Doesn't Work with Auth¶
agentmemory demo fails with 401 against authenticated remote servers. CLI doesn't pass AGENTMEMORY_SECRET as Bearer header.
- Workaround: Seed via REST API with curl, or use MCP
memory_save
Observe API Requires Hook Fields¶
POST /agentmemory/observe needs: hookType, sessionId, project, cwd, timestamp. Content goes in prompt/response, not content. Use POST /agentmemory/remember or MCP memory_save for direct memory operations.
Komodo Sync: file_paths Only Lists Compose Files¶
Komodo validates every file in file_paths as Docker Compose. Non-compose files (iii-config, etc.) cause validation errors.
file_paths = ["compose.yaml", "iii-config.docker.yaml"]→ validation error:additional properties 'workers' not allowed- Fix:
file_paths = ["compose.yaml"]only. Pre_deploy copies config from run_directory (all files synced regardless of file_paths) file_pathstells Komodo WHICH files to validate as compose, not which to sync
agentmemory Server Requires AGENTMEMORY_URL + III_ENGINE_URL¶
The @agentmemory/agentmemory server needs BOTH env vars to connect to a separate iii-engine:
AGENTMEMORY_URL=http://iii-engine:3111— REST API base URL (tells server where agentmemory API lives)III_ENGINE_URL=ws://iii-engine:49134— WebSocket bridge protocol (tells server to connect to existing engine instead of spawning local)- Without
AGENTMEMORY_URL: server can't find REST endpoints - Without
III_ENGINE_URL: server tries to download and spawn local iii-engine binary → fails in container - Both containers must be on same Docker network for inter-container DNS resolution
iii-engine Bridge Protocol Port (49134)¶
iii-engine listens on port 49134 for the internal bridge protocol (separate from REST 3111 and Stream 3112).
- Port 49134 must be exposed if iii-engine runs in a separate container
- agentmemory connects via WebSocket:
ws://iii-engine:49134 - This is the primary connection method, NOT the REST API
Pending Sync Blocks Stack Creation¶
Komodo Resource Sync with pending_alert = true requires manual UI approval before creating new resources.
- Destroyed stacks are NOT recreated until pending changes are accepted in UI
- Disable
pending_alert(comment out) for automatic sync application - After disabling, run
run-sync root-syncsfirst to update sync config, thenrun-sync <category> - State transitions: Ok → Pending (changes detected) → Ok (after accept or auto-apply)
Reverse-Proxy Network Pattern¶
All unraid stacks use reverse-proxy external network + bind mounts from /mnt/user/appdata/.
- Bind mounts in compose resolve on HOST, not inside periphery container
- Pre_deploy copies config files from repo path to
/mnt/user/appdata/ - iii-config.docker.yaml:
host: 0.0.0.0required for external access (not 127.0.0.1) - Pattern: compose mounts
/mnt/user/appdata/<service>/config.yaml, pre_deploy copies from./config.yaml
Central Server Architecture (Verified)¶
- Server:
reverse-proxyexternal network + iii-confighost: 0.0.0.0on 3111/3112/49134 - Three containers: iii-engine (iiidev/iii:0.11.2) + server (node:20 running npx @agentmemory/agentmemory) + viewer (nginx:alpine)
- Server connects to iii-engine via
III_ENGINE_URL=ws://iii-engine:49134(bridge protocol) - Server also needs
AGENTMEMORY_URL=http://iii-engine:3111for REST API - Pre_deploy copies iii-config.docker.yaml + nginx.conf to
/mnt/user/appdata/agentmemory/ - Client:
.mcp.jsonwithAGENTMEMORY_URL,AGENTMEMORY_FORCE_PROXY=1,AGENTMEMORY_SECRET - No local iii-engine spawned with FORCE_PROXY=1
- All MCP ops (save, recall, search, forget) verified end-to-end
- Viewer at
http://<server>:3113/(nginx proxy to iii-engine:3111) - API also accessible at
http://<server>:3113/agentmemory/livez