Skip to content

Worktree 001 mcp stream dockerize - #939

Closed
Noodle05 wants to merge 10 commits into
rohitg00:mainfrom
Noodle05:worktree-001-mcp-stream-dockerize
Closed

Worktree 001 mcp stream dockerize#939
Noodle05 wants to merge 10 commits into
rohitg00:mainfrom
Noodle05:worktree-001-mcp-stream-dockerize

Conversation

@Noodle05

@Noodle05 Noodle05 commented Jun 15, 2026

Copy link
Copy Markdown

Summary by CodeRabbit

New Features

  • Full Docker and Docker Compose support with service orchestration, automated health checks, and persistent named volumes
  • MCP Streamable HTTP transport endpoint on port 3114 with Bearer token-based authentication

Documentation

  • New Docker quickstart guide including setup commands, secret management, and health verification
  • HTTP client configuration examples for MCP Streamable transport connections

Noodle05 and others added 10 commits June 14, 2026 23:52
- Install @modelcontextprotocol/node SDK for MCP Streamable HTTP transport
- Add @modelcontextprotocol/node to tsdown external array (ESM, not bundled)
- Add mcpPort field to AgentMemoryConfig type (defaults to restPort + 3)
- Add AGENTMEMORY_MCP_PORT env var support in loadConfig()

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Move handleToolsList() and handleToolCall() plus all their internal
helpers (validate, handleProxy, handleLocal, handleProxyGeneric,
normalizeList, parseLimit, textResponse, announceMode) from
src/mcp/standalone.ts into a new src/mcp/handler.ts shared module.

The extracted functions accept explicit sdk, kv, and config parameters
so they can be reused by both the existing stdio transport and the
upcoming Stream HTTP transport without code duplication.

standalone.ts retains:
- InMemoryKV instantiation
- createStdioTransport and the stdio message dispatch loop
- SIGINT/SIGTERM handlers
- Backward-compatible wrapper exports (old signatures) for tests

All 1410 non-integration tests pass; no behavioral changes.

Co-Authored-By: Claude <noreply@anthropic.com>
Implement JSON-RPC-over-HTTP MCP transport that coexists with existing stdio
transport. Uses Node.js http.createServer() with manual JSON-RPC handling,
Bearer auth via timingSafeCompare(), and session management via a Map.

- src/mcp/stream-http.ts: HTTP server with MCP JSON-RPC handling (initialize,
  tools/list, tools/call, notifications)
- test/mcp-stream-http.test.ts: 22 tests covering initialize, tools/list,
  tools/call, Bearer auth, JSON-RPC errors, session management
- test/mcp-transport-coexistence.test.ts: 5 tests verifying HTTP and stdio
  transports expose identical tool sets and handle notifications
- src/index.ts: Wire up MCP server on config.mcpPort (3114), add to boot log
  and graceful shutdown
- package.json: Add @cfworker/json-schema peer dependency

Port scheme: restPort + 3 (3114), configurable via AGENTMEMORY_MCP_PORT

Co-Authored-By: Claude <noreply@anthropic.com>
- Add session TTL with lastUsedAt tracking and periodic eviction (every 10 min)
- Fix session-not-found error code from -32001 to -32000 per contract
- Add explanation comment for manual JSON-RPC vs SDK transport
- Add 5MB request body size limit with 413 response
- Add HTTP method validation (POST/DELETE only, 405 for others)
- Add Content-Type validation (application/json required, 415 otherwise)

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix JsonRpcMessage.id type to allow null (JSON-RPC notification compliant)
- Remove as cast in errorResponse() now that id type includes null
- Remove dead req.headers["Mcp-Session-Id"] branch (Node.js lowercases headers)
- DELETE handler now removes session from sessions Map
- Remove unused @cfworker/json-schema dependency
- Tighten parse error test to assert exactly -32700
- Add SDK bug reference URL in header comment
- Add safety guard comment for res.headersSent in body-too-large handler

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
…cker

