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

# MCP Server

The Upstash MCP server lets your agent manage and debug your Upstash resources directly, across Redis, QStash, Workflow, Vector, Search, [Upstash Box](/docs/box/overall/quickstart), and [Blob](/docs/blob/overall/quickstart).

Run it two ways:

* **Remote (hosted)** — nothing to install. Connect over HTTP to `https://mcp.upstash.com/mcp` with OAuth or a developer API key. Covers Redis, QStash, Workflow, Vector, Search, Box, and Blob.
* **Local (stdio)** — run [`@upstash/mcp-server`](https://github.com/upstash/mcp-server) with `npx`, authenticated with your email and API key. Covers Redis, QStash, Workflow, and Upstash Box.

<Tip>
  Only running commands against a single Redis database? Use the dedicated [Redis MCP](/docs/redis/sdks/mcp) with only that database's REST/TCP credentials.
</Tip>

# Remote server (recommended)

Connect any MCP client over streamable HTTP to:

```
https://mcp.upstash.com/mcp
```

Tokens never reach the agent: data-plane tools resolve each resource's REST credentials server-side and call the endpoint directly.

## Connect

Snippets for popular clients. For every client — and the plugin-based setup — see [Install by agent](/docs/agent-resources/clients).

<Tabs>
  <Tab title="Claude Code">
    ```sh theme={"system"}
    claude mcp add --scope user --transport http upstash https://mcp.upstash.com/mcp
    ```

    Then run `/mcp` → **Authenticate**.
  </Tab>

  <Tab title="Cursor">
    Edit `~/.cursor/mcp.json` (or `.cursor/mcp.json` in a project):

    ```json theme={"system"}
    {
      "mcpServers": {
        "upstash": { "url": "https://mcp.upstash.com/mcp" }
      }
    }
    ```
  </Tab>

  <Tab title="OpenCode">
    Edit `~/.config/opencode/opencode.json` (or a project `opencode.json`):

    ```json theme={"system"}
    {
      "mcp": {
        "upstash": {
          "type": "remote",
          "url": "https://mcp.upstash.com/mcp",
          "enabled": true
        }
      }
    }
    ```
  </Tab>

  <Tab title="OpenAI Codex">
    Add to `~/.codex/config.toml` (or `.codex/config.toml`):

    ```toml theme={"system"}
    [mcp_servers.upstash]
    url = "https://mcp.upstash.com/mcp"
    ```
  </Tab>
</Tabs>

<Note>
  The Upstash plugin for **Claude Code, Claude Desktop, and Codex** bundles this remote MCP server (over OAuth), so installing the plugin sets up the skills **and** the MCP in one step — no separate command. See [Install by agent](/docs/agent-resources/clients).
</Note>

## Authentication

Two ways in — the remote server verifies neither locally; the Upstash API is the authority.

### OAuth (default)

The first tool call opens a browser consent page where you pick the **account scope** (personal or a team) and whether the connection is **read-only**. The grant is per client and revocable from the console under **Account → OAuth Clients**. Nothing to configure — this is what the `Connect` snippets above use.

### Developer API key (headless / CI)

No browser. Pass an API key as an `Authorization` header, in the form `email:API_KEY`:

```sh theme={"system"}
claude mcp add --scope user --transport http upstash https://mcp.upstash.com/mcp \
  --header "Authorization: Bearer you@example.com:YOUR_API_KEY"
```

Create a key from the console — see [Developer API → Create an API key](/docs/devops/developer-api/introduction#create-an-api-key).

<Note>
  Read-only API keys (and read-only OAuth grants) are supported — the server then disables every tool that would change state, and credential fields are omitted from tool results.
</Note>

## Feature groups

Append `?features=` to the URL to scope which product tools the agent sees — comma-separated values from `redis`, `qstash_workflow`, `vector_search`, `box`, `blob`; omitted means all five:

```
https://mcp.upstash.com/mcp?features=redis,qstash_workflow
```

A group covers every product it names, because those products share their tools: `qstash_workflow` carries the QStash *and* Workflow tools, and `vector_search` carries the Vector *and* Search tools. Each product's own name works as an alias for its group — `qstash`, `workflow`, `vector` and `search` are all accepted — so `?features=vector` and `?features=vector_search` return the same tools.

`box` and `blob` are the two halves of one workflow — an agent works in a sandbox, then gets what it produced out of it as a URL — so a client scoping down to that names both: `?features=box,blob`.

<Note>
  A name the server does not recognize is dropped, so `?features=redis,typo` still returns the Redis tools. But if *every* name is dropped, the server starts with no tools at all — and a client then reports `tools/list` as an unknown method rather than showing an empty list. If a fresh connection looks like it has no tools, check the spelling here first.
</Note>

## Tools

49 tools, grouped the way `?features=` groups them. The access column is the tool's own annotation, which clients use to decide what to confirm with you: **read** never changes anything, **write** only adds, **destructive** can delete or overwrite what is already there. On a read-only connection every write and destructive tool is refused.

The management tools that describe a resource (`redis_get_database`, `redis_create_database`, `index_get`, `index_create`, `qstash_list_users`) return its REST credentials only when called with `include_credentials: true`, so a routine lookup never carries a secret into the conversation. Listings never include credentials, and on a read-only connection they are omitted regardless.

<AccordionGroup>
  <Accordion title="Redis — 11 tools">
    | Tool                     | Access      | What it does                                                           |
    | ------------------------ | ----------- | ---------------------------------------------------------------------- |
    | `redis_list_databases`   | read        | Every Redis database in the account scope                              |
    | `redis_get_database`     | read        | One database in detail; REST credentials with `include_credentials`    |
    | `redis_get_stats`        | read        | Throughput, data size, hit and miss counts                             |
    | `redis_list_backups`     | read        | Backups taken of a database                                            |
    | `redis_create_database`  | write       | Creates a database; returns its credentials with `include_credentials` |
    | `redis_create_backup`    | write       | Takes a manual backup                                                  |
    | `redis_rename_database`  | destructive | Renames a database, replacing its current name                         |
    | `redis_set_eviction`     | destructive | Turns key eviction on or off                                           |
    | `redis_set_auto_upgrade` | destructive | Turns automatic plan upgrade on or off                                 |
    | `redis_delete_database`  | destructive | Deletes a database and everything in it                                |
    | `redis_run_command`      | destructive | Runs Redis commands over the REST API, one or a pipeline               |

    `redis_run_command` is annotated destructive because it takes arbitrary commands. On a read-only connection it still works, but only for commands on an allowlist of read-only ones — anything else, including a command the server does not recognize, is refused.
  </Accordion>

  <Accordion title="QStash and Workflow — 10 tools">
    Every tool here takes a `region` (`eu` or `us`), which picks the QStash user. The three shared ones take a `service` (`qstash` or `workflow`) to say which side you mean.

    | Tool                         | Access      | What it does                                                                        |
    | ---------------------------- | ----------- | ----------------------------------------------------------------------------------- |
    | `qstash_list_users`          | read        | The QStash user per region; REST tokens and signing keys with `include_credentials` |
    | `qstash_list_schedules`      | read        | Schedules in a region                                                               |
    | `qstash_flow_control_get`    | read        | Rate and parallelism for a flow-control key, or the account's global parallelism    |
    | `logs_list`                  | read        | Delivery and run logs, paginated by cursor                                          |
    | `dlq_list`                   | read        | The dead-letter queue, paginated by cursor                                          |
    | `qstash_publish_message`     | write       | Publishes a message to a destination URL                                            |
    | `qstash_flow_control_manage` | destructive | Pauses, resumes, pins, unpins or resets the rate on a key                           |
    | `qstash_manage_schedule`     | destructive | Creates, reads, deletes, pauses or resumes a schedule                               |
    | `workflow_manage_run`        | destructive | Reads a run's steps, or cancels the run                                             |
    | `dlq_manage`                 | destructive | Reads or deletes a DLQ entry; Workflow entries can also be restarted or resumed     |
  </Accordion>

  <Accordion title="Vector and Search — 17 tools">
    A Search database is a Vector index whose named indexes are namespaces, so most tools serve both and take a `service` (`vector` or `search`). Only querying and writing documents differ, which is why those four keep product names.

    | Tool                     | Access      | What it does                                                                         |
    | ------------------------ | ----------- | ------------------------------------------------------------------------------------ |
    | `index_list`             | read        | Every Vector index or Search database in the account scope                           |
    | `index_get`              | read        | One of them in detail; REST tokens with `include_credentials`                        |
    | `index_info`             | read        | Document counts, index size, per-namespace breakdown                                 |
    | `index_list_namespaces`  | read        | Namespaces, which for Search are its named indexes                                   |
    | `index_fetch`            | read        | Documents by ID or ID prefix                                                         |
    | `index_range`            | read        | Pages through the documents of a namespace                                           |
    | `index_create`           | write       | Creates a Vector index or a Search database; tokens with `include_credentials`       |
    | `index_update`           | destructive | Edits one document in place, including a metadata patch mode                         |
    | `index_rename_namespace` | destructive | Renames a namespace                                                                  |
    | `index_delete`           | destructive | Deletes an index or database and everything in it                                    |
    | `index_delete_documents` | destructive | Deletes documents by ID, prefix or filter                                            |
    | `index_reset`            | destructive | Empties a namespace, or every namespace, keeping the index                           |
    | `index_delete_namespace` | destructive | Deletes a namespace and its contents                                                 |
    | `vector_query`           | read        | Vector similarity search, with server-side embedding optional                        |
    | `search_query`           | read        | Full-text and semantic search over one named index                                   |
    | `vector_upsert`          | destructive | Upserts vectors, or text for the server to embed; an existing ID is overwritten      |
    | `search_upsert`          | destructive | Upserts documents, creating the named index if needed; an existing ID is overwritten |
  </Accordion>

  <Accordion title="Box — 9 tools">
    Sandboxed cloud containers with a shell, a filesystem, git and an optional headless browser. Each tool takes an `action`, so the names and parameters match the [local server's](https://github.com/upstash/mcp-server) Box tools.

    | Tool            | Access      | Actions                                                                                                                               |
    | --------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
    | `box_logs`      | read        | Timestamped log entries from a box, filterable by source, level, text and time window                                                 |
    | `box_browser`   | write       | `goto`, `content`, `screenshot`, `tabs`, `tab_new`, `tab_close`, `live_view` — needs a box created with `browser: true`               |
    | `box_git`       | write       | `clone`, `status`, `diff`, `commit`, `checkout`, `push`, `create_pr` — authenticated by the GitHub installation linked to the account |
    | `box_manage`    | destructive | `create`, `list`, `get`, `delete`, `pause`, `resume`, `fork`                                                                          |
    | `box_exec`      | destructive | Runs a shell command (argv array, optional `folder`) and waits for it                                                                 |
    | `box_preview`   | destructive | `create`, `list`, `delete` — public URLs for ports in a box                                                                           |
    | `box_runs`      | destructive | `list`, `get`, `cancel` — a box's run history                                                                                         |
    | `box_snapshots` | destructive | `create`, `list`, `list_all`, `delete`, `restore`                                                                                     |
    | `box_apikey`    | destructive | `list`, `create`, `delete` — Box API keys for the account scope; `create` returns the secret once                                     |

    `box_git` `clone` is what writes the GitHub credentials into the box, so a repository cloned with `git` in `box_exec` cannot `push` or `create_pr`. A clone lands at `/workspace/home/<repo>`; pass that as `folder` on later calls. A Box API key made with `box_apikey` outlives the OAuth grant that created it — revoke it from the console when it is no longer needed.
  </Accordion>

  <Accordion title="Blob — 2 tools">
    Object storage for getting files an agent produced somewhere else — a screenshot in a box, a build in CI — into a bucket and back out as a URL. Bytes never pass through the MCP server.

    | Tool              | Access | Actions                                                                                    |
    | ----------------- | ------ | ------------------------------------------------------------------------------------------ |
    | `blob_bucket`     | write  | `list`, `create` — `create` defaults to a public bucket, whose objects get a permanent URL |
    | `blob_upload_url` | write  | Mints presigned `PUT` URLs for paths in a bucket, valid for at most 10 minutes             |

    Upload with the returned headers sent verbatim — they are part of the signature, and a changed or missing one is refused by storage. Neither tool returns bucket tokens. On a read-only connection both are refused.
  </Accordion>
</AccordionGroup>

# Local server (`@upstash/mcp-server`)

A stdio server you run with `npx`, authenticated with your account email and a Developer API key. Adds [Upstash Box](/docs/box/overall/quickstart) tools on top of Redis, QStash, and Workflow. Repository [here](https://github.com/upstash/mcp-server).

Create an API key from the console — see [Developer API → Create an API key](/docs/devops/developer-api/introduction#create-an-api-key). The base command every client uses is:

```bash theme={"system"}
npx -y @upstash/mcp-server@latest --email YOUR_EMAIL --api-key YOUR_API_KEY
```

Add it to your client with the stdio transport, e.g. Claude Code:

```sh theme={"system"}
claude mcp add --transport stdio upstash -- npx -y @upstash/mcp-server@latest --email YOUR_EMAIL --api-key YOUR_API_KEY
```

See [Install by agent](/docs/agent-resources/clients) for a config snippet for every client.

<Note>
  Readonly API keys are supported. When the server starts with one, it disables every tool that would modify state, such as creating databases, deleting backups, or retrying workflows. Your agent can still read and query your account, but it cannot make changes.
</Note>

## Upstash Box API key (optional)

For the local server to interact with [Upstash Box](/docs/box/overall/quickstart), the agent needs your Box API key. To avoid pasting it into the chat each time, wire it into the setup — as a CLI flag or an environment variable.

<AccordionGroup>
  <Accordion title="CLI flag">
    ```json theme={"system"}
    {
      "mcpServers": {
        "upstash": {
          "command": "npx",
          "args": [
            "-y", "@upstash/mcp-server@latest",
            "--email", "YOUR_EMAIL",
            "--api-key", "YOUR_API_KEY",
            "--box-api-key", "YOUR_BOX_API_KEY"
          ]
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Environment variable">
    ```json theme={"system"}
    {
      "mcpServers": {
        "upstash": {
          "command": "npx",
          "args": ["-y", "@upstash/mcp-server@latest", "--email", "YOUR_EMAIL", "--api-key", "YOUR_API_KEY"],
          "env": {
            "UPSTASH_BOX_API_KEY": "YOUR_BOX_API_KEY"
          }
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

# Example prompts

## Redis

* "Start a free temporary Redis I can experiment with"
* "Create a new Redis database in us-east-1"
* "List my databases sorted by memory usage"
* "Give me the schema of how users are stored in this Redis"
* "Find all session keys expiring in the next hour and show me their payloads"
* "Create a backup of this db, then clear it"
* "Show me throughput spikes during the last 7 days"

## QStash & Workflow

* "Check the QStash logs and figure out why my webhook keeps failing"
* "Find failed workflow runs for user `@ysfk_0x` in the last 24 hours"
* "Retry the failed workflow run that started 2 hours ago"
* "Summarize what's in the DLQ right now, grouped by error type"
* "Pause the `daily-report` schedule until Monday"

## Vector & Search

* "List my Vector indexes and show the dimensions of each"
* "Query my Vector index for the 5 nearest neighbours of this text"
* "Upsert these documents into my Search index"

## Upstash Box

* "Spin up a Box, clone this repo, and run the tests"
* "Snapshot this Box and create 5 copies from it, assign each one a GitHub issue"
* "My Box keeps failing to start, check the logs and tell me what's wrong"
* "Run the app in a Box, screenshot the home page, upload it to Blob and open a PR with the image"

# Telemetry

The local server sends anonymous diagnostic info to Upstash with each request: the MCP server SDK version, your runtime version (Node, Bun, etc.), and basic platform info (OS and architecture). No account data, tool arguments, or results are collected. To opt out, add `--disable-telemetry` to the args.


## Related topics

- [Upstash Redis MCP](/docs/redis/sdks/mcp.md)
- [Install by agent](/docs/agent-resources/clients.md)
- [AI Tools](/docs/agent-resources/overview.md)
- [Overview](/docs/introduction.md)
- [Skills](/docs/agent-resources/skills.md)
