The Error That Almost Killed Our Production Deployment

It was 2:47 AM when our on-call engineer received the alert: ConnectionError: timeout after 30000ms — MCP gateway unreachable from subnet 10.0.3.0/24. We had just deployed the Model Context Protocol (MCP) server behind our enterprise firewall, and everything looked perfect on paper. The security team had signed off, the network team had opened the ports, and our CI/CD pipeline had passed all tests. But production traffic from our downstream microservices was failing silently, leaving our RAG pipeline serving stale data while our users complained about hallucinated responses.

I spent the next four hours tracing packet flows, reading RFCs, and finally—after checking the audit log—realized our TCP keepalive settings were incompatible with the corporate load balancer's timeout policies. That single misconfiguration cost us a Saturday night and taught me more about MCP enterprise deployment than any documentation ever could.

This guide is the tutorial I wish I had. I'll walk you through deploying MCP in enterprise intranets with proper security gateways, comprehensive audit logging, and the production-hardened configuration that keeps systems running at 99.95% uptime. Whether you're connecting to HolySheep's AI infrastructure or building your own MCP gateway, the patterns here apply universally.

What is the Model Context Protocol (MCP)?

The Model Context Protocol is an open standard developed by Anthropic that enables AI assistants to connect with external data sources, tools, and services through a standardized interface. Think of it as USB for AI applications—a universal connector that eliminates the need for custom integrations for every AI provider and data source combination.

In enterprise environments, MCP becomes critical infrastructure. When your legal AI needs to query contract databases, your customer service bot needs real-time inventory data, or your code review assistant needs access to your GitLab instance, MCP provides the secure, auditable bridge between your AI models and your internal systems.

HolySheep AI supports native MCP integration with their unified API endpoint, allowing you to connect any MCP-compatible tool to their infrastructure while maintaining enterprise-grade security controls. Their rate structure of $1 = ¥1 represents an 85%+ cost savings compared to domestic alternatives charging ¥7.3 per dollar, and their sub-50ms latency makes real-time AI applications feasible even in latency-sensitive environments.

Architecture Overview: MCP Enterprise Deployment Patterns

Before diving into configuration, let's understand the three primary deployment patterns for MCP in enterprise intranets:

For most enterprise deployments, the Forward Proxy pattern offers the best balance of security, performance, and operational complexity. Let's build it.

Prerequisites and Environment Setup

You'll need the following components before starting your MCP enterprise deployment:

# Initialize the deployment environment
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y docker.io docker-compose nginx postgresql-15 redis-server certbot python3-certbot-nginx

Configure system limits for high-throughput scenarios

sudo tee /etc/security/limits.d/mcp.conf <Enable IP forwarding for proxy mode sudo sysctl -w net.ipv4.ip_forward=1 sudo tee /etc/sysctl.d/99-mcp.conf <Verify installation docker --version && docker-compose --version && nginx -v

Building the Security Gateway

The MCP Security Gateway is the cornerstone of your enterprise deployment. It intercepts all MCP traffic, applies policy checks, maintains audit logs, and forwards approved requests to backend services. Here's the complete implementation:

# docker-compose.yml — MCP Security Gateway Stack
version: '3.8'