- T039: Add "stream-http" connection category to ConnectAdapter types
- T040: Add AGENTMEMORY_MCP_HTTP_BLOCK constant and HTTP transport comments
  in CLI connect adapters for Stream HTTP URL-based connections
- T041: Add AGENTMEMORY_MCP_PORT entry to .env.example ports section
- T042: Add Docker quickstart section to README.md
- T045: Add mcpPort to startup banner alongside REST API and MCP surface lines

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove @modelcontextprotocol/node from package.json dependencies
- Remove @modelcontextprotocol/node from tsdown.config.ts external array
- Update stream-http.ts comment to remove SDK revisit suggestion
- Update spec.md assumptions: Stream HTTP uses hand-rolled JSON-RPC
  server on port 3114 (separate from REST on 3111)
- 1450 tests pass (6 pre-existing environmental failures in worktree)

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

@Noodle05 is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Noodle05 Noodle05 closed this Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 805bf3fb-0cef-447a-bc5b-f1e0811954e8

📥 Commits

Reviewing files that changed from the base of the PR and between f6f9e3c and 153102a.

📒 Files selected for processing (33)
  • .dockerignore
  • .env.example
  • Dockerfile
  • README.md
  • docker-compose.yml
  • entrypoint.sh
  • iii-config.docker.yaml
  • plugin/scripts/notification.mjs
  • plugin/scripts/post-commit.mjs
  • plugin/scripts/post-tool-failure.mjs
  • plugin/scripts/post-tool-use.mjs
  • plugin/scripts/pre-compact.mjs
  • plugin/scripts/pre-tool-use.mjs
  • plugin/scripts/prompt-submit.mjs
  • plugin/scripts/session-end.mjs
  • plugin/scripts/session-start.mjs
  • plugin/scripts/stop.mjs
  • plugin/scripts/subagent-start.mjs
  • plugin/scripts/subagent-stop.mjs
  • plugin/scripts/task-completed.mjs
  • specs/001-mcp-stream-dockerize/spec.md
  • src/cli/connect/json-mcp-adapter.ts
  • src/cli/connect/types.ts
  • src/cli/connect/util.ts
  • src/config.ts
  • src/index.ts
  • src/mcp/handler.ts
  • src/mcp/standalone.ts
  • src/mcp/stream-http.ts
  • src/types.ts
  • test/mcp-stream-http.test.ts
  • test/mcp-transport-coexistence.test.ts
  • test/multi-instance-port.test.ts

📝 Walkthrough

Walkthrough

Adds an MCP Streamable HTTP transport (hand-rolled JSON-RPC 2.0 on port 3114), refactors existing standalone MCP logic into a shared handler.ts module, introduces a complete Docker/Compose deployment stack (Dockerfile, entrypoint.sh, auto-generated HMAC secret, health checks), and normalizes ESM empty exports across all generated plugin scripts.

Changes

MCP Stream HTTP Transport and Docker Deployment

