Skip to content

fix(mcp): probe diagnostics + sandbox escape hatch (#234, #278)#280

Merged
rohitg00 merged 2 commits into
mainfrom
fix/234-shim-probe-diagnostics
May 11, 2026
Merged

fix(mcp): probe diagnostics + sandbox escape hatch (#234, #278)#280
rohitg00 merged 2 commits into
mainfrom
fix/234-shim-probe-diagnostics

Conversation

@rohitg00
Copy link
Copy Markdown
Owner

@rohitg00 rohitg00 commented May 11, 2026

Summary

Three small follow-ups to v0.9.6 from live field reports on #234 and #278.

Root cause walkthrough

Why Roo Code in VS Codeium (Flatpak) saw 7 tools while the host shell saw 51

host shell                Flatpak (VS Codeium)
─────────────             ──────────────────────
curl localhost:3111       (Roo Code spawns shim)
  ↓                         ↓
livez 200 OK              connect: ECONNREFUSED
  ↓                         ↓ (catch swallows it)
proxy mode → 51 tools     local mode → IMPLEMENTED_TOOLS (7)

The probe in src/mcp/rest-proxy.ts:31 had:

} catch {
  return false;
}

No log line. 500ms timeout. The fix surfaces every failure with the URL, the HTTP status (or thrown reason), and the active timeout, so users actually see why they fell into local mode instead of staring at a 7-tool list with no explanation.

For Flatpak / Snap / network-restricted clients that genuinely can't probe but can reach the server through some other route (LAN IP, configured upstream, sidecar), AGENTMEMORY_FORCE_PROXY=1 short-circuits the probe and trusts AGENTMEMORY_URL directly.

Why docker compose down wiped state

docker-compose.yml:           iii-config.docker.yaml:
  volumes:                      iii-state:
    - iii-data:/data              file_path: ./data/state_store.db
                                                ^^^^^^
                                  resolved against WORKDIR=/home/nonroot
                                  inside container → /home/nonroot/data/...
                                  NOT /data (the volume mount).

So every write went to the ephemeral container layer, not the named volume, and docker compose down discarded it. Bumping both paths to absolute (/data/state_store.db, /data/stream_store) routes them through the volume the compose file always intended.

Migration note for existing users: one-time docker compose down -v to drop the (empty) old volume layout, then docker compose up — fresh data goes to the right place from then on.

Changes

  • src/mcp/rest-proxy.ts — log probe failures to stderr; 500ms → 2000ms default; AGENTMEMORY_PROBE_TIMEOUT_MS knob; AGENTMEMORY_FORCE_PROXY=1 skip-probe escape hatch.
  • src/cli.ts — pipe which's stderr in whichBinary().
  • iii-config.docker.yaml — absolute file_path for iii-state and iii-stream.
  • docker-compose.ymllogging.driver: json-file + max-size: 10m + max-file: 3 on the iii-engine service.
  • Version bump 0.9.6 → 0.9.7 across package.json, packages/mcp/package.json, plugin/.claude-plugin/plugin.json, src/version.ts, the ExportData literal in src/types.ts, the supportedVersions set in src/functions/export-import.ts, and the round-trip test in test/export-import.test.ts.
  • test/mcp-standalone-proxy.test.ts — 4 new tests:
    • AGENTMEMORY_FORCE_PROXY=1 skips the livez probe and forwards directly.
    • Probe failure writes diagnostic to stderr with AGENTMEMORY_FORCE_PROXY hint.
    • AGENTMEMORY_PROBE_TIMEOUT_MS overrides the default probe timeout.
    • (Plus tightening on existing tests for the new stderr writes.)

Test plan

  • npm test — 859/859 pass on this branch (baseline: 856 on main; +3 net new tests).
  • npm run build — clean tsdown build, no type errors.
  • Smoke test in a sandboxed MCP client (Flatpak VS Codeium → Roo Code) after publish — set AGENTMEMORY_FORCE_PROXY=1, expect 51 tools.
  • Smoke test docker compose down && docker compose up — verify /data/state_store.db persists across restarts.

Out of scope (filed separately)

Summary by CodeRabbit

  • Bug Fixes

    • CLI banner no longer leaks system errors
    • Container logs now rotate/capped to prevent disk growth (≈30MB)
    • Engine state is preserved across service restarts
  • New Features

    • Health-probe timeout is configurable via environment variable
    • Escape hatch to bypass health checks when needed
    • Improved probe diagnostics and proxy logging
  • Chores

    • Bumped version to 0.9.7

Review Change Stack

Three small follow-ups to v0.9.6 reported live on #234 and #278:

1. @agentmemory/mcp shim silently degraded to 7-tool local fallback for
   sandboxed MCP clients (Flatpak VS Codeium / Roo Code) because the
   500ms livez probe failed inside the sandbox network namespace and the
   catch swallowed the error. Probe now logs the URL, status, and reason
   to stderr; default timeout raised to 2000ms; AGENTMEMORY_PROBE_TIMEOUT_MS
   overrides the timeout; AGENTMEMORY_FORCE_PROXY=1 skips the probe and
   trusts AGENTMEMORY_URL outright for sandboxed clients that can reach
   the server through a known route but not the host loopback. Closes
   the #234 follow-up reported by @jcalfee.

2. Docker compose stack persisted state to an ephemeral container path.
   iii-config.docker.yaml used file_path: ./data/state_store.db, which
   the engine resolved against its container WORKDIR=/home/nonroot --
   not the /data mount where iii-data is bound. State and stream stores
   were silently written to the container layer and lost on every
   docker compose down. Paths are now absolute (/data/state_store.db
   and /data/stream_store). Existing users need a one-time docker
   compose down -v before upgrade.

3. CLI banner leaked "which: no iii in ..." when iii wasn't on PATH.
   execFileSync default stdio inherits stderr; GNU which writes the
   miss line to stderr (exit 1). Switched to explicit
   stdio: ["ignore", "pipe", "pipe"] in whichBinary().

4. docker-compose.yml now caps engine container log size at 30MB total
   (json-file driver, max-size=10m, max-file=3) so the iiidev/iii
   crash/restart spam reported by @satabd in #278 can no longer fill
   the host disk. The upstream engine spam itself needs filing against
   iii-hq/iii -- this is the compose-side guardrail.

Version 0.9.6 -> 0.9.7 across package.json, packages/mcp/package.json,
plugin/.claude-plugin/plugin.json, src/version.ts, src/types.ts
ExportData literal, src/functions/export-import.ts supportedVersions,
and the export round-trip test expectation.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agentmemory Ready Ready Preview, Comment May 11, 2026 0:46am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0cd970bf-b62d-4dda-9de6-27769d769841

📥 Commits

Reviewing files that changed from the base of the PR and between 89e9672 and b9c4336.

📒 Files selected for processing (1)
  • src/mcp/standalone.ts

📝 Walkthrough

Walkthrough

v0.9.7 patch release bumps version across manifests and types, adds configurable MCP proxy health-probe timeout and an AGENTMEMORY_FORCE_PROXY escape hatch with enhanced stderr logging, switches Docker KV adapter paths to absolute container mount paths for persistence, captures CLI stdio to suppress which/where noise, expands export-import version validation, and updates tests and changelog.

Changes

Release v0.9.7

Layer / File(s) Summary
Version & Type Declarations
src/version.ts, src/types.ts
VERSION constant and ExportData.version type union are updated to include "0.9.7".
Package Manifests
package.json, packages/mcp/package.json, plugin/.claude-plugin/plugin.json
Version fields are incremented from 0.9.6 to 0.9.7 across root and scoped packages.
MCP Proxy Enhancements
src/mcp/rest-proxy.ts
Probe timeout becomes configurable via AGENTMEMORY_PROBE_TIMEOUT_MS environment variable with default; AGENTMEMORY_FORCE_PROXY=1 toggle skips /agentmemory/livez probe and trusts resolved base URL; probe failures now log detailed diagnostics (elapsed time, error message) to stderr.
Standalone MCP Handler
src/mcp/standalone.ts
tools/list handler adds AGENTMEMORY_DEBUG-gated logging, validates proxied /agentmemory/mcp/tools response shape, and falls back to local visible tools when remote response is malformed.
Docker Infrastructure
docker-compose.yml, iii-config.docker.yaml
iii-engine service adds json-file logging with max-size: 10m and max-file: 3; KV adapter file_path values changed from ./data/... to /data/... for correct mounted persistence.
CLI Improvements
src/cli.ts
whichBinary() explicitly configures stdio to ignore stdin and pipe stdout/stderr, preventing spurious stderr output from which/where.
Export-Import Version Support
src/functions/export-import.ts
Supported versions set expanded to accept 0.9.7 exports in mem::import validation.
Tests & Changelog
test/mcp-standalone-proxy.test.ts, test/export-import.test.ts, CHANGELOG.md
Tests added/updated to cover force-proxy, probe logging, timeout override, and export version; changelog documents v0.9.7 (2026-05-11).

Sequence Diagram(s)

sequenceDiagram
  participant resolveHandle as resolveHandle()
  participant forceProxy as AGENTMEMORY_FORCE_PROXY
  participant probeTimeout as AGENTMEMORY_PROBE_TIMEOUT_MS
  participant probe as probe(url)
  participant proxy as Remote MCP
  participant standalone as Standalone MCP
  resolveHandle->>forceProxy: read flag
  alt Force proxy enabled
    resolveHandle-->>proxy: trust base URL (no probe)
    proxy-->>resolveHandle: proxy handle returned
  else Normal mode
    resolveHandle->>probeTimeout: read timeout
    resolveHandle->>probe: call /agentmemory/livez with timeout
    probe->>proxy: HTTP GET /agentmemory/livez
    alt Probe OK
      proxy-->>probe: 200 OK
      probe-->>resolveHandle: up=true
      resolveHandle-->>proxy: return proxy handle
    else Probe fails
      probe-->>resolveHandle: log stderr (elapsed + error)
      resolveHandle-->>standalone: return local handle (fallback)
    end
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 A hop, a skip, a version's flight,
To 0.9.7, shining bright!
With timeouts set and proxies forced,
And Docker paths on proper course,
The CLI hushed, the tests all gleam. 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(mcp): probe diagnostics + sandbox escape hatch (#234, #278)' accurately describes the main changes: MCP probe improvements with diagnostics and the escape hatch feature (AGENTMEMORY_FORCE_PROXY), addressing the specified issues.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/234-shim-probe-diagnostics

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Line 9: The changelog entry "## [0.9.7] — 2026-05-11" references a missing
link target; add a matching reference-link definition for "[0.9.7]" in the link
table at the bottom of CHANGELOG.md using the same format as the other releases
(i.e., a `[0.9.7]: <compare-URL-or-tag>` line that points to the repo's compare
or tag URL for 0.9.7 so the header resolves correctly).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8874c10f-6dc2-4bfa-8fcd-b22f096033a9

📥 Commits

Reviewing files that changed from the base of the PR and between 13924d2 and 89e9672.

📒 Files selected for processing (13)
  • CHANGELOG.md
  • docker-compose.yml
  • iii-config.docker.yaml
  • package.json
  • packages/mcp/package.json
  • plugin/.claude-plugin/plugin.json
  • src/cli.ts
  • src/functions/export-import.ts
  • src/mcp/rest-proxy.ts
  • src/types.ts
  • src/version.ts
  • test/export-import.test.ts
  • test/mcp-standalone-proxy.test.ts

Comment thread CHANGELOG.md

## [Unreleased]

## [0.9.7] — 2026-05-11
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add the missing [0.9.7] reference link target.

Line 9 uses reference-link syntax ([0.9.7]), but the corresponding definition is missing in the link table, so this entry won’t resolve to a compare URL.

📎 Proposed doc fix
+[0.9.7]: https://github.com/rohitg00/agentmemory/compare/v0.9.6...v0.9.7
 [0.9.6]: https://github.com/rohitg00/agentmemory/compare/v0.9.5...v0.9.6
 [0.9.5]: https://github.com/rohitg00/agentmemory/compare/v0.9.4...v0.9.5
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` at line 9, The changelog entry "## [0.9.7] — 2026-05-11"
references a missing link target; add a matching reference-link definition for
"[0.9.7]" in the link table at the bottom of CHANGELOG.md using the same format
as the other releases (i.e., a `[0.9.7]: <compare-URL-or-tag>` line that points
to the repo's compare or tag URL for 0.9.7 so the header resolves correctly).

@jcalfee on #234 confirmed the v0.9.6 fix (and PR #280's escape hatch)
still surfaces 7 tools in Roo Code even though:
  - Flatpak share=network is on (probe succeeds via curl in-sandbox)
  - server's /agentmemory/mcp/tools returns 51 tools via curl
  - AGENTMEMORY_FORCE_PROXY=1 is set

Roo Code shows 7 tools even when docker is down -- strong signal of
client-side caching at the Roo Code layer, not a shim regression.
But the shim has zero visibility into what it actually returns to
the MCP client right now: success path is silent, only failure paths
log.

Add AGENTMEMORY_DEBUG=1 (or =true) so the shim writes to stderr:
  - which mode handle.mode resolved to (proxy vs local) and baseUrl
  - shape of the /agentmemory/mcp/tools response (keys + tools type)
  - count of tools returned to the MCP client
  - tool names in the local-fallback list if we hit it

Also: previously, when the server returned a JSON shape that wasn't
{tools: Array}, the shim silently fell back to the 7-tool local list
with no log line. Now that path warns to stderr unconditionally,
pointing at AGENTMEMORY_DEBUG=1 for inspection.

This is diagnosis enablement -- not a fix for whatever is making
Roo Code show 7 tools. Once @jcalfee can run the shim with
AGENTMEMORY_DEBUG=1 and share the stderr output, we'll know whether
the shim returns 51 (Roo Code bug) or 7 (deeper shim bug).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant