Connecting a remote MCP server means trusting how it handles a request. Running a local one — the kind you start with npx some-mcp-server or uvx some-mcp-server — means something bigger: you’re executing someone else’s code directly on your machine, with your user account’s full permissions, before a single tool call has happened. That’s the supply chain question, and it’s separate from whether the server’s tools themselves are well-behaved. Here’s what you’re actually trusting when you install an MCP server, and what’s worth checking first.

Two different things you’re trusting

“Is this MCP server safe” is really two separate questions that get bundled together:

  • Do its tools behave honestly? This is the question a security scan answers — whether a tool’s name, description, and schema try to manipulate the model calling it. We covered that in what an MCP security scanner actually checks.
  • Is the code that runs the server itself trustworthy? This is a different layer entirely — the package, its dependencies, and anything that executes on your machine before the MCP server even starts answering requests. A tool scan doesn’t touch this at all, because it never runs the package; it only reads the protocol messages the server sends once it’s already running.

A server can pass every tool-description check and still be a supply chain risk, because the two questions are about entirely different code paths.

Why local servers carry the sharper version of this

As we covered in remote vs. local MCP servers, a local server runs as a process on your own machine over stdio, started by a command your AI client (or you) invokes directly — typically npx, uvx, or a similar package runner. A remote server, by contrast, runs on infrastructure someone else operates; you talk to it over HTTP, and its code never touches your machine at all.

That difference matters here specifically because a package runner doesn’t sandbox anything by default. When you run npx some-package, npm downloads the package (and its full dependency tree) and executes it — including any postinstall script the package defines, which runs automatically before you’ve seen a single line of the actual server code. That script runs with your full user permissions: it can read files, make network requests, or write to disk, all before the MCP server has accepted its first connection. This isn’t an MCP-specific flaw — it’s how npm and most package runners have always worked — but MCP servers put it in a new context: you’re often installing one on the recommendation of a README or a catalog listing, not after the kind of dependency review a team might apply to production code.

What to actually check before you run one

None of this means avoid local servers — plenty of well-maintained ones exist, and for some workflows (a filesystem tool, a local database) a local server is the only option that makes sense. It means treat installing one the way you’d treat adding any new dependency to a project, not like clicking a link:

  • Who publishes it? An official server from the vendor whose product it wraps (published under their npm org, linked from their own docs) is a different trust level than an unaffiliated third party’s reimplementation of the same idea. The same impersonation risk we covered for remote servers in how to tell a real MCP server from a fake one applies here too — nothing stops anyone from publishing a package called notion-mcp-server.
  • Pin a version, don’t float on latest. npx package@latest means the code that runs today can be different code tomorrow, with no review step in between. Pinning a specific version means an update only takes effect when you deliberately bump it.
  • Is it actively maintained? A recent commit history and responsive issue tracker aren’t proof of safety, but an abandoned package with no updates in a long time is one more reason to look closer before trusting it with local execution.
  • What does it actually need access to? A server wrapping a REST API needs network access and an API key — it has no reason to also read your SSH keys or shell history. If a server’s permissions look broader than its stated job, that mismatch is worth asking about, the same way we recommend in how to vet an MCP server.

Where a scanner helps here, and where it doesn’t

Gate’s free MCP security scanner reads a server’s tool descriptions and schemas for prompt-injection and manipulation patterns once the server is running and answering MCP protocol messages. That’s a genuinely useful check — but it’s worth being precise about what it covers: it doesn’t install the package, doesn’t run its postinstall scripts, and doesn’t audit its dependency tree. Supply chain risk lives earlier in the process than anything a protocol-level scan can reach. Treat a clean scan result as one input into the decision, not a substitute for checking who published the package in the first place.

Why a gateway changes the shape of this problem

One practical way to sidestep the local-install question entirely: connect through remote servers wherever a vendor offers one, instead of running a local package per machine per person. That’s part of what a gateway like gate is for — it centralizes connections to remote MCP servers (see the catalog on the MCP servers page) so nobody on a team needs to run npx locally just to get access to a tool. It doesn’t eliminate supply chain risk for servers that only exist as local packages, but it does mean that risk gets evaluated once, centrally, instead of separately on every teammate’s machine.

The bottom line

A tool-description scan and a supply chain review answer different questions. Before you run a local MCP server with npx or uvx, check who publishes it, pin the version, and ask whether its access matches its job — the same diligence you’d apply to any new dependency, because that’s exactly what it is.