Live Webinar
The Festive Growth Sessions: How Top Brands Drive More Leads· 23 Sept, 3:30 PM ISTSave Your Seat
Wati

Where Should You Host Your MCP Server?

Rohan Chaturvedi
6 mins read
Fact-checked by: Namitha Sudhakar
|According to: Editorial Policies
Where Should You Host Your MCP Server?
CategoriesAI Agent

Too Long? Read This First

  • MCP has no built-in requirement to run on any particular platform; the deciding factors are statefulness, expected connection duration, and how much operational control you want.
  • Cloudflare Workers fit a stateless, globally distributed server well, and pairing them with Durable Objects covers cases that need per-session state.
  • Vercel Functions cap fluid compute duration at 300 seconds on the Hobby tier and 800 seconds on Pro and Enterprise, with a 1,800-second beta ceiling; a server that needs to stream indefinitely will outgrow that.
  • AWS Lambda invocations are capped at 15 minutes, and response streaming through a Function URL is capped at 200MB, with the first 6MB uncapped and the rest limited to 2MB/s.
  • Cloud Run defaults to a 5-minute request timeout but can be configured up to 60 minutes, and an open WebSocket keeps the instance active and billed the whole time.

Picking a host for a remote MCP server is not the same decision as picking a host for a normal web API, because Model Context Protocol connections can be long-lived, streamed, and session-aware in ways a typical REST endpoint isn't. Get the platform wrong and you'll either pay for idle capacity you don't need or watch sessions drop mid-stream when a serverless function hits its duration cap.

The right answer depends on one question more than any other: does your server need to remember anything about a specific connection between requests, or can any replica answer any request? Everything else in this guide follows from that.

Stateless vs Stateful: The Question That Decides Everything

As of the 2026-07-28 revision, MCP dropped its protocol-level session concept along with the required initialization handshake, so in principle any request can land on any server instance with no sticky routing needed. That's a real simplification for the infrastructure side, but it does not make your application stateless by default.

If a workflow spans multiple calls, your server still needs to track something: a cart, a browser context, a job in progress.

The fix is an explicit opaque handle, a basket_id or job_id, passed as an ordinary argument on every subsequent call, with the actual state stored in a database or cache rather than in process memory.

Do this, and almost any hosting platform works, because no request depends on hitting the same replica twice.

If your server genuinely needs server-initiated messages, subscriptions, or an in-memory session object per client, you're building a stateful server, and your platform choice narrows considerably.

Platform Comparison

Platform

Session state

Duration and streaming

Best fit

Cloudflare Workers

Global memory isn't a session store; use D1, KV, R2, or Durable Objects for per-session state

No hard wall-time limit while the client stays connected; isolates start very quickly

Stateless global tools, edge-near latency, streaming

Cloudflare Workers + Durable Objects

A Durable Object is a globally addressable single-threaded actor with durable storage

Can hibernate and discard in-memory state, so persist what matters

Servers needing per-session routing, replay, or coordination

Vercel Functions

Instances may be reused but shouldn't be relied on for session maps

300s (Hobby), 800s (Pro/Enterprise), 1,800s in beta

TypeScript/Node servers already living on Vercel, short-to-moderate calls

AWS Lambda

Frozen/reused execution environments are not a reliable session store; use DynamoDB or ElastiCache

15-minute hard invocation cap; response streaming up to 200MB via Function URL

AWS-native stacks with bounded-duration requests

Cloud Run/containers

A normal process can hold session state in memory, but scaling makes a single replica unsafe without external storage

5-minute default timeout, configurable to 60 minutes; open WebSockets bill the whole time

Long-lived connections, custom runtimes, private networking

Managed MCP hosting

Provider-dependent; confirm whether custom stateful sessions are actually supported

Usually the simplest operational path, but confirm max stream duration and idle timeouts

Teams that want a production endpoint without managing infrastructure

What Each Platform Actually Costs You

Cloudflare's Workers Standard plan lists a $5 monthly minimum with 10 million included requests and included CPU time; Durable Objects add separate request, duration, and storage charges, and a connected WebSocket that can't hibernate keeps accruing duration cost.

Vercel bills active CPU, provisioned memory, and invocations, with no charge between requests.

AWS Lambda charges per request plus GB-seconds of execution, with extra charges for response-stream bytes above the free allowance, and Provisioned Concurrency adds an always-on capacity fee if you use it to cut cold starts.

