Enterprise Deployments
Remote Deployment stands the server up for other people: a service unit, a container, a reverse proxy, a certificate, and a first pass at several instances. This section is what changes when “other people” is hundreds of them.
Everything here is HTTP mode. Read HTTP Server Mode first if the pool, the instance allow-list and the authentication modes are not already familiar.
In the order an operator meets them
Section titled “In the order an operator meets them”What is different about this server at scale
Section titled “What is different about this server at scale”It holds no credential of its own. Every request carries the caller’s token,
as PRIVATE-TOKEN or Authorization: Bearer, so there is no server token to
protect, /health needs no authentication, and per-user identity, tiering and
rate limiting survive as long as the credential does. Every design decision in
this section follows from that: affinity, gateways and the rate limiter are all
questions about the credential’s path to the process.
One MCP server is built per configuration shape, not per credential. A credential is a GitLab client and its bookkeeping, and the registered catalog is shared by everyone whose configuration matches, which is what makes a large population cheap to hold and a busy one expensive to serve. The design and its invariants are recorded in ADR-0020.
Nothing here needs a reverse proxy to be correct. The binary answers its own CORS preflights, its own 404s and its own security headers, terminates TLS, and listens on a unix socket. A proxy is for what a proxy is good at: many clients, one certificate, one address.
Further reading
Section titled “Further reading”- Remote Deployment for service units, containers, the individual proxies and the first pass at several instances.
- HTTP Server Mode for every flag, the pool, the instance allow-list, the authentication modes and the ceilings on calls held open and sessions kept.
- Resource Benchmark for the measurements this section sizes from, and the host they were taken on.
- Compatibility for gateway validators and per-client limits.
- OpenTelemetry for what an instance reports about itself and its callers.
- Security for the threat model, the authentication budgets and the recommendations for HTTP mode.
Frequently asked questions
Do I still need token affinity across instances?
For ordinary calls it is an optimisation rather than a requirement: an instance a caller moves to already has the catalog built, so the move costs a credential probe, a licensing lookup and a client. Affinity still keeps one rate-limit bucket and one identity probe per caller instead of one per instance. It is mandatory for three things: legacy stateful sessions, which live in the process that minted the session id; resource subscriptions, whose watchers are held by one process; and the rounds of a multi-round-trip elicitation (a guided creation flow, or a confirmation before a destructive change), whose state is signed with a key only the asking process holds.
What is the one setting people forget behind a proxy?
--trusted-proxy-header together with --trusted-proxies. Without them every caller's authentication failures are charged to the balancer's address, and ten bad tokens a minute from anywhere in the population block that address for a minute: every credential the deployment does not already hold is answered 429 until the window ends, whoever sends it, while callers it is already serving stay served. Each flag is refused without the other.
Why does HAProxy mark every instance DOWN?
option httpchk sends no Host header unless one is configured, and a server bound to a specific host used to refuse such a request with 403. Version 3.0.0 serves it, because a request naming no host is not the DNS-rebinding attack that check exists for. On an older server, add hdr Host your.host.name to the http-check send line, which is good practice either way.