services:
  mcp-gateway:
    image: holysheep/mcp-gateway:2.4.1
    container_name: mcp-gateway
    restart: unless-stopped
    ports:
      - "8443:8443"
      - "8444:8444"
    environment:
      - NODE_ENV=production
      - LOG_LEVEL=info
      - GATEWAY_PORT=8443
      - ADMIN_PORT=8444
      - REDIS_URL=redis://redis:6379
      - DATABASE_URL=postgresql://mcp_user:SecureP@ss123@postgres:5432/mcp_audit
      - SESSION_SECRET=${SESSION_SECRET}
      - MAX_REQUEST_SIZE=10mb
      - REQUEST_TIMEOUT=30000
      - KEEPALIVE_TIMEOUT=65000
      - TCP_KEEPALIVE=true
      - RATE_LIMIT_WINDOW=60000
      - RATE_LIMIT_MAX_REQUESTS=1000
    volumes:
      - ./policies:/app/policies:ro
      - ./certs:/app/certs:ro
      - ./logs:/app/logs
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - redis
      - postgres
    networks:
      - mcp-internal
    healthcheck:
      test: ["CMD", "curl", "-f", "https://localhost:8444/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  postgres:
    image: postgres:15-alpine
    container_name: mcp-postgres
    restart: unless-stopped
    environment:
      - POSTGRES_DB=mcp_audit
      - POSTGRES_USER=mcp_user
      - POSTGRES_PASSWORD=SecureP@ss123
      - POSTGRES_INITDB_ARGS=--encoding=UTF8 --lc-collate=C --lc-ctype=C
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro
    command:
      - "postgres"
      - "-c", "log_destination=stderr"
      - "-c", "logging_collector=off"
      - "-c", "log_statement=all"
      - "-c", "log_duration=on"
      - "-c", "pgaudit.log=ddl,write,role"
      - "-c", "pgaudit.log_catalog=off"
    networks:
      - mcp-internal
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U mcp_user -d mcp_audit"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: mcp-redis
    restart: unless-stopped
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru --tcp-keepalive 300
    volumes:
      - redisdata:/data
    networks:
      - mcp-internal
    sysctls:
      - net.core.somaxconn=65535

  nginx:
    image: nginx:1.25-alpine
    container_name: mcp-nginx
    restart: unless-stopped
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
      - ./logs/nginx:/var/log/nginx
    depends_on:
      - mcp-gateway
    networks:
      - mcp-internal

volumes:
  pgdata:
  redisdata:

networks:
  mcp-internal:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16

The gateway configuration uses TCP keepalive settings that are critical for enterprise load balancers. Notice tcp_keepalive_time=600 and tcp_keepalive_probes=3—these prevent the silent connection drops that caused our 2:47 AM incident. The keepalive_timeout=65000 ensures nginx doesn't close idle connections before your corporate load balancer does.

Database Schema for Audit Logging

Comprehensive audit logging is non-negotiable in enterprise deployments. Your compliance team will need detailed records of every MCP interaction, including request payloads, response data (sanitized), execution timing, and user attribution.

-- schema.sql — MCP Audit Log Database Schema

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgaudit";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";

-- Core audit table with partitioning for high-volume scenarios
CREATE TABLE mcp_audit_log (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    request_id UUID NOT NULL,
    session_id UUID,
    user_id VARCHAR(255),
    source_ip INET NOT NULL,
    user_agent TEXT,
    
    -- MCP Protocol fields
    mcp_method VARCHAR(50) NOT NULL,
    mcp_resource VARCHAR(500),
    mcp_tool_name VARCHAR(255),
    
    -- Request details (sanitized JSON)
    request_headers JSONB,
    request_body JSONB,
    request_size_bytes INTEGER,
    
    -- Response details
    response_status_code SMALLINT,
    response_headers JSONB,
    response_body JSONB,
    response_size_bytes INTEGER,
    
    -- Timing metrics (milliseconds)
    total_duration_ms INTEGER,
    gateway_processing_ms INTEGER,
    upstream_response_ms INTEGER,
    
    -- Security metadata
    auth_method VARCHAR(50),
    auth_user VARCHAR(255),
    policy_result VARCHAR(20), -- ALLOW, DENY, FLAG
    threat_indicators JSONB,
    
    -- Error tracking
    error_code VARCHAR(50),
    error_message TEXT,
    stack_trace TEXT,
    
    -- Correlation
    correlation_id VARCHAR(100),
    upstream_request_id VARCHAR(100),
    
    -- Index for high-performance queries
    CONSTRAINT mcp_audit_log_timestamp_check CHECK (timestamp > '2020-01-01')
) PARTITION BY RANGE (timestamp);

-- Create monthly partitions for efficient data management
CREATE TABLE mcp_audit_log_2026_01 PARTITION OF mcp_audit_log
    FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');
CREATE TABLE mcp_audit_log_2026_02 PARTITION OF mcp_audit_log
    FOR VALUES FROM ('2026-02-01') TO ('2026-03-01');
CREATE TABLE mcp_audit_log_2026_03 PARTITION OF mcp_audit_log
    FOR VALUES FROM ('2026-03-01') TO ('2026-04-01');

-- Critical indexes for common query patterns
CREATE INDEX idx_audit_timestamp ON mcp_audit_log (timestamp DESC);
CREATE INDEX idx_audit_user_id ON mcp_audit_log (user_id, timestamp DESC);
CREATE INDEX idx_audit_request_id ON mcp_audit_log (request_id);
CREATE INDEX idx_audit_source_ip ON mcp_audit_log (source_ip, timestamp DESC);
CREATE INDEX idx_audit_method ON mcp_audit_log (mcp_method, timestamp DESC);
CREATE INDEX idx_audit_policy_result ON mcp_audit_log (policy_result, timestamp DESC) WHERE policy_result = 'DENY';
CREATE INDEX idx_audit_correlation ON mcp_audit_log (correlation_id) WHERE correlation_id IS NOT NULL;

-- Full-text search index for content analysis
CREATE INDEX idx_audit_content_search ON mcp_audit_log USING gin (request_body gin_trgm_ops, response_body gin_trgm_ops);

-- Sensitive data exposure tracking table
CREATE TABLE sensitive_data_exposure (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    audit_log_id UUID NOT NULL REFERENCES mcp_audit_log(id),
    exposure_type VARCHAR(50) NOT NULL, -- PII, PCI, PHI, CREDENTIALS
    data_category VARCHAR(100),
    detection_method VARCHAR(50),
    sanitized_value TEXT,
    detection_timestamp TIMESTAMPTZ DEFAULT NOW(),
    reviewed BOOLEAN DEFAULT FALSE,
    reviewed_by VARCHAR(255),
    reviewed_at TIMESTAMPTZ
);

CREATE INDEX idx_exposure_reviewed ON sensitive_data_exposure (reviewed, detection_timestamp DESC);

-- Policy violation tracking
CREATE TABLE policy_violations (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    audit_log_id UUID NOT NULL REFERENCES mcp_audit_log(id),
    policy_name VARCHAR(255) NOT NULL,
    policy_version VARCHAR(20),
    violation_severity VARCHAR(20), -- LOW, MEDIUM, HIGH, CRITICAL
    violation_details JSONB,
    automated_action VARCHAR(50),
    manual_review_required BOOLEAN DEFAULT FALSE,
    resolved BOOLEAN DEFAULT FALSE,
    resolved_by VARCHAR(255),
    resolved_at TIMESTAMPTZ,
    resolution_notes TEXT
);

CREATE INDEX idx_violations_unresolved ON policy_violations (resolved, violation_severity) WHERE NOT resolved;

-- View for compliance reporting
CREATE OR REPLACE VIEW compliance_daily_summary AS
SELECT 
    DATE(timestamp) as report_date,
    COUNT(*) as total_requests,
    COUNT(DISTINCT user_id) as unique_users,
    COUNT(DISTINCT source_ip) as unique_sources,
    SUM(CASE WHEN policy_result = 'DENY' THEN 1 ELSE 0 END) as denied_requests,
    SUM(CASE WHEN error_code IS NOT NULL THEN 1 ELSE 0 END) as error_requests,
    AVG(total_duration_ms)::INTEGER as avg_latency_ms,
    PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY total_duration_ms)::INTEGER as p95_latency_ms,
    SUM(request_size_bytes)::BIGINT as total_request_bytes,
    SUM(response_size_bytes)::BIGINT as total_response_bytes
