> ## Documentation Index
> Fetch the complete documentation index at: https://docs.swarms.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Swarms API MCP Server

> Connect any MCP-compatible agent to the Swarms API through the hosted remote MCP server at mcp.swarms.world. Run agents, orchestrate swarms, and process batches over a standard Streamable HTTP transport.

The Swarms API MCP Server is a **hosted remote server** that exposes the entire Swarms API as Model Context Protocol tools. There is nothing to install and nothing to run locally — point your MCP client at one URL, send your API key as a header, and your agent can execute agents, orchestrate multi-agent swarms, run reasoning workflows, and process batches.

**MCP Server URL:** `https://mcp.swarms.world/mcp`

## Overview

| Property | Value |
| - | - |
| **URL** | `https://mcp.swarms.world/mcp` |
| **Transport** | Streamable HTTP |
| **Protocol version** | `2025-06-18` |
| **Session handling** | Stateless — no `Mcp-Session-Id` to track |
| **Authentication** | `x-api-key` header, supplied per request by the caller |
| **Tools exposed** | 23 |
| **Upstream base URL** | `https://api.swarms.world` |
| **Installation** | None |

### Authentication

The server holds **no API key of its own**. Every caller supplies their own key on the MCP request via the `x-api-key` header, and the server forwards it upstream. Your key is never passed as a tool argument, so it is never visible to the model driving the tools.

Get a key from the [API Keys page](https://swarms.world/platform/api-keys).

Calling a tool without a key returns a normal MCP error result rather than a transport failure:

```
This server requires callers to supply their own credentials. Send x-api-key
with your MCP request.
```

<Note>
  `tools/list` works without a key, so agents can discover the tool surface before you authenticate. Only `tools/call` requires credentials.
</Note>

## Setup by Client

### Claude Code

```bash theme={null}
claude mcp add --transport http swarms https://mcp.swarms.world/mcp \
    --header "x-api-key: your_api_key_here"
```

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):

```json theme={null}
{
  "mcpServers": {
    "swarms": {
      "url": "https://mcp.swarms.world/mcp",
      "headers": {
        "x-api-key": "your_api_key_here"
      }
    }
  }
}
```

### Cursor

Add to **Cursor Settings → MCP**, or to your project-level `.cursor/mcp.json`:

```json theme={null}
{
  "mcpServers": {
    "swarms": {
      "url": "https://mcp.swarms.world/mcp",
      "headers": {
        "x-api-key": "your_api_key_here"
      }
    }
  }
}
```

### Windsurf, Codex, and other MCP clients

Any client that supports remote MCP servers over Streamable HTTP works with the same two values — the URL and the `x-api-key` header.

```json theme={null}
{
  "mcpServers": {
    "swarms": {
      "url": "https://mcp.swarms.world/mcp",
      "headers": {
        "x-api-key": "your_api_key_here"
      }
    }
  }
}
```

## Available Tools

