-
Notifications
You must be signed in to change notification settings - Fork 7
HTTP Transport
HTTP transport configuration and reference for Memory Journal MCP Server.
Memory Journal supports two MCP transport protocols simultaneously when running in HTTP mode:
| Protocol | Spec Version | Endpoints | Session Management |
|---|---|---|---|
| Streamable HTTP | 2025-03-26 | POST/GET/DELETE /mcp |
mcp-session-id header |
| Legacy SSE | 2024-11-05 |
GET /sse, POST /messages
|
sessionId query param |
Why both? Streamable HTTP is the current MCP standard. Legacy SSE ensures backward compatibility with older MCP clients (e.g., MCP Inspector, older SDK versions).
Note
Legacy SSE is only available in stateful mode. Stateless mode only supports Streamable HTTP.
npm:
# Stateful (default) — supports both protocols
memory-journal-mcp --transport http --port 3000
# Bind to all interfaces (required for containers)
memory-journal-mcp --transport http --port 3000 --server-host 0.0.0.0
# Stateless (serverless) — Streamable HTTP only
memory-journal-mcp --transport http --port 3000 --statelessDocker:
# Stateful
docker run --rm -p 3000:3000 \
-v ./data:/app/data \
writenotenow/memory-journal-mcp:latest \
--transport http --port 3000 --server-host 0.0.0.0
# Stateless
docker run --rm -p 3000:3000 \
-v ./data:/app/data \
writenotenow/memory-journal-mcp:latest \
--transport http --port 3000 --server-host 0.0.0.0 --statelessImportant
Docker containers must use --server-host 0.0.0.0 to accept connections from outside the container.
| Endpoint | Description | Mode |
|---|---|---|
GET / |
Server info (name, version, protocols, endpoints) | Both |
POST /mcp |
JSON-RPC requests (initialize, tools/call, etc.) | Both |
GET /mcp |
SSE stream for server-to-client notifications | Stateful |
DELETE /mcp |
Session termination | Stateful |
GET /sse |
Legacy SSE connection (MCP 2024-11-05) | Stateful |
POST /messages |
Legacy SSE message endpoint | Stateful |
GET /health |
Health check ({ status: "ok", timestamp }) |
Both |
Returns server metadata and available endpoints:
{
"name": "memory-journal-mcp",
"version": "4.x.x",
"status": "running",
"protocols": [
"Streamable HTTP (MCP 2025-03-26)",
"Legacy SSE (MCP 2024-11-05)"
],
"endpoints": {
"POST /mcp": "Streamable HTTP endpoint",
"GET /mcp": "SSE stream (stateful)",
"DELETE /mcp": "Session termination",
"GET /sse": "Legacy SSE connection (MCP 2024-11-05)",
"POST /messages": "Legacy SSE message endpoint",
"GET /health": "Health check"
}
}Always public (no authentication, no rate limiting):
{
"status": "healthy",
"timestamp": "2026-03-05T07:00:00.000Z"
}Every HTTP response includes the following security headers:
| Header | Value |
|---|---|
X-Content-Type-Options |
nosniff |
X-Frame-Options |
DENY |
Content-Security-Policy |
default-src 'none'; frame-ancestors 'none' |
Cache-Control |
no-store |
Referrer-Policy |
no-referrer |
Permissions-Policy |
camera=(), microphone=(), geolocation=() |
- 100 requests per minute per IP (sliding window)
- Returns
429 Too Many Requestswhen exceeded - Health check (
GET /health) is exempt
Configurable via CLI or environment variable:
# CLI flag
memory-journal-mcp --transport http --cors-origin "http://localhost:3000"
# Environment variable
MCP_CORS_ORIGIN=http://localhost:3000 memory-journal-mcp --transport httpDefault: * (all origins). Use a specific origin in production.
Request bodies are limited to 1 MB to prevent memory exhaustion. Requests exceeding this limit receive 413 Payload Too Large.
Unknown paths return a structured JSON response:
{
"error": "Not found"
}Session IDs are protocol-scoped:
- SSE session IDs are rejected on
/mcpendpoints - Streamable HTTP session IDs are rejected on
/messagesendpoint
This prevents session confusion when both protocols are active simultaneously.
- UUID-based session IDs via
crypto.randomUUID() - 30-minute timeout with automatic cleanup
- 5-minute sweep interval for expired sessions
Streamable HTTP sessions:
# 1. Initialize — server returns mcp-session-id header
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
# 2. Subsequent requests — include mcp-session-id
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "mcp-session-id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
# 3. Terminate session
curl -X DELETE http://localhost:3000/mcp \
-H "mcp-session-id: YOUR_SESSION_ID"Legacy SSE sessions:
# 1. Open SSE connection — server sends endpoint event with sessionId
curl -N http://localhost:3000/sse
# 2. Send messages to the returned endpoint
curl -X POST "http://localhost:3000/messages?sessionId=YOUR_SSE_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'No session tracking. Each request is independent. Best for serverless deployments.
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"test_simple","arguments":{"message":"Hello"}}}'| Feature | Stateful (default) | Stateless (--stateless) |
|---|---|---|
| Progress Notifications | ✅ Yes | ❌ No |
| SSE Streaming | ✅ Yes | ❌ No |
| Legacy SSE Protocol | ✅ Yes | ❌ No |
| Session Management | ✅ Yes | ❌ No |
| Serverless Compatible | ✅ Native | |
| Horizontal Scaling | ✅ Any instance |
Choose Stateful when:
- Running on persistent infrastructure (VMs, containers, dedicated servers)
- Need progress notifications for long-running tools
- Need Legacy SSE for backward compatibility
Choose Stateless when:
- Deploying to serverless (AWS Lambda, Cloudflare Workers, Vercel)
- Horizontal scaling without sticky sessions
- Simple request-response patterns
The HTTP transport is implemented as a standalone module:
src/transports/http.ts — HttpTransport class
Key design decisions:
-
Extracted from McpServer.ts — HTTP logic lives in its own module, keeping
McpServer.tsfocused on tool/resource/prompt registration -
Dual-protocol — Both
StreamableHTTPServerTransportandSSEServerTransportshare the same Express app - Per-IP rate limiting — Sliding window with automatic cleanup (no external dependencies)
- Session isolation — Each protocol maintains its own session map; cross-protocol access is blocked
| CLI Flag | Env Variable | Default | Description |
|---|---|---|---|
--transport http |
— | stdio |
Enable HTTP transport |
--port <number> |
PORT |
3000 |
HTTP port |
--server-host <host> |
MCP_HOST |
localhost |
Bind address (0.0.0.0 for containers) |
--stateless |
— | false |
Disable session management |
--cors-origin <origin> |
MCP_CORS_ORIGIN |
* |
CORS allowed origin |
--backup-interval <minutes> |
— | 0 |
Automated backup interval (0 = off) |
--keep-backups <count> |
— | 5 |
Max backups retained during cleanup |
--vacuum-interval <minutes> |
— | 0 |
Database optimize interval (0 = off) |
--rebuild-index-interval <minutes> |
— | 0 |
Vector index rebuild interval (0 = off) |
Next: Learn about Configuration or check Security.