Join our Newsletter — 33% off our NHI Course
Home› Guides› Streamable HTTP vs stdio MCP Transport: Threat Models,…
Guide MCP, Protocols & Agent Platforms

Streamable HTTP vs stdio MCP Transport: Threat Models, Controls and Decision Criteria

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 14 November 2026 17 min read
On this page

Choosing between stdio and Streamable HTTP for an MCP server is a security decision, not a packaging detail, because the two transports put the trust boundary in completely different places. With stdio the client launches the server as a child process on the same machine, so the risk is local code execution and a poisoned software supply chain. With Streamable HTTP the server is an independent network service, so the risk is authentication, token handling, DNS rebinding and everything that comes with exposing an endpoint. This guide compares threat models, controls and decision criteria for each. It is for security architects, platform engineers and MCP server owners. Protocol details reflect MCP specification revision 2026-07-28, checked on 14 November 2026; the move off the older HTTP+SSE transport is covered in the MCP SSE to Streamable HTTP Migration guide and protocol threats in general in the MCP Security Guide.

Key takeaways

  • Short answer: use stdio for a server that only one user's client needs, that works on local resources, and that you can pin and sandbox on the endpoint; use Streamable HTTP when several users or agents share the server, when it fronts a shared system of record, or when you need central authentication and audit.
  • stdio has no authentication layer, by design. The authorisation specification says stdio implementations should not follow the OAuth flow and should take credentials from the environment, so the security of a stdio server is the security of the process, its package source and the secrets it inherits.
  • Streamable HTTP inherits every web risk. Servers must validate the Origin header and return 403 on an invalid one, should bind to 127.0.0.1 when local, should authenticate every connection, and must only accept tokens issued for themselves.
  • A local HTTP server is the worst of both. It carries stdio's supply chain exposure plus a listening port that any local process or, through DNS rebinding, any web page can reach. The security best practices advise local servers to use stdio, or to restrict an HTTP transport with an authorisation token or an access-controlled IPC channel.
  • The transport does not change what a tool can do. Tool poisoning, prompt injection and excessive scopes apply on either; transport decides where you enforce controls, not whether you need them.

The two transports in plain terms

stdio: the MCP client launches the server as a subprocess. The server reads newline-delimited JSON-RPC messages from stdin and writes them to stdout; it may write UTF-8 logging to stderr, and it must not write anything to stdout that is not a valid MCP message. All metadata travels in the message body under _meta; there is no header layer. The server runs with whatever user, filesystem, network and environment the client process has, unless something else restricts it.

Streamable HTTP: the server runs as an independent process that can handle many clients. It exposes one MCP endpoint, for example https://example.com/mcp, and every client message is its own HTTP POST. In revision 2026-07-28 the transport is stateless: there are no protocol sessions, the old GET stream and Mcp-Session-Id header are gone, and a server should answer GET or DELETE with 405. Each POST carries MCP-Protocol-Version, Mcp-Method and, for tools/call, resources/read and prompts/get, an Mcp-Name header mirrored from the body. Authorisation follows the MCP authorisation specification, built on OAuth 2.1 with RFC 9728 Protected Resource Metadata and RFC 8707 resource indicators.

Protocol semantics are identical on both. What differs is who can reach the server, how the caller is identified and where an intermediary can see the traffic.

Side-by-side comparison

DimensionstdioStreamable HTTP
Who can reach the serverOnly the parent process holding its standard streamsAnything that can reach the endpoint over the network, subject to binding, Origin checks and authentication
Caller identityImplicit: whoever launched the processExplicit: bearer access token in the Authorization header on every request
Where server credentials come fromEnvironment variables, files or OS keychain on the hostThe server's own secret store; per-user tokens issued by an authorisation server
Main threat classMalicious launch commands, malicious or compromised packages, inherited secretsBroken authentication, token passthrough and theft, DNS rebinding, SSRF during OAuth discovery
Visibility to a network gatewayNone; traffic never leaves the hostFull; gateways can route on mirrored headers after body validation
Audit evidenceClient logs, optional stderr capture, endpoint telemetryHTTP access logs, token claims, server-side tool call logs
Multi-user useOne process per client; no sharingDesigned for many clients; tenancy and per-user authorisation become the server's job

Threat model: stdio