FROM mcp_audit_log
GROUP BY DATE(timestamp)
ORDER BY report_date DESC;

-- Grant appropriate permissions
GRANT SELECT ON compliance_daily_summary TO mcp_analyst;
GRANT INSERT, SELECT, UPDATE ON mcp_audit_log TO mcp_service;
GRANT INSERT ON sensitive_data_exposure TO mcp_service;
GRANT INSERT ON policy_violations TO mcp_service;

Connecting HolySheep AI via MCP Gateway

HolySheep AI provides a unified API that speaks MCP natively, making it straightforward to integrate with your security gateway while maintaining full audit trails. Their pricing model is particularly attractive for enterprise deployments: $1 = ¥1 represents 85%+ savings versus domestic providers charging ¥7.3 per dollar, and their sub-50ms latency ensures responsive AI experiences.

#!/usr/bin/env node
// mcp-holysheep-client.js — HolySheep AI MCP Client with Enterprise Features

const https = require('https');
const crypto = require('crypto');

class HolySheepMCPClient {
    constructor(config) {
        this.baseUrl = 'https://api.holysheep.ai/v1';
        this.apiKey = config.apiKey || process.env.HOLYSHEEP_API_KEY;
        this.gatewayUrl = config.gatewayUrl || 'https://your-mcp-gateway.internal:8443';
        this.requestTimeout = config.requestTimeout || 30000;
        this.maxRetries = config.maxRetries || 3;
        this.auditCorrelationId = null;
        
        if (!this.apiKey) {
            throw new Error('HolySheep API key required. Get yours at https://www.holysheep.ai/register');
        }
    }

