Skip to content

Latest commit

 

History

History
421 lines (311 loc) · 14.5 KB

File metadata and controls

421 lines (311 loc) · 14.5 KB

Remote MCP Setup for claude.ai

mcp-memory-service supports Remote MCP, allowing native integration with claude.ai (browser) without requiring Claude Desktop. All 12 memory tools work directly in your browser conversations.


How It Works

┌──────────────┐     HTTPS/TLS      ┌─────────────────────────┐
│  claude.ai   │ ◄────────────────► │  MCP Memory Service     │
│  (Browser)   │   Streamable HTTP  │                         │
│              │   POST /mcp        │  ┌───────────────────┐  │
│  Settings >  │                    │  │ Streamable HTTP    │  │
│  Connectors  │   OAuth 2.0 DCR   │  │ Transport          │  │
│              │ ◄────────────────► │  │ (Port 8765)        │  │
└──────────────┘                    │  └─────────┬─────────┘  │
                                    │            │             │
                                    │  ┌─────────▼─────────┐  │
                                    │  │ MCP Server         │  │
                                    │  │ (12 Tools)         │  │
                                    │  └─────────┬─────────┘  │
                                    │            │             │
                                    │  ┌─────────▼─────────┐  │
                                    │  │ Storage Backend    │  │
                                    │  │ (Hybrid/SQLite)    │  │
                                    │  └───────────────────┘  │
                                    └─────────────────────────┘

claude.ai connects to your self-hosted MCP Memory Service via Streamable HTTP (POST requests to /mcp). Authentication uses OAuth 2.0 with Dynamic Client Registration — claude.ai handles the OAuth flow automatically when you add the connector.


Requirements

All requirements are already implemented in mcp-memory-service — you just need to expose the server publicly.

Requirement Details Since
Streamable HTTP Transport HTTP POST endpoint at /mcp v10.20.0
HTTPS/TLS Valid certificate from recognized CA v10.20.0
OAuth 2.0 with DCR Dynamic Client Registration (RFC 7591) v7.0.0
Safety Annotations readOnlyHint/destructiveHint on all tools v8.69.0
CORS Configured for browser clients v7.0.0

Note: SSE transport is being deprecated by Anthropic. Use Streamable HTTP for all new deployments.


Quick Start (Cloudflare Tunnel)

The easiest method — no port forwarding, no certificate management, free:

1. Install Cloudflare Tunnel

# macOS
brew install cloudflared

# Linux (Debian/Ubuntu)
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb

# Windows
winget install Cloudflare.cloudflared

2. Configure Environment

Add to your .env file (or export directly):

# Remote MCP transport
MCP_STREAMABLE_HTTP_MODE=1
MCP_SSE_HOST=0.0.0.0
MCP_SSE_PORT=8765

# OAuth (recommended for claude.ai)
MCP_OAUTH_ENABLED=true
MCP_OAUTH_STORAGE_BACKEND=sqlite
MCP_OAUTH_SQLITE_PATH=./data/oauth.db

3. Start the MCP Server

python -m mcp_memory_service.server

You should see output confirming Streamable HTTP mode on port 8765.

4. Start Cloudflare Tunnel

In a second terminal:

cloudflared tunnel --url http://localhost:8765

This outputs a URL like:

https://random-name.trycloudflare.com

5. Connect in claude.ai

  1. Open claude.ai
  2. Go to SettingsConnectors
  3. Click Add Connector
  4. Paste the URL: https://random-name.trycloudflare.com/mcp
  5. Complete the OAuth flow (automatic)
  6. All 12 memory tools are now available in your conversations!

Note: Temporary Cloudflare Tunnels change URL on restart. For persistent access, create a named tunnel.


Production Setup

Option A: Let's Encrypt + Direct HTTPS

For a server with a public domain name:

# 1. Get SSL certificate
sudo certbot certonly --standalone -d memory.yourdomain.com

