Transport, authentication and trust all change at once. A remote server can alter its tool descriptions without a deploy on your side, which means it can change your prompt, and a shared service credential leaves it unable to tell your users apart.
Three things change when the server is not yours
Connect to a local server covers stdio: a process you launch, on your machine, whose lifetime you control. Going remote changes the transport, the trust, and who can reach it.
Take them in that order, because the first is mechanical and the other two are where the decisions are.
Transport
Remote servers use streamable HTTP: HTTP POST for client-to-server messages, with optional Server-Sent Events for streaming. Transport layer covers the choice and what moving off stdio forces you to add.
Two immediate consequences. The stdout rule from the local case disappears,
because you are no longer sharing a pipe with the protocol. And the network is now
in the path, so timeouts, retries and reconnects are yours to handle. A
subscriptions/listen stream is exactly the kind of long-lived connection that
drops, and
the data layer notes that notifications can
be lost across a reconnect.
Authentication
A local server inherits your machine's identity. A remote one does not, so it needs credentials.
MCP supports standard HTTP authentication, and the recommendation is OAuth to obtain tokens, with bearer tokens, API keys and custom headers also supported.
The question this raises is whose identity the token carries. A single service credential shared by all your users means the remote server cannot tell them apart, and every action is attributed to your application. Per-user tokens preserve the distinction, which matters for anything the server logs, bills or authorizes.
That is the same argument adding end-user IDs makes about provider abuse systems: without per-user attribution, the consequences land on your account.
Trust
Here is the part with no protocol answer.
A local server is code you installed. A remote one is a service someone else operates, which can change its tool descriptions and its results at any time, without a deploy on your side.
Both MCP articles here state that server output is untrusted input to the model. For a remote server the same applies to the tool definitions, not just the results. A description is text that reaches your model, and a server that changes it has changed your prompt.
Three practical defences:
Review what you connect to, with the scrutiny you would give a dependency. Hugging Face Hub makes the supply-chain argument for model weights and it holds here.
Re-read definitions rather than caching them forever. The caching fields tell you how long a listing is fresh, and honouring them means you see a change rather than running on a stale copy.
Do not grant capability you would not grant the operator. A remote server with a tool that writes to your systems is that operator writing to your systems. MCP server frames the server as a capability boundary, and when the server is remote the boundary is around someone else.
What to check before connecting
Five questions, in order:
- Who operates it, and what happens if they change it?
- What credentials does it need, and do they carry per-user identity?
- What can its tools do, and which of those need user confirmation?
- What does it log about your requests?
- What happens to your application when it is unreachable?
The last one is routinely skipped. A remote server is a dependency with an uptime, and a client that blocks forever on a connection nobody is maintaining is a failure mode you can write down today.
Further reading
- Transport layer: streamable HTTP, and what leaving stdio adds.
- Connect to a local server: the simpler case, and its own pitfalls.
- MCP server: the server as a capability boundary.
- Building an MCP client: where the trust decisions get implemented.
Knowledge check
Question 1 of 3
Sign in to save your progress and pick up where you left off.