> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pyleeai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Remotes Configuration

> Configure and manage remotes using Streamable HTTP or SSE transport protocols to run your MCP servers

# Remote MCP Server Connections

Remote connections allow you to connect to Model Context Protocol (MCP) servers hosted on remote machines, cloud infrastructure, or different networks. This enables distributed architectures where MCP servers can be deployed separately from client applications.

## Understanding Remote MCP Architecture

Remote MCP servers enable scalable, distributed AI systems by allowing:

* **Centralized server deployment** - Host specialized MCP servers on dedicated infrastructure
* **Cross-network access** - Connect to servers across different networks and cloud providers
* **Load distribution** - Distribute processing across multiple server instances
* **Shared resources** - Multiple clients can access the same MCP server capabilities

For comprehensive information about the MCP specification and architecture, visit the [official MCP documentation](https://modelcontextprotocol.io/docs).

## Transport Protocols

Pylee supports two transport protocols for remote MCP server connections:

### Streamable HTTP (Recommended)

The Streamable HTTP transport uses modern HTTP streaming capabilities for efficient communication with remote MCP servers. This is the recommended protocol for most use cases.

**Transport Type:** `streamable`

**URL Format:**

```
https://api.example.com/v1/mcp
http://localhost:3000/mcp
```

**Key Features:**

* Efficient HTTP streaming for real-time communication
* Built-in error handling and retry mechanisms
* Support for bidirectional communication
* Compatible with standard HTTP infrastructure
* Automatic connection management

**Advantages:**

* Modern streaming capabilities
* Lower latency than traditional request-response
* Firewall and proxy friendly
* Built-in HTTPS security support
* Excellent performance for high-frequency operations

**Best for:**

* Production deployments
* Real-time applications
* High-performance scenarios
* Modern cloud infrastructure
* Client applications with intermittent connectivity needs

### WebSocket Protocol

Provides persistent, bidirectional communication channels for real-time interaction.

**URL Format:**

```
ws://hostname:port/mcp
wss://hostname:port/mcp
```

**Advantages:**

* Real-time bidirectional communication
* Lower latency for frequent operations
* Persistent connection reduces overhead
* Native browser support

**Disadvantages:**

* More complex connection management
* May require special network configuration
* Connection state management complexity

**Best for:**

* Interactive applications requiring immediate responses
* High-frequency tool invocation scenarios
* Real-time collaborative environments
* Applications needing bidirectional data flow

### Server-Sent Events (SSE)

Uses Server-Sent Events for server-to-client streaming communication.

**URL Format:**

```
http://hostname:port/mcp/events
https://hostname:port/mcp/events
```

**Advantages:**

* Real-time server-to-client updates
* Automatic reconnection handling
* HTTP-based (firewall friendly)
* Built-in browser support

**Disadvantages:**

* Unidirectional (server to client only)
* Limited browser connection limits
* May require additional endpoint for client-to-server requests

**Best for:**

* Live monitoring and status updates
* Progress tracking for long-running operations
* Event-driven architectures
* Applications requiring server push notifications

## Configuring Remote Connections in Pylee

### Using the Pylee Configuration Interface

Navigate to your server's configuration page and select **Remote Configuration** to set up remote MCP connections:

1. **Go to Configuration**
   ```
   /{organization}/server/{server}/configuration/remotes
   ```

2. **Add Remote Connection**
   * Click "Add Remote" to create a new remote connection
   * Configure the transport type and endpoint URL
   * Set up authentication headers if required

### Remote Configuration Options

#### Basic Configuration

**Transport Type:** Choose between `streamable` (recommended) or `sse` (deprecated)

**URL:** The endpoint URL for your remote MCP server

```
https://api.example.com/v1/mcp
```

#### Authentication Headers

Configure HTTP headers for authentication and custom requirements:

**Common Authentication Patterns:**

```json theme={null}
{
  "name": "Authorization",
  "value": "Bearer your-api-token",
  "description": "API authentication token",
  "is_required": true,
  "is_secret": true
}
```

```json theme={null}
{
  "name": "X-API-Key",
  "value": "your-api-key",
  "description": "Service API key",
  "is_required": true,
  "is_secret": true
}
```

#### Header Configuration Fields

* **Name**: The HTTP header name (e.g., "Authorization", "X-API-Key")
* **Value**: The header value (tokens, keys, etc.)
* **Description**: Optional description of the header's purpose
* **Required**: Mark if this header is mandatory for the connection
* **Secret**: Mark if this header contains sensitive information

#### Variables in Remote Configuration

Remote configuration supports dynamic variables using bracket notation (`{variable_name}`) to avoid hardcoding sensitive information. Variables are resolved at runtime through a hierarchical lookup system.

**Variable Resolution Order:**

1. **Organization variables or secrets** - Global settings for your organization
2. **Registry variables or secrets** - Shared configuration across the registry
3. **User prompt** - Interactive prompt when no value is found for required variables

**Example with Variables:**

```json theme={null}
{
  "name": "Authorization",
  "value": "Bearer {api_token}",
  "description": "Dynamic API token from variables",
  "is_required": true,
  "is_secret": true
}
```

For comprehensive information about variables configuration, see the [Variables Configuration Guide](/understanding-pylee/variables-configuration).

### Example Configurations

#### Production API with Authentication

```json theme={null}
{
  "transport_type": "streamable",
  "url": "https://mcp-api.yourcompany.com/v1/mcp",
  "headers": [
    {
      "name": "Authorization",
      "value": "Bearer prod_token_xyz123",
      "description": "Production API authentication",
      "is_required": true,
      "is_secret": true
    },
    {
      "name": "X-Client-Version",
      "value": "1.0.0",
      "description": "Client version identifier",
      "is_required": false,
      "is_secret": false
    }
  ]
}
```

#### Development Environment

```json theme={null}
{
  "transport_type": "streamable",
  "url": "http://localhost:3000/mcp",
  "headers": [
    {
      "name": "X-Environment",
      "value": "development",
      "description": "Environment identifier",
      "is_required": false,
      "is_secret": false
    }
  ]
}
```

### Legacy Server Configuration

For reference, here's how to configure an MCP server to accept remote connections:

```javascript Node.js Streamable Server theme={null}
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StreamableTransport } from '@modelcontextprotocol/sdk/server/streamable.js';
import express from 'express';

const app = express();
const server = new Server(
  {
    name: 'remote-mcp-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      resources: {},
      tools: {},
    },
  }
);

// Configure HTTP transport
const transport = new HTTPServerTransport({
  port: 8080,
  host: '0.0.0.0',
  cors: {
    origin: ['https://your-client-domain.com'],
    credentials: true
  }
});

await server.connect(transport);
console.log('MCP server listening on http://0.0.0.0:8080');
```

<CodeGroup>
  ```javascript WebSocket Server theme={null}
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
  import { WebSocketServerTransport } from '@modelcontextprotocol/sdk/server/websocket.js';

  const server = new Server(
    {
      name: 'websocket-mcp-server',
      version: '1.0.0',
    },
    {
      capabilities: {
        resources: {},
        tools: {},
      },
    }
  );

  const transport = new WebSocketServerTransport({
    port: 8080,
    host: '0.0.0.0',
    path: '/mcp',
    // Optional authentication
    authenticate: async (request) => {
      const token = request.headers.authorization;
      return validateToken(token);
    }
  });

  await server.connect(transport);
  console.log('WebSocket MCP server listening on ws://0.0.0.0:8080/mcp');
  ```

  ```python Python HTTP Server theme={null}
  from mcp import Server, HTTPServerTransport
  import asyncio

  server = Server("remote-mcp-server")

  @server.list_resources()
  async def handle_list_resources():
      return [
          {
              "uri": "remote://data/example",
              "name": "Remote Data",
              "description": "Remote data resource"
          }
      ]

  @server.list_tools()
  async def handle_list_tools():
      return [
          {
              "name": "remote_tool",
              "description": "A tool running on remote server",
              "inputSchema": {
                  "type": "object",
                  "properties": {
                      "input": {"type": "string"}
                  }
              }
          }
      ]

  async def main():
      transport = HTTPServerTransport(
          host="0.0.0.0",
          port=8080,
          cors_origins=["https://your-client-domain.com"]
      )
      await server.run(transport)

  if __name__ == "__main__":
      asyncio.run(main())
  ```
</CodeGroup>

### Client Configuration

Configure your client to connect to remote MCP servers:

<CodeGroup>
  ```javascript HTTP Client theme={null}
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
  import { HTTPClientTransport } from '@modelcontextprotocol/sdk/client/http.js';

  const client = new Client(
    {
      name: 'mcp-client',
      version: '1.0.0',
    },
    {
      capabilities: {},
    }
  );

  const transport = new HTTPClientTransport({
    baseUrl: 'https://your-mcp-server.com:8080',
    headers: {
      'Authorization': 'Bearer your-api-token',
      'Content-Type': 'application/json'
    },
    timeout: 30000
  });

  await client.connect(transport);

  // Use the client
  const resources = await client.listResources();
  console.log('Available resources:', resources);
  ```

  ```javascript WebSocket Client theme={null}
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
  import { WebSocketClientTransport } from '@modelcontextprotocol/sdk/client/websocket.js';

  const client = new Client(
    {
      name: 'websocket-client',
      version: '1.0.0',
    },
    {
      capabilities: {},
    }
  );

  const transport = new WebSocketClientTransport({
    url: 'wss://your-mcp-server.com:8080/mcp',
    headers: {
      'Authorization': 'Bearer your-api-token'
    },
    reconnect: true,
    reconnectInterval: 5000
  });

  await client.connect(transport);

  // Real-time communication
  transport.onMessage((message) => {
    console.log('Received:', message);
  });
  ```

  ```bash cURL Testing theme={null}
  # Test HTTP MCP server
  curl -X POST https://your-mcp-server.com:8080/mcp \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer your-api-token" \
    -d '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "resources/list",
      "params": {}
    }'

  # Test server health
  curl -X GET https://your-mcp-server.com:8080/health
  ```
</CodeGroup>

## Authentication and Security

### Authentication Methods

Implement proper authentication for remote MCP servers:

```javascript theme={null}
// Token-based authentication
const authenticateToken = async (token) => {
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    return { valid: true, user: decoded };
  } catch (error) {
    return { valid: false, error: error.message };
  }
};

// API key authentication
const authenticateApiKey = async (apiKey) => {
  const validKeys = await loadValidApiKeys();
  return validKeys.includes(apiKey);
};

// Custom authentication middleware
server.setAuthenticationHandler(async (request) => {
  const authHeader = request.headers.authorization;
  
  if (!authHeader) {
    throw new Error('Authentication required');
  }
  
  if (authHeader.startsWith('Bearer ')) {
    const token = authHeader.substring(7);
    const result = await authenticateToken(token);
    if (!result.valid) {
      throw new Error('Invalid token');
    }
    return result.user;
  }
  
  if (authHeader.startsWith('ApiKey ')) {
    const apiKey = authHeader.substring(7);
    const isValid = await authenticateApiKey(apiKey);
    if (!isValid) {
      throw new Error('Invalid API key');
    }
    return { apiKey };
  }
  
  throw new Error('Unsupported authentication method');
});
```

### Security Best Practices

<Warning>
  Always implement these security measures for remote MCP servers:
</Warning>

* **Use HTTPS/WSS** - Always encrypt connections in production
* **Implement authentication** - Require valid credentials for all requests
* **Validate inputs** - Sanitize and validate all tool parameters and resource requests
* **Rate limiting** - Implement request rate limiting to prevent abuse
* **CORS configuration** - Configure Cross-Origin Resource Sharing appropriately
* **Audit logging** - Log all access attempts and operations
* **Regular updates** - Keep MCP SDK and dependencies updated

```javascript theme={null}
// Security middleware example
import rateLimit from 'express-rate-limit';
import helmet from 'helmet';

// Rate limiting
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  message: 'Too many requests from this IP'
});

// Security headers
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      connectSrc: ["'self'", "wss:"]
    }
  }
}));

app.use('/mcp', limiter);

// Input validation
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  
  // Validate tool name
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
    throw new Error('Invalid tool name format');
  }
  
  // Validate arguments
  const validated = await validateToolArguments(name, args);
  if (!validated.valid) {
    throw new Error(`Invalid arguments: ${validated.error}`);
  }
  
  return await executeTool(name, validated.args);
});
```

## Load Balancing and Scaling

### Multiple Server Instances

Deploy multiple MCP server instances for high availability:

```javascript theme={null}
// Load balancer configuration example
const servers = [
  'https://mcp-server-1.com:8080',
  'https://mcp-server-2.com:8080',
  'https://mcp-server-3.com:8080'
];

class LoadBalancedMCPClient {
  constructor(serverUrls) {
    this.servers = serverUrls;
    this.currentIndex = 0;
    this.clients = new Map();
  }
  
  async getClient() {
    const serverUrl = this.servers[this.currentIndex];
    
    if (!this.clients.has(serverUrl)) {
      const client = new Client({
        name: 'load-balanced-client',
        version: '1.0.0'
      }, { capabilities: {} });
      
      const transport = new HTTPClientTransport({
        baseUrl: serverUrl,
        timeout: 10000
      });
      
      await client.connect(transport);
      this.clients.set(serverUrl, client);
    }
    
    // Round-robin selection
    this.currentIndex = (this.currentIndex + 1) % this.servers.length;
    
    return this.clients.get(serverUrl);
  }
  
  async callTool(name, arguments) {
    const maxRetries = 3;
    let lastError;
    
    for (let i = 0; i < maxRetries; i++) {
      try {
        const client = await this.getClient();
        return await client.callTool({ name, arguments });
      } catch (error) {
        lastError = error;
        console.warn(`Server failed, trying next: ${error.message}`);
      }
    }
    
    throw new Error(`All servers failed: ${lastError.message}`);
  }
}
```

### Docker Deployment

Deploy MCP servers using Docker for scalability:

```dockerfile theme={null}
# Dockerfile for MCP server
FROM node:18-slim

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy application code
COPY . .

# Create non-root user
RUN useradd -m -u 1001 mcpuser
RUN chown -R mcpuser:mcpuser /app
USER mcpuser

# Expose port
EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

# Start server
CMD ["node", "dist/server.js"]
```

```yaml theme={null}
# docker-compose.yml for multiple instances
version: '3.8'
services:
  mcp-server-1:
    build: .
    ports:
      - "8081:8080"
    environment:
      - NODE_ENV=production
      - SERVER_ID=server-1
    restart: unless-stopped
    
  mcp-server-2:
    build: .
    ports:
      - "8082:8080"
    environment:
      - NODE_ENV=production
      - SERVER_ID=server-2
    restart: unless-stopped
    
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - mcp-server-1
      - mcp-server-2
    restart: unless-stopped
```

## Monitoring and Observability

### Health Checks

Implement health monitoring for remote MCP servers:

```javascript theme={null}
// Health check endpoint
server.addHealthCheck('/health', async () => {
  const checks = {
    server: 'healthy',
    database: await checkDatabase(),
    externalServices: await checkExternalServices(),
    memory: process.memoryUsage(),
    uptime: process.uptime()
  };
  
  const allHealthy = Object.values(checks)
    .filter(v => typeof v === 'string')
    .every(status => status === 'healthy');
  
  return {
    status: allHealthy ? 'healthy' : 'unhealthy',
    timestamp: new Date().toISOString(),
    checks
  };
});

// Readiness check for load balancers
server.addHealthCheck('/ready', async () => {
  const isReady = await checkServerReadiness();
  return {
    status: isReady ? 'ready' : 'not-ready',
    timestamp: new Date().toISOString()
  };
});
```

### Metrics Collection

Track server performance and usage:

```javascript theme={null}
// Prometheus metrics example
import prometheus from 'prom-client';

const requestCounter = new prometheus.Counter({
  name: 'mcp_requests_total',
  help: 'Total number of MCP requests',
  labelNames: ['method', 'status']
});

const requestDuration = new prometheus.Histogram({
  name: 'mcp_request_duration_seconds',
  help: 'Duration of MCP requests',
  labelNames: ['method']
});

const activeConnections = new prometheus.Gauge({
  name: 'mcp_active_connections',
  help: 'Number of active MCP connections'
});

// Instrument request handling
server.onRequest(async (request, response) => {
  const startTime = Date.now();
  const method = request.method;
  
  try {
    const result = await handleRequest(request);
    requestCounter.inc({ method, status: 'success' });
    return result;
  } catch (error) {
    requestCounter.inc({ method, status: 'error' });
    throw error;
  } finally {
    const duration = (Date.now() - startTime) / 1000;
    requestDuration.observe({ method }, duration);
  }
});

// Expose metrics endpoint
server.addRoute('/metrics', async (req, res) => {
  res.set('Content-Type', prometheus.register.contentType);
  res.end(await prometheus.register.metrics());
});
```

## Security Best Practices

### Authentication

* Always use HTTPS for production deployments
* Implement proper API key or token-based authentication
* Mark sensitive headers as "secret" in the configuration
* Rotate authentication credentials regularly

### Network Security

* Use secure transport protocols (HTTPS)
* Configure proper CORS policies on your MCP servers
* Implement rate limiting and request throttling
* Monitor and log connection attempts

## Troubleshooting Remote Connections

### Configuration Issues

**Remote endpoint not accessible:**

* Verify the URL is correct and reachable
* Check network connectivity and firewall rules
* Ensure the remote server is running and accepting connections

**Authentication failures:**

* Verify API keys or tokens are correct and not expired
* Check that required headers are properly configured
* Ensure sensitive headers are marked as "secret"

**Transport protocol issues:**

* Use `streamable` transport for new implementations
* Migrate from `sse` to `streamable` for better performance
* Verify the remote server supports the selected transport type

### Debugging Steps

1. **Test connectivity:**
   ```bash theme={null}
   curl -I https://your-mcp-endpoint.com/v1/mcp
   ```

2. **Verify authentication:**
   ```bash theme={null}
   curl -H "Authorization: Bearer your-token" https://your-mcp-endpoint.com/v1/mcp
   ```

3. **Check server logs** for connection attempts and errors

4. **Monitor network traffic** to identify connection issues

### Common Issues

**Connection Timeouts**

* Check network connectivity between client and server
* Verify firewall rules allow traffic on required ports
* Increase client timeout settings if operations are slow
* Monitor server resource usage and performance

**Authentication Failures**

* Verify API keys or tokens are valid and not expired
* Check authentication headers are properly formatted
* Ensure server authentication configuration matches client
* Review server logs for specific authentication errors

**Protocol Errors**

* Validate MCP message format compliance using [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector)
* Check JSON-RPC 2.0 format adherence
* Verify required fields are present in all messages
* Test with minimal client to isolate issues

**Performance Issues**

* Monitor server resource usage (CPU, memory, network)
* Check for database connection pooling bottlenecks
* Implement caching for frequently accessed resources
* Consider using connection pooling on the client side

### Debugging Tools

Use these tools to debug remote MCP connections:

```bash theme={null}
# Test server connectivity
curl -v https://your-mcp-server.com:8080/health

# WebSocket connection testing
wscat -c wss://your-mcp-server.com:8080/mcp

# MCP protocol testing
npx @modelcontextprotocol/inspector http https://your-mcp-server.com:8080/mcp

# Load testing
npx autocannon -c 10 -d 30 https://your-mcp-server.com:8080/mcp
```

## Protocol Selection Guide

Choose the right protocol based on your requirements:

| Use Case               | Recommended Protocol | Reason                                         |
| ---------------------- | -------------------- | ---------------------------------------------- |
| Web APIs               | HTTP/HTTPS           | Standard, cacheable, firewall-friendly         |
| Real-time Apps         | WebSocket            | Bidirectional, low-latency communication       |
| Live Dashboards        | SSE                  | Server push, automatic reconnection            |
| Mobile Apps            | HTTP/HTTPS           | Better battery life, intermittent connectivity |
| High-frequency Tools   | WebSocket            | Persistent connection, lower overhead          |
| Enterprise Integration | HTTP/HTTPS           | Security policies, monitoring tools            |
| Microservices          | HTTP/HTTPS           | Service mesh compatibility, load balancing     |

## Deployment Patterns

### Cloud Deployment

Common patterns for deploying remote MCP servers:

* **Container orchestration** - Use Kubernetes or Docker Swarm for scaling
* **Serverless functions** - Deploy as AWS Lambda, Azure Functions, or Google Cloud Functions
* **API Gateway integration** - Use cloud API gateways for routing and authentication
* **CDN deployment** - Cache resources using content delivery networks
* **Multi-region deployment** - Deploy servers across regions for global access

### Edge Computing

Deploy MCP servers closer to users:

```javascript theme={null}
// Edge-optimized MCP server
const edgeServer = new Server({
  name: 'edge-mcp-server',
  version: '1.0.0'
}, {
  capabilities: {
    resources: {},
    tools: {},
    // Enable caching for edge deployment
    caching: {
      enabled: true,
      ttl: 300,
      regions: ['us-east-1', 'eu-west-1', 'ap-southeast-1']
    }
  }
});

// Implement geo-aware resource routing
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const clientRegion = request.headers['cf-ipcountry'] || 'US';
  const nearestCache = await findNearestCache(clientRegion);
  
  return await nearestCache.getResource(request.params.uri);
});
```

## Next Steps

Once you have remote MCP server connections working:

* [Set up local MCP connections](/using-pylee/local-connections) for development
* [Learn about MCP server configuration](/mcp-servers/configuration) best practices
* [Explore the MCP specification](https://modelcontextprotocol.io/docs/specification) in detail
* [Browse community MCP servers](https://github.com/modelcontextprotocol/servers) for examples
* [Study MCP security guidelines](https://modelcontextprotocol.io/docs/security) for production deployment

## Migration from SSE to Streamable

If you're currently using SSE transport, consider migrating to Streamable HTTP:

### Migration Steps

1. **Update transport type** from `sse` to `streamable` in your remote configuration
2. **Verify endpoint compatibility** with Streamable HTTP protocol
3. **Test the connection** thoroughly in a development environment
4. **Update monitoring and logging** to account for the new transport
5. **Deploy gradually** using canary or blue-green deployment strategies

### Benefits of Migration

* Improved performance and reliability
* Better error handling and recovery
* Enhanced streaming capabilities
* Future-proof protocol choice

## Resources and Support

For additional help with remote MCP connections:

* [Official MCP Documentation](https://modelcontextprotocol.io/docs)
* [MCP SDK Reference](https://modelcontextprotocol.io/docs/sdk)
* [MCP GitHub Repository](https://github.com/modelcontextprotocol/specification)
* [Community Examples](https://github.com/modelcontextprotocol/servers)
* [MCP Discussion Forum](https://github.com/modelcontextprotocol/specification/discussions)
