# MCP pools

## Introduction

A pool can front a remote **MCP server**. swarmvia is the server's MCP
client: it holds the server's credential, keeps the session, and admits every
tool call against the pool's concurrency limit. Agents reach the server's
tools through the swarmvia MCP server they already have, or through the pool's
own two endpoints.

The server's URL is the only setting. Choose **MCP server** when you create a
pool, enter the URL, and choose **Check**. swarmvia asks the server what it
needs, the way an MCP client does:

| The server answers | What the pool does |
|---|---|
| An `initialize` result, with no token | Nothing to connect. The pool is ready. |
| `401` with OAuth metadata | swarmvia becomes an OAuth client of the server (with its published client metadata where the server accepts it, otherwise by registering) and you connect once. A server that allows neither, such as GitHub's, needs an OAuth app you register with its provider: the dialog shows the redirect URI and asks for the app's client ID and secret. |
| `401` with no OAuth metadata | The server takes a static token. Paste it at creation or on the pool page. |

The URL, like the backend, is fixed at creation. Create another pool for
another server.

The pool shows the server's logo when the server publishes one, or its
company's site icon otherwise. swarmvia fetches it once, re-encodes it, and
serves its own copy, so the vendor never sees which teams front it.

## Whose account the pool uses

For an OAuth server, choose at creation:

- **One shared connection**: you sign in once and every caller acts as that
  account. The access log records who called.
- **Each member's own account**: every member connects their own account
  from the pool page, and their calls act as them. Keys must act for a
  member; machine keys are refused. See
  [Per-member credentials](/docs/credentials#per-member-credentials).

The credential belongs to the pool. It is not offered to other pools or
webhooks, and it is deleted with the pool.

## Tools

The pool page lists the server's tools, fetched live from the server. By
default callers see every tool the server lists, including ones it adds
later. Uncheck tools to narrow the list: hidden tools are neither listed nor
callable, and a call to one is refused before it reaches the server.

A read-only key sees and calls only tools the server marks read-only
(`readOnlyHint`).

## Endpoints

```
GET   https://{pool}.swarmvia.cloud/tools
POST  https://{pool}.swarmvia.cloud/tools/call   {"name": "search", "arguments": {"query": "…"}}
```

Send the pool key in `X-Swarmvia-Key`. `GET /tools` returns the tools this
key may use and the server's own description; add `?refresh=1` to list again
instead of using the five-minute cache. `POST /tools/call` returns the
server's result as it sent it, including `isError: true` for a tool that ran
and failed.

Each call holds a slot until the server's answer has arrived in full, streamed
or not. A cached list takes no slot. Async admission does not apply to MCP
pools.

See [Admission errors](/docs/knowledge-base/admission-errors#mcp-pools) for
what each error means.

## Moving servers from a harness

Most teams start with MCP servers configured in each person's harness:
`.cursor/mcp.json`, Claude Code, VS Code, Codex. To move them behind pools,
ask the assistant for the `migrate_mcp` prompt, or install the plugin's
`migrate-mcp-to-swarmvia` skill. It reads the harness config, sorts servers
into ones to move and ones that must stay local (stdio commands, localhost),
and moves one at a time: create or reuse the pool, give you the link to
connect it, check its tools, then remove the old entry from the config with a
backup. Tokens never pass through the chat; you add them on the pool page.
The full procedure is [Migrating MCP servers into swarmvia](/docs/agents/migrate-mcp).
