Spanly Docs

Sidecar patterns

Run Spanly alongside your MCP server in docker-compose or Kubernetes.

The recommended deployment shape for the Spanly container is as a sidecar that proxies traffic to your MCP server. The MCP server stays internal, the sidecar takes the public port.

docker-compose

A typical setup: your MCP server container plus a Spanly sidecar in the same compose service group.

services:
  mcp:
    image: my-org/my-mcp:1.0.0
    expose:
      - '3000' # reachable from the sidecar only, not the host
    environment:
      MCP_PORT: 3000

  spanly:
    image: spanly/spanly:latest
    command: ['proxy', 'mcp:3000', '0.0.0.0:3001']
    ports:
      - '3001:3001' # this is what your MCP client connects to
    environment:
      SPANLY_API_KEY: ${SPANLY_API_KEY}
    depends_on:
      - mcp

Point your MCP client at http://localhost:3001. The MCP server itself is no longer exposed externally.

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-mcp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-mcp
  template:
    metadata:
      labels:
        app: my-mcp
    spec:
      containers:
        - name: mcp
          image: my-org/my-mcp:1.0.0
          ports:
            - containerPort: 3000

        - name: spanly
          image: spanly/spanly:latest
          args: ['proxy', 'localhost:3000', '0.0.0.0:3001']
          ports:
            - containerPort: 3001
          env:
            - name: SPANLY_API_KEY
              valueFrom:
                secretKeyRef:
                  name: spanly
                  key: api-key

The Service exposes port 3001 (the Spanly proxy), not 3000.

Session grouping

If your MCP server runs sessionless, the sidecar assigns a synthetic Mcp-Session-Id on initialize responses so Spanly can still group requests into sessions. The ID is stripped before requests are forwarded to your server. Add --inject-session-id=false to the proxy arguments to turn this off. See Session tracking.

A maintained Kustomize component is at kustomize/spanly-sidecar. For a standalone Pod + Service pattern, see the Helm chart.

On this page