Tool names mirror the underlying API operation IDs, so a tool maps one-to-one onto an endpoint you can find in the [API Reference](https://docs.swarms.ai/api-reference).

### Agents

| Tool | Endpoint | Purpose |
| - | - | - |
| `run_agent_v1_agent_completions_post` | `POST /v1/agent/completions` | Execute a single agent completion |
| `run_agent_batch_v1_agent_batch_completions_post` | `POST /v1/agent/batch/completions` | Execute many agent completions in parallel |
| `list_agents_v1_agents_list_get` | `GET /v1/agents/list` | List available agent configurations |

### Swarms

| Tool | Endpoint | Purpose |
| - | - | - |
| `run_swarm_v1_swarm_completions_post` | `POST /v1/swarm/completions` | Execute a multi-agent swarm |
| `run_batch_completions_v1_swarm_batch_completions_post` | `POST /v1/swarm/batch/completions` | Execute many swarms in parallel |
| `check_swarm_types_v1_swarms_available_get` | `GET /v1/swarms/available` | List available swarm architectures |

### Specialized Workflows

| Tool | Endpoint | Purpose |
| - | - | - |
| `run_graph_workflow_v1_graph_workflow_completions_post` | `POST /v1/graph-workflow/completions` | Execute a graph-based workflow |
| `run_batched_grid_workflow_v1_batched_grid_workflow_comple_0dda3b` | `POST /v1/batched-grid-workflow/completions` | Execute a batched grid workflow |
| `run_auto_agent_builder_v1_auto_agent_builder_completions_post` | `POST /v1/auto-agent-builder/completions` | Generate agent configurations from a task |
| `run_reasoning_agent_completions_v1_reasoning_agent_comple_a8b363` | `POST /v1/reasoning-agent/completions` | Execute a reasoning agent completion |
| `get_reasoning_agent_types_v1_reasoning_agent_types_get` | `GET /v1/reasoning-agent/types` | List reasoning agent types |

### Models and Tools

| Tool | Endpoint | Purpose |
| - | - | - |
| `get_available_models_v1_models_available_get` | `GET /v1/models/available` | List available AI models |
| `list_models_v1_models_get` | `GET /v1/models` | List models (OpenAI-compatible shape) |
| `chat_completions_v1_chat_completions_post` | `POST /v1/chat/completions` | OpenAI-compatible chat completions |
| `get_available_tools_v1_tools_available_get` | `GET /v1/tools/available` | List available API tools |

### Account and Monitoring

| Tool | Endpoint | Purpose |
| - | - | - |
| `get_rate_limits_v1_rate_limits_get` | `GET /v1/rate/limits` | Rate limits and current usage |
| `credit_balance_v1_account_credits_get` | `GET /v1/account/credits` | Credit balance |
| `usage_costs_v1_usage_costs_get` | `GET /v1/usage/costs` | Comprehensive pricing details |
| `get_metrics_summary_v1_account_metrics_summary_get` | `GET /v1/account/metrics/summary` | User metrics summary |
| `get_logs_v1_account_logs_get` | `GET /v1/account/logs` | API request logs |
| `premium_endpoints_v1_account_premium_endpoints_get` | `GET /v1/account/premium-endpoints` | Premium endpoint availability |
| `health_health_get` | `GET /health` | Health check |
| `root_get` | `GET /` | API root |

<Note>
  Two tool names are truncated with a hash suffix (`..._comple_a8b363`, `..._comple_0dda3b`). MCP caps tool-name length, so the server truncates and appends a stable hash to keep names unique. Copy them exactly as written.
</Note>

## Reading a Tool Result

Every tool call returns both representations of the upstream response:

* **`structuredContent`** — the parsed JSON object. Use this. No string parsing.
* **`content[0].text`** — a human-readable rendering: an HTTP status line, then the pretty-printed JSON body.

```json theme={null}
{
  "content": [
    {
      "type": "text",
      "text": "HTTP 200 OK — POST /v1/agent/completions\n{\n  \"job_id\": \"agent-b0abf28…\",\n  …\n}"
    }
  ],
  "structuredContent": {
    "job_id": "agent-b0abf28…",
    "success": true,
    "name": "research-agent",
    "outputs": [
      { "role": "research-agent", "content": "…", "timestamp": "…" }
    ],
    "usage": {
      "input_tokens": 7,
      "output_tokens": 62,
      "total_tokens": 69,
      "total_cost": 0.001192
    }
  },
  "isError": false
}
```

An upstream failure comes back as `isError: true` with the message in `content[0].text` — it is a tool-level error, not a transport exception, so your client will not throw.

## Core Tool Parameters

### `run_agent_v1_agent_completions_post`

| Parameter | Type | Required | Description |
| - | - | - | - |
| `agent_config` | object | **Yes** | The agent specification (see below) |
| `task` | string | No | The task for the agent to complete |
| `history` | object \| array | No | Prior tasks and responses |
| `img` | string | No | A single base64-encoded image |
| `imgs` | array of string | No | Multiple base64-encoded images |
| `tools_enabled` | array of string | No | Tools the agent may use |

Common `agent_config` fields:

| Field | Type | Default | Description |
| - | - | - | - |
| `agent_name` | string | — | Identifies the agent's role |
| `system_prompt` | string | — | Initial instruction shaping behavior |
| `model_name` | string | `claude-sonnet-5` | Model to run |
| `max_tokens` | integer | `16000` | Output token cap |
| `max_loops` | integer \| `"auto"` | `1` | Iterations, 1–50 or `"auto"` |
| `temperature` | number | provider default | Randomness, 0–2 |
| `fallback_models` | array of string | — | Models tried in order if the primary errors |
| `role` | string | `worker` | Role within a swarm |

### `run_swarm_v1_swarm_completions_post`

| Parameter | Type | Required | Description |
| - | - | - | - |
| `name` | string | No | Swarm identifier, max 100 chars |
| `description` | string | No | What the swarm is for |
| `agents` | array of agent specs | No | Participating agents, up to 2000 |
| `swarm_type` | string | No | Architecture — see below |
| `task` | string | No | The objective |
| `tasks` | array of string | No | Multiple objectives |
| `max_loops` | integer | `1` | Execution loops, up to 50 |
| `rearrange_flow` | string | No | Task ordering for `AgentRearrange` |
| `stream` | boolean | `false` | Stream output |

Valid `swarm_type` values (from `GET /v1/swarms/available`):

`AgentRearrange`, `MixtureOfAgents`, `SequentialWorkflow`, `ConcurrentWorkflow`, `GroupChat`, `MultiAgentRouter`, `HierarchicalSwarm`, `MajorityVoting`, `CouncilAsAJudge`, `HeavySwarm`, `LLMCouncil`, `DebateWithJudge`, `RoundRobin`, `PlannerWorkerSwarm`

<Note>
  Batched grid workflows and graph workflows are separate endpoints
  (`POST /v1/batched-grid-workflow/completions`, `POST /v1/graph-workflow/completions`),
  not `swarm_type` values — see the Specialized Workflows tools below.
</Note>

## TypeScript

Install the official MCP SDK:

```bash theme={null}
npm install @modelcontextprotocol/sdk
```

### Agent Completions

```typescript theme={null}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const apiKey = process.env.SWARMS_API_KEY;
if (!apiKey) throw new Error("set SWARMS_API_KEY");

// The credential is a transport header. No tool takes it as an argument.
const transport = new StreamableHTTPClientTransport(
  new URL("https://mcp.swarms.world/mcp"),
  { requestInit: { headers: { "x-api-key": apiKey } } },
);

const client = new Client({ name: "swarms-client", version: "1.0.0" });
await client.connect(transport);

const result = await client.callTool({
  name: "run_agent_v1_agent_completions_post",
  arguments: {
    agent_config: {
      agent_name: "research-agent",
      description: "Analyzes technical topics and reports concisely.",
      model_name: "gpt-4o-mini",
      max_loops: 1,
      max_tokens: 2000,
    },
    task: "Explain the CAP theorem in three bullets.",
  },
});

if (result.isError) {
  throw new Error(result.content[0].text);
}

// structuredContent is the parsed upstream JSON — no string parsing needed.
const payload = result.structuredContent as any;
console.log(payload.outputs[0].content);
console.log(`cost: $${payload.usage.total_cost}`);

await client.close();
```

### Swarm Completions

```typescript theme={null}
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://mcp.swarms.world/mcp"),
  { requestInit: { headers: { "x-api-key": process.env.SWARMS_API_KEY! } } },
);

const client = new Client({ name: "swarms-client", version: "1.0.0" });
await client.connect(transport);

const result = await client.callTool({
  name: "run_swarm_v1_swarm_completions_post",
  arguments: {
    name: "market-analysis",
    description: "Research a market, then critique the research.",
    swarm_type: "SequentialWorkflow",
    task: "Analyze the market for autonomous delivery robots.",
    max_loops: 1,
    agents: [
      {
        agent_name: "researcher",
        system_prompt: "Gather and summarize market facts.",
        model_name: "gpt-4o-mini",
        max_loops: 1,
        max_tokens: 2000,
      },
      {
        agent_name: "critic",
        system_prompt: "Challenge weak claims in the research above.",
        model_name: "gpt-4o-mini",
        max_loops: 1,
        max_tokens: 2000,
      },
    ],
  },
});

if (result.isError) {
  throw new Error(result.content[0].text);
}

const payload = result.structuredContent as any;
for (const message of payload.output) {
  console.log(`--- ${message.role} ---`);
  console.log(message.content);
}
console.log(`agents: ${payload.number_of_agents}`);
console.log(`elapsed: ${payload.execution_time}s`);

await client.close();
```

### Discovering Tools

```typescript theme={null}
const { tools } = await client.listTools();
for (const tool of tools) {
  console.log(tool.name);
}
```

## Rust

Add the official Rust MCP SDK to `Cargo.toml`:

```toml theme={null}
[dependencies]
rmcp = { version = "3.1", features = [
    "client",
    "reqwest",
    "transport-streamable-http-client-reqwest",
] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
serde_json = "1"
```

### Agent Completions

```rust theme={null}
use std::collections::HashMap;

use rmcp::model::CallToolRequestParams;
use rmcp::transport::{
    streamable_http_client::StreamableHttpClientTransportConfig,
    StreamableHttpClientTransport,
};
use rmcp::ServiceExt;
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api_key = std::env::var("SWARMS_API_KEY")?;

    // The credential is a transport header. No tool takes it as an argument.
    let mut headers = HashMap::new();
    headers.insert("x-api-key".parse()?, api_key.parse()?);

    let transport = StreamableHttpClientTransport::from_config(
        StreamableHttpClientTransportConfig::with_uri("https://mcp.swarms.world/mcp")
            .custom_headers(headers),
    );

    let client = ().serve(transport).await?;

    let result = client
        .call_tool(
            CallToolRequestParams::new("run_agent_v1_agent_completions_post").with_arguments(
                json!({
                    "agent_config": {
                        "agent_name": "research-agent",
                        "description": "Analyzes technical topics and reports concisely.",
                        "model_name": "gpt-4o-mini",
                        "max_loops": 1,
                        "max_tokens": 2000
                    },
                    "task": "Explain the CAP theorem in three bullets."
                })
                .as_object()
                .cloned()
                .unwrap(),
            ),
        )
        .await?;

    if result.is_error.unwrap_or(false) {
        return Err(format!("{:?}", result.content).into());
    }

    // structured_content is the parsed upstream JSON — no string parsing needed.
    let payload = result.structured_content.ok_or("no structured content")?;
    println!("{}", payload["outputs"][0]["content"]);
    println!("cost: ${}", payload["usage"]["total_cost"]);

    client.cancel().await?;
    Ok(())
}
```

### Swarm Completions

```rust theme={null}
use std::collections::HashMap;

use rmcp::model::CallToolRequestParams;
use rmcp::transport::{
    streamable_http_client::StreamableHttpClientTransportConfig,
    StreamableHttpClientTransport,
};
use rmcp::ServiceExt;
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api_key = std::env::var("SWARMS_API_KEY")?;

    let mut headers = HashMap::new();
    headers.insert("x-api-key".parse()?, api_key.parse()?);

    let transport = StreamableHttpClientTransport::from_config(
        StreamableHttpClientTransportConfig::with_uri("https://mcp.swarms.world/mcp")
            .custom_headers(headers),
    );

    let client = ().serve(transport).await?;

    let result = client
        .call_tool(
            CallToolRequestParams::new("run_swarm_v1_swarm_completions_post").with_arguments(
                json!({
                    "name": "market-analysis",
                    "description": "Research a market, then critique the research.",
                    "swarm_type": "SequentialWorkflow",
                    "task": "Analyze the market for autonomous delivery robots.",
                    "max_loops": 1,
                    "agents": [
                        {
                            "agent_name": "researcher",
                            "system_prompt": "Gather and summarize market facts.",
                            "model_name": "gpt-4o-mini",
                            "max_loops": 1,
                            "max_tokens": 2000
                        },
                        {
                            "agent_name": "critic",
                            "system_prompt": "Challenge weak claims in the research above.",
                            "model_name": "gpt-4o-mini",
                            "max_loops": 1,
                            "max_tokens": 2000
                        }
                    ]
                })
                .as_object()
                .cloned()
                .unwrap(),
            ),
        )
        .await?;

    if result.is_error.unwrap_or(false) {
        return Err(format!("{:?}", result.content).into());
    }

    let payload = result.structured_content.ok_or("no structured content")?;
    for message in payload["output"].as_array().unwrap() {
        println!("--- {} ---", message["role"].as_str().unwrap_or("?"));
        println!("{}", message["content"].as_str().unwrap_or(""));
    }
    println!("agents: {}", payload["number_of_agents"]);
    println!("elapsed: {}s", payload["execution_time"]);

    client.cancel().await?;
    Ok(())
}
```

### Discovering Tools

```rust theme={null}
let tools = client.list_tools(Default::default()).await?;
for tool in tools.tools {
    println!("{}", tool.name);
}
```

## Python

The [official Python SDK](https://github.com/modelcontextprotocol/python-sdk) follows the same shape:

```bash theme={null}
pip install mcp
```

```python theme={null}
import asyncio
import os

import httpx
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client

SERVER = "https://mcp.swarms.world/mcp"


async def main() -> None:
    api_key = os.environ["SWARMS_API_KEY"]

    async with (
        httpx.AsyncClient(
            headers={"x-api-key": api_key}, timeout=180
        ) as http_client,
        streamable_http_client(
            SERVER, http_client=http_client
        ) as (read, write),
        ClientSession(read, write) as session,
    ):
        await session.initialize()

        result = await session.call_tool(
            "run_agent_v1_agent_completions_post",
            {
                "agent_config": {
                    "agent_name": "research-agent",
                    "model_name": "gpt-4o-mini",
                    "max_loops": 1,
                    "max_tokens": 2000,
                },
                "task": "Explain the CAP theorem in three bullets.",
            },
        )

        if result.is_error:
            raise RuntimeError(result.content[0].text)

        payload = result.structured_content
        print(payload["outputs"][0]["content"])


if __name__ == "__main__":
    asyncio.run(main())
```

## Verifying the Connection with curl

The server speaks plain JSON-RPC over HTTP POST, so you can exercise it without any SDK:

```bash theme={null}
curl -sS -X POST https://mcp.swarms.world/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "x-api-key: $SWARMS_API_KEY" \
  -d '{
        "jsonrpc": "2.0",
        "id": 1,
        "method": "tools/call",
        "params": {
          "name": "get_available_models_v1_models_available_get",
          "arguments": {}
        }
      }'
```

Responses come back as a single SSE `data:` frame. Because the server is stateless, there is no session to establish first and no `Mcp-Session-Id` to echo back.

## Error Handling

| Scenario | How it surfaces | What to do |
| - | - | - |
| Missing or invalid API key | `isError: true`, message names the `x-api-key` header | Set the header on the transport, not in tool arguments |
| Rate limit exceeded | `isError: true` with the upstream 429 status line | Back off; check `get_rate_limits_v1_rate_limits_get` |
| Invalid parameters | `isError: true` with the upstream 422 body | Compare against the tool's `inputSchema` from `tools/list` |
| Insufficient credits | `isError: true` with the upstream error | Check `credit_balance_v1_account_credits_get` |
| Long-running swarm | Client-side timeout | Raise the client's request timeout — large swarms can run for minutes |

Because failures arrive as `isError: true` rather than thrown exceptions, always check that flag before reading `structuredContent`.

## Best Practices

| Practice | Why |
| - | - |
| Read `structuredContent`, not `content[0].text` | The text block is a rendering with a status-line prefix; the structured block is already parsed |
| Keep the key in the transport header | It stays out of tool arguments, so the model never sees it |
| Check `isError` before reading results | Upstream failures are tool-level results, not exceptions |
| Raise client timeouts for swarms | Multi-agent runs routinely exceed default HTTP timeouts |
| Cache `get_available_models_v1_models_available_get` | The model list changes rarely |
| Prefer batch tools for bulk work | One call with many tasks beats many calls |
| Watch `usage.total_cost` in responses | Every completion reports its own cost |

## Alternative: Local stdio Server

If you need to run the bridge yourself — for network-isolated environments or custom tool filtering — the `swarms-ts-mcp` npm package runs a local stdio MCP server against the same API.

```json theme={null}
{
  "mcpServers": {
    "swarms": {
      "command": "npx",
      "args": ["-y", "swarms-ts-mcp@latest", "--client=claude", "--tools=all"],
      "env": {
        "SWARMS_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

<Warning>
  The local package exposes a different, smaller tool set with different tool names (`run_agent`, `run_swarms`, and so on) than the hosted server documented above. Code written against one will not run unchanged against the other. The hosted server at `mcp.swarms.world` is the recommended path.
</Warning>

## Resources

| Resource | Link |
| - | - |
| **MCP Server URL** | `https://mcp.swarms.world/mcp` |
| **Get an API key** | [swarms.world/platform/api-keys](https://swarms.world/platform/api-keys) |
| **API Reference** | [docs.swarms.ai/api-reference](https://docs.swarms.ai/api-reference) |
| **Docs MCP Server** | [Docs MCP and LLMs txt](/docs/documentation/clients/swarms-docs-mcp) |
| **Model Context Protocol** | [modelcontextprotocol.io](https://modelcontextprotocol.io) |
| **TypeScript SDK** | [@modelcontextprotocol/sdk](https://www.npmjs.com/package/@modelcontextprotocol/sdk) |
| **Rust SDK** | [rmcp on crates.io](https://crates.io/crates/rmcp) |
| **Python SDK** | [mcp on PyPI](https://pypi.org/project/mcp/) |
| **Support** | [Discord](https://discord.gg/EamjgSaEQf) |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.