Tools the agent can call, as separate processes
A Model Context Protocol server is a subprocess that exposes tools the agent can call: read a file, query a database, look at git history, talk to an internal service. It is how you extend what the agent can do without changing the editor.
Onyx Code ships a curated bundle and supports your own servers. The /mcp command opens the panel where both are managed.
On tiers, stated precisely: the bundled pack is available on the free tier, which runs one MCP server at a time: the one you start, with as many configured as you like. Once another one you start is running, the one before it stops. Pro runs them all at once. MCP itself is not a paid feature.
Ask about the service, chat calls its tool
With a server running, chat offers its tools to the model beside its own, and calls one when you ask about the service the server connects: ask for the projects in your Azure DevOps organization and the answer comes from the server, not from a guess.
The step above the reply names the tool and the server while it runs. A tool the server does not mark as read-only asks first, with Allow and Deny right under that step and the arguments the model chose, in every mode. A call that names a file you keep from AI (one .onyxnoai excludes, a key under ~/.ssh, anything in .git) is never run, so a server that reads files cannot reach what chat’s own file tools protect. What a tool returns reaches the model with secrets redacted, and as the service’s data, not instructions to follow.
A local model does not always pick the tool. If it answers with a command for you to run instead, ask again and name the service, or use a larger model.
Four servers, one click each
The usual first experience of MCP is editing a JSON file to launch a process you have not read, to get tools you have not seen. The bundled pack skips that: four presets, installed from the panel.
| Server | What it gives the agent |
|---|---|
filesystem | Reading and listing files within the workspace |
git | status, log, diff and show |
sqlite | Querying a local SQLite database |
fetch | Fetching an HTTP or HTTPS URL |
The first three work on local files and data once running; their launcher (npx or uvx) downloads the package the first time they start. fetch exists to reach the network, which is why it behaves differently under Air-Gap Mode.
What MCP does to an air-gap guarantee
This is the section worth reading if you are the person who has to sign off on the tool. An extension mechanism that launches arbitrary subprocesses is exactly how a no-network promise normally springs a leak.
The enforcement is active rather than advisory. With Air-Gap Mode on, an HTTP MCP server that is not on this machine is blocked: the server is stopped the moment it tries to start, and a warning fires once for that server. In the panel, fetch’s install button is replaced by a Blocked by Air-Gap pill rather than failing silently when you press it.
- Stdio-transport servers are always allowed, and Air-Gap Mode does not filter their networking. A stdio server is a separate program on your machine: if it makes its own requests, or if
npxoruvxdownloads it at first start, that traffic is not blocked. That includes afetchserver installed before Air-Gap Mode was turned on. Contain stdio servers with an OS or network firewall. - HTTP servers pointing at the loopback interface are allowed too, meaning
localhost,127.0.0.1,::1, and unix or pipe transports. A local service is not an exit route. On Windows apipe:address must name a named pipe on this computer (inmcp.json,"url": "pipe:///\\.\\pipe\\<name>#/mcp"); one that points at another machine is refused, with Air-Gap Mode on or off.
So an HTTP MCP server that is not on this machine cannot connect while Air-Gap Mode is on. That is a claim we can make specifically because the check happens at start time in the host, not in a document telling users which servers to avoid.
Your own servers, and OAuth ones
Any MCP server works, not just the bundled four. The interesting case is an internal server behind authentication, which is where most first-party integrations live.
For those, Onyx Codedefers to VS Code’s native OAuth handshake rather than inventing one. The server answers with a 401 and a WWW-Authenticateheader, the authorisation server is discovered from its metadata, a client is registered dynamically if needed, your system browser opens at the provider’s authorise page, and the code is exchanged for a token that is stored through VS Code’s auth provider.
Nothing about that flow is Onyx-specific, which is the point: a server your team already uses in another editor works here without a second implementation to trust.
MCP tools obey the same rules as everything else
An MCP tool is not a way around the agent’s permission model. The same three layers apply, and the same deny tier wins.
Rules can name an exact tool, or a server prefix to cover every tool it exposes, in the same .onyx/permissions.json your team commits. Because deny beats allow at every level, a server that is denied there stays denied under a local override and under a session-level approval bypass.
For example, MCP(azure-devops:*) in deny blocks every tool of that server, and MCP(azure-devops:core_list_projects) in allow runs that one tool without asking.
Allow rules wait for trust.A project’s allow rules apply once you trust its folder, so a repository you clone can’t approve a tool in advance; its deny rules apply from the start. Until then every tool that asks still asks, and the folder’s own .vscode/settings.jsoncan’t add tools to the always-allow list either.
Extend the agent without opening a route out
Local servers by default, and HTTP transports blocked at start time when Air-Gap Mode is on.
Free tier, no account, no sign-up, no telemetry. macOS, Windows and Linux.