feat(pi-bridge): external MemPalace transport via MEMPALACE_REMOTE_URL
Let the pi<->mempalace bridge connect to a shared MemPalace over HTTP instead of always spawning a local mempalace-mcp: - Extract IMcpClient; rename McpClient -> StdioMcpClient (ctor command, arg-less start()). - Add RemoteMcpClient (vendored from pi-extensions/mcp-loader.ts): streamable-HTTP with AbortController timeouts, protocolVersion pinned 2024-11-05, alive/ensureAlive. mempalace-mcp --transport http is sessionless JSON-RPC today; session/SSE/404 branches retained for a future streamable-HTTP server. - createClient() selects transport from MEMPALACE_REMOTE_URL; MEMPALACE_REMOTE_TOKEN -> Authorization: Bearer. Lifecycle automation (wake-up, /mempalace-diary) unchanged. - scripts/check-mcp-client-sync.sh: drift guard vs canonical mcp-loader.ts. - README: document local-vs-external transport. Typechecks clean (strict); both transports smoke-tested against live mempalace-mcp.
This commit is contained in:
+34
-3
@@ -15,6 +15,7 @@ dependencies (~300 MB).
|
||||
|
||||
**Jump to:**
|
||||
- [What it does](#what-it-does)
|
||||
- [Transport: local vs external](#transport-local-vs-external)
|
||||
- [The `Type.Unsafe` gotcha](#the-typeunsafe-gotcha)
|
||||
- [Deploying pi with mempalace on a new machine](#deploying-pi-with-mempalace-on-a-new-machine)
|
||||
- [Fail-soft, identity, debugging](#fail-soft)
|
||||
@@ -23,9 +24,12 @@ dependencies (~300 MB).
|
||||
|
||||
## What it does
|
||||
|
||||
1. **Spawns `mempalace-mcp`** as a subprocess and does the MCP stdio
|
||||
JSON-RPC handshake (`initialize` + `notifications/initialized` +
|
||||
`tools/list`).
|
||||
1. **Connects to MemPalace** and does the MCP handshake (`initialize` +
|
||||
`notifications/initialized` + `tools/list`). By default it **spawns
|
||||
`mempalace-mcp`** as a local stdio subprocess (`StdioMcpClient`); if
|
||||
`$MEMPALACE_REMOTE_URL` is set it instead talks to a shared MemPalace over
|
||||
HTTP (`RemoteMcpClient`) and spawns no local process — see
|
||||
[Transport](#transport-local-vs-external).
|
||||
2. **Registers each MCP tool** as a pi tool with its real `inputSchema`
|
||||
passed through via `Type.Unsafe(...)` (see gotcha below).
|
||||
3. **Wake-up auto-injection** (`before_agent_start`, one-shot per fresh
|
||||
@@ -39,6 +43,33 @@ dependencies (~300 MB).
|
||||
because pi sessions are typically short/tactical and
|
||||
`session_shutdown` fires too late to drive another LLM turn.
|
||||
|
||||
## Transport: local vs external
|
||||
|
||||
The bridge speaks the same MCP protocol over two interchangeable transports,
|
||||
chosen at load time:
|
||||
|
||||
- **Local (default)** — spawns `mempalace-mcp` as a stdio subprocess; the palace
|
||||
lives wherever that process opens it (default `~/.mempalace`). This is the
|
||||
hardened path with per-request timeouts and respawn/self-heal (below).
|
||||
- **External** — set `MEMPALACE_REMOTE_URL` to a MemPalace HTTP endpoint (e.g.
|
||||
`http://mempalace.lan:8765/mcp`) and the bridge connects over HTTP instead,
|
||||
spawning no local process. Use this to share **one** palace across several
|
||||
harnesses/containers (pi + opencode + native). `MEMPALACE_REMOTE_TOKEN`, if
|
||||
set, is sent as `Authorization: Bearer <token>`.
|
||||
|
||||
Serve such an endpoint with `mempalace-mcp --transport http --host 0.0.0.0
|
||||
--port 8765` (the `pi-devbox` / `opencode-devbox` repos ship a
|
||||
`docker-compose.mempalace.yml` for exactly this). Note: that HTTP transport is
|
||||
currently sessionless and **unauthenticated** — keep it on a trusted network
|
||||
or behind a reverse proxy that enforces the bearer token.
|
||||
|
||||
Implementation note: the HTTP client (`RemoteMcpClient`) is **vendored** from
|
||||
[`pi-extensions`](https://gitea.jordbo.se/joakimp/pi-extensions)'
|
||||
`mcp-loader.ts`. A `MCP-STREAMABLE-HTTP-CLIENT-SYNC` token keeps the two
|
||||
copies from drifting — [`scripts/check-mcp-client-sync.sh`](../../scripts/check-mcp-client-sync.sh)
|
||||
fails if they diverge (it skips gracefully when the `pi-extensions` checkout
|
||||
isn't present).
|
||||
|
||||
## Fail-soft
|
||||
|
||||
If `mempalace-mcp` can't be spawned (PATH missing, binary crashes at
|
||||
|
||||
Reference in New Issue
Block a user