Home › Setup and operations › How to Deploy an MCP Server: From Local to Remote, Step by Step
How to Deploy an MCP Server: From Local to Remote, Step by Step
To deploy an MCP server, build it with an SDK, expose it over streamable HTTP, require authentication on every request, add logging and rate limits, test it with the MCP Inspector, then run it behind HTTPS on a container or serverless host and paste the URL into your client. Keep the code transport-agnostic so local and remote share one codebase.
Step 1: build a server with a clean structure
BusinessMCP’s build guide uses Node.js 18 or later with the MCP SDK, Zod and Express, in ES modules with nodenext in TypeScript. The structure it recommends is worth copying whatever language you use: a transport-agnostic server factory, separate files for tools and resources, and thin entry points for stdio and HTTP.
Register each tool with a name, a description the model will read, and an input schema. Return structured output and flag failures with isError. Prefer a few well-described tools over many vague ones; the guide notes that descriptions shape whether a model picks a tool.
Use a tool when the agent should decide to fetch something and a resource when the host should load it into context.
Step 2: test locally over stdio first
Run the server with stdio and open it in the MCP Inspector. The Inspector shows the tool list, lets you call tools and often reveals vague descriptions that unit tests miss, per the same guide. One rule matters here: a stdio server must not write to standard output other than protocol messages. Log to standard error.
Step 3: add the remote transport
Switch the entry point to streamable HTTP. The guide’s stateless pattern creates a fresh server and transport per request, which scales horizontally and suits serverless runtimes. If you need sessions, long-lived streams or server-initiated messages, plan for sticky routing or shared session storage.
| Pattern | Good for | Watch out for |
|---|---|---|
| Stateless per request | Serverless, horizontal scale | No session state between calls |
| Stateful sessions | Streaming, subscriptions | Sticky routing, memory use |
| stdio only | Local tools | One machine, one install |
Step 4: secure it before you expose it
Do this before the URL goes anywhere. Require authentication on every request, scope each token to an allowlist of tools, log every call, rate-limit per caller and validate inputs in the handler. The guide says a bearer token is the minimum for internal use and OAuth 2.1 suits public multi-tenant servers. The full picture is in MCP server hosting with authentication.
Key takeaway: never deploy first and add auth later. A public MCP URL with real tools behind it is found and probed quickly.
Step 5: choose where it runs
Choose by your skills and constraints.
- Container platform or VM. Simple mental model, easy debugging, you patch it.
- Serverless or edge. Cheap at low volume and scales automatically, limited by timeouts and statelessness.
- Your own Kubernetes. Best if you already run it; overkill otherwise.
Put a reverse proxy or platform router in front for TLS. Make sure it does not buffer streamed responses.
See also the primer on MCP hosting if any term here is new.
Step 6: connect clients and test the handshake
Give each client the URL and credentials. Test from every client you support. Per-client setup differs: BusinessMCP documents Claude Desktop, ChatGPT, Gemini, Cursor and VS Code in its connect guide, which shows how much the connection steps vary. Remember that ChatGPT cannot use local servers at all, so a remote deployment is required for it.
Step 7: monitor and plan updates
Add a protocol-level check: initialize, notifications/initialized, tools/list. Alert on repeated failures. Hash tool definitions to catch drift. See MCP server monitoring for cadence and costs.
The alternative: do not deploy code at all
If what you want is an assistant that works with your existing business tools rather than a custom server, a managed endpoint skips this entire process. BusinessMCP’s MCP hosting takes that approach: connect sources, get a hosted endpoint, paste it into your client. It does not host code you wrote, so it does not replace deployment for a custom server, but it can sit beside one by aggregating it as an upstream. We discuss that split in self-hosted versus managed.
Deployment checklist
- [ ] Server builds from a transport-agnostic factory.
- [ ] Tools have clear descriptions and input schemas.
- [ ] Tested in the Inspector over stdio.
- [ ] Streamable HTTP entry point added.
- [ ] Auth, allowlists, logging and rate limits in place.
- [ ] HTTPS with a valid certificate.
- [ ] Proxy does not buffer streams.
- [ ] Each target client connected and tested.
- [ ] Handshake monitor and alert owner set.
- [ ] Spec revision noted with a review date.
Treat the first week after launch as part of deployment. Read the logs daily, and expect to adjust tool descriptions once real prompts hit the server. The requirements checklist is a good second pass once the basics work.
Troubleshooting the first deployment
Most first deployments fail in one of a few predictable ways. Work through these in order.
The client cannot connect at all. Confirm the URL is https and reachable from outside your network, the certificate is valid, and the path matches what the client expects. Test with a plain HTTP client by sending an initialize request before blaming the AI client.
The connection works, but no tools appear. Check that tools/list returns results and that you handle pagination. Servers with many tools can spread them across pages; a client that stops at the first page looks like it lost tools.
It works in your editor but not in ChatGPT. ChatGPT only supports remote servers, and consumer assistants usually require an OAuth sign-in flow rather than a static header. A bearer-token-only server may be reachable in developer tools yet fail in the assistant’s connector screen.
Responses hang or arrive all at once. A proxy or platform router is probably buffering streamed responses. Disable response buffering for the MCP route.
Tools are called with wrong arguments. Improve the descriptions and schemas. Models read them. Add examples to descriptions and tighten types with enums and bounds.
It worked yesterday and fails today. Look for an expired certificate, a rotated key, a changed upstream API, or a client update that moved to a newer protocol revision. BusinessMCP’s pages reference both the 2025-06-18 and 2026-07-28 revisions, which is a reminder that clients and servers can drift apart.
| Symptom | First thing to check |
|---|---|
| Cannot connect | URL, TLS, firewall |
| Connected, no tools | tools/list and pagination |
| Fails only in ChatGPT | OAuth flow and remote reachability |
| Streams stall | Proxy buffering |
| Wrong arguments | Tool descriptions and schemas |
| Sudden failure | Certificates, keys, spec revision |
Keep a short runbook with these entries and the commands you use to test each one. The second person who deploys your server will thank you.
Frequently asked questions
How do I deploy an MCP server?
Build it with an MCP SDK, expose it over streamable HTTP, add authentication and logging, test with the MCP Inspector, then run it on a container or serverless platform behind HTTPS and connect your client to the URL.
Can I deploy an MCP server to serverless?
Often yes, using a stateless pattern where each request creates a fresh server and transport. BusinessMCP’s build guide describes this as suiting horizontal scaling and serverless hosts. Features needing session state need more design.
What Node.js version do I need?
BusinessMCP’s build guide uses Node.js 18 or later with the MCP SDK, Zod and Express. Check your SDK’s current requirements, since the SDK line changes with spec revisions.
Why does my stdio MCP server break when I add logging?
Stdio servers must not write to standard output, because stray text corrupts the protocol. Log to standard error instead.
Sources
- Model Context Protocol – Transports specification – https://modelcontextprotocol.io/specification/2025-06-18/basic/transports
- Model Context Protocol – Authorization specification – https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization
- BusinessMCP – Build an MCP server – https://businessmcp.com/docs/build-mcp-server