# MCP Server

ModelStack exposes image, video, and audio generation plus LLM chat as [Model Context Protocol](https://modelcontextprotocol.io) tools. Any MCP-capable agent — Claude Code, Cursor, Codex, Cline, or your own — can generate media and call models using your existing ModelStack API key.

The endpoint is:

```
https://api.modelstack.cc/mcp
```

<Info>
  This is different from the rest of the API. The Chat and Generations APIs are
  things *you* call. The MCP server is something your **agent** calls on its
  own, deciding when to generate an image or delegate a prompt to another model.
</Info>

## Install

<CodeGroup>

```bash Claude Code
claude mcp add --transport http modelstack https://api.modelstack.cc/mcp \
  --header "Authorization: Bearer YOUR_MODELSTACK_API_KEY" \
  --scope user
```

```json mcp.json
{
  "mcpServers": {
    "modelstack": {
      "type": "http",
      "url": "https://api.modelstack.cc/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_MODELSTACK_API_KEY"
      }
    }
  }
}
```

</CodeGroup>

Verify the connection:

```bash
claude mcp list          # modelstack ✓ connected
```

Inside a session, `/mcp` lists the server and its tools. They reach the model as `mcp__modelstack__generate_image`, `mcp__modelstack__llm_chat`, and so on.

`x-api-key: YOUR_KEY` works in place of the `Authorization` header if your client prefers it.

## Choosing a scope

The scope decides where your key is written.

| Scope | Written to | Use when |
| --- | --- | --- |
| `user` | `~/.claude.json` | Recommended — available in every project, key stays out of the repo |
| `local` (default) | `~/.claude.json`, current project only | Trying it out |
| `project` | `.mcp.json` in the repo | Sharing with teammates |

<Warning>
  Do not use `--scope project` with the key written inline. `.mcp.json` is meant
  to be committed, so the key would be published to your repository and could be
  used to spend your balance. For a shared setup, commit an environment
  variable reference instead and have each person export their own key:

```json
{
  "mcpServers": {
    "modelstack": {
      "type": "http",
      "url": "https://api.modelstack.cc/mcp",
      "headers": { "Authorization": "Bearer ${MODELSTACK_API_KEY}" }
    }
  }
}
```

</Warning>

## What your agent can do

<CardGroup cols={2}>
  <Card title="Generate media" icon="image">
    Image, video, and audio generation across 29 models — the same catalog the
    Generations API serves.
  </Card>
  <Card title="Delegate to another model" icon="forum">
    `llm_chat` routes a prompt to any of 50+ chat models, so an agent can hand
    bulk work to a cheaper model than it runs on.
  </Card>
  <Card title="Discover models at runtime" icon="search">
    `list_models` and `list_generation_models` return live catalogs, including
    which parameters each variant accepts and what it costs.
  </Card>
  <Card title="Use reference images" icon="upload">
    Upload media and feed it to image-to-image or image-to-video variants.
  </Card>
</CardGroup>

See the [Tools Reference](/docs/mcp/tools) for every tool and its parameters.

## Generation is asynchronous

This is the one behaviour worth knowing before you prompt.

`generate_image`, `generate_video`, and `generate_audio` return a `job_id` **immediately** — they do not wait for the image. Your agent then polls `get_generation` until the status is `completed` or `failed`.

```
generate_image(model: "google/nano-banana-2", prompt: "a red maple leaf")
  → { job_id: "58eae738…", status: "pending" }

get_generation(job_id: "58eae738…")
  → { status: "processing" }

get_generation(job_id: "58eae738…")
  → { status: "completed",
      output_urls: ["https://…"],   // signed, ~1 hour
      cost_usd: 0.04 }
```

Agents chain this on their own — the tool descriptions instruct them to. It matters because a video job can take several minutes, and a tool that blocked that long would hit client-side timeouts. Nothing blocks, so nothing times out.

<Tip>
  A useful prompt shape: *"Generate a hero image of a mountain at dusk, poll
  until it's ready, then give me the URL."* The agent handles the polling loop
  itself.
</Tip>

## Billing and limits

MCP calls are billed exactly like direct API calls — the server routes them back through the same path, so your entitlement rate limit, spending cap, prepaid balance, and usage analytics all apply unchanged. There is no separate MCP quota.

`get_generation` reports `cost_usd` per job, and everything shows up in [Analytics](/docs/dashboard/analytics) alongside your other traffic.

## Authentication

The MCP specification makes its OAuth chapter optional for HTTP transports, so this server authenticates with a static ModelStack API key — the same key you use everywhere else.

An invalid key returns HTTP `401` with a JSON-RPC error. The response deliberately carries no `WWW-Authenticate` challenge, because that header would push clients into an OAuth discovery flow this server does not implement, surfacing as a stray browser redirect instead of a clear "your key is wrong".

## Protocol support

The endpoint is stateless and serves both eras of the MCP specification, so it works with current clients and with clients that adopt the newer revision.

| Era | Versions | Entry point |
| --- | --- | --- |
| Legacy | `2025-03-26`, `2025-06-18`, `2025-11-25` | `initialize` handshake |
| Modern | `2026-07-28` | per-request `_meta` |

No session IDs are ever issued, so there is no connection state to lose and no reconnect logic to get wrong. `GET` and `DELETE` on the endpoint return `405`.

## Next steps

<CardGroup cols={2}>
  <Card title="Tools Reference" icon="build" href="/docs/mcp/tools">
    Every tool, its parameters, and complete workflows.
  </Card>
  <Card title="Generations API" icon="movie_creation" href="/docs/api-reference/generations-overview">
    The same media generation, called directly over HTTP.
  </Card>
  <Card title="Model Catalog" icon="neurology" href="/docs/api-reference/generation-models">
    Every generation model, variant, and price.
  </Card>
  <Card title="API Keys" icon="key" href="/docs/dashboard/api-keys">
    Create and manage the key your MCP client uses.
  </Card>
</CardGroup>

---
