MCP Bridge
The MCP Bridge connects AI platforms to AutoMem’s memory service. It exists in two forms that serve different integration scenarios:
-
mcp-sse-server (in the
automemrepo) — A Node.js/Express service that exposes AutoMem’s HTTP API as an MCP server over Streamable HTTP or SSE transports, enabling cloud-hosted AI platforms (ChatGPT, Claude.ai, ElevenLabs) to access memory over the network. -
mcp-automem (separate npm package) — A TypeScript package that runs as a local stdio MCP server, spawned directly by AI platforms on the developer’s machine (Claude Desktop, Cursor, Claude Code, OpenAI Codex).
Both approaches implement the same six MCP tools and use the same AutoMemClient HTTP client to call the AutoMem API, but they differ in their transport mechanism, deployment model, and target use case.
Architecture Overview
Section titled “Architecture Overview”graph TB
subgraph "Cloud AI Platforms"
ChatGPT["ChatGPT / Claude.ai<br/>ElevenLabs"]
end
subgraph "Local AI Platforms"
LocalAI["Claude Desktop<br/>Cursor IDE / Claude Code<br/>OpenAI Codex"]
end
subgraph "MCP Bridge (mcp-sse-server)"
Express["Express App<br/>:8080"]
AutoMemClientSSE["AutoMemClient<br/>(HTTP)"]
Sessions["Session Map<br/>+ InMemoryEventStore"]
end
subgraph "MCP Bridge (mcp-automem package)"
StdioServer["stdio MCP Server<br/>spawned by platform"]
AutoMemClientLocal["AutoMemClient<br/>(HTTP)"]
end
subgraph "AutoMem API"
Flask["Flask App<br/>:8001"]
end
ChatGPT -->|"HTTPS MCP<br/>Streamable HTTP / SSE"| Express
Express --> AutoMemClientSSE
AutoMemClientSSE -->|"HTTP REST"| Flask
LocalAI -->|"stdin/stdout<br/>MCP protocol"| StdioServer
StdioServer --> AutoMemClientLocal
AutoMemClientLocal -->|"HTTP REST"| Flask
mcp-sse-server Key Components
Section titled “mcp-sse-server Key Components”| Component | File Location | Purpose |
|---|---|---|
| Express app | server.js:458-779 | HTTP server with endpoint routing |
AutoMemClient | server.js:60-169 | HTTP client for AutoMem API |
buildMcpServer() | server.js:228-456 | MCP server factory with tool handlers |
InMemoryEventStore | server.js:18-57 | Event buffering for stream resumption |
| Session management | server.js:468-492 | Map-based session tracking with TTL |
mcp-automem: Local stdio Server
Section titled “mcp-automem: Local stdio Server”The mcp-automem npm package operates as a local MCP server using stdio transport. When invoked with no arguments, it launches the server; with arguments, it runs CLI commands.
Entry Mode Detection
Section titled “Entry Mode Detection”graph LR
START["npx @verygoodplugins/mcp-automem"]
subgraph Detection["Mode Detection<br/>src/index.ts:36-38"]
CHECK{"process.argv[2]<br/>exists?"}
end
subgraph Server_Mode["Server Mode"]
STDIO_GUARD["installStdioErrorGuards()<br/>src/index.ts:69-79"]
MCP_SERVER["new Server()<br/>src/index.ts:314-317"]
STDIO_TRANSPORT["StdioServerTransport<br/>stdin/stdout"]
TOOL_HANDLER["CallToolRequestSchema<br/>handler<br/>src/index.ts:878-1234"]
end
subgraph CLI_Mode["CLI Mode"]
SETUP["runSetup()<br/>src/cli/setup.js"]
CONFIG["runConfig()<br/>src/cli/setup.js"]
CURSOR["runCursorSetup()<br/>src/cli/cursor.js"]
CLAUDE_CODE["runClaudeCodeSetup()<br/>src/cli/claude-code.js"]
CODEX["runCodexSetup()<br/>src/cli/codex.js"]
OPENCLAW["runOpenClawSetup()<br/>src/cli/openclaw.js"]
QUEUE["runQueueCommand()<br/>src/cli/queue.js"]
RECALL["Direct recall via<br/>AutoMemClient"]
end
START --> CHECK
CHECK -->|"No args"| STDIO_GUARD
CHECK -->|"Command"| SETUP
STDIO_GUARD --> MCP_SERVER
MCP_SERVER --> STDIO_TRANSPORT
MCP_SERVER --> TOOL_HANDLER
CHECK --> CONFIG
CHECK --> CURSOR
CHECK --> CLAUDE_CODE
CHECK --> CODEX
CHECK --> OPENCLAW
CHECK --> QUEUE
CHECK --> RECALL
Server Mode (no arguments): Launches an MCP server using stdio transport. AI platforms (Claude Desktop, Cursor, etc.) spawn this process as an MCP server. Console output is redirected to stderr to avoid corrupting the stdio protocol stream.
CLI Mode (with arguments): Provides interactive commands for setup, configuration, platform installation, and memory operations.
Standard MCP Integration Pattern
Section titled “Standard MCP Integration Pattern”graph LR
subgraph Platform_Config["Platform Configuration"]
CD_JSON["claude_desktop_config.json<br/>~/.config/Claude/"]
CURSOR_MCP["mcp.json<br/>~/.cursor/"]
CODEX_TOML["config.toml<br/>~/.codex/"]
COPILOT_JSON["MCP configuration<br/>GitHub repo settings"]
end
subgraph Rule_Files["Memory-First Rules"]
CURSOR_MDC["automem.mdc<br/>.cursor/rules/"]
CLAUDE_MD["CLAUDE.md<br/>~/.claude/"]
AGENTS_MD["AGENTS.md<br/>project root"]
end
subgraph MCP_Server["MCP Server Process"]
NPX["npx -y<br/>@verygoodplugins/mcp-automem"]
SERVER_PROC["Server Mode<br/>stdio transport"]
end
CD_JSON -->|"Launch command"| NPX
CURSOR_MCP -->|"Launch command"| NPX
CODEX_TOML -->|"Launch command"| NPX
COPILOT_JSON -->|"Launch command"| NPX
NPX --> SERVER_PROC
CURSOR_MDC -.->|"Guides behavior"| SERVER_PROC
CLAUDE_MD -.->|"Guides behavior"| SERVER_PROC
AGENTS_MD -.->|"Guides behavior"| SERVER_PROC
mcp-sse-server: Transport Protocols
Section titled “mcp-sse-server: Transport Protocols”The mcp-sse-server bridge supports two MCP transport protocols with different characteristics and lifecycle models.
Streamable HTTP Transport (2025-03-26)
Section titled “Streamable HTTP Transport (2025-03-26)”Implementation Details:
- Session initialization: server.js:673-704 — Checks
isInitializeRequest()andreq.method === 'POST' - Session reuse: server.js:656-671 — Validates existing sessions and updates
lastAccess - Event storage: server.js:38-49 — Stores up to 1000 events per stream
- Session cleanup: server.js:472-492 — Sweeps every 5 minutes, 1-hour TTL
- Resumability: server.js:50-56 —
replayEventsAfter()forLast-Event-IDsupport
SSE Transport (2024-11-05, Deprecated)
Section titled “SSE Transport (2024-11-05, Deprecated)”Implementation Details:
- Stream setup: server.js:728-759 — Creates
SSEServerTransportwith/mcp/messagesendpoint - Heartbeat: server.js:744-746 — Sends
: ping\n\nevery 20 seconds - Message handling: server.js:762-776 — Routes POST to
handlePostMessage() - Cleanup: server.js:747-751 —
res.on('close')clears heartbeat and session
Transport Comparison
Section titled “Transport Comparison”| Feature | Streamable HTTP | SSE (Deprecated) |
|---|---|---|
| Protocol version | 2025-03-26 | 2024-11-05 |
| Initialization | Single endpoint (POST /mcp) | Separate endpoints (GET /mcp/sse, POST /mcp/messages) |
| Session ID | Mcp-Session-Id header | Query param in POST URL |
| Resumability | Last-Event-ID header | None |
| Event buffering | InMemoryEventStore (1000 events) | None |
| Connection style | Stateful sessions with TTL | Long-lived SSE stream |
| Heartbeat | Not needed (stateless requests) | 20-second ping interval |
Protocol Translation
Section titled “Protocol Translation”Both bridge implementations translate between MCP JSON-RPC tool calls and AutoMem’s REST API.
Tool-to-Endpoint Mapping
Section titled “Tool-to-Endpoint Mapping”graph LR
subgraph mcp["MCP JSON-RPC Tools"]
StoreMemory["store_memory"]
RecallMemory["recall_memory"]
AssociateMemories["associate_memories"]
UpdateMemory["update_memory"]
DeleteMemory["delete_memory"]
CheckHealth["check_database_health"]
end
subgraph client["AutoMemClient Methods"]
StoreMethod["storeMemory(args)"]
RecallMethod["recallMemory(args)"]
AssociateMethod["associateMemories(args)"]
UpdateMethod["updateMemory(args)"]
DeleteMethod["deleteMemory(args)"]
HealthMethod["checkHealth()"]
end
subgraph api["AutoMem HTTP API"]
PostMemory["POST /memory"]
GetRecall["GET /recall"]
PostAssociate["POST /associate"]
PatchMemory["PATCH /memory/:id"]
DeleteMemoryEndpoint["DELETE /memory/:id"]
GetHealth["GET /health"]
end
StoreMemory --> StoreMethod
RecallMemory --> RecallMethod
AssociateMemories --> AssociateMethod
UpdateMemory --> UpdateMethod
DeleteMemory --> DeleteMethod
CheckHealth --> HealthMethod
StoreMethod -->|"JSON body"| PostMemory
RecallMethod -->|"Query params"| GetRecall
AssociateMethod -->|"JSON body"| PostAssociate
UpdateMethod -->|"JSON body"| PatchMemory
DeleteMethod -->|"URL param"| DeleteMemoryEndpoint
HealthMethod -->|"No params"| GetHealth
AutoMemClient HTTP Request Flow
Section titled “AutoMemClient HTTP Request Flow”sequenceDiagram
participant Handler as "Tool Handler"
participant Client as "AutoMemClient"
participant Request as "_request(method, path, body)"
participant API as "Flask API :8001"
Handler->>Client: client.storeMemory({content, tags, ...})
Client->>Client: Build request body with all fields
Client->>Request: _request('POST', 'memory', body)
Request->>Request: Construct URL:<br/>endpoint + '/' + path
Request->>Request: Add headers:<br/>Content-Type: application/json<br/>Authorization: Bearer ${apiKey}
Request->>API: fetch(url, {method, headers, body})
API-->>Request: HTTP response
Request->>Request: await res.json()
alt Response OK
Request-->>Client: Parsed JSON data
Client-->>Handler: {memory_id, message}
else Response Error
Request->>Request: throw Error(data.message || data.detail)
Request-->>Handler: Error thrown
end
Key AutoMemClient Methods (mcp-sse-server):
| Method | HTTP Method | Endpoint Pattern | Request Body |
|---|---|---|---|
storeMemory() | POST | /memory | All Memory fields |
recallMemory() | GET | /recall?{params} | URLSearchParams encoding |
associateMemories() | POST | /associate | Two IDs + type/strength |
updateMemory() | PATCH | /memory/{id} | Partial updates |
deleteMemory() | DELETE | /memory/{id} | ID in URL |
checkHealth() | GET | /health | No body |
Error Handling: server.js:76-87 wraps fetch failures and non-OK responses into Error objects.
Authentication
Section titled “Authentication”Both bridge implementations support multiple authentication methods for flexibility across different client platforms.
Authentication Flow
Section titled “Authentication Flow”graph TB
subgraph client["Client Request"]
ReqHeaders["Request Headers:<br/>- Authorization: Bearer TOKEN<br/>- X-API-Key: TOKEN<br/>- X-API-Token: TOKEN"]
ReqQuery["Query Parameters:<br/>?api_key=TOKEN<br/>?apiKey=TOKEN<br/>?api_token=TOKEN"]
end
subgraph bridge["MCP Bridge"]
GetAuthToken["getAuthToken(req)<br/>Extraction priority:<br/>1. Bearer Authorization<br/>2. X-API-Key/X-API-Token<br/>3. Query params"]
Validate["Token validation"]
ConfigToken["process.env.AUTOMEM_API_TOKEN"]
end
subgraph forwarding["Request Forwarding"]
AddHeader["Add Authorization:<br/>Bearer ${apiKey}<br/>to AutoMem request"]
AutoMemAPI["AutoMem API<br/>require_api_token middleware"]
end
ReqHeaders --> GetAuthToken
ReqQuery --> GetAuthToken
GetAuthToken --> Validate
ConfigToken --> Validate
Validate -->|"Valid"| AddHeader
Validate -->|"Missing/Invalid"| Reject["401 Unauthorized"]
AddHeader --> AutoMemAPI
AutoMemAPI -->|"Valid token"| Success["Process request"]
AutoMemAPI -->|"Invalid token"| ApiReject["403 Forbidden"]
Token Extraction Priority (mcp-sse-server):
Authorization: Bearerheader (preferred)X-API-KeyorX-API-Tokenheader- Query parameters:
api_key,apiKey, orapi_token
Environment Fallback: If client doesn’t provide token, uses process.env.AUTOMEM_API_TOKEN from server.js:577 (Alexa endpoint), server.js:676 (Streamable HTTP), and server.js:731 (SSE).
mcp-automem environment variable priority:
AUTOMEM_API_KEY(primary, current)AUTOMEM_API_TOKEN(fallback)MEMORY_API_KEY(legacy)
The readAutoMemApiKeyFromEnv() function in src/env.js implements this priority chain.
Tool Definitions
Section titled “Tool Definitions”Both bridge implementations expose six MCP tools with JSON schemas for validation.
Detailed Tool Specifications
Section titled “Detailed Tool Specifications”store_memory — server.js:232-254
| Parameter | Type | Required | Constraints | Description |
|---|---|---|---|---|
content | string | Yes | — | Memory text content |
tags | string[] | No | — | Classification tags |
importance | number | No | 0.0-1.0 | Relevance score |
embedding | number[] | No | — | Pre-computed vector |
metadata | object | No | — | Custom key-value pairs |
timestamp | string | No | ISO 8601 | Creation time |
type | string | No | — | Memory classification |
confidence | number | No | 0.0-1.0 | Classification confidence |
recall_memory — server.js:255-300
Advanced recall parameters (lines 278-291):
expand_relations(boolean): Enable graph traversalexpand_entities(boolean): Multi-hop via entitiesauto_decompose(boolean): Generate sub-queriesexpansion_limit(integer 1-500): Max expanded resultsrelation_limit(integer 1-200): Relations per seedexpand_min_importance(number 0-1): Filter thresholdexpand_min_strength(number 0-1): Relation strength threshold
Context hints (lines 286-291):
context(string): e.g., “coding-style”, “architecture”language(string): e.g., “python”, “typescript”active_path(string): Current file pathcontext_tags(string[]): Priority tagscontext_types(string[]): Priority memory typespriority_ids(string[]): Specific IDs to boost
Output Formats (server.js:401-429):
text(default): Single-block text with all resultsitems: One MCP content item per memorydetailed: Items with timestamps, relations, scoresjson: Raw API response as JSON string
Result Formatting
Section titled “Result Formatting”formatRecallAsItems() Function:
server.js:171-225 transforms AutoMem API responses into MCP content items.
Relation Summarization: server.js:211-221 — Shows up to 5 relations with type, strength, and source ID.
Session Management (mcp-sse-server)
Section titled “Session Management (mcp-sse-server)”The mcp-sse-server bridge maintains stateful sessions for both transport protocols with different lifecycle strategies.
Session State Structure
Section titled “Session State Structure”Session Creation:
Streamable HTTP — server.js:684-691
SSE — server.js:751
Session Cleanup:
| Transport | Cleanup Strategy | TTL | Implementation |
|---|---|---|---|
| Streamable HTTP | Sweep interval | 1 hour idle | server.js:472-492 — 5 minute sweeps |
| SSE | Connection close | Until disconnect | server.js:747-750 — res.on('close') |
Event Store Implementation
Section titled “Event Store Implementation”Purpose: Enable session resumption with Last-Event-ID header for Streamable HTTP transport.
server.js:18-57 InMemoryEventStore class:
| Method | Parameters | Return | Description |
|---|---|---|---|
storeEvent() | streamId, message | eventId | Store event with auto-generated ID, limit 1000 per stream |
replayEventsAfter() | streamId, lastEventId | message[] | Return all events after specified ID |
removeStream() | streamId | void | Delete all events for stream |
stopCleanup() | — | void | Stop TTL sweep timer |
Event ID Format: server.js:39 — ${streamId}-${Date.now()}-${randomUUID().slice(0, 8)}
TTL Sweep: server.js:22-30 — Runs every 5 minutes (default), removes streams idle > 1 hour.
Additional Features
Section titled “Additional Features”Alexa Integration (mcp-sse-server)
Section titled “Alexa Integration (mcp-sse-server)”The bridge includes a custom Alexa skill endpoint separate from MCP protocol handling.
Implementation Details:
| Component | File Location | Purpose |
|---|---|---|
| Endpoint handler | server.js:569-647 | Routes Alexa JSON to AutoMem API |
speech() helper | server.js:521-532 | Builds Alexa response JSON |
getSlot() | server.js:537-540 | Extracts intent slot values |
buildAlexaTags() | server.js:545-552 | Adds alexa, user:{id}, device:{id} tags |
formatRecallSpeech() | server.js:557-566 | Converts memories to spoken text (240 char limit) |
Supported Intents:
| Intent | Slot | Action | Response |
|---|---|---|---|
RememberIntent | note | Store memory with Alexa tags | ”Saved to memory.” |
RecallIntent | query | Search with tags, fallback without | Speak up to 3 results |
AMAZON.HelpIntent | — | — | Usage instructions |
LaunchRequest | — | — | Welcome message |
Tag Scoping: server.js:616-626 — Recall tries user-specific tags first, falls back to unscoped search.
Health Endpoint
Section titled “Health Endpoint”Route: GET /health — server.js:495-500
Purpose: Railway health checks, monitoring systems, and client capability detection.
Deployment Integration (mcp-sse-server)
Section titled “Deployment Integration (mcp-sse-server)”Railway Configuration
Section titled “Railway Configuration”The MCP Bridge deploys as a separate service alongside the AutoMem API service.
Required Environment Variables:
| Variable | Example | Purpose |
|---|---|---|
PORT | 8080 | Express listener port (Railway requires) |
AUTOMEM_API_URL | http://memory-service.railway.internal:8001 | Internal AutoMem API endpoint |
AUTOMEM_API_TOKEN | ${shared.AUTOMEM_API_TOKEN} | Shared secret for API authentication |
Railway Template Setup: docs/RAILWAY_DEPLOYMENT.md:95-139 — One-click deployment includes mcp-sse-server by default.
Manual Setup: Add service with root directory mcp-sse-server, auto-detects Dockerfile.
Internal Networking: Uses *.railway.internal domains for service-to-service communication (IPv6).
Network Architecture
Section titled “Network Architecture”Port Configuration:
- MCP Bridge: External
:443(HTTPS) → Internal:8080(HTTP) - AutoMem API: Internal
:8001(HTTP only, no public domain by default) - FalkorDB: Internal
:6379(Redis protocol, no public access)
Cost Optimization
Section titled “Cost Optimization”Resource Sizing:
| Component | CPU | Memory | Monthly Cost |
|---|---|---|---|
| mcp-sse-server | 0.25 vCPU | 256 MB | ~$2-3 |
| memory-service | 0.5 vCPU | 512 MB | ~$5 |
| FalkorDB | 1 vCPU | 1 GB | ~$10 |
Security Considerations
Section titled “Security Considerations”Token Exposure:
- Query parameter auth (
?api_token=) may appear in logs - Prefer header-based auth (
Authorization: Bearer) when platform supports it - Railway internal logs capture all request URLs
Network Isolation:
- MCP bridge has public domain (required for cloud AI platforms)
- AutoMem API should remain internal (
*.railway.internal) - FalkorDB never exposed publicly
Token Rotation:
- Update
AUTOMEM_API_TOKENin both mcp-sse-server and memory-service simultaneously - Use Railway shared variables (
${shared.AUTOMEM_API_TOKEN}) to maintain consistency
Choosing the Right Integration
Section titled “Choosing the Right Integration”| Scenario | Recommended Approach |
|---|---|
| Claude Desktop, Cursor, Claude Code, Codex | mcp-automem npm package (local stdio) |
| ChatGPT, Claude.ai, ElevenLabs, any cloud AI | mcp-sse-server (Railway deployment) |
| Alexa voice interface | mcp-sse-server Alexa endpoint |
| Self-hosted local AI with network access | Either approach depending on platform support |
For platform-specific integration guides, see Platform Integrations.