🚀 ChromaDB Remote MCP Server
A Streamable HTTP MCP (Model Context Protocol) server that provides remote access to ChromaDB for AI assistants like Claude, enabling semantic search and vector database operations from mobile devices and remote locations.

Note: This project uses MCP Streamable HTTP (2025-03-26 spec). SSE transport is deprecated.
Korean Documentation
🚀 Quick Start
One-Command Installation
curl -fsSL https://raw.githubusercontent.com/meloncafe/chromadb-remote-mcp/release/scripts/install.sh | bash
This will:
- Download
docker-compose.yml and .env.example.
- Auto-detect Docker Compose command (
docker-compose or docker compose).
- Auto-generate a secure authentication token (optional).
- Configure ChromaDB data storage location (Docker volume, local directory, or custom path).
- Pull Docker images.
- Display your authentication token and connection URL.
Manual Installation
Option 1: Docker (Recommended - Pre-built Image)
mkdir chromadb-remote-mcp && cd chromadb-remote-mcp
curl -O https://raw.githubusercontent.com/meloncafe/chromadb-remote-mcp/release/docker-compose.yml
curl -O https://raw.githubusercontent.com/meloncafe/chromadb-remote-mcp/release/.env.example
cp .env.example .env
docker compose up -d
curl http://localhost:8080/health
docker compose logs -f
Option 2: Build from Source
git clone https://github.com/meloncafe/chromadb-remote-mcp.git
cd chromadb-remote-mcp
cp .env.example .env
docker compose -f docker-compose.dev.yml up -d
Option 3: Local Development
git clone https://github.com/meloncafe/chromadb-remote-mcp.git
cd chromadb-remote-mcp
yarn install
cp .env.example .env
yarn build
yarn start
Generate Secure Token
For production use, generate a secure token for MCP_AUTH_TOKEN in .env:
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
openssl rand -base64 32 | tr '+/' '-_' | tr -d '='
Copy the generated token and paste it into your .env file:
MCP_AUTH_TOKEN=your-generated-token-here
Server Endpoints
- MCP:
http://localhost:8080/mcp (via Caddy proxy)
- Health:
http://localhost:8080/health
- ChromaDB API:
http://localhost:8080/api/v2/*
- Swagger UI:
http://localhost:8080/docs
✨ Features
Remote MCP server that enables all Claude clients (Desktop, Code, Mobile) to access the same self-hosted ChromaDB instance.
- Shared Memory Across Devices - All Claude clients use the same ChromaDB instance.
- Self-Hosted & Private - Your data stays on your infrastructure.
- Remote Access - Connect from anywhere via Tailscale or public internet.
- Complete ChromaDB Support - All CRUD operations via MCP tools.
- REST API Proxy - Direct ChromaDB access for Python/JavaScript.
- Unified Authentication - Single token protects both MCP and REST API endpoints.
- Easy Deployment - One-command installation with Docker.
📦 Installation
One-Command Installation
curl -fsSL https://raw.githubusercontent.com/meloncafe/chromadb-remote-mcp/release/scripts/install.sh | bash
Manual Installation
Option 1: Docker (Recommended - Pre-built Image)
mkdir chromadb-remote-mcp && cd chromadb-remote-mcp
curl -O https://raw.githubusercontent.com/meloncafe/chromadb-remote-mcp/release/docker-compose.yml
curl -O https://raw.githubusercontent.com/meloncafe/chromadb-remote-mcp/release/.env.example
cp .env.example .env
docker compose up -d
curl http://localhost:8080/health
docker compose logs -f
Option 2: Build from Source
git clone https://github.com/meloncafe/chromadb-remote-mcp.git
cd chromadb-remote-mcp
cp .env.example .env
docker compose -f docker-compose.dev.yml up -d
Option 3: Local Development
git clone https://github.com/meloncafe/chromadb-remote-mcp.git
cd chromadb-remote-mcp
yarn install
cp .env.example .env
yarn build
yarn start
Generate Secure Token
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
openssl rand -base64 32 | tr '+/' '-_' | tr -d '='
MCP_AUTH_TOKEN=your-generated-token-here
💻 Usage Examples
Using ChromaDB from Python
import chromadb
client = chromadb.HttpClient(
host="your-server.com",
port=443,
ssl=True,
headers={
"X-Chroma-Token": "YOUR_TOKEN"
}
)
client = chromadb.HttpClient(
host="localhost",
port=8080,
ssl=False,
headers={
"X-Chroma-Token": "YOUR_TOKEN"
}
)
collection = client.create_collection("my_collection")
collection.add(
documents=["Document 1", "Document 2"],
ids=["id1", "id2"]
)
results = collection.query(query_texts=["query"], n_results=2)
Alternative authentication:
from chromadb.config import Settings
client = chromadb.HttpClient(
host="your-server.com",
port=443,
ssl=True,
settings=Settings(
chroma_client_auth_provider="chromadb.auth.token_authn.TokenAuthClientProvider",
chroma_client_auth_credentials="YOUR_TOKEN"
)
)
📚 Documentation
Cross-Platform AI Memory Server
Compatible with ALL major AI platforms:
- Claude (Desktop, Mobile, Code)
- Gemini (CLI, Code Assist)
- Cursor, Cline, Windsurf, VS Code Copilot
- and use Remote MCP with any other MCP-compatible client
Architecture
Overview
┌──────────────────────────────┐ ┌──────────────┐
│ Claude Desktop + Mobile │ │ Claude Code │
│ (Custom Connector - synced) │ │ (CLI setup) │
└──────────────┬───────────────┘ └──────┬───────┘
│ │
│ MCP Remote Connector │
└─────────────┬───────────────┘
│ HTTPS
┌─────────▼──────────┐
│ Remote MCP │
│ Server (Node.js) │
│ │
│ • Auth Gateway │
│ • MCP Protocol │
│ • REST API Proxy │
└─────────┬──────────┘
│
┌─────────▼──────────┐
│ ChromaDB │
│ (Vector Database) │
│ │
│ • Embeddings │
│ • Collections │
│ • Semantic Search │
└────────────────────┘
How Clients Connect:
- Claude Desktop + Mobile: Set up once using custom connector in Claude Desktop, and it automatically syncs to the mobile app. Both share the same connection automatically.
- Claude Code: Requires separate setup using
claude mcp add CLI command.
All clients access the same self-hosted ChromaDB through this remote MCP server. Vector embeddings and semantic search results persist across all platforms.
API Endpoints
| Path |
Purpose |
Client |
Authentication |
/mcp |
MCP Protocol |
Claude Desktop/Code/Mobile |
✅ |
/api/v2/* |
ChromaDB REST API |
Python |
✅ |
/docs |
Swagger UI |
Browser (API docs) |
✅ |
/openapi.json |
OpenAPI Spec |
API tools |
✅ |
/health |
Health check |
Monitoring |
❌ |
How It Works
- Claude Desktop/Mobile: Add MCP server via custom connector (syncs automatically between devices).
- Claude Code: Add MCP server using
claude mcp add CLI command.
- Remote MCP Server authenticates requests and translates MCP protocol to ChromaDB operations.
- ChromaDB stores and retrieves vector embeddings for semantic search.
- Python can also access ChromaDB directly via the proxied REST API.
Benefits:
- Same vector database across all clients.
- Desktop and mobile share connection automatically.
- Self-hosted and private.
- Persistent memory across app restarts.
- Single source of truth for embeddings.
Configuration
Environment Variables (.env file)
All configuration is done through the .env file. Copy .env.example to .env and customize:
cp .env.example .env
| Variable |
Description |
Default |
Required |
PORT |
External port (Caddy reverse proxy) |
8080 |
No |
CHROMA_DATA_PATH |
ChromaDB data storage path (volume name, ./data, or absolute path) |
chroma-data |
No |
CHROMA_HOST |
ChromaDB host (internal) |
chromadb |
No |
CHROMA_PORT |
ChromaDB port (internal) |
8000 |
No |
CHROMA_TENANT |
ChromaDB tenant |
default_tenant |
No |
CHROMA_DATABASE |
ChromaDB database |
default_database |
No |
MCP_AUTH_TOKEN |
Authentication token for MCP and REST API |
- |
Yes (for public access) |
CHROMA_AUTH_TOKEN |
ChromaDB auth token (if ChromaDB requires auth) |
- |
No |
RATE_LIMIT_MAX |
Max requests per IP per 15 minutes |
100 |
No |
ALLOWED_ORIGINS |
Comma-separated list of allowed origins (DNS rebinding protection) |
- |
No |
ALLOW_QUERY_AUTH |
Enable authentication via query parameters (?apiKey=TOKEN) |
true |
No |
Authentication
IMPORTANT: For public internet access (Tailscale Funnel, Cloudflare Tunnel, etc.), you must set MCP_AUTH_TOKEN in your .env file.
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
openssl rand -base64 32 | tr '+/' '-_' | tr -d '='
MCP_AUTH_TOKEN=your-generated-token-here
Then restart the services:
docker compose restart
Supported authentication methods:
- Authorization Header (Most Secure):
Authorization: Bearer TOKEN
- Recommended for API clients and automated tools.
- Compliant with MCP specification.
- Example:
curl -H "Authorization: Bearer YOUR_TOKEN"
- X-Chroma-Token Header:
X-Chroma-Token: TOKEN
- For ChromaDB Python/JavaScript libraries.
- Compatible with ChromaDB client SDKs.
- Example:
client = chromadb.HttpClient(headers={"X-Chroma-Token": "TOKEN"})
- Query Parameter (Default Enabled):
?apiKey=TOKEN
- Required for Claude Desktop Custom Connector.
- Enables browser-based integrations.
- Enabled by default (
ALLOW_QUERY_AUTH=true).
- Set
ALLOW_QUERY_AUTH=false to disable if not needed.
Origin Header Validation (DNS Rebinding Protection)
The server validates the Origin header for browser requests to prevent DNS rebinding attacks. This security feature is enabled by default and protects your local MCP server from malicious websites.
Default allowed origins (always permitted):
- Localhost variants:
localhost, 127.0.0.1, [::1]
- Claude.ai domains:
https://claude.ai, https://api.anthropic.com
Configure additional allowed origins:
If you need to allow additional web applications or custom domains, add them to ALLOWED_ORIGINS in your .env file:
# Add additional custom domains (Claude.ai is already allowed by default)
ALLOWED_ORIGINS=https://myapp.com,https://yourdomain.com
When to configure ALLOWED_ORIGINS:
- ✅ Using Claude Desktop Custom Connector → No configuration needed (allowed by default).
- ✅ Accessing from custom web applications → Add your application's domain.
- ✅ Using Swagger UI remotely → Add your server's domain.
- ❌ Using Claude Code CLI → Not needed (no Origin header).
- ❌ Using Python/JavaScript clients → Not needed (no Origin header).
- ❌ Local development only → Not needed (localhost is allowed by default).
Example configurations:
# For custom web application
ALLOWED_ORIGINS=https://myapp.com,https://app.mycompany.com
# Multiple custom domains (comma-separated, spaces are trimmed)
ALLOWED_ORIGINS=https://myapp.com, https://api.example.com, https://dashboard.mycompany.com
# Leave empty if you only need Claude.ai and localhost
ALLOWED_ORIGINS=
Note: Claude.ai domains (https://claude.ai, https://api.anthropic.com) and localhost are always allowed, even if ALLOWED_ORIGINS is empty. Server-to-server requests (without Origin header) are always permitted.
Data Storage Configuration
ChromaDB data can be stored in three ways:
- Docker volume (default):
CHROMA_DATA_PATH=chroma-data
- Managed by Docker.
- Survives container restarts.
- Use
docker volume ls and docker volume inspect chroma-data to locate.
- Local directory:
CHROMA_DATA_PATH=./data
- Easy to backup and access.
- Stored in installation directory.
- Custom path:
CHROMA_DATA_PATH=/path/to/data
- Must be an absolute path.
- Useful for mounting external storage.
After changing CHROMA_DATA_PATH, restart the services:
docker compose restart
Connecting Claude
Claude Desktop + Mobile
Method 1: Custom Connector (Recommended - Pro/Team/Enterprise)
- Open Claude Desktop → Settings → Integrations → Custom Connector.
- Click "Add Custom Server".
- Enter:
- Name:
ChromaDB
- URL:
https://your-server.com/mcp?apiKey=YOUR_TOKEN
Note: Custom connector automatically syncs to the mobile app. Authentication is mandatory for remote access.
Method 2: mcp-remote Wrapper (Free/Pro Users)
If you don't have access to Custom Connectors, use the mcp-remote package as a workaround:
Configuration file location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add to configuration file:
{
"mcpServers": {
"chromadb": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://your-server.com/mcp?apiKey=YOUR_TOKEN"]
}
}
}
Restart Claude Desktop after editing the file.
Important: Remote MCP servers cannot be configured directly in claude_desktop_config.json using streamableHttp transport. You must either use Custom Connectors or the mcp-remote wrapper package.
Claude Code
CLI Command:
claude mcp add --transport http chromadb https://your-server.com/mcp
claude mcp add --transport http chromadb https://your-server.com/mcp?apiKey=YOUR_TOKEN
claude mcp add --transport http chromadb https://your-server.com/mcp \
--header "Authorization: Bearer YOUR_TOKEN"
claude mcp list
Available Tools
The MCP server provides these tools for Claude:
Collection Management
chroma_list_collections - List all collections.
chroma_create_collection - Create a new collection.
chroma_delete_collection - Delete a collection.
chroma_get_collection_info - Get collection metadata.
chroma_get_collection_count - Get document count.
chroma_peek_collection - Preview collection contents.
Document Operations
chroma_add_documents - Add documents with embeddings.
chroma_query_documents - Semantic search (vector similarity).
chroma_get_documents - Retrieve documents by ID or filter.
chroma_update_documents - Update existing documents.
chroma_delete_documents - Delete documents.
🔧 Technical Details
Deployment
Option 1: Tailscale VPN (Recommended)
docker compose up -d
tailscale serve https / http://127.0.0.1:8080
tailscale serve status
Advantages:
- Automatic HTTPS certificates.
- No public internet exposure.
- Encrypted VPN tunnel.
- Authentication optional (VPN provides security layer).
Option 2: Tailscale Funnel (Public Internet)
tailscale funnel 8080 on
tailscale serve https / http://127.0.0.1:8080
tailscale serve status
Warning: This exposes your server to the public internet. Authentication is mandatory! Set MCP_AUTH_TOKEN in your environment.
tailscale funnel 8080 off
Option 3: Cloudflare Tunnel
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o cloudflared
chmod +x cloudflared
./cloudflared tunnel login
./cloudflared tunnel create chroma-mcp
./cloudflared tunnel --url http://localhost:3000
Option 4: Nginx Reverse Proxy
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
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;
}
}
Security
Code Quality & Security Analysis
This project follows strict security practices and has resolved all security issues identified by static analysis:
- ✅ Zero Active Issues: All OWASP and CWE security findings have been resolved.
- 🔒 Static Analysis: Continuous monitoring with DeepSource.
- 🛡️ Security Standards: Compliant with OWASP Top 10 and Node.js security best practices.
- 📊 Automated Scanning: Dependabot, CodeQL, and container vulnerability scanning.
For detailed security information, see Security Policy.
Security Recommendations
- Enable Authentication for Public Access
- Set
MCP_AUTH_TOKEN when using Tailscale Funnel or public internet.
- Generate strong tokens:
openssl rand -base64 32 | tr '+/' '-_' | tr -d '='.
- Rotate tokens regularly.
- Use HTTPS
- Tailscale provides automatic HTTPS certificates.
- Use reverse proxy (Nginx/Caddy) with Let's Encrypt for other deployments.
- Prefer VPN Over Public Internet
- Tailscale Serve (VPN-only) is more secure than Funnel (public).
- Authentication is optional within VPN but mandatory for public access.
- Monitor Access
docker compose logs mcp-server | grep "Unauthorized"
- Network Isolation
- Keep ChromaDB on private network.
- Only expose MCP server to public internet.
Testing
Local Testing
curl http://localhost:3000/health
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl http://localhost:3000/api/v2/heartbeat
Remote Testing (with authentication)
curl -X POST https://your-server.com/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
curl -X POST "https://your-server.com/mcp?apiKey=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
curl https://your-server.com/api/v2/heartbeat \
-H "X-Chroma-Token: YOUR_TOKEN"
https://your-server.com/docs?apiKey=YOUR_TOKEN
Troubleshooting
ChromaDB Connection Failed
curl http://localhost:8000/api/v2/heartbeat
docker run -d -p 8000:8000 chromadb/chroma:latest
docker compose logs mcp-server
MCP Server Not Responding
docker compose logs mcp-server
lsof -i :3000
docker compose restart
Claude Desktop Connection Issues
- Restart Claude Desktop.
- Verify URL includes
/mcp path.
- Confirm transport type is
streamableHttp (not sse).
- Check authentication token if enabled.
- For Custom Connector: Ensure Tailscale Funnel is active.
TLS Handshake Timeout on Local Network
If you're connecting from the same local network as the server and using Tailscale Funnel HTTPS:
Problem: TLS handshake fails with timeout when accessing https://your-server.ts.net from the same network.
Root cause: Tailscale Funnel has issues with TLS termination when clients on the same LAN try to connect via the public Funnel domain.
Solution: Use direct local network connection instead of Tailscale HTTPS:
claude mcp remove chromadb
claude mcp add chromadb --transport http \
http://192.168.x.x:8080/mcp \
--header "Authorization: Bearer YOUR_TOKEN"
claude mcp add chromadb --transport http \
http://server-hostname:8080/mcp \
--header "Authorization: Bearer YOUR_TOKEN"
Verification:
curl http://192.168.x.x:8080/health
Note: External clients should continue using Tailscale Funnel HTTPS. This issue only affects clients on the same LAN as the server.
Authentication Errors (401)
docker compose exec mcp-server env | grep MCP_AUTH_TOKEN
curl -X POST https://your-server.com/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
curl -X POST https://your-server.com/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
Development
Building from Source
git clone https://github.com/meloncafe/chromadb-remote-mcp.git
cd chromadb-remote-mcp
yarn install
yarn dev
yarn build
yarn type-check
Testing
The project includes integration tests with Docker-based E2E validation:
yarn test
yarn test:keep
./scripts/test.sh --help
Integration Test Coverage:
- ✅ Health check endpoint.
- ✅ Authentication (Bearer token, X-Chroma-Token, query parameter).
- ✅ MCP protocol (tools/list, tools/call).
- ✅ ChromaDB REST API proxy.
- ✅ Collection CRUD operations.
- ✅ Rate limiting.
- ✅ Unauthorized access handling.
Unit Tests:
yarn test:unit
yarn test:unit:watch
yarn test:unit:coverage
yarn test:all
Unit Test Coverage:
- ✅ Authentication utilities (timing-safe comparison, buffer operations).
- ✅ Input validation (collection names, document IDs, metadata).
- ✅ Data processing (response formatting, JSON serialization).
- ✅ Error message formatting.
See __tests__/README.md for detailed testing strategy.
Code Quality & Coverage
This project uses Codecov for code coverage tracking and test analytics.
Docker Development
Local Build and Test
yarn docker:build:local
./scripts/build.sh --platform linux/amd64 --load
docker run -p 3000:3000 \
-e MCP_AUTH_TOKEN=test123 \
devsaurus/chromadb-remote-mcp:latest
Multi-Platform Build
yarn docker:build
./scripts/build.sh --version 1.2.3
./scripts/build.sh --repo myuser/my-mcp --version dev
Push to Docker Hub
yarn docker:push
VERSION=1.2.3 yarn docker:push
./scripts/build.sh --version 1.2.3 --push
DOCKER_REPO=myuser/my-mcp ./scripts/build.sh --version 1.2.3 --push
Environment Variables for Docker Scripts:
export DOCKER_REPO=myuser/my-mcp
export VERSION=1.2.3
export DOCKER_USERNAME=myuser
export DOCKER_PASSWORD=mytoken
Development Scripts
All development scripts are located in scripts/:
| Script |
Purpose |
Usage |
build.sh |
Build and push Docker images |
./scripts/build.sh --help |
test.sh |
Run integration tests |
./scripts/test.sh --help |
install.sh |
One-command installation |
curl ... | bash |
Quick Development Workflow:
vim src/index.ts
yarn dev
yarn test
yarn docker:build:local
docker-compose up
./scripts/build.sh --version 1.2.3 --push
Project Structure
chromadb-remote-mcp/
├── .github/
│ ├── ISSUE_TEMPLATE/ # GitHub issue templates
│ └── workflows/ # GitHub Actions (publish-release, security-scan, chromadb-version-check)
├── scripts/
│ ├── build.sh # Docker build and push script (multi-platform)
│ ├── test.sh # Integration test runner
│ └── install.sh # One-command installation
├── src/
│ ├── index.ts # Main server entry point
│ ├── chroma-tools.ts # MCP tool definitions and handlers
│ └── types.ts # TypeScript type definitions
├── docker-compose.yml # Production (prebuilt image)
├── docker-compose.dev.yml # Development (builds from source)
├── Dockerfile # MCP server Docker image
├── .env.example # Environment variables template
├── package.json # Node.js dependencies
├── tsconfig.json # TypeScript configuration
├── SECURITY.md # Security policy
├── CONTRIBUTING.md # Contribution guidelines
├── CODE_OF_CONDUCT.md # Code of conduct
├── CHANGELOG.md # Version history
└── LICENSE # MIT license
📄 License
MIT License
Resources
Support
If you encounter any issues or have questions, please open an issue.