Skip to content
Black FridayCode BLACK150: 150% on your first deposit of $100 or more, up to $500 bonus. New accounts, until 1 Dec, 00:00 UTC.Get the code
LiteKeep
Sign inDeploy a server

Tutorial, MCP spec 2026-07-28

Host an MCP server on a VPS. Your tools, reachable by Claude from anywhere.

Most MCP hosting guides deploy to a serverless platform, or stop before HTTPS and auth. Here’s the whole path on a server you control, tested against the official Python SDK.

  • 10 min read
  • 5 chapters
  • Updated

What a remote MCP server needs

  • TransportStreamable HTTP/mcp
  • Claude on the webConnects from the cloudPublic HTTPS
  • AuthOptional in the specAdd a token

A server on your laptop can't be reached by claude.ai.

Host it on a Lite 2

$4

  • Always on
  • Fixed IP
  • HTTPS
  • Claude
  • Cursor
  • Python

2 vCPU, 2 GB, 40 GB NVMe. Billed by the hour, paid in crypto.

The short answer

A remote MCP server is a normal HTTPS service with one endpoint, /mcp, speaking Streamable HTTP. Run it on 127.0.0.1, put Caddy in front for HTTPS and a token check, and keep it up with systemd.

Claude on the web connects from Anthropic’s cloud, so the server needs a public address: a laptop or a home network won’t do. The builder below writes every file.

MCP, the Model Context Protocol, is how Claude, Cursor and other AI apps call your tools: a database query, an internal API, a search over your files. Locally, a tool runs as a subprocess. Remotely, it’s a web service.

A VPS gives that service a fixed address, no cold starts, and your data on a machine you control.

In this guide you’ll learn

  • Local or remote: which you need
  • A builder for server, service, proxy and client
  • Deploy step by step on Ubuntu
  • Auth: a token, or OAuth
  • Fixes for 421, 401 and old SSE guides

Chapter 1

Local or remote MCP server?

The MCP spec defines two transports. Which one you need depends on who connects.

MCP transports, from the spec
stdio (local)Streamable HTTP (remote)
How it runsThe client starts it as a subprocessA web service on one endpoint, /mcp
Who can use itApps on the same computerAny client that can reach the URL
Claude on the webNoYes, with a public HTTPS address
AuthCredentials from the environmentOptional in the spec; add a token or OAuth

The older HTTP+SSE transport has been deprecated since 2025; new servers should use Streamable HTTP.

Chapter 2

Build your MCP server files

Enter the domain you’ll point at the server and the client you’ll use. The token is generated in your browser and never sent anywhere.

Your server

1. ~/server/server.py

from mcp.server import MCPServer
from mcp.server.transport_security import TransportSecuritySettings

mcp = MCPServer("My tools")

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

security = TransportSecuritySettings(allowed_hosts=["mcp.example.com", "mcp.example.com:*"])
app = mcp.streamable_http_app(transport_security=security)

2. /etc/systemd/system/mcp.service

[Unit]
Description=MCP server
After=network.target

[Service]
User=mcp
WorkingDirectory=/home/mcp/server
ExecStart=/home/mcp/server/.venv/bin/uvicorn server:app --host 127.0.0.1 --port 8000 --proxy-headers --forwarded-allow-ips=127.0.0.1
Restart=always

[Install]
WantedBy=multi-user.target

3. /etc/caddy/Caddyfile

mcp.example.com {
  @nokey not header Authorization "Bearer YOUR_TOKEN"
  respond @nokey 401
  reverse_proxy 127.0.0.1:8000
}

4. Connect

claude mcp add --transport http my-tools https://mcp.example.com/mcp --header "Authorization: Bearer YOUR_TOKEN"

Deploy a Lite 2

Chapter 3

Deploy it on Ubuntu, step by step

On a fresh Ubuntu 24.04 server, as root or with sudo.

  1. Point your domain at the server

    Add an A record for mcp.example.com with the server’s IP address.

  2. Install Python and Caddy

    apt update && apt install -y python3-venv caddy
  3. A user and an environment for the server

    adduser --disabled-password --gecos "" mcp
    sudo -u mcp mkdir -p /home/mcp/server
    sudo -u mcp python3 -m venv /home/mcp/server/.venv
    sudo -u mcp /home/mcp/server/.venv/bin/pip install "mcp[cli]" uvicorn
  4. Add the files from the builder

    Save server.py in /home/mcp/server/, the unit as /etc/systemd/system/mcp.service, and the Caddyfile as /etc/caddy/Caddyfile.

  5. Start everything

    systemctl daemon-reload
    systemctl enable --now mcp
    systemctl reload caddy
  6. Test from your laptop

    npx @modelcontextprotocol/inspector --server-url https://mcp.example.com/mcp --transport http

    The Inspector needs Node 22.19 or newer. Run it on your laptop, not the server.

Then close everything except 22, 80 and 443 in your firewall. Caddy gets the HTTPS certificate on its own.

Chapter 4

Auth: a token, or OAuth?

The spec makes authorization optional. When a server uses it over HTTP, the spec’s method is OAuth 2.1, with the server publishing protected resource metadata.

Two ways to protect a remote MCP server
A fixed tokenOAuth 2.1
What it isA secret sent as Authorization: BearerPer-user sign-in through an identity provider
Clients that accept itClaude Code, Claude (request headers), CursorClients that support MCP OAuth
Good forYour own tools, a small teamMany users, revocable per person
EffortOne line in the CaddyfileAn identity provider and token checks in the server

Chapter 5

Fixing common MCP deploy errors

What goes wrong after the server works on localhost.

  1. 421 Misdirected Request, "Invalid Host header"How to check: The Python SDK only accepts localhost until you allowlist your domain. The builder’s server.py does that; we checked it against the official SDK.
  2. 401 from every requestHow to check: Caddy rejected the token. The header must be exactly Authorization: Bearer and your token, with no extra spaces.
  3. An old guide uses /sseHow to check: That’s the deprecated transport. Use /mcp and Streamable HTTP; Claude Code’s docs say the same.
  4. FastMCP or MCPServer?How to check: Version 2 of the Python SDK renamed FastMCP to MCPServer. Older code imports from mcp.server.fastmcp import FastMCP.
  5. Tools that run commands or read filesHow to check: Anyone with the token can call them. Expose only what you’d hand that person directly.

Now it’s your move

One endpoint, HTTPS in front, a token at the door, systemd behind it. That’s a remote MCP server Claude can reach from anywhere.

Deploy a Lite 2 and paste the files above. Running agents too? See self-hosted AI agents and Claude Code on a VPS.