createmcps.com

Comparison

Where should I host an MCP server?

Last verified: 10 August 2026 · spec 2026-07-28 · ruleset 1.4.2

2026-07-28 removed protocol sessions, which changed this decision more than any platform announcement has. With no session to pin a client to an instance, serverless became the natural fit rather than a workaround. The one question that still forks the decision is whether you need long-lived streaming.
No prices or platform limits on this page — deliberately: Vendor pricing and request-duration caps change constantly, and a hosting page full of stale numbers is worse than no hosting page. What the protocol requires of a host changes rarely, so that is what this page covers, along with the exact questions to put to whichever platform you are evaluating today.

What statelessness changed about hosting

Servers MUST NOT rely on prior requests over the same connection to establish context (e.g., capabilities, protocol version, client identity). Every request supplies this metadata in its _meta field.
MCP-STL-004 MUST_NOT · spec 2026-07-28

Read that as an infrastructure statement and the consequences fall out immediately. Under the session-based revisions, a client established a session with one instance and had to keep reaching that instance — which meant sticky routing, or a shared session store, or both. Neither is a natural fit for serverless.

Before (session-based)2026-07-28 (stateless)
Load balancingSticky sessions requiredAny instance, any request
Shared stateSession store between instancesNone needed
Scale to zeroDrops live sessionsSafe
DeploysDrain sessions firstRoll freely
ServerlessAwkwardNatural fit

If you are carrying hosting decisions made for a session-based MCP server — a Redis session store, sticky routing rules, a minimum instance count to avoid dropping sessions — those are now cost and complexity with nothing behind them.

What the spec actually requires of a host

Five things, each traceable to a rule. Everything else is preference.

1. HTTPS with a valid certificate

All the OAuth protocol URLs (URLs exposed by the AS, RS and Client) MUST use the https scheme except for loopback interface redirect URIs, which MAY use the http scheme.
MCP-SEC-002 MAY · spec 2026-07-28

Rules out plain-HTTP deployments and self-signed certificates for anything with authorization. Practically every platform gives you this now; the thing to check is that it also covers your custom domain, not just a platform subdomain — see point 4.

2. Control over response headers

Servers MUST validate the Origin header on all incoming connections to prevent DNS rebinding attacks. If the Origin header is present and invalid, servers MUST respond with HTTP 403 Forbidden.
MCP-SEC-001 MUST · spec 2026-07-28

You need to read Origin and return 403, and to set WWW-Authenticate on a 401. Any platform that lets you run a real handler does this. A platform where a CDN or WAF layer rewrites your response headers is worth checking before you commit.

3. Correct Content-Type, and unbuffered streams if you stream

The server MUST return either Content-Type: application/json (a single JSON object) or Content-Type: text/event-stream (an SSE response stream).
MCP-RES-005 MUST · spec 2026-07-28
When initiating an SSE stream, servers SHOULD include the X-Accel-Buffering: no header in the HTTP response.
MCP-RES-006 SHOULD · spec 2026-07-28

The X-Accel-Buffering: no recommendation exists because a proxy that buffers an SSE stream defeats the point of streaming. This is the requirement most likely to be violated by your platform rather than your code.

4. A stable canonical URI

The resource parameter MUST identify the MCP server that the client intends to use the token with, using the canonical URI as defined in RFC 8707 Section 2.
MCP-AUT-003 MUST · spec 2026-07-28

Your Protected Resource Metadata names a canonical URI, and your token audience check compares against it. Both break if the URL changes — which rules out deploying on per-deployment preview URLs and means you want a custom domain pinned to a stable address.

5. Static paths at /.well-known/

MCP servers MUST implement OAuth 2.0 Protected Resource Metadata (RFC9728).
MCP-AUT-002 MUST · spec 2026-07-28

If your server does authorization, it must serve a document at /.well-known/oauth-protected-resource on the same origin. Straightforward anywhere you control routing; awkward if your MCP server sits behind a gateway that owns the root path.

The one question that actually forks the decision

Everything above is satisfiable almost anywhere. The real fork is whether your server implements subscriptions/listen — the single long-lived stream that replaced resources/subscribe and the standalone GET endpoint.

Replace the HTTP GET endpoint and resources/subscribe/resources/unsubscribe with subscriptions/listen: a single long-lived POST-response stream for opted-in server-to-client change notifications.
MCP-DEP-003 MAY · spec 2026-07-28
  • No subscriptions — every request is a short request/response cycle. Serverless is ideal, scale-to-zero is free, and request-duration limits never come up.
  • With subscriptions — you hold a response open indefinitely. Now you need a platform that permits long-running responses and does not buffer them, which is a much smaller set.
Our recommendation, not a spec quote: most servers do not need subscriptions. Tools and resources cover the great majority of real MCP servers, and adding a subscription stream constrains your hosting far more than it looks. Ship without it, and add it when a client actually asks for change notifications.

Platform categories against those requirements