A stdio server is code that the client executes. The security best practices describe local servers as binaries downloaded and executed on the same machine as the client, and list three attack routes: a malicious startup command placed in client configuration, a malicious payload inside the server itself, and an insecure local server left running on localhost and reached through DNS rebinding. The first two are stdio problems; the third applies only when a "local" server listens on a port.

  • Configuration as an execution path: an MCP configuration entry is a command line. Whoever can write that file chooses what runs. In the Amazon Q MCP Config Vulnerability 2026, the IDE extension loaded server definitions from a repository's .amazonq/mcp.json and ran their commands without asking, and the processes inherited the developer's environment, including cloud access keys and session tokens. The fix added an untrusted server consent prompt.
  • Package supply chain: most stdio servers are launched through a package runner, so the version that runs is whatever the registry serves at launch time unless it is pinned. The postmark-mcp Malicious MCP Server 2025 worked normally for fifteen versions before version 1.0.16 added one line that blind-copied every outgoing email to an attacker address. This maps to ATT&CK T1195.002 Compromise Software Supply Chain.
  • Inherited secrets: because stdio servers take credentials from the environment, a server often receives far more than it needs: the whole shell environment, cloud CLI profiles, SSH agent sockets and tokens in dotfiles (T1552.001 Credentials In Files).
  • Same privileges as the client: the security best practices tell clients to warn that MCP servers run with the same privileges as the client. Without a sandbox, a stdio server can read the home directory, open outbound connections and spawn further processes (T1059 Command and Scripting Interpreter).
  • Proxies that spawn stdio servers: the specification is explicit that stdio itself is not inherently vulnerable, but a local proxy service that spawns servers on request creates an escalation path. A client-side flaw such as cross-site scripting can steal the proxy token and ask the proxy to launch arbitrary commands. The MCP Inspector advisory GHSA-7f8r-222p-6f5g (CVE-2025-49596, fixed in 0.14.1) describes this class: missing authentication between the Inspector client and its proxy let unauthenticated requests launch MCP commands over stdio.

What stdio does well is reachability: no other machine and no web page can send it a message, and there is no token in transit. That is why the specification recommends it for servers intended to run locally.

Threat model: Streamable HTTP

A Streamable HTTP server is a web service that acts as an OAuth resource server. Its main assets are the access tokens presented to it, the downstream credentials it holds, and the data behind its tools.

  • Missing or weak authentication: authorisation is optional in MCP, and the transport says only that servers should implement proper authentication for all connections. An unauthenticated remote server is an open API to whatever its tools touch. The LiteLLM MCP Auth Bypass 2026 shows how a validation path that falls back to an empty authentication object instead of rejecting the request turns any bearer token into a full MCP session.
  • DNS rebinding: a web page the user visits re-points its own hostname to 127.0.0.1 or an internal address, and the browser then sends requests to the MCP endpoint as if same-origin. The transport requires servers to validate the Origin header on all incoming connections and to respond 403 when it is present and invalid, and says local servers should bind to 127.0.0.1 rather than 0.0.0.0. Without these, the specification warns, attackers could use DNS rebinding to interact with local MCP servers from remote websites.
  • Token passthrough and audience confusion: servers must validate that access tokens were issued specifically for them, must not accept or transit any other tokens, and must not pass the client's token to upstream APIs. Forwarding loses the audit trail and lets one compromised service replay a token at another (T1550.001 Application Access Token).
  • Token theft: tokens cached or logged on the server, or stored by the client, can be replayed (T1528 Steal Application Access Token). The specification requires secure token storage, forbids tokens in the query string and says authorisation servers should issue short-lived access tokens.
  • SSRF during discovery: a client fetches the resource_metadata URL, authorisation server URLs and endpoint URLs supplied by the server. A malicious server can point them at internal ranges or 169.254.169.254. Clients should require HTTPS, block private, loopback and link-local ranges, validate redirect targets and, when deployed server-side, route discovery through an egress proxy.
  • Header and body disagreement: intermediaries route on Mcp-Method, Mcp-Name and Mcp-Param-* headers, but the server executes the body. Servers that process the body must reject mismatches with HTTP 400 and JSON-RPC error -32020 (HeaderMismatch), and intermediaries enforcing policy on headers should reject protocol versions that do not require that validation.

What Streamable HTTP does well is control: one deployment can be patched, logged, put behind a gateway and given its own least-privilege identity.

The local HTTP server problem

