MCP Server (Self-Hosted)
Run the MCP (Model Context Protocol) server on your self-hosted Synjar instance to enable ChatGPT and Claude integrations.
Overview
MCP allows AI assistants like ChatGPT and Claude to search your knowledge base automatically. No code required - just copy your MCP URL and add it to your AI assistant.
What you get:
- ChatGPT Developer Mode integration
- Claude Custom Connectors integration
- Automatic searching (no manual link pasting)
- Same privacy controls as direct search
Prerequisites
Before setting up MCP:
- ✅ Synjar self-hosted instance running (Docker/Kubernetes)
- ✅ HTTPS certificate (required - ChatGPT/Claude reject HTTP)
- ✅ Port 443 accessible from the internet
- ✅ Search Link created in your workspace
ChatGPT and Claude will REJECT HTTP connections. HTTPS is mandatory for MCP to work.
Docker Compose Setup
Your existing docker-compose.yml already includes the MCP endpoint. No additional services required.
# docker-compose.yml
services:
synjar:
image: synjar/community:latest
environment:
DATABASE_URL: postgresql://synjar:password@postgres:5432/synjar
DEPLOYMENT_MODE: self-hosted
JWT_SECRET: ${JWT_SECRET}
ports:
- "3000:3000" # Internal port
depends_on:
- postgres
nginx:
image: nginx:alpine
ports:
- "443:443"
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- synjar
postgres:
image: postgres:15
environment:
POSTGRES_DB: synjar
POSTGRES_USER: synjar
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
HTTPS Setup
Option 1: Let's Encrypt (Recommended)
Free, automatic SSL certificates:
# Install certbot
sudo apt install certbot python3-certbot-nginx
# Get certificate
sudo certbot --nginx -d your-domain.com
# Auto-renewal is configured automatically
Option 2: Custom Certificate
For enterprise PKI or internal CA:
# nginx.conf
events {
worker_connections 1024;
}
http {
# Redirect HTTP to HTTPS
server {
listen 80;
server_name your-domain.com;
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# HSTS header (enforce HTTPS for 1 year)
add_header Strict-Transport-Security "max-age=31536000" always;
# Security headers
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
# Proxy to Synjar
location / {
proxy_pass http://synjar: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;
}
}
}
SSL Requirements
| Requirement | Minimum | Recommended |
|---|---|---|
| TLS Version | 1.2 | 1.3 |
| Certificate | Valid CA-signed | Let's Encrypt or Enterprise CA |
| Self-signed | ❌ Not supported | - |
ChatGPT and Claude reject self-signed certificates. Use Let's Encrypt (free) or a commercial CA.
Get Your MCP URL
- Log in to your Synjar instance
- Go to Workspace Settings → Search Links
- Click on your Search Link (or create one)
- Find the "MCP Server URL" section
- Copy the URL
Your URL will look like:
https://your-domain.com/mcp/abc123def456...
Add to ChatGPT
- Open ChatGPT
- Go to Settings → Developer Mode
- Click "Add Custom Connector"
- Paste your MCP URL
- You'll see "Unverified Connector" warning - this is normal for self-hosted
- Click "Add Anyway"
- Done! ✅
Add to Claude
- Open Claude
- Go to Settings → Custom Connectors
- Click "Add New"
- Paste your MCP URL
- You'll see "Unverified Connector" warning - this is normal for self-hosted
- Click "Add Anyway"
- Done! ✅
Self-hosted instances show an "Unverified Connector" warning because they're not registered with Anthropic/OpenAI. This is expected behavior - click "Add Anyway" to proceed.
Verification
Test your MCP endpoint:
# Check HTTPS connection
curl -v https://your-domain.com/mcp/your-token
# Expected: HTTP 200 or 400 (valid connection, even if method wrong)
# Not expected: Connection refused or SSL errors
Verify TLS version:
openssl s_client -connect your-domain.com:443 -tls1_2
Rate Limiting
Default rate limits for MCP endpoint:
| Limit | Value | Purpose |
|---|---|---|
| Per IP | 100 req/min | Prevent DDoS |
| Per Link | 30 req/min | Prevent abuse |
Override in environment variables:
MCP_RATE_LIMIT_IP=200
MCP_RATE_LIMIT_LINK=50
Firewall Configuration
Allow incoming traffic:
# UFW (Ubuntu)
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp # For HTTP→HTTPS redirect
# iptables
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
For restrictive environments, MCP only needs:
- Inbound: Port 443 (HTTPS) from internet
- Outbound: None (MCP is stateless)
Troubleshooting
"Connection failed" in ChatGPT/Claude
Checklist:
- URL starts with
https://(nothttp://) - SSL certificate is valid (not expired)
- Certificate is NOT self-signed
- Port 443 is open
- Domain resolves correctly
Test:
curl -v https://your-domain.com/mcp/test
"Invalid or expired token"
The Search Link token is invalid or revoked.
Fix:
- Check Search Link is active in Synjar UI
- Check
expiresAtdate hasn't passed - Create new Search Link if needed
"TLS handshake failed"
Your server may not support TLS 1.2+.
Check TLS versions:
nmap --script ssl-enum-ciphers -p 443 your-domain.com
Fix: Update nginx configuration to require TLS 1.2+:
ssl_protocols TLSv1.2 TLSv1.3;
Certificate chain issues
Check certificate chain:
openssl s_client -connect your-domain.com:443 -showcerts
Fix: Include intermediate certificates in your cert.pem:
cat your-cert.pem intermediate.pem > full-chain.pem
Monitoring
Monitor MCP endpoint health:
# Add to your monitoring
curl -s -o /dev/null -w "%{http_code}" https://your-domain.com/health
Key metrics:
- MCP request count (via Search Link usage in UI)
- Error rate (should be < 1%)
- Latency (should be < 2s p95)
Security Best Practices
- Rotate tokens every 90 days - Set calendar reminder
- Use expiry dates - For temporary access (contractors, demos)
- Monitor usage - Check for anomalies in Search Link dashboard
- Keep nginx updated - Security patches
- Enable HSTS - Force HTTPS for all requests
See also
- MCP Connectors Guide - Full MCP documentation
- Search Links - Creating Search Links
- Environment Variables - All config options
- Monitoring - Health checks and metrics