Courses/Introduction to Model Context Protocol (MCP)/Remote Servers with Streamable HTTP
Advanced and ProductionLesson 17 of 21

Remote Servers with Streamable HTTP

From Local Script to Shared Service

Everything we've built ran locally over stdio. But the most impactful MCP servers are remote: hosted once and shared by many users (think of the official Sentry or GitHub servers). Going remote means switching to the Streamable HTTP transport — and, thanks to MCP's two-layer design, your tools, resources, and prompts don't change at all.

pythonThe same document server, now reachable over HTTP. Primitives untouched.
# The only change to go remote:
if __name__ == "__main__":
    mcp.run(transport="streamable-http")

What Changes When You Go Remote

While your primitive code is identical, the operational picture shifts. A remote server serves many clients concurrently instead of one, needs authentication (covered next lesson), and communicates over the network with optional streaming.

ConcernLocal (stdio)Remote (Streamable HTTP)
Clients servedUsually oneMany, concurrently
Launched byThe host, as a subprocessRuns independently as a service
CredentialsEnvironment variablesHTTP auth / OAuth tokens
StreamingN/AOptional SSE for partial results
StatefulnessPer-processCan be stateless per request (a subset of MCP)

The data layer is constant; the transport layer brings concurrency, network, and auth concerns.

Streaming and Statelessness

Streamable HTTP uses HTTP POST for client→server messages. For responses, it can optionally use Server-Sent Events (SSE) to stream partial results over a single response — handy for long-running tools that produce output incrementally. The SDK can also run a subset of MCP statelessly over HTTP, which suits serverless deployments where each request is independent.

⚠️

Don't confuse SSE-the-feature with a transport

SSE appears here as an optional streaming mechanism inside Streamable HTTP. It is NOT a separate transport. Older docs that say 'HTTP+SSE transport' are describing what is now simply 'Streamable HTTP'. There are still only two transports: stdio and Streamable HTTP.

Connecting a Client to a Remote Server

On the client side, connecting to a remote server uses streamable_http_client instead of stdio_client — but the ClientSession and everything above it (list_tools, call_tool, read_resource, get_prompt) is identical. Your application logic doesn't care which transport carries the messages.

pythonConnecting to a remote server. Only the connect call changes; the session API is the same.
from mcp.client.streamable_http import streamable_http_client
from mcp import ClientSession

async with streamable_http_client("https://mcp.example.com/mcp") as (read, write, _):
    async with ClientSession(read, write) as session:
        await session.initialize()
        tools = await session.list_tools()   # same API as stdio

Next: lock it down

A remote server is reachable by anyone on the network — so authentication and authorization become essential. Next we cover MCP's OAuth-based auth and the security rules every remote server must follow.

Key Takeaways

  • The most impactful MCP servers are remote — hosted once, shared by many — and use the Streamable HTTP transport.
  • Going remote is a one-line change (mcp.run(transport="streamable-http")); tools/resources/prompts are unchanged thanks to MCP's two-layer design.
  • Remote shifts the operational picture: many concurrent clients, independent service lifecycle, network auth, and optional streaming.
  • Streamable HTTP uses HTTP POST for requests and optional SSE to stream partial responses; a subset of MCP can run statelessly (good for serverless).
  • SSE is a streaming feature INSIDE Streamable HTTP, not a separate transport — there are still only two transports.
  • Clients connect to remote servers with streamable_http_client instead of stdio_client, but ClientSession and its methods (list_tools/call_tool/...) are identical.

Check Your Understanding

Test what you learned in this lesson.

Q1.What transport do remote, multi-client MCP servers use?

Q2.How much of your tool/resource/prompt code changes when moving a server from stdio to Streamable HTTP?

Q3.What is the correct description of SSE in the current MCP spec?

Q4.On the client side, what changes when connecting to a remote server instead of a local one?

Practice This Lesson