@rhofkens/mcp-quotes-server-claude-code
Version:
Model Context Protocol (MCP) server for managing and serving quotes
477 lines (397 loc) • 11.4 kB
Markdown
# MCP Quotes Server Deployment Guide
## Table of Contents
- [Prerequisites](#prerequisites)
- [Deployment Options](#deployment-options)
- [Environment Configuration](#environment-configuration)
- [Transport Modes](#transport-modes)
- [Docker Deployment](#docker-deployment)
- [Production Deployment](#production-deployment)
- [Security Considerations](#security-considerations)
- [Monitoring and Logging](#monitoring-and-logging)
- [Scaling Considerations](#scaling-considerations)
- [Troubleshooting](#troubleshooting)
## Prerequisites
### System Requirements
- Node.js >= 18.0.0
- npm >= 8.0.0
- RAM: Minimum 512MB, recommended 1GB
- Disk Space: 200MB for application and dependencies
### Required API Keys
- **Serper.dev API Key**: Required for quote searches
- Sign up at https://serper.dev
- Free tier includes 2,500 queries/month
- Set as `SERPER_API_KEY` environment variable
## Deployment Options
### 1. Local Development
```bash
# Clone the repository
git clone https://github.com/yourusername/mcp-quotes-server.git
cd mcp-quotes-server
# Install dependencies
npm install
# Build the project
npm run build
# Set environment variables
export SERPER_API_KEY="your-api-key"
# Run the server (STDIO mode)
node dist/index.js
```
### 2. NPM Global Installation
```bash
# Install globally
npm install -g mcp-quotes-server
# Run with environment variable
SERPER_API_KEY="your-api-key" mcp-quotes-server
```
### 3. Direct Execution with npx
```bash
# Run without installation
SERPER_API_KEY="your-api-key" npx mcp-quotes-server
```
## Environment Configuration
### Required Environment Variables
| Variable | Description | Required | Default |
|----------|-------------|----------|---------|
| `SERPER_API_KEY` | Serper.dev API key for quote searches | Yes | None |
### Optional Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `NODE_ENV` | Environment mode (development/production) | development |
| `LOG_LEVEL` | Logging level (debug/info/warn/error) | info |
| `MCP_TRANSPORT` | Transport type (stdio/http) | stdio |
| `MCP_HTTP_PORT` | HTTP server port | 3000 |
| `MCP_HTTP_HOST` | HTTP server host | localhost |
| `MCP_HTTP_PATH` | HTTP endpoint path | /mcp |
| `API_TIMEOUT` | API request timeout (ms) | 5000 |
| `MAX_RETRIES` | Maximum retry attempts | 3 |
| `CACHE_TTL` | Cache time-to-live (seconds) | 3600 |
### Configuration File (.env)
Create a `.env` file in the project root:
```env
# Required
SERPER_API_KEY=your-serper-api-key
# Optional
NODE_ENV=production
LOG_LEVEL=info
MCP_TRANSPORT=http
MCP_HTTP_PORT=3000
MCP_HTTP_HOST=0.0.0.0
MCP_HTTP_PATH=/mcp
```
## Transport Modes
### STDIO Transport (Default)
STDIO transport is used for direct integration with Claude Desktop or other MCP clients.
```bash
# Start in STDIO mode (default)
SERPER_API_KEY="your-api-key" node dist/index.js
```
**Claude Desktop Configuration:**
```json
{
"mcpServers": {
"quotes": {
"command": "node",
"args": ["/path/to/mcp-quotes-server/dist/index.js"],
"env": {
"SERPER_API_KEY": "your-api-key"
}
}
}
}
```
### HTTP Transport
HTTP transport enables remote access and better scalability.
```bash
# Start in HTTP mode
MCP_TRANSPORT=http \
MCP_HTTP_PORT=3000 \
MCP_HTTP_HOST=0.0.0.0 \
SERPER_API_KEY="your-api-key" \
node dist/index.js
```
**Endpoints:**
- **MCP Protocol**: `POST http://localhost:3000/mcp`
- **Health Check**: `GET http://localhost:3000/health`
**Testing HTTP Mode:**
```bash
# Initialize session
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "curl-client",
"version": "1.0.0"
}
}
}'
```
## Docker Deployment
### Dockerfile
```dockerfile
FROM node:18-alpine
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./
RUN npm ci --only=production
# Bundle app source
COPY dist ./dist
# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs
# Expose port for HTTP transport
EXPOSE 3000
# Start the server
CMD ["node", "dist/index.js"]
```
### docker-compose.yml
```yaml
version: '3.8'
services:
mcp-quotes-server:
build: .
environment:
- SERPER_API_KEY=${SERPER_API_KEY}
- MCP_TRANSPORT=http
- MCP_HTTP_HOST=0.0.0.0
- MCP_HTTP_PORT=3000
- NODE_ENV=production
- LOG_LEVEL=info
ports:
- "3000:3000"
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
### Building and Running
```bash
# Build the Docker image
docker build -t mcp-quotes-server .
# Run with Docker
docker run -d \
--name mcp-quotes \
-p 3000:3000 \
-e SERPER_API_KEY="your-api-key" \
-e MCP_TRANSPORT=http \
mcp-quotes-server
# Run with docker-compose
docker-compose up -d
```
## Production Deployment
### 1. Process Management with PM2
```bash
# Install PM2
npm install -g pm2
# Create ecosystem file
cat > ecosystem.config.js << EOF
module.exports = {
apps: [{
name: 'mcp-quotes-server',
script: './dist/index.js',
instances: 1,
exec_mode: 'fork',
env: {
NODE_ENV: 'production',
MCP_TRANSPORT: 'http',
MCP_HTTP_PORT: 3000,
MCP_HTTP_HOST: '0.0.0.0',
SERPER_API_KEY: process.env.SERPER_API_KEY
},
error_file: './logs/err.log',
out_file: './logs/out.log',
log_file: './logs/combined.log',
time: true
}]
};
EOF
# Start with PM2
pm2 start ecosystem.config.js
# Save PM2 configuration
pm2 save
pm2 startup
```
### 2. Systemd Service
```ini
# /etc/systemd/system/mcp-quotes-server.service
[Unit]
Description=MCP Quotes Server
After=network.target
[Service]
Type=simple
User=nodejs
WorkingDirectory=/opt/mcp-quotes-server
ExecStart=/usr/bin/node /opt/mcp-quotes-server/dist/index.js
Restart=on-failure
RestartSec=10
Environment="NODE_ENV=production"
Environment="MCP_TRANSPORT=http"
Environment="MCP_HTTP_PORT=3000"
Environment="MCP_HTTP_HOST=0.0.0.0"
EnvironmentFile=/etc/mcp-quotes-server/config.env
[Install]
WantedBy=multi-user.target
```
### 3. Reverse Proxy with Nginx
```nginx
server {
listen 80;
server_name quotes.example.com;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name quotes.example.com;
ssl_certificate /etc/letsencrypt/live/quotes.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/quotes.example.com/privkey.pem;
location /mcp {
proxy_pass http://localhost:3000/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;
proxy_cache_bypass $http_upgrade;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location /health {
proxy_pass http://localhost:3000/health;
}
}
```
## Security Considerations
### 1. API Key Management
- **Never commit API keys** to version control
- Use environment variables or secure key management services
- Rotate API keys regularly
- Use different keys for development and production
### 2. Network Security
- **Bind to localhost** for local deployments
- Use **HTTPS** for production HTTP transport
- Implement **rate limiting** for public endpoints
- Use **firewall rules** to restrict access
### 3. Authentication (HTTP Transport)
- Consider implementing API key authentication for HTTP endpoints
- Use OAuth 2.0 for production deployments
- Implement request signing for additional security
### 4. Input Validation
- The server validates all inputs automatically
- Additional validation can be added for specific deployment needs
### 5. Security Headers (HTTP Transport)
Add security headers in your reverse proxy:
```nginx
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
```
## Monitoring and Logging
### 1. Log Files
Logs are stored in the `logs/` directory:
- `error.log`: Error-level messages only
- `combined.log`: All log messages
- `debug.log`: Debug messages (development only)
### 2. Health Monitoring
```bash
# Check health endpoint
curl http://localhost:3000/health
# Response:
{
"status": "ok",
"transport": "http",
"sessions": 0
}
```
### 3. Metrics to Monitor
- **Response Times**: Target < 2 seconds
- **Error Rates**: Monitor 4xx and 5xx errors
- **API Usage**: Track Serper.dev API calls
- **Cache Hit Rate**: Target > 60%
- **Memory Usage**: Should stay under 500MB
### 4. Monitoring Tools
- **Prometheus + Grafana**: For metrics visualization
- **ELK Stack**: For log aggregation
- **Uptime Robot**: For availability monitoring
- **New Relic / DataDog**: For APM
### 5. Alerting
Set up alerts for:
- Server downtime
- High error rates (> 5%)
- Slow response times (> 5s)
- API quota warnings
- Memory usage > 80%
## Scaling Considerations
### 1. Horizontal Scaling (HTTP Transport)
- Deploy multiple instances behind a load balancer
- Use sticky sessions for WebSocket connections
- Consider using Redis for shared cache
### 2. Caching Strategy
- Local cache handles most repeated queries
- Cache TTL is configurable (default: 1 hour)
- Pre-warming cache for popular quotes
### 3. Rate Limiting
- Implement rate limiting at reverse proxy level
- Consider per-client rate limits
- Monitor Serper.dev API quota usage
### 4. Database Integration (Future)
- Consider adding database for persistent cache
- Store popular quotes locally
- Reduce external API dependency
## Troubleshooting
### Common Issues
**1. Server Won't Start**
- Check Node.js version: `node --version` (must be >= 18)
- Verify build completed: `npm run build`
- Check for port conflicts (HTTP mode)
- Review error logs in `logs/error.log`
**2. API Key Issues**
```bash
# Test API key directly
curl -X POST https://google.serper.dev/search \
-H "X-API-KEY: your-api-key" \
-H "Content-Type: application/json" \
-d '{"q": "test"}'
```
**3. HTTP Transport Connection Issues**
- Verify server is running: `ps aux | grep node`
- Check port availability: `netstat -tulpn | grep 3000`
- Test with curl before using MCP client
- Check firewall rules
**4. High Memory Usage**
- Review cache size and TTL settings
- Check for memory leaks with `node --inspect`
- Monitor with: `pm2 monit`
**5. Slow Response Times**
- Check Serper.dev API response times
- Review network latency
- Monitor cache hit rates
- Consider increasing `API_TIMEOUT`
### Debug Mode
```bash
# Enable debug logging
LOG_LEVEL=debug \
NODE_ENV=development \
SERPER_API_KEY="your-api-key" \
node dist/index.js
```
### Support
- GitHub Issues: [Report bugs and request features]
- Documentation: Check `/docs` folder
- Logs: Review `logs/` directory for detailed error information