> For the complete documentation index, see [llms.txt](https://umber.gitbook.io/umber/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://umber.gitbook.io/umber/ai-agents/mcp-server.md).

# Connect AI Agents (MCP)

## Overview

Umber has an [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server. Connect it to an AI agent, such as Claude Code, Cursor, VS Code or your own agent, and the agent can work with your assets directly:

* *"Find the hero banner and tell me which environments it's live in."*
* *"Upload `designs/hero-v2.png` as a new version of `hero-banner` and deploy it to staging."*
* *"Production is serving the wrong logo. Roll `brand-logo` back in production."*
* *"Create a collection called Spring Campaign for images, and add everything in `campaign/`."*
* *"How much bandwidth have we used this month?"*

The agent can only do what your [platform API key](/umber/concepts/api-keys.md) allows. The MCP server has no permissions of its own: every action is an ordinary [v2 API](/umber/api-reference-v2/overview.md) call made with your key, checked against its [scopes](/umber/concepts/api-keys.md#scopes) and against the [role](/umber/concepts/roles-and-permissions.md) of the person it acts as. No tool deletes anything.

## Local or hosted

There are two ways to connect. Both offer the same tools and use the same kind of key, so you can use either one, or both.

|          | Local                                                                                  | Hosted                                                                 |
| -------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| Runs     | On your computer, through the [Umber CLI](/umber/cli-tools/umber-cli.md) (`umber mcp`) | On Umber's servers, at `https://mcp.umbercloud.io`                     |
| Needs    | Node.js 20+                                                                            | Nothing to install                                                     |
| Sign-in  | `umber login` in your browser; no key to paste                                         | A platform API key and your workspace's domain ID                      |
| Uploads  | Any local file, by path                                                                | File content sent by the agent, up to 10 MB                            |
| Best for | Working in an IDE on your own machine                                                  | Agents running in the cloud or in CI, and clients that only take a URL |

## Connect the local server

### 1. Log in

```bash
npx @umbercloud/cli login
```

This opens your browser, and Umber gives the CLI a platform API key. See [Logging in](/umber/cli-tools/umber-cli.md#logging-in-browser). Only Owners and Admins can log in through the browser, because logging in creates a key. Anyone else needs an Owner or Admin to create a key for them (see [Without a browser](#without-a-browser) below).

The agent acts as you: anything it uploads or deploys names you as `createdBy`, and Umber checks that [your role](/umber/concepts/roles-and-permissions.md) allows it.

### 2. Add the server to your client

**Claude Code**

```bash
claude mcp add umber -- npx -y @umbercloud/cli mcp
```

**Cursor** (`~/.cursor/mcp.json`), **Windsurf**, **Claude Desktop** and most other clients

```json
{
  "mcpServers": {
    "umber": { "command": "npx", "args": ["-y", "@umbercloud/cli", "mcp"] }
  }
}
```

**VS Code** (`.vscode/mcp.json`)

```json
{
  "servers": {
    "umber": { "type": "stdio", "command": "npx", "args": ["-y", "@umbercloud/cli", "mcp"] }
  }
}
```

Restart the client or reload its MCP servers, then ask the agent *"Which Umber workspace am I connected to?"* It answers by calling the `whoami` tool.

{% hint style="info" %}
The server reads your login each time the agent calls a tool. If you run `umber login` again, there's no need to restart anything.
{% endhint %}

### Without a browser

On a machine with no browser, such as a CI runner or a remote dev box, give the server a key through environment variables. An Owner or Admin creates the key on the **Organization** page under **Platform API Keys** (see [Creating a key](/umber/concepts/api-keys.md#creating-a-key)).

```json
{
  "mcpServers": {
    "umber": {
      "command": "npx",
      "args": ["-y", "@umbercloud/cli", "mcp"],
      "env": {
        "UMBER_API_KEY": "umber_sk_...",
        "UMBER_DOMAIN_ID": "<your domain ID>",
        "UMBER_EMAIL": "you@yourcompany.com",
        "UMBER_ENV": "dev"
      }
    }
  }
}
```

`UMBER_EMAIL` is whose uploads and deploys these are: the email of a workspace member whose role allows them. `UMBER_ENV` is the default environment.

### Options

| Option                  | Effect                                                                                                               |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `umber mcp --read-only` | Exposes only the tools that read. Add `"--read-only"` to `args`.                                                     |
| `UMBER_ENV`             | The default environment, used when the agent doesn't name one. After `umber login`, it's the environment you picked. |

## Connect the hosted server

### 1. Get a key and your domain ID

* **A platform API key.** An Owner or Admin creates one on the **Organization** page under **Platform API Keys**. Give it the [scopes](#choosing-scopes) the agent needs, and a label such as `Cursor (Priya)` so you can tell it apart later.
* **Your domain ID.** Open the account menu (top right), choose **Profile**, and copy **Domain Id**.

Writes made through the hosted server are attributed to the person who **created the key**, and Umber checks that their role allows each one.

### 2. Add the server to your client

**Claude Code**

```bash
claude mcp add --transport http umber https://mcp.umbercloud.io \
  --header "Authorization: Bearer umber_sk_..." \
  --header "X-Umber-Domain: <your domain ID>"
```

**Cursor** (`~/.cursor/mcp.json`)

```json
{
  "mcpServers": {
    "umber": {
      "url": "https://mcp.umbercloud.io",
      "headers": {
        "Authorization": "Bearer umber_sk_...",
        "X-Umber-Domain": "<your domain ID>"
      }
    }
  }
}
```

**VS Code** (`.vscode/mcp.json`). VS Code prompts for the key, so it never sits in the file:

```json
{
  "inputs": [
    { "type": "promptString", "id": "umber-key", "description": "Umber platform API key", "password": true }
  ],
  "servers": {
    "umber": {
      "type": "http",
      "url": "https://mcp.umbercloud.io",
      "headers": {
        "Authorization": "Bearer ${input:umber-key}",
        "X-Umber-Domain": "<your domain ID>"
      }
    }
  }
}
```

Other clients work the same way if they support remote MCP servers with custom headers.

{% hint style="warning" %}
**Keep the key out of version control.** Put it in your user-level config (such as `~/.cursor/mcp.json`), not a project file you commit, or use a prompt as in the VS Code example. If a key leaks, revoke it on the **Organization** page.
{% endhint %}

### Optional headers

| Header                         | Effect                                      |
| ------------------------------ | ------------------------------------------- |
| `X-Umber-Env: <envId or name>` | The default environment for this connection |
| `X-Umber-Read-Only: true`      | Hides every tool that writes                |

Opening `https://mcp.umbercloud.io` in a browser shows a short setup page. The address is meant for MCP clients.

## Tools

| Tool                  | What it does                                                                                                                                                                     | Scope needed                                       |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| `whoami`              | The workspace, who the agent acts as, the default environment, and the environments available. On the hosted server, also the key's scopes.                                      | none (lists environments with `environments:read`) |
| `list_environments`   | Every environment in the workspace                                                                                                                                               | `environments:read`                                |
| `search_assets`       | Finds assets by name, ID or description, or lists them all                                                                                                                       | `assets:read`                                      |
| `get_asset`           | One asset: details, recent versions, and where each version is deployed                                                                                                          | `assets:read`                                      |
| `get_asset_url`       | An asset's delivery URLs in one environment                                                                                                                                      | `assets:read`                                      |
| `list_collections`    | The workspace's [collections](/umber/concepts/virtual-collections.md)                                                                                                            | `collections:read`                                 |
| `get_collection`      | One collection and a page of its items                                                                                                                                           | `collections:read`, `collection-items:read`        |
| `get_usage`           | A month's usage and cost estimate                                                                                                                                                | `billing:read`                                     |
| `upload_file`         | Creates an asset, or adds a version to an existing one. **Never deploys.**                                                                                                       | `assets:write`                                     |
| `deploy_version`      | Deploys a version to an environment, by default making it what the stable URL serves                                                                                             | `deploy`, `assets:read`                            |
| `rollback_asset`      | Makes the previous default version the default again                                                                                                                             | `deploy`, `assets:read`                            |
| `create_collection`   | Creates an empty, undeployed [collection](/umber/concepts/virtual-collections.md) for the asset types you name                                                                   | `collections:write`                                |
| `add_collection_item` | Adds a file to a collection. **If the collection is deployed, asks for confirmation first**, because the item goes live immediately ([details](#how-agents-add-to-collections)). | `collection-items:write`, `collections:read`       |

On the hosted server, the agent only sees the tools its key's scopes allow. A key with only `assets:read` shows four tools. The local server lists every tool, and a call outside the key's scopes is refused with a message naming the missing scope.

`upload_file` and `add_collection_item` are the tools whose inputs differ between the two servers. The local server takes a file path. The hosted server takes the file's name and its content as base64, up to 10 MB; for bigger files, use the [CLI](/umber/cli-tools/umber-cli.md).

## How agents upload and deploy

Uploading and deploying are separate steps, so nothing reaches an environment until something deploys it:

1. **`upload_file`** stores the file. With `assetId`, it becomes the next version of that asset. Without it, a new asset is created with an ID taken from the file name (`Hero Banner.png` becomes `hero-banner`; if that ID is taken, a short suffix is added). Assets created this way are not [secured](/umber/concepts/api-keys.md#secured-downloads-use-download-keys), so their delivery URLs need no download key, the same as assets the CLI creates.
2. **`deploy_version`** deploys the version to an environment and, by default, makes it the **default**: the version the asset's stable delivery URL serves. The previous default stays deployed, reachable at its version-pinned URL. With `makeDefault: false`, the version is added as **LIVE** only (see [Deployment States](/umber/concepts/deployment-states.md)).
3. **`rollback_asset`** makes the previous default the default again.

**Naming the environment.** Agents can name an environment by its ID or its name ("staging"). If they don't name one:

* On the **local** server, the default environment is used: the one you picked at `umber login`, or `UMBER_ENV`.
* On the **hosted** server, reads use `X-Umber-Env` if set, otherwise the workspace's default environment. **Deploys and rollbacks are refused** unless the agent names an environment or `X-Umber-Env` is set, so an agent never deploys somewhere nobody chose.

{% hint style="info" %}
Agents are told to confirm the environment with you before deploying to production. Most clients also ask you to approve each tool call that changes something.
{% endhint %}

## How agents add to collections

Collections work differently from single assets. When a file is added to a collection that's deployed, Umber republishes the collection straight away in every environment where it's live, so the new item is served there within seconds. There's no separate deploy step.

So that an agent can't publish something without you knowing, `add_collection_item` first checks where the collection is deployed:

* **Not deployed anywhere:** the item is added, and nothing is published.
* **Deployed somewhere:** the tool refuses and tells the agent where, for example *"Collection `spring-campaign` is deployed in Production (env-prod), so a new item is published there immediately."* The agent should ask you. If you agree, it calls again with `goLive: true`, and the result lists the environments the item went live in.

`create_collection` makes a new collection that isn't deployed anywhere, so filling it with `add_collection_item` publishes nothing. Deploy it from the dashboard or the [API](/umber/api-reference-v2/collections/collection-deployment.md) when it's ready. A new collection is **not secured** unless the agent passes `secured: true`, and that setting can't be changed later.

The collection's own rules still apply: a file of a type the collection doesn't accept, or one that would take it past its item limit, is refused.

## Choosing scopes

Give an agent's key only what it needs:

| The agent should                   | Scopes                                                                                                                         |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Look things up                     | `assets:read`, `environments:read` (add `collections:read`, `collection-items:read` for collections, `billing:read` for usage) |
| Also upload                        | add `assets:write`                                                                                                             |
| Also deploy and roll back          | add `deploy`                                                                                                                   |
| Create collections and add to them | add `collections:read`, `collections:write`, `collection-items:write`                                                          |

The key `umber login` creates has `assets:read`, `assets:write`, `deploy`, `environments:read` and `billing:read`. It has no collection scopes, so the collection tools are refused on the local server unless you configure it with a key that has them (see [Without a browser](#without-a-browser)).

No tool deletes assets, versions, collections or environments, or creates releases, whatever scopes the key has.

## Troubleshooting

| The agent reports                                                                                                             | What to do                                                                                                                                                                                                                                                                                                       |
| ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *Not signed in to Umber*                                                                                                      | Run `umber login`, or set `UMBER_API_KEY` and `UMBER_DOMAIN_ID` in the server's `env`.                                                                                                                                                                                                                           |
| *The saved API key is an environment download key*                                                                            | Your login is from CLI 0.3 or earlier. Run `umber login` again.                                                                                                                                                                                                                                                  |
| *The platform API key was rejected*                                                                                           | The key was revoked or has expired. Create a new one, or run `umber login` again.                                                                                                                                                                                                                                |
| *…needs the `deploy` scope* (or another scope)                                                                                | The key lacks that scope. Create a key that has it. For writes, the person the agent acts as also needs a role that allows the action.                                                                                                                                                                           |
| *No environment "…". Available: …*                                                                                            | The environment name or ID doesn't exist. The message lists the real ones.                                                                                                                                                                                                                                       |
| *Say which environment to use* (hosted)                                                                                       | Name the environment in your request, or set the `X-Umber-Env` header.                                                                                                                                                                                                                                           |
| *Collection "…" is deployed in …, so a new item is published there immediately*                                               | Working as intended. If you want the item live there, tell the agent to go ahead.                                                                                                                                                                                                                                |
| *Asset Type not allowed in this collection*                                                                                   | The collection doesn't accept that kind of file. Use another collection, or create one for that type.                                                                                                                                                                                                            |
| *The file is over the 10 MB limit* (hosted)                                                                                   | Upload it with the [CLI](/umber/cli-tools/umber-cli.md) or the local server.                                                                                                                                                                                                                                     |
| The client can't connect to the hosted server (401)                                                                           | Check both headers: `Authorization: Bearer umber_sk_…` and `X-Umber-Domain` with the domain ID of the workspace that owns the key.                                                                                                                                                                               |
| *Dynamic Client Registration rejected*, *oauth\_not\_supported*, or the client asks you to sign in through a browser (hosted) | The server refused the key, so the client fell back to OAuth sign-in, which Umber doesn't use. Fix the headers as in the row above: the key must be created in the workspace named in `X-Umber-Domain`, and must not be revoked or expired. Then reconnect. In Claude Code, run `/mcp` and reconnect the server. |
| The client lists no Umber tools (local)                                                                                       | Check you have Node.js 20+. If an old version is cached, use `@umbercloud/cli@latest` in `args`. `umber mcp` needs CLI 0.5.0 or later.                                                                                                                                                                           |

## Limitations

* **No sign-in flow for connectors yet.** The hosted server takes a key in a header, so it doesn't yet work as a claude.ai or ChatGPT connector, which sign in through OAuth. Use the local server with Claude Desktop.
* **Collections: create and add only.** Agents can create collections and add items, but not deploy, undeploy or roll back a collection, or move, copy or remove items. Do those in the dashboard.
* **Hosted uploads are capped at 10 MB.**
* **The local server knows fewer file types.** It recognizes common images, video, audio, PDF, Office documents, CSV, JSON and XML. The hosted server accepts every type Umber supports.
* **No deletes,** by design.