    // Generate request signature for gateway verification
    generateSignature(payload, timestamp) {
        const hmac = crypto.createHmac('sha256', this.apiKey);
        hmac.update(${timestamp}.${JSON.stringify(payload)});
        return hmac.digest('base64');
    }

    // Unified MCP request handler with gateway proxy support
    async mcpRequest(method, params = {}, options = {}) {
        this.auditCorrelationId = crypto.randomUUID();
        const timestamp = Date.now();
        
        const requestBody = {
            jsonrpc: '2.0',
            id: this.auditCorrelationId,
            method: method,
            params: {
                ...params,
                _gatewayMeta: {
                    correlationId: this.auditCorrelationId,
                    sourceSubnet: options.sourceSubnet || '10.0.0.0/8',
                    userAgent: options.userAgent || 'HolySheep-MCP-Client/2.4',
                    gatewayTimestamp: timestamp
                }
            }
        };

        const requestBodyString = JSON.stringify(requestBody);
        const signature = this.generateSignature(requestBody, timestamp);

        const requestOptions = {
            hostname: new URL(this.gatewayUrl).hostname,
            port: new URL(this.gatewayUrl).port || 443,
            path: '/mcp/v1/rpc',
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Content-Length': Buffer.byteLength(requestBodyString),
                'X-HolySheep-Key': this.apiKey,
                'X-Gateway-Signature': signature,
                'X-Correlation-ID': this.auditCorrelationId,
                'X-Request-Timestamp': timestamp.toString(),
                'User-Agent': 'HolySheep-MCP-Enterprise/1.0',
                'X-Forwarded-For': options.clientIp || 'unknown',
                'Accept-Encoding': 'gzip, deflate, br',
                'Connection': 'keep-alive'
            },
            timeout: this.requestTimeout,
            rejectUnauthorized: true // Critical for enterprise security
        };

