Local vs Remote MCP Servers: stdio vs Streamable HTTP

Local vs remote MCP servers explained: how stdio and Streamable HTTP work, how OAuth authorization fits in, the security trade-offs, and when to choose each.

By Esha Sabir · Updated November 12, 2026 · 10 min read · How we write

Part of our guide to MCP Server Security: How to Vet a Server Before You Use It.

An MCP server can run in two places. A local MCP server runs on your machine as a child process of the client and talks over stdio (standard input and output). A remote MCP server runs somewhere else and talks over Streamable HTTP, the spec's standard HTTP transport. Pick local when the server needs your files, local tools or offline access. Pick remote when many users or devices share it, when it wraps a hosted service, or when you do not want third-party code running on your machine.

Security differs too. A local server runs with your user's permissions, so the risk is the code itself. A remote server cannot touch your disk, but it receives your tokens and data, so the risk is the operator and the auth setup. This post covers both transports as defined in the current MCP spec (revision 2026-07-28).

How does a local stdio MCP server work?

With stdio, the client launches the server as a subprocess and they exchange newline-delimited JSON-RPC messages over the process's standard streams. The transports overview in the spec describes it in one line: messages over the standard streams of a client-launched subprocess.

That has a few practical consequences:

  • Only the launching client can talk to it. No port is opened, so other processes and websites cannot reach it.
  • stdout is reserved for protocol messages. Server logs must go to stderr. A stray console.log or print corrupts the stream.
  • One server process per client. Each user and each client runs its own copy.
  • Credentials come from the environment. The authorization spec says stdio servers should not use the OAuth flow and should read credentials from the environment instead, typically the env block in the client config.

A typical local config looks like this:

{
  "mcpServers": {
    "git": {
      "command": "uvx",
      "args": ["mcp-server-git", "--repository", "/path/to/repo"]
    }
  }
}

How does a remote Streamable HTTP MCP server work?

Streamable HTTP is defined on its own spec page. The server exposes one endpoint, such as https://example.com/mcp. The client sends every JSON-RPC request as its own HTTP POST. The server replies with either a single JSON object or a Server-Sent Events stream scoped to that one request, which lets it send progress updates before the final result.

The 2026-07-28 revision simplified the transport. It removed protocol-level sessions (the old Mcp-Session-Id header) and the standalone GET stream. Long-lived change notifications now come through a subscriptions/listen request. Each POST also carries headers such as MCP-Protocol-Version, Mcp-Method and, for tool calls, Mcp-Name, so gateways and load balancers can route traffic without parsing the body. The July 2026 changes are covered in detail in our MCP vs API post.

Other transport changes in the 2026-07-28 changelog that matter when you run a remote server:

  • No initialize handshake. Servers must implement server/discover to advertise their supported versions, capabilities and identity. Clients may call it first, or go straight to a request that carries its protocol version.
  • No resumable streams. Last-Event-ID and SSE event IDs are gone. If a response stream breaks, the client re-issues the request with a new ID.
  • GET and DELETE return 405. The Streamable HTTP page says a server that supports only this revision should answer GET or DELETE on the MCP endpoint with 405 Method Not Allowed, and should ignore any Mcp-Session-Id or Last-Event-ID header sent by older clients.

The older HTTP+SSE transport from 2024-11-05 has been deprecated since 2025-03-26. Revision 2026-07-28 reclassifies it as Deprecated under the new feature lifecycle policy, which makes it eligible for removal in a future revision. New implementations should not adopt it. If a server only offers SSE, treat it as legacy.

Remote server security basics

The Streamable HTTP spec lists three protections, with different strengths:

  1. Servers MUST validate the Origin header on all incoming connections to block DNS rebinding, and MUST answer an invalid Origin with HTTP 403.
  2. When running locally, servers SHOULD bind only to 127.0.0.1, not 0.0.0.0.
  3. Servers SHOULD implement proper authentication for all connections.

Only the first is a hard requirement, but treat all three as required in practice. Without Origin checks and auth, a test server on your laptop can be reached by websites your browser opens.

How does OAuth work for remote MCP servers?

Authorization is optional in MCP, but when an HTTP server uses it, the spec defines a specific OAuth 2.1 profile. In short:

  • The MCP server is an OAuth resource server. It must publish Protected Resource Metadata (RFC 9728) so the client can find its authorization server.
  • On an unauthenticated request, the server returns 401 with a WWW-Authenticate header pointing to that metadata, and ideally the scopes it needs.
  • The client gets a client ID through one of three mechanisms: Client ID Metadata Documents (which clients and authorization servers should support), a pre-registered client ID, or Dynamic Client Registration, which is now deprecated and kept for backward compatibility.
  • The client uses PKCE and sends a resource parameter (RFC 8707) naming the exact MCP server, so tokens are bound to it.
  • Tokens go in the Authorization: Bearer header on every request, never in the URL.
  • The server must check that each token was issued for it, and must not accept or pass through tokens meant for other services.

That last rule targets a real anti-pattern. The MCP security best practices call it token passthrough: a server forwarding a client's token straight to a downstream API, which breaks audit trails and lets stolen tokens be reused.

For users, the visible part is a sign-in and consent screen. Read the scopes. A server asking for full write access when it only reads issues is a warning sign.

Local vs remote MCP servers: the trade-offs

Local (stdio)Remote (Streamable HTTP)
Where code runsYour machine, as your userThe operator's infrastructure
Access to your filesYes, whatever your user can readNo, only what you send in tool calls
Who you trustThe code and its dependenciesThe operator, their auth and their logging
CredentialsEnvironment variables in your configOAuth tokens scoped to the server
UpdatesWhen you (or npx) fetch a new versionWhenever the operator deploys
Sharing across devicesInstall on each oneConnect from anywhere
Works offlineYesNo

