Skip to main content

Configuration

Complete configuration guide for vMCP.

Environment Variables

Backend Configuration

Create a .env file in the backend/ directory:

# Database
DATABASE_URL=postgresql://vmcp:vmcp@localhost:5432/vmcp

# Server
HOST=0.0.0.0
PORT=8000

# Logging
LOG_LEVEL=INFO

# Frontend
FRONTEND_DIR=../frontend/dist

# CORS (Optional)
CORS_ORIGINS=http://localhost:3000,http://localhost:8000

Database Configuration

PostgreSQL Connection String Format

postgresql://[user]:[password]@[host]:[port]/[database]

Examples:

Local development:

DATABASE_URL=postgresql://vmcp:vmcp@localhost:5432/vmcp

Docker container:

DATABASE_URL=postgresql://vmcp:vmcp@postgres:5432/vmcp

Cloud hosted (with SSL):

DATABASE_URL=postgresql://user:pass@host.com:5432/db?sslmode=require

Connection Pool Settings

For high-traffic deployments, configure the connection pool in backend/vmcp/database.py:

engine = create_async_engine(
DATABASE_URL,
echo=False,
pool_size=20, # Number of persistent connections
max_overflow=10, # Max additional connections
pool_timeout=30, # Seconds to wait for connection
pool_recycle=3600, # Recycle connections after 1 hour
)

Logging Configuration

Log Levels

LOG_LEVEL=DEBUG   # Verbose, shows all operations
LOG_LEVEL=INFO # Standard operational info (recommended)
LOG_LEVEL=WARNING # Only warnings and errors
LOG_LEVEL=ERROR # Only errors

Structured Logging

vMCP uses structured logging. Configure in backend/vmcp/logging_config.py:

LOGGING_CONFIG = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"default": {
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
},
"json": {
"()": "pythonjsonlogger.jsonlogger.JsonFormatter",
"format": "%(asctime)s %(name)s %(levelname)s %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "default",
"stream": "ext://sys.stdout"
},
"file": {
"class": "logging.handlers.RotatingFileHandler",
"formatter": "json",
"filename": "logs/vmcp.log",
"maxBytes": 10485760, # 10MB
"backupCount": 5
}
},
"root": {
"level": "INFO",
"handlers": ["console", "file"]
}
}

CORS Configuration

For frontend development or custom domains:

CORS_ORIGINS=http://localhost:3000,http://localhost:8000,https://vmcp.yourdomain.com

In production, restrict to your domain:

CORS_ORIGINS=https://vmcp.yourdomain.com

Docker Configuration

docker-compose.yml

version: '3.8'

services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: vmcp
POSTGRES_PASSWORD: vmcp
POSTGRES_DB: vmcp
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-LABEL", "pg_isready", "-U", "vmcp"]
interval: 10s
timeout: 5s
retries: 5

backend:
build:
context: .
dockerfile: Dockerfile
environment:
DATABASE_URL: postgresql://vmcp:vmcp@postgres:5432/vmcp
LOG_LEVEL: INFO
HOST: 0.0.0.0
PORT: 8000
ports:
- "8000:8000"
depends_on:
postgres:
condition: service_healthy
volumes:
# Mount for development
- ./backend:/app/backend
- ./frontend/dist:/app/frontend/dist

volumes:
postgres_data:

Environment Overrides

Override environment variables:

# Single variable
DATABASE_URL=postgresql://custom@localhost/db docker compose up

# Environment file
docker compose --env-file .env.production up

Frontend Configuration

Vite Configuration

The frontend build configuration is in frontend/vite.config.ts:

export default defineConfig({
plugins: [react()],
server: {
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
},
},
},
build: {
outDir: 'dist',
assetsDir: 'assets',
sourcemap: false,
rollupOptions: {
output: {
manualChunks: {
'react-vendor': ['react', 'react-dom'],
'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu'],
},
},
},
},
})

API Configuration

Update API base URL in frontend/src/lib/api.ts:

const API_BASE_URL = import.meta.env.VITE_API_URL || '/api'

// For development with separate backend:
// VITE_API_URL=http://localhost:8000/api

MCP Server Configuration

Server Transport Types

Stdio (Command-line)

{
"transport_type": "stdio",
"config": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"],
"env": {
"VAR_NAME": "value"
},
"cwd": "/working/directory"
}
}

HTTP

{
"transport_type": "http",
"config": {
"url": "https://api.example.com/mcp",
"method": "POST",
"headers": {
"Authorization": "Bearer token",
"Content-Type": "application/json"
},
"timeout": 30
}
}

SSE (Server-Sent Events)

{
"transport_type": "sse",
"config": {
"url": "https://sse.example.com/events",
"headers": {
"Authorization": "Bearer token"
},
"reconnect": true,
"reconnect_interval": 5
}
}

OAuth Configuration

For MCP servers requiring OAuth:

{
"oauth": {
"provider": "github",
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"scopes": ["repo", "user"],
"redirect_uri": "http://localhost:8000/oauth/callback"
}
}

Production Deployment

# Production .env
DATABASE_URL=postgresql://vmcp:secure_password@db.internal:5432/vmcp?sslmode=require
LOG_LEVEL=WARNING
HOST=0.0.0.0
PORT=8000
CORS_ORIGINS=https://vmcp.yourdomain.com

Security Considerations

  1. Use strong database passwords
  2. Enable SSL for database connections (?sslmode=require)
  3. Restrict CORS origins to your domain only
  4. Use environment variables for secrets (never commit .env)
  5. Enable HTTPS with reverse proxy (nginx, Caddy)

Reverse Proxy (nginx)

server {
listen 80;
server_name vmcp.yourdomain.com;
return 301 https://$server_name$request_uri;
}

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

ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;

location / {
proxy_pass http://localhost:8000;
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;
}

location /api {
proxy_pass http://localhost:8000/api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Performance Tuning

Database Indexes

Add indexes for frequently queried fields:

CREATE INDEX idx_vmcp_user_id ON vmcps(user_id);
CREATE INDEX idx_mcp_server_user_id ON mcp_servers(user_id);
CREATE INDEX idx_logs_timestamp ON logs(timestamp);
CREATE INDEX idx_logs_vmcp_id ON logs(vmcp_id);

Cache Configuration

Configure Redis for caching (optional):

REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0")

# Cache tool results for 5 minutes
TOOL_CACHE_TTL = 300

# Cache resource reads for 10 minutes
RESOURCE_CACHE_TTL = 600

Worker Configuration

For high concurrency:

# Run with multiple workers
uvicorn vmcp.main:app --workers 4 --host 0.0.0.0 --port 8000

Monitoring

Health Check Endpoint

GET /health

Returns:

{
"status": "healthy",
"database": "connected",
"version": "1.0.0"
}

Metrics (Prometheus)

Enable Prometheus metrics:

from prometheus_fastapi_instrumentator import Instrumentator

Instrumentator().instrument(app).expose(app)

Access metrics at:

GET /metrics

Backup and Recovery

Database Backup

# Backup
pg_dump -h localhost -U vmcp -d vmcp > backup.sql

# Restore
psql -h localhost -U vmcp -d vmcp < backup.sql

Automated Backups

#!/bin/bash
# backup.sh
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump -h localhost -U vmcp -d vmcp | gzip > backups/vmcp_$DATE.sql.gz

# Keep only last 7 days
find backups/ -name "vmcp_*.sql.gz" -mtime +7 -delete

Run daily with cron:

0 2 * * * /path/to/backup.sh

Next Steps