Layer / File(s) Summary
Config, types, and connect adapter contracts
src/types.ts, src/cli/connect/types.ts, src/cli/connect/util.ts, src/cli/connect/json-mcp-adapter.ts, src/config.ts, .env.example
AgentMemoryConfig gains mcpPort; ConnectAdapter.category adds "stream-http"; AGENTMEMORY_MCP_HTTP_BLOCK exported; loadConfig derives mcpPort from AGENTMEMORY_MCP_PORT or restPort+3.
Shared MCP tool handler and standalone refactor
src/mcp/handler.ts, src/mcp/standalone.ts
New handler.ts exports handleToolCall and handleToolsList with proxy/local routing, per-tool validation, REST proxy calls, and KV-backed local fallback. standalone.ts is gutted of 422 lines of inlined logic and delegates to the new module.
MCP Streamable HTTP server
src/mcp/stream-http.ts
New file implementing startMcpStreamServer with JSON-RPC 2.0 request parsing, 5 MB body limit, optional Bearer auth, in-memory session map with idle eviction (1 h TTL), and routing for initialize, tools/list, tools/call.
Main app startup/shutdown wiring
src/index.ts
Imports and starts mcpServer via startMcpStreamServer on config.mcpPort; logs the MCP Stream HTTP endpoint; awaits mcpServer.shutdown() during teardown.
Docker infrastructure
Dockerfile, entrypoint.sh, docker-compose.yml, iii-config.docker.yaml, .dockerignore
Multi-stage Dockerfile builds and packages the app. entrypoint.sh creates data dir, generates/persists HMAC secret, writes iii-config.yaml, and execs Node. Compose adds iii-engine health checks, restart: unless-stopped, and wires the agentmemory service with health-gated startup, port exposure, and shared volume. CORS origins extended to port 3114; iii-exec worker removed.
Tests
test/mcp-stream-http.test.ts, test/mcp-transport-coexistence.test.ts, test/multi-instance-port.test.ts
~1200 lines of Vitest coverage: initialize/tools/call/auth/session lifecycle/eviction/HTTP constraints for the stream server; HTTP vs handleToolsList parity and notification handling for coexistence; mcpPort derivation and explicit-override assertions for port config.
Feature spec and docs
specs/001-mcp-stream-dockerize/spec.md, README.md
Spec document defines user stories, FR-001–FR-012, edge cases, and success criteria. README adds a Docker Quick Start section with compose commands, secret retrieval, health check, and MCP client config examples.

Plugin Scripts ESM Export Normalization

Layer / File(s) Summary
ESM export and region marker normalization
plugin/scripts/*.mjs (14 files)
All generated scripts normalize trailing empty export from export { }; to export {}; and adjust //#region///#endregion comment placement. No runtime logic changes.

Sequence Diagram(s)

sequenceDiagram
    participant Client as MCP Client
    participant StreamHTTP as stream-http.ts (port 3114)
    participant Sessions as SessionMap
    participant Handler as handler.ts

    rect rgba(70, 130, 180, 0.5)
        Note over Client, Sessions: Session initialization
        Client->>StreamHTTP: POST /mcp {method: initialize}
        StreamHTTP->>StreamHTTP: validate method, Content-Type, Bearer token
        StreamHTTP->>Sessions: create SessionEntry
        StreamHTTP-->>Client: 200 + mcp-session-id header
    end

    rect rgba(60, 179, 113, 0.5)
        Note over Client, Handler: Tool discovery
        Client->>StreamHTTP: POST /mcp + Mcp-Session-Id {method: tools/list}
        StreamHTTP->>Sessions: lookup + bump lastUsedAt
        StreamHTTP->>Handler: handleToolsList(null, kv)
        Handler-->>StreamHTTP: tools array
        StreamHTTP-->>Client: 200 JSON-RPC response
    end

    rect rgba(255, 165, 0, 0.5)
        Note over Client, Handler: Tool invocation
        Client->>StreamHTTP: POST /mcp + Mcp-Session-Id {method: tools/call, name, args}
        StreamHTTP->>Handler: handleToolCall(name, args, null, kv)
        Handler->>Handler: validate args, route proxy or local KV
        Handler-->>StreamHTTP: content array
        StreamHTTP-->>Client: 200 JSON-RPC response
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • rohitg00/agentmemory#815: Both PRs modify loadConfig() port-derivation and the shared test/multi-instance-port.test.ts harness to extend the multi-instance REST-anchor cascade (#815 adjusts streams/engine ports; this PR adds mcpPort).
  • rohitg00/agentmemory#887: Both PRs touch src/cli/connect/types.ts's ConnectAdapter.category union — #887 establishes the "native" | "mcp" pair that this PR extends with "stream-http".

Poem

🐇 A rabbit hopped in, typed compose up with glee,
JSON-RPC streams now flow wild and free,
Port 3114 listens, sessions tick away,
An HMAC secret born fresh every day,
export {}; — clean, no spaces between,
The fluffiest HTTP server you've ever seen! 🌟

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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