Cloud Run offers both request-based and instance-based billing, and an always-open connection tends to push the economics toward paying for instance time rather than per request.

One managed MCP hosting vendor currently advertises a $5 per month hobby tier covering one active server, with usage pricing starting at one credit per server-hour beyond that; treat that as one vendor's number rather than a market standard.

OAuth Isn't Optional for a Protected Remote Server

Whichever platform you pick, a protected remote MCP server needs to follow the MCP authorization specification rather than a homegrown login flow.

In practice, that means publishing protected-resource metadata so a client can discover the authorization server, using OAuth 2.1 authorization code with PKCE for interactive clients, requiring a bearer token on every request in a session (not just the first), validating issuer, audience, expiry, and scope on each call, and returning 401 Unauthorized with the correct WWW-Authenticate metadata when a token is missing or invalid.

It's worth being precise here: an access token authenticates the caller, but it does not by itself guarantee that a POST, a reconnecting GET, and a later notification all reach the same in-memory transport object.

Session routing and OAuth solve different problems, and platforms that only solve one of them will leave a gap.

Picking a Default

For a new general-purpose remote server, start with a stateless handler on Cloudflare Workers, and add Durable Objects only once you have a concrete reason (replay, subscriptions, coordinated per-session state) rather than by default.

Use Vercel when the server is already a Vercel web app, and every interaction comfortably fits inside its duration limits. Use Lambda when the rest of your stack is AWS and requests are naturally bounded, not when you need an indefinite stream.

Reach for Cloud Run, ECS, Kubernetes, or an always-on VM when you need a conventional persistent process, custom dependencies, or private network access that serverless platforms don't give you. And use managed MCP hosting when turnkey OAuth, monitoring, and a stable endpoint matter more to you than infrastructure control.

Whichever you choose, build for reconnection: persist state that matters, make initialization idempotent, handle an expired session gracefully, and assume any given connection can be torn down and picked up by a different replica.

Hosting a WhatsApp MCP Server in Practice

A WhatsApp-facing MCP server adds a wrinkle most generic examples skip: every tool call is ultimately talking to a real customer conversation, so a dropped connection mid-send is a worse failure mode than a dropped connection on a read-only lookup.

That pushes the calculus toward a durable state for anything that touches an active send, and toward stateless, cacheable handling for read paths such as listing conversations or checking a template's status.

Wati already runs this trade-off for you: the Wati MCP server is hosted and maintained centrally rather than something each customer sets up themselves, so the platform decisions in this article apply if you're building your own connector into it, not to consuming it directly.

If you're extending Wati's Astra orchestration layer with your own MCP connectors, the same stateless-by-default, explicit-handle pattern described above is the one to follow, and the same coordination principles covered in Wati's agent orchestration guide apply to how connectors slot into a larger run.

For the mechanics of pointing an existing client at a hosted server rather than standing up your own, see connecting Wati's MCP server to Claude.

Skip the Hosting Decision Entirely

If you'd rather not make any of these trade-offs yourself for your WhatsApp tooling, the decision is already made.

Book a demo to walk through how to connect it to your agent.

Frequently asked questions

Do I need Durable Objects if I'm using Cloudflare Workers?

Only if your server needs per-session state, server-initiated messages, or coordination that a database alone doesn't solve cleanly. A purely stateless server, where every request carries what it needs and reads/writes go straight to an external store, runs fine on plain Workers.

Can I run an MCP server on Vercel if it needs to stream for more than 30 minutes?

Not reliably. Even the extended 1,800-second beta ceiling on fluid compute tops out at 30 minutes, so an indefinite or very long stream is better suited to a container platform or Cloudflare Workers, which has no hard wall-time limit while the client stays connected.

Is AWS Lambda a bad choice for MCP?

Not inherently, but it fits bounded-duration work better than long-lived sessions. The 15-minute invocation cap and the need to externalize any session state to DynamoDB or a similar store make it a good match for an AWS-native stack with predictable request lengths, not a default for indefinite streaming.

Does managed MCP hosting remove the need to think about statefulness?

No. It removes infrastructure management, but you still need to confirm whether the provider actually supports custom stateful sessions, what its maximum stream duration is, and how it handles reconnects, before assuming it behaves like a container you'd run yourself.

Related posts