MCP servers

An MCP server is a dependency that talks to your model

It runs on your machine with your rights, like any package. Unlike a package, its tool descriptions land inside the model's context, where they read as instructions. MCP server security has to account for both halves of that.

descriptions are prompt, not documentationstdio servers inherit your environmenta schema can change after you approved it
Risks

MCP server security risks, concretely

None of these is exotic. They follow from how the protocol works and from where people put their credentials.

tool poisoning

The description is part of the prompt

A tool's name, description, and parameter schema go to the model as text. A server can write a description that tells the model to read a file and pass its contents as an argument, and the model has no way to tell that apart from a legitimate instruction.

prompt path

credential handoff

A local server gets whatever you hand it

Local MCP servers run over stdio as child processes. They receive the environment you give them, which usually means a long-lived token in a variable. From there the credential is out of your hands.

key exposure

schema drift

You approved a version, not a behavior

Tool descriptions and schemas can change on the next update. The server you reviewed in March is not necessarily the server running in June, and nothing in the protocol makes that change loud.

silent change

token scope

A token minted for one thing, spent on another

Remote servers hold access tokens on your behalf. A server that accepts or forwards a token issued for a different resource turns into a convenient deputy for reaching things you never authorized.

scope creep

no record

You cannot audit what you did not log

Most setups have no record of which MCP tool ran, with what arguments, against which host. Trouble surfaces on someone else's schedule, usually in a bill or a breach notice.

blind spot

The common thread: the model is the one reading the tool descriptions, and the credential is sitting somewhere the server can read it. Fix the second half and the first half stops being able to pay off.

Authentication

MCP authentication and OAuth 2.1

Local and remote MCP servers authenticate in completely different ways, and the difference matters more than most setup guides suggest.

Local, over stdio

There is no authentication step. The server is a child process you launched, and it is as trusted as the environment you started it with. Whatever token you exported is now the server's token too.

trust = your environment

Remote, over HTTP

The MCP authorization profile builds on OAuth 2.1: the client discovers the authorization server, you consent in a browser, and the client holds a short-lived access token with a refresh token behind it.

trust = the token's scope

01 · Short-lived beats long-lived
An OAuth token you can revoke from the provider's dashboard is a better position than a personal access token pasted into a config file two months ago.
02 · Tokens should name their audience
MCP's profile expects a token bound to the resource it was issued for. A server willing to accept a token minted elsewhere is a design you should decline.
03 · Refresh is where tokens leak
Refresh tokens live longer than everything else in the flow and usually end up in a plaintext file in a home directory. Sallyport seals them in the vault and refreshes them inside the app.
Best practices

Eight checks before you install an MCP server

Nothing here needs a product. It is the review you would give any dependency, plus the two questions that are specific to MCP.

  1. 01

    Pin the version

    Install a specific version rather than whatever latest resolves to today. A server that updates itself can change its tool descriptions after you approved them.

  2. 02

    Read the tool descriptions, not the README

    The README is written for you. The descriptions are written for the model. Read the ones the model will actually receive.

  3. 03

    Assume a local server keeps everything you give it

    A stdio server is a child process with your rights. Hand it the narrowest credential that still does the job, never a root token that happens to be nearby.

  4. 04

    Prefer OAuth over a pasted key

    A revocable, short-lived token beats a personal access token in an environment variable, even when the setup takes five more minutes.

  5. 05

    Check what the token is scoped to

    One resource, one audience. A server that wants a broadly scoped token, or accepts one issued for something else, is telling you how it will behave.

  6. 06

    One server, one job

    Aggregating five services behind a single MCP server concentrates every credential in one process. Split them and the worst case gets smaller.

  7. 07

    Keep a record of the calls

    If you cannot say what a server did last Tuesday, you are trusting it rather than verifying it. Logs are what turn an incident into a bounded incident.

  8. 08

    Re-review on update

    Treat a tool-schema change like a dependency bump: look at the diff. This is the check almost nobody does, which is exactly why it works as an attack.

Through the gate

Proxy your MCP servers instead of trusting them

Sallyport sits in front of the MCP servers your agent talks to. Their calls climb the same ladder as everything else and land in the same journal.

  1. 01

    One connection for the agent

    Claude Code, Cursor, or any MCP client connects to Sallyport. Sallyport presents http.request, ssh.exec, and the upstream servers you configured.

  2. 02

    Upstream servers stay behind it

    Local stdio servers and remote OAuth 2.1 servers are both proxied. Sallyport seals their tokens in the vault and refreshes them inside the app.

  3. 03

    Every call climbs the ladder

    A locked vault denies the call. A key flagged for approval per call raises a card. Otherwise the session approval you already gave covers the run.

  4. 04

    The journal records it

    Encrypted and hash-chained as it happens, so an answer to "what did that server do last Tuesday" exists before you need it.

One honest limit: a local stdio MCP server you configure does receive the credential you bind to it. Proxying gives you approval and a record for its calls; it does not take the key back out of a process you chose to start.

FAQ

MCP server security questions

What is a tool poisoning attack?
An MCP server writes instructions into the text the model reads as tool metadata: the description, a parameter name, an error message. The model treats it as guidance and acts on it. Detection does not get you far here, because a planted instruction looks exactly like a legitimate one. What works is making sure that following it cannot reach anything valuable.
How do I tell if an MCP server is malicious?
Often you cannot, which is the honest answer. You can read the tool descriptions the model will receive, pin a version, give it the narrowest credential that works, and keep a record of its calls. Those four steps turn an unknown into a bounded unknown.
Does MCP have built-in authentication?
For remote servers, the authorization profile builds on OAuth 2.1 with browser consent and scoped access tokens. For local servers over stdio there is no authentication step at all: the server is a child process running with your rights.
Where do my MCP OAuth tokens live?
By default, in a plaintext file in a home directory, which is exactly where credential-harvesting malware looks first. Sallyport keeps them in the encrypted vault and performs the refresh inside the app.
Can Sallyport sandbox an MCP server?
No, and we will not claim otherwise. Sallyport gates and records what an upstream server's calls do through it. It does not sandbox the server process, inspect request content, or firewall the host.

Put a gate in front of your MCP servers

Free download. Apple Silicon, macOS 14 or newer. No account, ever.

$brew install --cask olegsotnikov/tap/sallyport

macOS 14+ · Apple Silicon

Sallyport

Sallyport runs API calls and SSH commands for your AI agent. The keys stay in a local vault on your Mac; you approve each run and every action lands in a sealed journal.

© 2026 Sallyport · Open source under Apache-2.0 · Oleg Sotnikov