Download Cosmonic Desktop (Beta)
Learning Hub / MCP server security / Sandbox an MCP server

How to sandbox an MCP server in 5 minutes

Run untrusted server code with zero authority, then grant back only what it needs.

In this hands-on walkthrough, you'll take a real MCP server, run it in a sandbox where it can reach one host and nothing else, see why a planted attack has nowhere to go, and call it from your coding agent. It should take about five minutes and runs entirely on your machine.

What you'll need

You'll sandbox Who's in Space, a small MCP server that reports who is currently in orbit. It reaches one host, api.open-notify.org, and nothing else, which makes the sandbox boundary easy to see. The same four steps sandbox a database or GitHub server.

✓
Cosmonic Desktop, the free sandbox host for macOS, Windows, and Linux, in public beta now.
✓
About five minutes.
✓
A coding agent such as Claude Code, Codex, or Cursor for the last step. Optional: the server runs the same without one.

Get Cosmonic Desktop

Desktop is the host that enforces the sandbox. It runs each MCP server as a component that starts with no authority at all: no access to your files, network, or environment, and able to reach only what you grant. Everything runs on your machine. Nothing routes through a cloud.

Download Cosmonic Desktop (beta)

Launch the MCP server

In Desktop, open the Launchpad and go to AI & agents. Who's in Space MCP reports who is in orbit right now and where the International Space Station is, from live data, and it reaches exactly one place on the internet.

The Launchpad's AI & agents category in Cosmonic Desktop. Who's in Space MCP sits in the top row, its single declared capability, wasi:http, shown on the card.
The AI & agents category. Each card names the capabilities the server declares before you run it.
  1. Click the Who's in Space MCP card itself, not the Launch button. That opens a panel with more about the server, including the capabilities it declares.

  2. Scroll down to Review before launch. This stages the workload for inspection: nothing is downloaded or deployed yet.

  3. Read the manifest: the host interfaces the server declares, and its egress allowlist. This is the grant the host will enforce once the workload runs, so you are reading the boundary itself rather than taking the card's word for it.

    Who's in Space declares wasi:http to serve its own endpoint and to make its one outbound call, and its allowlist holds a single host: api.open-notify.org. That one API is the entire world it will be allowed to touch. A request to anywhere else never had the capability to begin with, so it fails at the boundary rather than being caught after the fact.

The Start workload review screen for iss-mcp. Components and services read Not downloaded, and Outbound network lists one host, api.open-notify.org.
The review screen. Note Not downloaded: nothing has been pulled yet, and Outbound network holds a single host.
  1. Click Deploy workload. Desktop pulls and verifies the component image, and moves you to Workloads, where you can watch the server reach Running.

The review screen is also where you can register the server with your coding agents before it runs. Launch straight from a Launchpad card instead and Desktop asks at that point, and either way you can do it later from Workloads with the server's Coding agents button.

See the sandbox boundary

The manifest told you what the host will grant. Inspect shows what the component itself asks for, read from the running binary.

  1. Open the running workload in Inspect, from its row in Workloads.

  2. Compare the two halves: the interfaces the component declares it depends on, and the egress the host has actually granted it.

The Inspect view for iss-mcp, showing the component's imported interfaces grouped as built-ins: cli, clocks, http, io and random.
Inspect, reading the running binary. These are the component’s dependencies, the interfaces it imports. What it is allowed to reach is a separate thing: the grant.

A component reaches a capability only when it is declared by the component and granted by the host, and Inspect shows you both halves for what is really running.

What you see listed here is the first half: the interfaces iss-mcp depends on. cli, clocks, http, io, random. A dependency is not an enabled capability. Importing http says the component knows how to make a request; whether it may make one, and where to, is the second half, and that is the grant you read on the review screen: one host, api.open-notify.org. A server that imports http and is granted nothing reaches nowhere.

MCP server whos-in-space.wasm capabilities
net → api.open-notify.org:80granted
net → * (all other hosts)denied
fs → /home, secrets, ~/.ssh …denied
env → API keys, tokensdenied

Suppose the server were poisoned and its code told to read ~/.ssh/id_rsa and post it somewhere: it has no filesystem grant to read the key, and no network beyond that one host to send it out. The injection would fire and land on the wall you can see above.

For more detail, see MCP server security.

Call it from your agent

Back in Workloads, the server's Tools column carries an MCP Inspector button alongside the usual actions. That button is Desktop telling you it understands this workload is a server your agents can call.

The Workloads view with iss-mcp running. The row is expanded to show the component and its capabilities, and the Tools column carries the MCP Inspector button.
Because the workload declares itself an MCP server, its Tools column gains an MCP Inspector button.
  1. Click MCP Inspector. It opens inside Desktop, connects to the running server, and lists every tool the server offers. Who's in Space has two: who_is_in_space returns the people currently in orbit and the craft each is aboard, and iss_position returns the station's current latitude and longitude.

  2. Select who_is_in_space and run it. The tool takes no input, so the live result appears right there: the astronauts in orbit at this moment. This is the point of the Inspector. You see exactly what each tool does, by hand, on your own machine, before any agent calls it.

  3. Click Coding agents on the server's row, pick your agent, and Desktop registers the sandboxed server for you.

  4. Ask your agent “Who's in space right now?” You can open a terminal from the lower status bar. The agent calls who_is_in_space and answers from live data, inside the boundary you just confirmed.

Your agent has the tool, and the tool can do only what you granted it. Whatever its instructions are told to do, the code still reaches one host and no more.

You sandboxed an MCP server

In four steps you ran untrusted server code with zero authority, granted it exactly one host, confirmed the boundary in Inspect, and let your coding agent call it, all on your own machine. A malicious version of that server is held to what you granted and can reach nothing else.

The methodStart at zero authority, grant only the hosts and paths the server needs, and verify the boundary in Inspect. It's the same for any MCP server. Only the grant changes.

That is how you sandbox an MCP server: get a host, launch the server, grant least authority, and verify the boundary before your agent calls it.

Sandboxing questions

Can I sandbox my existing Node or Python MCP server?
Not as a drop-in yet. A server gets this boundary by running as a WebAssembly component, built from a template (Rust today) or pulled from the Launchpad catalog. Run the ones you can as components, and keep the rest behind the other controls. You don't have to port it by hand, though: with Cosmonic Desktop's Builder and the cosmonic-sandbox skill, your coding agent can adapt an existing MCP server to Rust in as little as a few minutes.
Is a fresh instance per call slow?
No. A WebAssembly instance starts in well under a millisecond, so a fresh sandbox per call is practical at agent volume. Persistent state comes through a granted capability, not a long-lived pool.
Does this also sandbox the code my coding agent writes?
Yes. The same host runs any component under the same deny-by-default boundary, so the code your agent generates is contained the same way an MCP server is.

Run it yourself

Public beta

Cosmonic Desktop runs this deny-by-default model on your own machine, free forever for personal use, with no account and no cloud, and it's in public beta now. The docs walk through every step above.

Cosmonic Desktop's Inspect view showing a component's declared imports beside the egress the host grants it.