Neither column is "the safe one". Local servers can be audited but run close to your secrets. Remote servers keep code off your machine, but you cannot see what runs on the other end. Both share the risk of poisoned tool descriptions, covered in our guide to MCP tool poisoning.

When should you use a local or a remote MCP server?

Choose a local stdio server when:

  • It needs your filesystem, a local git repo, a local database or a CLI tool.
  • You want to pin and audit the exact code that runs.
  • You need it to work offline or keep data on your machine.

Choose a remote Streamable HTTP server when:

  • It wraps a hosted SaaS API that already has its own accounts and permissions.
  • Many people or devices need the same server, or you use web-based clients.
  • You do not want to install and update third-party code on every machine.

If you are building a server, you can support both. Most SDKs let the same tool code run over stdio for local use and over Streamable HTTP for hosted use. Our walkthrough on how to build your first MCP server starts with stdio, which is the simplest to test. For step-by-step setup in each client, see how to install an MCP server.

How do you add each type in Claude Code?

Both types use claude mcp add. These forms are from the Claude Code MCP docs.

A local stdio server. Everything after -- is the command Claude Code launches, and --env sets its credentials:

claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable -- npx -y airtable-mcp-server

A remote Streamable HTTP server. You give a URL instead of a command:

claude mcp add --transport http notion https://mcp.notion.com/mcp

--scope controls where the entry is saved: local (the default, this project only), project (shared through .mcp.json) or user (all your projects). The same docs mark the SSE transport as deprecated and say to use HTTP servers where available.

The hybrid pattern: a local server in front of a remote system

Local does not mean the data is local. A common setup, described by Greg Low at Redgate, is a local MCP server that connects to a remote database through its normal driver. The MCP server runs inside your machine's boundary over stdio, and only the database connection crosses the network. You keep the local setup (no OAuth, credentials in env) while the data stays where it lives. The trade-off is that every user needs the server installed and their own database credentials.

Admin-managed remote servers with SSO

Teams often go the other way and run remote servers behind a gateway. Archestra describes the pattern: an admin adds a server once, picks a version and configures credentials, and every client gets the tool on its next connection. Users sign in to the gateway through the company identity provider, the gateway holds the upstream API tokens, and disabling one account removes access everywhere. That replaces secrets pasted into each person's local config. If you take this route, the MCP rule against token passthrough still applies to the gateway.

How do you move an MCP server from local to remote?

The tool code can usually stay the same, since most SDKs support both transports. What changes is everything around it:

  1. Switch the transport to Streamable HTTP with a single POST endpoint.
  2. Add the transport protections: Origin validation, and authentication on every request.
  3. Replace env credentials with authorization. Under the authorization spec, an HTTP server is an OAuth resource server, checks that each token was issued for it, and does not pass tokens through to other APIs.
  4. Stop keeping per-connection state. Revision 2026-07-28 removed protocol sessions. Servers that need state across calls pass explicit, server-minted handles as ordinary tool arguments (changelog).
  5. Implement server/discover, which every server on 2026-07-28 must support.
  6. Separate users. A local server only ever saw one user. A remote one must keep each user's data and tokens apart.

How do you vet each type?

For local servers, review the code, dependencies, tool descriptions and network traffic before you run them. That is the core of our MCP server security guide. On AgenticMart, any listing in the MCP server directory can get a free automated scan, and each listing page shows its scan status. A scan starts the server in a locked-down container, lists its tools over stdio and records which domains it contacts. A scan is a malware and risk check, not a safety guarantee. The scan is designed for code you run yourself, so for hosted servers you also need to judge the operator, their OAuth scopes and their privacy terms.

FAQ

What is the difference between stdio and Streamable HTTP in MCP?

stdio runs the server as a local subprocess and exchanges JSON-RPC messages over standard input and output. Streamable HTTP runs the server as a web service with a single endpoint, where each message is an HTTP POST and replies come back as JSON or a request-scoped SSE stream. stdio is for local servers and Streamable HTTP is for remote or shared ones.

Is SSE still supported in MCP?

The original HTTP+SSE transport from 2024-11-05 is deprecated. Revision 2026-07-28 classifies it as Deprecated under the spec's lifecycle policy, so it can be removed in a future revision, and new implementations should use Streamable HTTP. Streamable HTTP still uses SSE inside responses when a server needs to stream progress, but that is part of the newer transport. Some clients keep SSE support for older servers.

Do local MCP servers need OAuth?

No. The spec says stdio servers should not use the OAuth flow and should take credentials from the environment, usually set in the client config's env block. OAuth applies to HTTP-based servers.

Are remote MCP servers more secure than local ones?

They are differently risky, not automatically safer. A remote server cannot read your local files, but it sees your tokens and any data you send, and the operator can change its behaviour at any time. Choose based on what the server needs to access and whom you trust.

Do remote MCP servers still use sessions?

Not under revision 2026-07-28. It removed protocol-level sessions and the Mcp-Session-Id header, and each request carries its own protocol version and capabilities. Servers on older revisions may still use sessions.

How do I add a remote MCP server to Claude Code?

Run claude mcp add --transport http <name> <url>. For a local server, use claude mcp add --transport stdio <name> -- <command> instead. Add --scope project to share the entry through .mcp.json.

Built something, or looking for a tool?

Browse agents, MCP servers and skills on AgenticMart, see what each can touch, and explore the newest standards on our agent protocol map. List yours free now, paid selling opens soon.

More on MCP Servers