# 2. Configure .env
MCP_STREAMABLE_HTTP_MODE=1
MCP_SSE_HOST=0.0.0.0
MCP_SSE_PORT=8765
MCP_HTTPS_ENABLED=true
MCP_SSL_CERT_FILE=/etc/letsencrypt/live/memory.yourdomain.com/fullchain.pem
MCP_SSL_KEY_FILE=/etc/letsencrypt/live/memory.yourdomain.com/privkey.pem
MCP_OAUTH_ENABLED=true
MCP_OAUTH_STORAGE_BACKEND=sqlite
MCP_OAUTH_SQLITE_PATH=./data/oauth.db

# 3. Open firewall port
sudo ufw allow 8765/tcp

# 4. Start server
python -m mcp_memory_service.server

# 5. In claude.ai: Add https://memory.yourdomain.com:8765/mcp

Option B: Reverse Proxy (nginx)

Use nginx for TLS termination, rate limiting, and logging:

server {
    listen 443 ssl http2;
    server_name memory.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/memory.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/memory.yourdomain.com/privkey.pem;

    location /mcp {
        proxy_pass http://localhost:8765/mcp;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Important for streaming responses
        proxy_buffering off;
        proxy_cache off;
    }
}

Then start the MCP server on localhost (no HTTPS needed, nginx handles it):

MCP_STREAMABLE_HTTP_MODE=1 MCP_SSE_HOST=127.0.0.1 MCP_SSE_PORT=8765 \
MCP_OAUTH_ENABLED=true python -m mcp_memory_service.server

Option C: Reverse Proxy (Caddy)

Caddy automatically handles TLS certificates:

memory.yourdomain.com {
    reverse_proxy /mcp* localhost:8765 {
        header_up X-Real-IP {remote_host}
        flush_interval -1
    }
}
# Start Caddy
caddy run

# Start MCP server (HTTP only, Caddy handles TLS)
MCP_STREAMABLE_HTTP_MODE=1 MCP_SSE_HOST=127.0.0.1 MCP_SSE_PORT=8765 \
MCP_OAUTH_ENABLED=true python -m mcp_memory_service.server

Option D: Docker Deployment

# docker-compose.yml
services:
  mcp-memory:
    image: ghcr.io/doobidoo/mcp-memory-service:latest
    environment:
      - MCP_STREAMABLE_HTTP_MODE=1
      - MCP_SSE_HOST=0.0.0.0
      - MCP_SSE_PORT=8765
      - MCP_OAUTH_ENABLED=true
      - MCP_OAUTH_STORAGE_BACKEND=sqlite
      - MCP_OAUTH_SQLITE_PATH=/data/oauth.db
      - MCP_MEMORY_STORAGE_BACKEND=sqlite_vec
      - MCP_MEMORY_SQLITE_PRAGMAS=journal_mode=WAL,busy_timeout=15000
    ports:
      - "8765:8765"
    volumes:
      - ./data:/data
    restart: unless-stopped
docker compose up -d
# Then use Cloudflare Tunnel or reverse proxy for HTTPS

OAuth Configuration

How OAuth Works with claude.ai

  1. User adds the connector URL in claude.ai Settings → Connectors
  2. claude.ai discovers OAuth metadata at /.well-known/oauth-authorization-server
  3. claude.ai registers itself via Dynamic Client Registration (DCR)
  4. User is redirected to your server's authorization endpoint
  5. After authorization, claude.ai receives an access token
  6. All subsequent MCP requests include the Bearer token

Callback URLs

Your OAuth server must accept these callback URLs from claude.ai:

URL Purpose
https://claude.ai/api/mcp/auth_callback Current production
https://claude.com/api/mcp/auth_callback Future (also allowlist now)

For Claude Code (local development), also allowlist:

URL Purpose
http://localhost:6274/oauth/callback Claude Code OAuth
http://localhost:6274/oauth/callback/debug Claude Code debug

Token Management

mcp-memory-service supports token expiry and refresh out of the box. claude.ai will automatically refresh tokens when they expire — no user interaction needed.


Firewall & IP Allowlisting

If your server is behind a firewall, you must allowlist Claude's IP addresses for inbound connections.

Reference: https://docs.claude.com/en/api/ip-addresses

Important: IP allowlisting alone is NOT recommended as a security measure. Always use OAuth 2.0 for authentication.


Available Tools

Once connected, these 12 tools become available in claude.ai conversations:

Tool Annotation Description
memory_store destructiveHint Store new memories with tags and metadata
memory_search readOnlyHint Semantic search across all memories
memory_delete destructiveHint Delete specific memories
memory_update destructiveHint Update existing memory content
memory_list readOnlyHint List memories with filtering
memory_stats readOnlyHint Storage statistics and metrics
memory_health readOnlyHint System health check
memory_consolidate destructiveHint Run memory consolidation
memory_graph readOnlyHint Query knowledge graph
memory_quality readOnlyHint Quality scoring and analytics
memory_cleanup destructiveHint Clean up low-quality memories
memory_ingest destructiveHint Ingest documents into memory

Limit: claude.ai enforces a maximum of 25,000 tokens per tool result. Large search results may be truncated — use filters and pagination to stay within limits.


Security Best Practices

  1. Always use HTTPS — never expose the MCP endpoint over plain HTTP
  2. Enable OAuth — API key authentication alone is insufficient for browser-based access
  3. Restrict CORS origins — limit to https://claude.ai and https://claude.com in production
  4. Use firewall rules — allowlist only Claude's IP ranges
  5. Monitor access logs — watch for unauthorized connection attempts
  6. Rotate OAuth secrets — periodically regenerate JWT signing keys
  7. Use persistent named tunnels — avoid sharing temporary Cloudflare Tunnel URLs publicly

Testing Your Setup

Verify Server is Running

# Check if the MCP endpoint responds
curl -X POST https://your-domain.com/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'

# Check OAuth metadata
curl https://your-domain.com/.well-known/oauth-authorization-server

# Health check (if HTTP API also running)
curl https://your-domain.com/api/health

Checklist

  • Server starts in Streamable HTTP mode (check logs for port 8765)
  • HTTPS endpoint is accessible from the internet
  • OAuth metadata endpoint responds at /.well-known/oauth-authorization-server
  • Connector added successfully in claude.ai Settings
  • OAuth flow completes without errors
  • memory_store works in a claude.ai conversation
  • memory_search returns results
  • All 12 tools appear in Claude's tool list

Troubleshooting

Connection Issues

Problem Solution
"Failed to connect" in claude.ai Verify URL is HTTPS and publicly accessible
OAuth flow fails Check callback URLs are allowlisted, check server logs
"Certificate error" Ensure valid TLS cert from recognized CA (not self-signed)
Tools not appearing Verify MCP_STREAMABLE_HTTP_MODE=1 is set
Timeout during connection Increase MCP_INIT_TIMEOUT, check network latency
"Max token limit exceeded" Use search filters to narrow results (tags, limit)

Debug Logging

# Start with verbose logging
MCP_STREAMABLE_HTTP_MODE=1 MCP_LOG_LEVEL=DEBUG \
python -m mcp_memory_service.server 2>&1 | grep -i "connect\|oauth\|error\|mcp"

SSL Certificate Verification

# Check certificate validity
openssl s_client -connect your-domain.com:8765 -servername your-domain.com < /dev/null 2>/dev/null | openssl x509 -noout -dates

# Check certificate chain
curl -vI https://your-domain.com:8765/mcp 2>&1 | grep -i "ssl\|cert\|expire"

Performance

Metric Local MCP (stdio) Remote MCP (HTTPS)
Latency <1ms 50-200ms
Setup complexity Config file HTTPS + OAuth
Works in browser No Yes
Works on mobile No Yes
Multi-device No Yes
Team sharing Complex Built-in

Remote MCP adds network latency (~50-200ms depending on location) but enables browser-based access, mobile support, and effortless team sharing.

Tips for minimizing latency:

  • Host close to Anthropic's servers (US regions)
  • Use Cloudflare Tunnel for automatic edge optimization
  • Enable connection keep-alive in reverse proxy config

Transport Comparison

Transport claude.ai Claude Desktop Claude Code Status
Stdio No Yes (default) Yes (default) Stable
Streamable HTTP Yes Yes Yes Recommended
SSE Deprecated Yes Yes Being phased out

Recommendation: Use Streamable HTTP for claude.ai and remote access. Keep Stdio for Claude Desktop (simplest local setup).


Related Documentation

References