The review before you install somebody else’s server
Lesson 5 of 5 in Building with MCP: Servers, Clients, and the Install Review.
Installing an MCP server is not adding a dependency. It is handing a process you did not write the ability to run code with your credentials, and handing its author a writing channel into your model’s context window.
Both halves matter. The code half is ordinary supply-chain risk with an unusual trigger — the model decides when it runs. The context half is newer: a server controls its own tool names, descriptions and outputs, and all three land in the model’s context as instructions-shaped text. That is why the spec is blunt that tool descriptions and annotations from an untrusted server cannot be trusted, and why an install is a decision that deserves a written review rather than a click.
1 · Provenance — who publishes this, and can they prove it?
Prefer first-party servers from the vendor whose system you are integrating. Where a registry entry exists, note what its guarantee actually is: the official MCP Registry uses namespace authentication — reverse-DNS names tied to verified GitHub accounts or domains via GitHub, DNS or HTTP challenges — so only the legitimate owner can publish under a namespace. That authenticates who published, and says nothing about whether the code is safe.
2 · What actually executes — package, pinning, update policy
Registry entries are metadata pointing at real artefacts on npm, PyPI, Docker Hub or a remote URL. So the question is the usual one: which exact version, from which package registry, pulled how often? An unpinned @latest in a launch command means the next silent update runs with your credentials. Pin it, and decide deliberately who reviews upgrades.
3 · Credentials — what does it ask for, and what is the smallest thing that works?
A stdio server takes its credentials from the environment, so “install” often means “paste a token.” Ask what scope that token really needs, whether a read-only key or a dedicated service account would do, and whether it can be scoped to one project rather than the whole org. Least privilege is the only control that survives the server turning out to be malicious.
4 · Transport and network reach
Local stdio: does it also open a port, and if so is it bound to 127.0.0.1 with Origin validation? Remote HTTP: is it TLS-only, is the token audience-bound to that server, and where does its traffic go? A server that reads your files and reaches the internet is the shape egress controls exist for.
5 · The tool surface — read every declaration before you accept it
Call tools/list yourself and read all of it. Count the write and destructive tools. Look for surprises: a filesystem server with a shell tool, a docs server with an HTTP-fetch tool, a “read-only” server with an admin endpoint. The surface you are approving is the one in tools/list, not the one in the README — and a server may change it later, which is what the notification and re-review question is for.
6 · Descriptions and outputs are attacker-controlled text
Tool descriptions arrive in the model’s context as authoritative-looking instructions, which makes them an injection channel; tool results are the same problem one step later (tool-output poisoning). Read the descriptions with an adversarial eye — “always call this tool first”, “ignore other instructions”, anything addressing the model rather than describing the tool. Then remember that an honest server can still relay poisoned content from the system it reads.
7 · Blast radius and gating
For each write-capable tool, decide the autonomy level before the first run: allowed, allowed-with-approval, or not exposed at all. Hosts can usually disable individual tools — use that. A server whose useful tools are read-only and whose dangerous tools you have switched off is a much smaller decision than “install everything and hope.”
8 · Observability and revocation — how would you know, and how do you stop it?
Before install: where do this server’s invocations show up in your traces, who reviews them, how do you revoke its credential, and how fast can you remove it from every host that has it? A local server installed by fifty developers has fifty independent update-and-revocation paths, which is the strongest operational argument for fronting shared systems with one governed remote server instead.
Which leaves the question that should come before the review: does this integration want to be an MCP server at all?
MCP earns its keep when a capability has many consumers or a surface that changes at runtime — that is the N×M problem it was designed for, and the reason discovery is part of the protocol. For a single agent you own, talking to one stable API you already have a client for, native function calling is less machinery, fewer moving parts, and one less process to secure. Walk the logic.
Build a server, call the API directly, or install an existing one?
Interactive decision tree — outcomes:
- Skip MCP — wire the tool directly
One consumer, one stable API: native function calling gives you the same name–description–schema contract with no extra process, no transport, no discovery, and no third-party trust decision. MCP is a reuse and discovery protocol; with nothing to reuse and nothing to discover, you would be paying the protocol tax for a diagram. Revisit when a second consumer appears.
- Install it — pinned, scoped, and monitored
The cheapest correct answer when a trustworthy server already exists. Pin the version, use the narrowest credential that works, disable the tools you do not need, and make sure its invocations land somewhere a human reviews. Re-run the review when the tool surface changes.
- Build a server
Multiple consumers and you own the system: this is exactly the case MCP was designed for. Build one governed server, prefer remote Streamable HTTP so upgrades and revocation are central, keep the tool surface deliberately small, and treat the declarations as the product — they are what every consumer actually integrates against.
- Build a narrow server over their API
You get the reuse without inheriting someone else’s tool surface. The win is control: you choose which endpoints become tools, you own the credential scope and the rate limits, and you can refuse to expose the destructive ones. The cost is that you now maintain an integration against an API you do not control.
- Do not install it as-is
A server that fails the review is not a small risk taken on trust — it is arbitrary code execution with your credentials plus a writing channel into your model’s context. Options in order of preference: get the publisher to fix it, vendor and pin a reviewed fork, or write a thin server of your own over the same API with only the tools you need.
Interactive flashcard deck.
Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.