        return this.executeWithRetry(requestOptions, requestBodyString, method, 0);
    }

    async executeWithRetry(requestOptions, body, method, attempt) {
        try {
            const response = await this.makeRequest(requestOptions, body);
            
            // Log to audit gateway (async, non-blocking)
            this.logToAuditGateway({
                correlationId: this.auditCorrelationId,
                method: method,
                status: response.statusCode,
                duration: response.duration
            }).catch(err => console.error('Audit log failed:', err.message));
            
            return response;
        } catch (error) {
            if (attempt < this.maxRetries && this.isRetryableError(error)) {
                const backoffMs = Math.min(1000 * Math.pow(2, attempt), 10000);
                console.warn(Retry ${attempt + 1}/${this.maxRetries} after ${backoffMs}ms);
                await this.sleep(backoffMs);
                return this.executeWithRetry(requestOptions, body, method, attempt + 1);
            }
            throw error;
        }
    }

    makeRequest(options, body) {
        return new Promise((resolve, reject) => {
            const startTime = Date.now();
            const req = https.request(options, (res) => {
                const chunks = [];
                res.on('data', chunk => chunks.push(chunk));
                res.on('end', () => {
                    const duration = Date.now() - startTime;
                    const responseBody = Buffer.concat(chunks).toString();
                    
                    try {
                        const parsed = JSON.parse(responseBody);
                        resolve({
                            statusCode: res.statusCode,
                            headers: res.headers,
                            body: parsed,
                            duration: duration,
                            rawBody: responseBody
                        });
                    } catch (parseError) {
                        resolve({
                            statusCode: res.statusCode,
                            headers: res.headers,
                            body: responseBody,
                            duration: duration,
                            rawBody: responseBody
                        });
                    }
                });
            });

            req.on('timeout', () => {
                req.destroy();
                reject(new Error(ConnectionError: timeout after ${this.requestTimeout}ms));
            });

            req.on('error', (error) => {
                if (error.code === 'ECONNREFUSED') {
                    reject(new Error(ConnectionError: gateway unreachable at ${options.hostname}:${options.port}));
                } else if (error.code === 'ETIMEDOUT') {
                    reject(new Error(ConnectionError: timeout after ${this.requestTimeout}ms));
                } else if (error.code === 'CERT_HAS_EXPIRED') {
                    reject(new Error(TLS Error: gateway certificate expired. Run certbot renew.));
                } else {
                    reject(new Error(ConnectionError: ${error.message}));
                }
            });

            req.write(body);
            req.end();
        });
    }

    isRetryableError(error) {
        return error.message.includes('timeout') || 
               error.message.includes('ECONNRESET') ||
               error.message.includes('ECONNREFUSED');
    }

    sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // Async audit logging (fire-and-forget for performance)
    async logToAuditGateway(logEntry) {
        // Implementation depends on your audit infrastructure
        // This would typically send to your SIEM or audit collector
    }

    // High-level MCP methods
    async listTools() {
        return this.mcpRequest('tools/list');
    }

    async callTool(toolName, args = {}) {
        return this.mcpRequest('tools/call', { name: toolName, arguments: args });
    }

    async listResources() {
        return this.mcpRequest('resources/list');
    }

    async readResource(uri) {
        return this.mcpRequest('resources/read', { uri: uri });
    }

    async createMessage(content, context = {}) {
        return this.mcpRequest('messages/create', { content, context });
    }

    async search(query, options = {}) {
        return this.mcpRequest('search/query', { query, ...options });
    }
}

// Usage example with enterprise configuration
async function main() {
    const client = new HolySheepMCPClient({
        apiKey: process.env.HOLYSHEEP_API_KEY,
        gatewayUrl: process.env.MCP_GATEWAY_URL || 'https://api.holysheep.ai/v1',
        requestTimeout: 30000
    });

    try {
        // Verify connection and list available tools
        const tools = await client.listTools();
        console.log('Available MCP tools:', JSON.stringify(tools, null, 2));

        // Example: Use a tool through the gateway
        const result = await client.callTool('web_search', {
            query: 'enterprise MCP deployment best practices',
            maxResults: 5
        });
        console.log('Tool result:', result);

    } catch (error) {
        console.error('MCP request failed:', error.message);
        process.exit(1);
    }
}

if (require.main === module) {
    main().catch(console.error);
}

module.exports = { HolySheepMCPClient };

nginx Reverse Proxy Configuration

The nginx layer provides TLS termination, load balancing, and additional security headers that your MCP gateway depends on. Here's the production-hardened configuration:

