---
title: Deploy the MCP Server
subtitle: Deployment using Docker containers, when to choose which option, and production considerations
---

To deploy Apollo MCP Server in your production environment, use the recommended [Apollo Runtime Container](#apollo-runtime-container-recommended). You can also use a [standalone Apollo MCP Server container](#standalone-apollo-mcp-server-container) if needed.

## Apollo Runtime Container (Recommended)

For most production deployments, use the all-in-one [Apollo Runtime Container](/graphos/routing/self-hosted/containerization/docker). It includes everything you need to serve both GraphQL and MCP requests in a single, optimized container.

### Why choose the Apollo Runtime Container?

- **Simplified operations**: Single container to deploy and manage
- **Optimized performance**: Apollo Router and Apollo MCP Server are co-located
- **Built-in best practices**: Pre-configured for production use
- **Easier scaling**: Scale both GraphQL and MCP together
- **Unified monitoring**: Single service to monitor and debug

### Deploy the Apollo Runtime Container

The Apollo Runtime Container includes all services necessary to serve GraphQL and MCP requests, including Apollo Router and Apollo MCP Server. Both port `4000` (GraphQL) and `8000` (MCP) are exposed.

```bash title="Deploy with GraphOS (Recommended)"
docker run \
  -p 4000:4000 \
  -p 8000:8000 \
  --env APOLLO_GRAPH_REF="<your-graph-ref>" \
  --env APOLLO_KEY="<your-graph-api-key>" \
  --env MCP_ENABLE=1 \
  -v /path/to/config:/config/mcp_config.yaml \
  --rm \
  ghcr.io/apollographql/apollo-runtime:latest
```

When you run this, it will:

- Fetch your schema from GraphOS using your graph credentials (`APOLLO_GRAPH_REF` and `APOLLO_KEY`)
- Start the Apollo Router with your graph configuration
- Provides a configuration file for the MCP server by mounting it to `config/mcp_config.yaml`
- Enable the Apollo MCP Server endpoint at `/mcp`

This command uses GraphOS-managed persisted queries for MCP tools. You'll need to publish your operations to the [GraphOS-managed persisted queries list](/apollo-mcp-server/define-tools#from-graphos-managed-persisted-queries). If you want to use other methods for defining MCP tools, see the [Define MCP Tools](/apollo-mcp-server/define-tools) page.

To learn more, see the [Apollo Runtime Container documentation](/graphos/routing/self-hosted/containerization/docker).

## Standalone Apollo MCP Server container

Use the standalone Apollo MCP Server container if you already have a GraphQL API running elsewhere and want to add MCP capabilities to it.

### Deploy standalone Apollo MCP Server container

Apollo MCP Server is available as a standalone Docker container. Container images are downloadable using the image `ghcr.io/apollographql/apollo-mcp-server`.

By default, the container expects all schema and operation files to be present in the `/data` directory within the container and that clients use Streamable HTTP transport on container port `8000`.

Here's an example `docker run` command that runs Apollo MCP Server for an example using [TheSpaceDevs graph](https://thespacedevs-production.up.railway.app/):

```yaml title="mcp_config.yaml"
endpoint: https://thespacedevs-production.up.railway.app/
operations:
  source: local
  paths:
    - /data/operations/
schema:
  source: local
  path: /data/api.graphql
```

```sh showLineNumbers=false
docker run \
  -it --rm \
  --name apollo-mcp-server \
  -p 8000:8000 \
  -v <path/to>/mcp_config.yaml:/config.yaml \
  -v $PWD/graphql/TheSpaceDevs:/data \
  --pull always \
  ghcr.io/apollographql/apollo-mcp-server:latest /config.yaml
```

## When to choose which option?

| Scenario                            | Recommended Option           | Why                                                                                                       |
| ----------------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------- |
| New GraphQL + MCP deployment        | Apollo Runtime Container     | Single container, easier to manage, optimized performance                                                 |
| GraphOS-managed graph               | Apollo Runtime Container     | Automatic sync for schema and persisted queries, unified telemetry                                        |
| Kubernetes/orchestrated environment | Apollo Runtime Container     | Fewer moving parts, simpler networking                                                                    |
| Adding MCP to existing GraphQL API  | Standalone Apollo MCP Server | Connect to your existing GraphQL endpoint                                                                 |
| Local development                   | `rover dev`                  | [Run `rover dev`](/apollo-mcp-server/run#with-the-rover-cli) to develop locally with both GraphQL and MCP |
          
## Production Considerations

### Load Balancing & Session Affinity

MCP is a stateful protocol that requires session affinity (sticky sessions).

When an MCP client initializes a session with Apollo MCP Server, it receives a session identifier unique to that server instance through the `mcp-session-id` header. You must enable session affinity in your load balancer so that all requests sharing the same `mcp-session-id` are routed to the same backend instance.

Nginx, HAProxy, or Envoy/Istio support proper session routing. Most cloud load balancers—such as the AWS Application Load Balancer (ALB) and the Google Cloud Load Balancer—do not support header-based session affinity.

#### Stateless mode

Although MCP is a stateful protocol by default, the Streamable HTTP transport supports operating in a stateless mode.
This means that the session ID will not be passed back and forth between the client and server and each request made to the MCP server happens in its own HTTP POST.
Disabling the session state being managed in memory by a single host allows for horizontal scaling of the server, though could lead to unknown issues if your MCP client has a dependency on sticky sessions.

You can configure stateless mode in the transport config section:

```yaml
transport:
  type: streamable_http
  stateful_mode: false
```

### Scaling Recommendations

For the Apollo Runtime Container:

- Scale both GraphQL and MCP together as a single unit
- Simpler horizontal scaling
- Consistent performance characteristics

For the standalone Apollo MCP Server container:

- Scale Apollo MCP Server independently of your GraphQL API
- More complex but enables fine-tuned resource allocation

### Next steps

After you deploy, configure:

1. [Health checks](/apollo-mcp-server/health-checks) for monitoring
2. [CORS settings](/apollo-mcp-server/cors) for browser clients
3. [Authorization](/apollo-mcp-server/auth) for production security