CategoryFits stateless MCPLong-lived streamsWatch out for
Edge runtimesCloudflare Workers, Deno DeployExcellent — no cold-start penaltyUsually supportedRestricted runtime; Node APIs and native deps may not work
Serverless functionsVercel, AWS Lambda, Cloud RunExcellent — the change that unlocked itCheck the duration capCold starts; per-request timeouts; response buffering
Managed containersFly.io, Railway, RenderGood — no constraints either wayYesYou pay for idle unless it scales to zero
Self-hostedYour own VM or clusterGood — full controlYesProxy buffering is on by default in most nginx configs
If you self-host behind nginx: proxy_buffering is on by default, which will buffer an SSE stream and break subscriptions/listen in a way that looks like your application hanging. The X-Accel-Buffering: no header your server sets is exactly what nginx reads to disable it — which is why MCP-RES-006 exists.

Questions to ask whichever platform you're evaluating

These are the ones that map to actual conformance rules, in the order they are likely to bite:

  • Can I attach a custom domain with TLS? Needed for a stable canonical URI (MCP-AUT-003).
  • Are my response headers passed through unmodified? WWW-Authenticate and X-Accel-Buffering must reach the client.
  • Is the response body buffered? Only matters if you stream — but it fails silently when it does.
  • What is the maximum response duration? Only matters for subscriptions/listen.
  • Can I serve arbitrary paths under /.well-known/? Needed for RFC 9728 metadata.
  • Does anything inject or rewrite headers? A WAF that strips unknown request headers will remove Mcp-Method and Mcp-Name — and then your own validation rejects every request as a mismatch.
Our recommendation, not a spec quote: that last one is worth testing before you commit rather than after. A gateway stripping unrecognised request headers produces a failure that looks entirely like an application bug — your server correctly returns -32020 for a mismatch it can see, and nothing in the logs says a header was removed upstream.

Cold starts, and why caching metadata is the answer

The honest downside of statelessness on serverless: a client that used to learn your tool list once per session may now ask far more often, and each ask can be a cold invocation. That is a real cost, and the spec anticipated it.

Require ttlMs and cacheScope fields on results returned by tools/list, prompts/list, resources/list, resources/read, and resources/templates/list via a new CacheableResult interface.
MCP-CAC-001 MUST · spec 2026-07-28

ttlMs and cacheScope are not paperwork — they are the mechanism that makes the stateless protocol affordable to host. A tools/list with a meaningful ttlMs and cacheScope: "public" can be served from a client or intermediary cache instead of waking your function.

The difference between a cheap server and an expensive one
// Conformant, but wakes your function on every list call
{ "resultType": "complete", "tools": [ … ], "ttlMs": 0, "cacheScope": "private" }

// Conformant, and cacheable by anything in the path
{ "resultType": "complete", "tools": [ … ], "ttlMs": 3600000, "cacheScope": "public" }

Only claim "public" if the response genuinely contains nothing user-specific — the wrong value here is a data-leak class, not a tuning mistake. See caching metadata.

Check the deployment, not the platform

Most hosting-related conformance failures come from the layer between your code and the client — a stripped header, a buffered stream, a certificate on the wrong hostname. The validator tests the deployed endpoint from outside, which is where those show up.

Validate a server →

Frequently asked

Where should I host an MCP server?

Since the 2026-07-28 revision removed protocol sessions, almost anywhere that serves HTTPS works — including serverless platforms that were previously awkward for MCP. The decision now turns on whether you need long-lived streaming for subscriptions/listen: if you do not, serverless is the natural fit; if you do, you need a platform that allows long-running responses without buffering them.

Can I run an MCP server on serverless?

Yes, and it is now the natural fit rather than a workaround. Statelessness means every request is independently processable with no session to pin a client to an instance, so there is nothing to share between invocations and no sticky routing to configure. This was the main thing that made serverless awkward under the session-based revisions.

Do I need sticky sessions for an MCP server?

Not under 2026-07-28. Sticky sessions existed because a client had to keep reaching the instance holding its Mcp-Session-Id. With sessions removed, any instance can serve any request, so ordinary round-robin load balancing is correct and sticky routing is unnecessary complexity.

Does an MCP server need to support SSE?

Only if it implements subscriptions/listen for server-to-client notifications. A server that only exposes tools and resources can answer every request with a single application/json response. If you do stream, the spec requires Content-Type: text/event-stream and recommends setting X-Accel-Buffering: no so proxies do not buffer the stream.

Does an MCP server need HTTPS?

In practice yes. The spec requires all OAuth protocol URLs to use HTTPS except loopback redirects, so any server with authorization must be served over TLS. Beyond that, the canonical server URI in your Protected Resource Metadata must match what clients actually connect to, which effectively means a stable custom domain with a valid certificate.

What about cold starts?

They matter more under 2026-07-28 than they used to, because a stateless client re-sends context on every request and may call tools/list far more often than a session-based one did. The mitigation is built into the spec: ttlMs and cacheScope let clients and intermediaries cache list responses, so a well-configured server sees far fewer cold invocations than a naive reading suggests.