# nginx.conf — MCP Gateway Reverse Proxy Configuration
events {
    worker_connections 65536;
    use epoll;
    multi_accept on;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # Logging with detailed timing information
    log_format mcp_audit '$remote_addr - $remote_user [$time_local] '
                          '"$request" $status $body_bytes_sent '
                          '"$http_referer" "$http_user_agent" '
                          'rt=$request_time uct="$upstream_connect_time" '
                          'uht="$upstream_header_time" urt="$upstream_response_time" '
                          'cs=$upstream_cache_status';

    access_log /var/log/nginx/access.log mcp_audit;
    error_log /var/log/nginx/error.log warn;

    # Performance optimizations
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65 65;
    keepalive_requests 10000;
    types_hash_max_size 2048;
    server_tokens off;

    # Buffer management for large payloads
    client_body_buffer_size 10m;
    client_max_body_size 10m;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types application/json application/javascript text/plain text/css;
    gzip_proxied any;

    # Rate limiting zones
    limit_req_zone $binary_remote_addr zone=mcp_limit:10m rate=1000r/s;
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    # Upstream definition for MCP gateway
    upstream mcp_backend {
        least_conn;
        server mcp-gateway:8443 max_fails=3 fail_timeout=30s;
        keepalive 1024;
        keepalive_timeout 600s;
        keepalive_requests 10000;
    }

    # Security headers upstream
    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_set_header X-Request-ID $request_id;
    proxy_set_header X-Correlation-ID $http_x_correlation_id;
    proxy_set_header Connection "";

    # Proxy timeouts matching TCP keepalive settings
    proxy_connect_timeout 60s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;

    # TCP keepalive for upstream connections
    proxy_http_version 1.1;

    server {
        listen 80;
        server_name mcp.yourcompany.internal;
        return 301 https://$server_name$request_uri;
    }

    server {
        listen 443 ssl http2;
        server_name mcp.yourcompany.internal;

        # TLS configuration
        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets off;
        
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
        ssl_prefer_server_ciphers off;
        
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8 8.8.4.4 valid=300s;

        # Security headers
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;
        add_header Content-Security-Policy "default-src 'none'; connect-src 'self' api.holysheep.ai;" always;

        # Apply rate limiting
        limit_req zone=mcp_limit burst=2000 nodelay;
        limit_conn conn_limit 100;

        # Health check endpoint (unrestricted)
        location /health {
            access_log off;
            proxy_pass https://mcp_backend/health;
            proxy_ssl_verify off; # Internal network only
        }

        # MCP RPC endpoint
        location /mcp/v1/rpc {
            proxy_pass https://mcp_backend;
            proxy_ssl_verify on;
            
            # Request ID for tracing
            map $request_id $rt {
                default $request_id;
            }
            
            add_header X-Request-ID $rt always;
        }

        # Admin/metrics endpoint (IP restricted)
        location /admin {
            allow 10.0.0.0/8;
            allow 172.16.0.0/12;
            allow 192.168.0.0/16;
            deny all;
            
            proxy_pass https://mcp_backend:8444;
            proxy_ssl_verify on;
        }

        # Metrics for Prometheus (IP restricted)
        location /metrics {
            allow 10.0.0.0/8;
            deny all;
            
            proxy_pass https://mcp_backend/metrics;
            proxy_ssl_verify off;
        }
    }
}

Policy Configuration for Access Control

Your security gateway needs policy rules that define which users can access which resources. HolySheep AI supports fine-grained access control through API key scoping, which integrates seamlessly with enterprise identity providers.

# policies/access-control.yaml — MCP Gateway Policy Configuration

