The 2026 shift: MCP started as local-only (stdio). Now remote servers over HTTP are the default for production. GitHub, Stripe, Linear, Notion, and Cloudflare all publish hosted MCP endpoints. Here’s how to build and deploy your own.
Local vs Remote MCP
| Feature | Local (stdio) | Remote (HTTP) |
|---|---|---|
| Runs on | Your machine | A server/cloud |
| Users | Just you | Your whole team |
| Auth | Not needed (local) | OAuth / API keys required |
| Setup | JSON config, restart client | URL + auth token |
| Best for | Development, personal tools | Production, shared tools |
Building a Remote MCP Server
TypeScript with Express
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import express from "express";
const app = express();
const server = new McpServer({ name: "my-remote-server" });
// Define your tools
server.tool("hello", { name: z.string() }, async ({ name }) => {
return { content: [{ type: "text", text: `Hello, ${name}!` }] };
});
// Mount MCP endpoint
app.post("/mcp", async (req, res) => {
const transport = new StreamableHTTPServerTransport("/mcp");
await server.connect(transport);
await transport.handleRequest(req, res);
});
app.listen(3000);
Deploying
Option 1: Cloudflare Workers
Serverless, global, free tier. Cloudflare has first-class MCP support with their Workers platform. Deploy and get a URL instantly.
Option 2: Vercel / Railway
Deploy as a standard Node.js app. Get a HTTPS URL. Add to any AI client.
Option 3: Your own EC2/VPS
Full control. Run behind nginx with SSL. Good for internal tools that shouldn’t be public.
Authentication for Remote Servers
Remote MCP servers MUST have auth. Two patterns:
API Key (Simple)
app.post("/mcp", (req, res, next) => {
const key = req.headers["authorization"]?.replace("Bearer ", "");
if (key !== process.env.MCP_API_KEY) return res.status(401).json({ error: "Unauthorized" });
next();
}, mcpHandler);
OAuth (Enterprise)
Redirect users to your OAuth flow, issue tokens, validate on each request. Required for multi-tenant deployments.
Connecting Clients to Remote Servers
// Claude Desktop config
{
"mcpServers": {
"my-remote-tool": {
"url": "https://my-mcp-server.railway.app/mcp",
"headers": { "Authorization": "Bearer sk_xxx" }
}
}
}
No command needed for remote servers – just the URL and auth headers.
When to Go Remote
- Your team needs the same tools (shared database access, shared project management)
- You want to publish a tool for others (like Stripe or GitHub did)
- You need the server to access resources your laptop can’t (production DB, internal APIs)
- You want uptime guarantees (server stays running even when laptop sleeps)