Many single-user servers still listen on a localhost port. This combines stdio's package and privilege risks with an endpoint that every local process can reach and that a browser can be tricked into reaching. The security best practices are direct: servers intended to run locally should use stdio to limit access to the MCP client, and if they use HTTP they should require an authorisation token or use Unix domain sockets or another IPC mechanism with restricted access. Because stdio framing works unchanged over Unix domain sockets, a socket restricted to one user keeps stdio's reachability properties without a TCP port.

If a local HTTP server cannot be avoided, treat it as a remote server that happens to run on a laptop: bind to 127.0.0.1 only, validate Origin against an explicit allowlist, require a per-launch random token, and never expose a "spawn command" endpoint without authentication. See the Local MCP Server Security Guide for workstation settings.

Controls per transport

Control objectivestdioStreamable HTTP
Decide what may run or connectManaged client allowlist of server commands; consent dialog showing the exact command, untruncated, before one-click installAllowlist of server URLs in client policy; gateway or egress rules for remote endpoints
Integrity of the codePin exact package versions or digests; install from the publisher's official source; review diffs before upgradeSigned images, controlled deployment pipeline, vendor security updates applied centrally
Caller authenticationNot applicable at protocol level; rely on OS user and process ancestryOAuth 2.1 bearer token on every request, audience bound with RFC 8707 resource; 401 on invalid or expired tokens
Credential scopePass only the named variables the server needs; prefer short-lived tokens from a broker over static keys in the environmentMinimal scopes_supported, step-up through insufficient_scope challenges, separate upstream tokens per API
ContainmentSandbox or container with restricted filesystem and network; explicit grants for extra directoriesContainer or workload isolation, its own non-human identity, no access to instance metadata unless needed
Browser and network exposureNone by default; keep it that way by avoiding HTTP wrappersOrigin validation with 403, 127.0.0.1 binding when local, TLS for remote, header and body validation
LoggingClient-side tool call logs, stderr capture, endpoint process telemetryServer-side call logs with token subject, client ID, method and tool name; gateway logs

For stdio, the endpoint is the control plane: see the How to audit MCP servers on developer laptops guide and the AI Agent Sandboxing and Code Execution Guide. For Streamable HTTP, the server and the authorisation server are the control plane: see the Remote MCP Server Hardening Guide and the MCP Authorisation Specification Guide.

Where identity fits

The transport choice decides which identity the server acts as. A stdio server acts as the user: it borrows the user's operating system account and whatever credentials sit in the user's environment, so its activity in downstream logs is indistinguishable from the user's own. A remote server has two identities: the caller's, in an audience-bound token, and its own workload identity for upstream systems. That second identity is a non-human identity needing an owner, rotation and least privilege. Static API keys are the common shortcut on both transports and the common finding in audits; see API Keys vs OAuth for MCP Servers and the MCP Static Token Audit.

Decision criteria

No standard sets the line between the two. These criteria are practitioner judgement built on the specification's recommendations.

FactorPoints to stdioPoints to Streamable HTTP
Who uses itOne user, one client, on their own machineMany users, agents or pipelines
What it touchesLocal files, local tools, the user's own repositoryA shared system of record, SaaS tenant or database
CredentialsThe user's own, already present on the deviceService credentials that should never sit on endpoints
Audit requirementEndpoint telemetry is acceptableCentral, per-call evidence is required
Where the agent runsDesktop or IDE on a managed deviceHosted agent platform, CI runner or cloud service
Endpoint controlManaged devices with sandboxing and client policyUnmanaged or contractor devices you cannot sandbox

In short: if the server needs data or credentials that should not live on laptops, or more than one caller will use it, host it on Streamable HTTP with per-user authorisation. If it is a single-user tool over local resources, use stdio, pinned and sandboxed. Remember that stdio traffic never crosses a gateway, so compliance needs for central evidence point to hosting.

Small teams usually do best with pinned, allowlisted stdio servers; larger estates host shared servers and keep stdio for personal tooling. See MCP Gateway vs Direct MCP Connections for the routing decision that follows.

Worked scenario

A software company runs three MCP servers: filesystem and git for IDE assistants, ticketing against its SaaS tracker, and a customer database for a support agent.

Filesystem and git: stdio. The platform team publishes it through the managed client configuration with an exact package version, launches it in a sandbox limited to the workspace directory with no network access, and passes no environment variables.

Ticketing: Streamable HTTP, hosted centrally. Each developer authorises once; the client obtains a token bound to https://mcp.example.internal/tickets through the resource parameter, and the server exchanges it for its own token to the tracker rather than passing the user token through. The initial scope is read only; write access is requested through an insufficient_scope challenge when a write tool is first used. Moving off a stdio version that used personal API keys removed long-lived keys from laptops.