policies:
  # Default deny with explicit allows
  default_action: DENY
  
  # Role-based access control
  roles:
    admin:
      description: "Full MCP access including admin endpoints"
      permissions:
        - resources: ["*"]
          methods: ["*"]
          tools: ["*"]
      ip_whitelist: ["10.0.0.0/8"]
      
    developer:
      description: "Development and testing access"
      permissions:
        - resources: ["internal/*", "docs/*"]
          methods: ["read", "list"]
          tools: ["web_search", "code_search", "document_analysis"]
        - resources: ["production/*"]
          methods: ["read"]
          tools: ["status_check"]
      ip_whitelist: ["10.0.0.0/8", "172.16.0.0/12"]
      rate_limit: 100  # requests per minute
      
    production_service:
      description: "Service account for production workloads"
      permissions:
        - resources: ["production/*"]
          methods: ["read", "write"]
          tools: ["*"]
      ip_whitelist: ["10.0.3.0/24"]
      rate_limit: 1000
      require_mtls: true
      
    read_only:
      description: "Read-only access for monitoring"
      permissions:
        - resources: ["*"]
          methods: ["read", "list"]
          tools: ["status_check"]
      rate_limit: 50

  # Content filtering rules
  content_filters:
    - name: "PII Detection"
      enabled: true
      action: FLAG
      patterns:
        - type: "email"
          regex: "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"
        - type: "ssn"
          regex: "\\d{3}-\\d{2}-\\d{4}"
        - type: "credit_card"
          regex: "\\d{4}[- ]?\\d{4}[- ]?\\d{4}[- ]?\\d{4}"
    
    - name: "Credential Detection"
      enabled: true
      action: DENY
      patterns:
        - type: "api_key"
          regex: "(?i)(api[_-]?key|apikey)\\s*[:=]\\s*['\"]?[a-zA-Z0-9]{20,}['\"]?"
        - type: "password"
          regex: "(?i)(password|passwd|pwd)\\s*[:=]\\s*['\"]?[^\\s'\"]{8,}['\"]?"

    - name: "Sensitive File Detection"
      enabled: true
      action: DENY
      patterns:
        - type: "file_extension"
          values: [".env", ".pem", ".key", ".p12", ".pfx"]
        - type: "filename"
          regex: "(?i)(id_rsa|aws_access_key|service_account|secrets?)"

  # Rate limiting policies by user class
  rate_limits:
    default:
      requests_per_minute: 100
      requests_per_hour: 5000
      burst: 50
      
    authenticated:
      requests_per_minute: 500
      requests_per_hour: 20000
      burst: 200
      
    enterprise:
      requests_per_minute: 2000
      requests_per_hour: 100000
      burst: 1000

  # Audit requirements
  audit:
    log_all_requests: true
    log_request_body: true
    log_response_body: true
    log_headers: ["authorization", "content-type", "x-correlation-id"]
    sanitize_fields: ["password", "api_key", "token", "secret", "credential"]
    retention_days: 365
    encryption_at_rest: true

Common Errors and Fixes

After deploying MCP gateways across dozens of enterprise environments, I've compiled the most frequent issues and their solutions. Bookmark this section—you'll refer back to it often.

Error 1: ConnectionError: timeout after 30000ms

Symptoms: Requests hang for exactly 30 seconds before failing with timeout error. Downstream services experience intermittent failures.

Root Cause: TCP keepalive misconfiguration between nginx, the gateway, and your corporate load balancer. When idle connections are terminated mid-session, new requests must re-establish connections, exceeding timeout thresholds.

Solution:

# Fix 1: Update nginx.conf with matching keepalive settings
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;

Fix 2: Ensure gateway has TCP keepalive enabled

In docker-compose.yml, add to mcp-gateway environment:

TCP_KEEPALIVE=true tcp_keepalive_time=600 tcp_keepalive_probes=3 tcp_keepalive_intvl=30

Fix 3: Verify load balancer idle timeout is longer than gateway timeout

For AWS ALB: set idle timeout to 400 seconds minimum

For nginx: keepalive_timeout 65 65;

Fix 4: Test with explicit connection checking

curl -v --keepalive-time 30 https://your-gateway/health

Should see: * Connection #0 to host