No per-service fees - one plan, unlimited appsFree tier available - start building today15% off your workspace - subscribe to our blogNo per-service fees - one plan, unlimited appsFree tier available - start building today15% off your workspace - subscribe to our blog
Miget x AIPlansEnterpriseCompareBlogDashboard
Start for Free
Blog/Tutorial/AI/
·

How to Host an MCP Server: Remote, Always-On, With a Real URL

The Model Context Protocol (MCP) is how AI assistants like Claude, Cursor, and ChatGPT connect to external tools and data. Building an MCP server is well documented. Hosting one so other people (or your whole team) can use it is where the guides go quiet - because the moment you move from a local server to a remote one, it stops being a script and becomes a service that has to stay up, answer over TLS, and hold sessions. This guide covers that part.

Disclosure: Miget is our platform, and the deployment steps use it - but the "what is an MCP server" and "local vs remote" parts are vendor-neutral, and the architecture is true wherever you host.

What is an MCP server?

An MCP server exposes tools (functions the model can call), resources (data the model can read), and prompts to any MCP-compatible client. The client - Claude Desktop, Cursor, an agent framework - discovers what your server offers and calls it during a conversation. Think of it as a typed, model-facing API.

There are two transports, and the difference decides how you host:

  • Local (stdio): the client launches your server as a subprocess on the same machine and talks over stdin/stdout. Zero hosting - but it only works for the person running it, on their laptop.
  • Remote (Streamable HTTP): the server runs as an HTTP service at a URL. Any client, anywhere, connects to https://your-server/mcp. This is what you host when the server is for a team, a product, or anything beyond your own machine.

Everything below is about the remote case.

Why serverless is the wrong default for a remote MCP server

The instinct is to drop an MCP server on a serverless function. Two things make that painful:

  1. Sessions. MCP is session-oriented - a client initializes, then makes many calls against that session. Serverless functions are designed to be stateless and short-lived; keeping a session alive across cold starts and instance recycling is a fight against the platform.
  2. Cold starts. A model waiting on a tool call is latency the user feels directly. Serverless cold starts land right in that path.

A remote MCP server wants what it actually is: a persistent, always-on HTTP service with a stable URL and TLS. That is an ordinary long-running app - which is exactly what a PaaS hosts well.

Why Miget fits

Nothing MCP-specific here, which is the point - a remote MCP server is a normal app, and Miget runs normal apps:

  • Persistent container, not a function. Your server stays running and holds sessions - no cold starts in the tool-call path.
  • Always-on on paid plans. No sleep, so a client's session does not die because traffic went quiet for a minute.
  • A TLS URL out of the box. Every app gets https://<your-app>.migetapp.com (or your custom domain) with automatic certificates - that URL is your MCP endpoint.
  • Any language. The official MCP SDKs are Python (mcp / FastMCP) and TypeScript (@modelcontextprotocol/sdk); Migetpacks build both from a Git push with no Dockerfile, or bring your own.
  • State when you need it. If your tools need to persist data, add a managed PostgreSQL or Valkey in the same plan at no extra cost.
  • Flat price. One compute plan runs the MCP server plus anything else - no per-request billing on a service the model may call hundreds of times per conversation.

Deploy one in three steps

1. Have a remote MCP server that speaks Streamable HTTP. A minimal Python example with FastMCP:

# server.py
import os
from mcp.server.fastmcp import FastMCP

# Bind to :: (IPv6 wildcard) so the server answers over both IPv6 and IPv4 -
# Miget is dual-stack, and :: accepts IPv4 too via v4-mapped addresses.
mcp = FastMCP("demo", host="::", port=int(os.environ.get("PORT", "5000")))

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

if __name__ == "__main__":
    # serve over HTTP so it can be hosted remotely
    mcp.run(transport="streamable-http")

With a requirements.txt containing mcp, that is a complete deployable server. (The TypeScript SDK is equivalent - a small HTTP server exposing /mcp.)

2. Point Miget at the repo. Create an app in app.miget.com from the Git repository. Migetpacks detect Python (or Node), install dependencies, and run it - no Dockerfile needed. Bind your server to :: (the IPv6 wildcard) rather than 0.0.0.0: Miget is dual-stack, and binding to :: serves both IPv6 and IPv4 (via v4-mapped addresses) from one socket, while 0.0.0.0 would answer IPv4 only. Read the port from the PORT environment variable Miget provides.

3. Deploy. Miget builds the app, brings it up, and assigns a TLS domain. Your MCP endpoint is https://<your-app>.migetapp.com/mcp. That URL is what you hand to clients.

Connect a client

Point any MCP client at the deployed URL. In Claude or Cursor's connector settings, add a remote MCP server with the URL https://<your-app>.migetapp.com/mcp. The client initializes a session, discovers your add tool, and can call it mid-conversation. Because the app is always-on, the first call after a quiet period does not pay a cold-start penalty.

Production notes

  • Keep it warm. Use a paid plan so the app never sleeps - MCP sessions are long-lived and a sleeping server drops them. This is the single most important setting for a real MCP deployment.
  • Put auth in front. The MCP spec supports OAuth for remote servers; at minimum, require a token. An unauthenticated tool server on a public URL is a tool server for the whole internet.
  • Give stateful tools a real database. Do not keep state in process memory if the server may restart - use a managed PostgreSQL or Valkey and your sessions survive redeploys.
  • Pin your SDK version. Both MCP SDKs move quickly; pin a version and upgrade deliberately.
  • Watch latency. The model waits on your tool calls. Keep tool handlers fast, and co-locate any database in the same plan so calls do not cross the internet.
  • Bind dual-stack. Listen on ::, not 0.0.0.0 - Miget serves every app over both IPv6 and IPv4, and a v4-only bind quietly drops IPv6 clients.

Frequently Asked Questions

What is an MCP server, in one sentence?

A service that exposes tools, data, and prompts to AI clients (Claude, Cursor, ChatGPT) over the Model Context Protocol, so the model can call your functions during a conversation.

Do I need a GPU to host an MCP server?

No. An MCP server is an I/O service, not a model - it routes tool calls, it does not run inference. A small always-on plan is plenty; the models run at whatever LLM provider your client uses.

What is the difference between a local and a remote MCP server?

Local servers run as a subprocess on your own machine (stdio transport) - great for personal use, invisible to everyone else. Remote servers run as an HTTP service at a URL (Streamable HTTP transport) - reachable by any client, which is what you host for a team or product.

Can I host an MCP server on serverless?

You can, but sessions and cold starts fight you: MCP is session-oriented and latency-sensitive, and serverless is built to be stateless and to cold-start. A persistent always-on app is a better fit, which is why this guide uses one.

How much does hosting an MCP server cost on Miget?

A small always-on plan starts at $5/month and runs the server plus any database it needs - flat, with no per-tool-call billing, which matters because a model can call an MCP tool many times in a single conversation.


How to Host an MCP Server (Remote, TLS, Always-On)