Database: Streamable HTTP behind the company's gateway, with its own workload identity that has read access to a reporting replica only. The gateway routes on Mcp-Name and rejects older protocol versions; the server validates header and body agreement and logs token subject, client ID and tool name per call.

How to implement

  1. Inventory: list every server with transport, launch command or URL, version and credentials used. See the MCP Server Inventory Template.
  2. Fix local HTTP first: find servers listening on localhost ports; move them to stdio or add binding, Origin validation and a launch token.
  3. Lock down stdio: enforce a client allowlist, pin versions, turn off repository-supplied configuration, and pilot sandboxing on one team first. Roll back by restoring the previous configuration.
  4. Host shared servers: move servers holding shared credentials to Streamable HTTP with OAuth and audience binding. Run old and new side by side for a fixed window, then remove the stdio entry and revoke the personal keys it used.
  5. Test: for HTTP servers, send a request with a forged Origin (expect 403), a token for another audience (expect 401), and a header and body mismatch (expect 400 with -32020). For stdio, confirm the sandbox blocks reads outside the workspace and outbound network calls. See the MCP Security Testing Guide.

Detection and measurement

  • What to log for stdio: process creation where the parent is an MCP client or IDE, with full command line and package version; outbound network connections from those child processes; file reads outside the workspace.
  • What to log for HTTP: 401, 403 and 400 -32020 responses by client and source, token audience failures, requests with unexpected Origin values, and scope step-up events.

Metrics:

  • Percentage of stdio servers launched from a pinned version in managed configuration.
  • Number of MCP servers listening on non-loopback interfaces (target zero) and on loopback without a token.
  • Number of long-lived API keys in endpoint environments used by MCP servers, trending down.
  • Percentage of remote servers rejecting foreign-audience tokens in testing.
  • Time from a published server security update to the pinned version changing on all endpoints.

Common failure patterns

  • Treating stdio as "safe because local": the absence of a network endpoint does nothing against a malicious package or a poisoned configuration file, as the postmark-mcp and Amazon Q cases show.
  • Passing the whole shell environment: the commonest source of unnecessary credential exposure in stdio deployments.
  • Forwarding the user's token to upstream APIs: explicitly forbidden by the specification and the quickest way to lose audit attribution.
  • Moving to HTTP without per-user authorisation: a shared server with one service credential and no caller identity turns every user into the most privileged user.

Framework mapping

FrameworkReferenceHow it applies
NIST CSF 2.0PR.PS-05Preventing unauthorised software: stdio server allowlists and pinning
NIST CSF 2.0PR.DS-02, PR.AA-05Data in transit for HTTP; least-privilege access for both transports
NIST SP 800-53 Rev 5CM-7, CM-11, SR-11Least functionality, user-installed software and component authenticity for stdio packages
NIST SP 800-53 Rev 5SC-7, SC-8, SC-23, IA-9Boundary protection, transport integrity, request authenticity and service authentication for HTTP
NIST SP 800-53 Rev 5AC-6, AU-12Least privilege for server identities and credentials; audit record generation on both
MITRE ATT&CKT1195.002, T1552.001, T1059Supply chain, credentials in files and command execution through stdio servers
MITRE ATT&CKT1528, T1550.001Token theft and replay against HTTP servers
MITRE ATLASAML.T0053, AML.T0098AI Agent Tool Invocation and AI Agent Tool Credential Harvesting, on either transport

Practitioner checklist

  • Every MCP server has a recorded transport, owner, version and credential source.
  • No server meant for local use listens on a TCP port without a token, Origin validation and 127.0.0.1 binding.
  • stdio servers run from exact pinned versions delivered through managed client configuration.
  • Repository-supplied MCP configuration is disabled or gated by a consent prompt showing the full command.
  • stdio servers receive only named environment variables, not the full shell environment.
  • stdio servers run sandboxed, with filesystem and network limited to what the tool needs.
  • Remote servers require an audience-bound bearer token on every request and reject all others.
  • Remote servers use their own upstream credentials and never pass client tokens through.
  • Servers validate header and body agreement, and gateways reject protocol versions without that validation.

Standards and references

Related NHI Mgmt Group resources: MCP Security Guide · Local MCP Server Security Guide · Remote MCP Server Hardening Guide · MCP SSE to Streamable HTTP Migration · Structured Outputs vs Free Text for Agent Actions

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 14 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org