Upstash enables AI agents to manage serverless Redis databases and vector search infrastructure. Create and query databases, execute Redis commands, inspect database metrics, manage vector indexes, and retrieve documentation for integrating Upstash services into applications and agent workflows.
Encrypted at rest, isolated from the model
Resolved from an AES-256-GCM vault at the moment of the call and attached to the request — the model never sees the secrets.
Try asking
Lists all Upstash Redis databases in the authorized account scope. Never includes credentials — call redis_get_database with include_credentials for one database's.
Gets details of a single Upstash Redis database: endpoint, region, plan, limits and state. Credentials (password and REST tokens) are included only when include_credentials is true and the connection is read-write; on a read-only connection they are omitted (get them from the Upstash console). A database with Protect Credentials enabled (is_password_protected) has none to return.
Gets usage statistics of an Upstash Redis database: throughput, latency, hits and misses, keys, data size and connections over the period, requests per day, and this month's requests, bandwidth and cost. With refresh, the API recomputes the cached figures first.
Creates a new Upstash Redis database and returns it. Its credentials (password and REST tokens) are included only when include_credentials is true — set it when the user is going to configure an app with the new database; they can also be fetched later with redis_get_database. Without plan the database is free or pay-as-you-go, depending on whether the account has a payment method. Plans and prices: https://upstash.com/pricing/redis.md; when the user picks a fixed tier, confirm its monthly price with them first.
Renames an Upstash Redis database.
Enables or disables key eviction for an Upstash Redis database.
Enables or disables automatic plan upgrade for an Upstash Redis database.
Moves an Upstash Redis database to another plan: pay-as-you-go (billed per command) or a fixed monthly tier. Prices and limits: https://upstash.com/pricing/redis.md — its "Pay as You Go" is payg and "Fixed 250MB" … "Fixed 500GB" are fixed_250mb … fixed_500gb. The current plan is the database's type and reserved_type in redis_get_database. A database cannot be moved back to the free plan, and the plan can change at most once every 5 minutes. prod_pack and auto_upgrade can be set in the same call. This changes what the account is billed: tell the user the price from the pricing page and get their confirmation before calling.
Enables or disables Prod Pack on an Upstash Redis database: a per-database monthly add-on for pay-as-you-go and fixed plans that adds an uptime SLA, multi-zone high availability, encryption at rest, SOC-2 compliance and Prometheus/Grafana/Datadog metrics. Price and the full feature list: https://upstash.com/pricing/redis.md. Only accounts with a payment method can enable it. This changes what the account is billed: tell the user the price from the pricing page and get their confirmation before calling.
Sets the monthly spending cap of a pay-as-you-go Upstash Redis database; fixed plans have none. The month's bill never exceeds the cap. Below $1000 the database is also rate limited once the cap is reached; at $1000 and above it keeps serving at full speed. Email warnings go out at 70% and 90%. 0 removes the cap. Changing the budget, including to 0, lifts an active rate limit right away. A non-zero cap must be above what the database has already cost this month, and setting the value it already has fails with "budget already set". The current cap is budget in redis_get_database. How budgets work: https://upstash.com/pricing/redis.md. Confirm the amount with the user before calling.
Replaces the read regions of a global Upstash Redis database with the given list: regions not in it are removed along with their replicas, new ones are added. Pass the full list (redis_get_database shows the current read_regions and primary_region); an empty list removes every read region. The primary region can't be a read region, a free database can have at most one, and the regions can change at most once every 30 minutes. Regional, HIPAA and Enterprise databases are refused. Adding read regions costs more: on a fixed plan each one adds the plan's per-region price, and on pay-as-you-go every write is replicated to each read region and billed as another command, with storage counted in every region (https://upstash.com/pricing/redis.md). Confirm the regions and the cost with the user before calling.
Resets an Upstash Redis database's password and REST tokens (read-write and read-only). Every client still using the old ones fails from that moment, so the user has to update their apps' environment variables. Refused for HIPAA-compliant databases and for databases whose credentials are managed as Vercel Marketplace environment variables. Also refused for a database with Protect Credentials enabled: its new password is shown only once, which this tool never does, so it would be lost; reset it in the Upstash console. The new credentials are not in the result: fetch them with redis_get_database and include_credentials: true. Confirm with the user before calling.
Lists backups of an Upstash Redis database.
Creates a manual backup of an Upstash Redis database.
PERMANENTLY deletes an Upstash Redis database and all of its data. This cannot be undone.
Runs Redis commands directly on an Upstash Redis database over its REST API. No tokens needed — credentials are resolved server-side and never exposed. Not available for a database with Protect Credentials enabled (is_password_protected in redis_get_database): Upstash keeps no password for it. Each command is an array of strings, e.g. [["SET","key","value"],["GET","key"]]. One command runs directly; several run as a pipeline. Note for SCAN: reuse the returned cursor, and stop to ask the user if results get large.
Gets the Redis Insights series of a database, as the Upstash console's Insights tab shows them: latency percentiles (overall, read, write, command, Lua, replication, wait), throughput, bandwidth, disk, expired entries and replication lag, for the whole database and per region (or one replica). Also counters over the period (throttled commands, auth failures, over-size requests, undeliverable messages, Lua executions, failures, timeouts and memory-limit hits, REST commands, connections opened), each metric's mean now against the window before, and anomalies the backend detected (start, peak, baseline and change, heaviest first). Start with anomalies and counters when asked why a database is slow or failing. `metrics` trims the per-metric series, which are most of the response. Needs Prod Pack (or a Pro or Enterprise plan): without it the API answers 404 "insights require Prod Pack"; redis_set_prod_pack turns it on.
Gets where a Redis database's traffic comes from and how it is served: the client networks the proxies sampled (masked prefixes, cloud provider and region, share), the SDKs, platforms and runtimes clients report with their retry rate, routes from entry region to serving region with requests, connections, bytes, errors and whether they cross regions, the entry regions by share, the cross-region share of bytes, and REST vs. Lua command counts. Use it to find clients far from the database, or traffic served cross-region. Needs Prod Pack (or a Pro or Enterprise plan): without it the API answers 404 "insights require Prod Pack"; redis_set_prod_pack turns it on.
Lists the QStash users in the authorized account scope, one per region. Each region's REST tokens, and with `region` ("eu" or "us") that region's request signing keys ({ current, next }, fetched live), are included only when include_credentials is true and the connection is read-write; on a read-only connection they are omitted. The REST base URL for a region is https://qstash-<region>.upstash.io (e.g. qstash-us-east-1.upstash.io).
Gets usage statistics of a region's QStash user, which QStash and Workflow share. daily_requests has one point per day of the current month (y: QStash messages, workflow_message: the Workflow share of them, workflow_run: Workflow runs), as do daily_billings (cost) and daily_bandwidths; days still to come in the month are zeros. daily_qstash_messages (delivered, failed, retry, error, canceled, total) and daily_workflow_messages (success, failed, canceled, total) are today's running counts by outcome, sampled across `period` and reset at 00:00 UTC, so their last point is today so far. Also global parallelism over the period and the DLQ size. `service` keeps only one side's outcome series. With refresh, the API recomputes the cached figures first.
Moves a region's QStash user to another plan: pay-as-you-go (billed per message) or a fixed monthly tier. QStash and Upstash Workflow share one QStash user per region, so this covers both. Prices: https://upstash.com/pricing/qstash.md (Workflow: https://upstash.com/pricing/workflow.md). On the pricing page "Pay as You Go" is payg, "Fixed 1M" is fixed_1m and "Fixed 10M" is fixed_10m. The current plan is type and reserved_type in qstash_list_users. The plan can change at most once an hour. This changes what the account is billed: tell the user the price from the pricing page and get their confirmation before calling.
Enables or disables Prod Pack on a region's QStash user, a monthly add-on for pay-as-you-go and fixed plans that adds an uptime SLA, encryption at rest, SOC-2 compliance and Prometheus/Datadog metrics. QStash and Upstash Workflow share one QStash user per region, so this covers both. Prices: https://upstash.com/pricing/qstash.md (Workflow: https://upstash.com/pricing/workflow.md). Only accounts with a payment method can enable it, and asking for the state it is already in fails with "Prod Pack is already enabled/disabled". This changes what the account is billed: tell the user the price from the pricing page and get their confirmation before calling.
Sets the monthly spending cap of a region's pay-as-you-go QStash user; fixed plans have none. Once the month's cost reaches the cap the bill stops growing and the user is rate limited. 0 removes the cap. Changing the budget, including to 0, lifts an active rate limit right away. A non-zero cap must be above what the user has already cost this month, and setting the value it already has fails with "budget already set". The current cap is budget in qstash_list_users. QStash and Upstash Workflow share one QStash user per region, so this covers both. Prices: https://upstash.com/pricing/qstash.md (Workflow: https://upstash.com/pricing/workflow.md). Confirm the amount with the user before calling.
Replaces a region's QStash token and read-only token with new ones. QStash and Workflow share one QStash user per region, so both stop accepting the old tokens from that moment: every app publishing with QSTASH_TOKEN, and every Workflow client, needs the new one. The request signing keys are not changed, so receivers verifying signatures keep working. The new tokens are not in the result: fetch them with qstash_list_users and include_credentials: true. Confirm with the user before calling.
Publishes a message to a destination URL via QStash. No tokens needed — the region's QStash token is resolved server-side.
Lists QStash schedules in a region.
Manages a QStash schedule: create (destinationUrl + cron required), get, delete, pause or resume (scheduleId required).
Gets flow-control state: rate/parallelism info for a flow-control key, or the account's global parallelism when key is omitted.
Manages a flow-control key: pause, resume, pin (payload = pin options JSON), unpin (payload = unpin options JSON) or reset_rate.
Operates on a Workflow run. To inspect a run by ID (its state, steps and errors, whether it has finished or not), use logs_list with service workflow and workflowRunId instead. get_steps is the narrower view: the live step state of a run that is still in progress. For a run that has finished or been cancelled, get_steps falls back to that run's log entry and says so. cancel asks QStash to stop the run and is asynchronous: the run moves to RUN_CANCELED in logs_list (service workflow) after a short delay, and the cancel call itself does not confirm that a run with this ID existed. Check logs_list, not get_steps, to verify a cancel.
Lists delivery/run logs for QStash messages or Workflow runs (service picks which), newest first. Paginated via cursor. This is the way to inspect a Workflow run by ID, whether it has finished or is still running: pass service workflow and workflowRunId, and the entry holds the run's state, its steps and their error bodies, in one call. workflowRunId, workflowUrl, state, workflowCreatedAt and label filter Workflow runs and are refused for service qstash; count works for both.
Lists the dead-letter queue for QStash messages or Workflow runs (service picks which). Paginated via cursor.
Manages a dead-letter-queue entry: get or delete (QStash and Workflow), restart or resume (Workflow only).
Lists the Upstash Vector indexes or Search databases in the authorized account scope. Never includes tokens — call index_get with include_credentials for one of them.
Gets details of one Vector index or Search database (endpoint, models, limits, usage). Its REST tokens are included only when include_credentials is true and the connection is read-write; on a read-only connection they are omitted (get them from the Upstash console).
Gets usage statistics of one Vector index or Search database: queries and updates today and this month, storage, bandwidth and cost this month, queries and updates per day, throughput and latency (mean and p99) over the period, and document count and data size over time. Search databases add rerank and input-enrichment figures.
Creates a Vector index or a Search database and returns it. Its REST tokens are included only when include_credentials is true — set it when the user is going to configure an app with it; they can also be fetched later with index_get. Search takes only name, region and plan — its embedding, reranking and enrichment models are fixed by the service, and its named indexes are created implicitly by the first search_upsert. Vector takes the rest: dimensions come from the embedding model when one is given, so pass dimensionCount only for an index you will supply your own vectors to; a SPARSE index takes neither and is described by sparseEmbeddingModel alone; a HYBRID index takes both models or neither. Plans and prices (Search is billed as Vector): https://upstash.com/pricing/vector.md; when the user picks fixed, confirm its monthly price with them first.
Moves a Vector index or a Search database to another plan: payg (billed per request) or fixed (a flat monthly price). Search is billed as Vector, so one pricing page covers both: https://upstash.com/pricing/vector.md — its "Pay as You Go" is payg and "Fixed" is fixed; Pro is sold by sales. The current plan is type in index_get. Only an index already on a paid plan can switch; the API refuses a free one. This changes what the account is billed: tell the user the price from the pricing page and get their confirmation before calling.
Resets the REST token and read-only token of a Vector index or a Search database. Every client still using the old ones fails from that moment, so the user has to update their apps' environment variables. The new tokens are not in the result: fetch them with index_get and include_credentials: true. Confirm with the user before calling.
PERMANENTLY deletes an entire Vector index or Search database, everything stored in it and its credentials. This cannot be undone. To empty one while keeping it, use index_reset; to remove a single namespace or named index, use index_delete_namespace.
Gets runtime info: total and pending document counts, index size, and a per-namespace breakdown. For Search those namespaces are its named indexes, with their document counts.
Lists the namespaces of a Vector index — or, for a Search database, its named indexes, which are the same thing. This is what search.listIndexes() calls.
Fetches documents by ID. Payload e.g. {"ids":["a","b"],"includeMetadata":true}, or {"prefix":"doc-","includeMetadata":true} to match an ID prefix.
Iterates through the documents of a namespace, a page at a time. Payload e.g. {"cursor":"0","limit":100,"includeMetadata":true}; reuse the returned cursor for the next page, and stop to ask the user if the results get large.
Deletes documents from a namespace, leaving the namespace and the index in place. Payload e.g. {"ids":["a","b"]}, {"prefix":"doc-"} or {"filter":"..."}. To empty a namespace entirely use index_reset; to delete the index itself use index_delete.
PERMANENTLY deletes every document in a namespace, leaving the empty namespace behind. Set allNamespaces to empty the whole index instead. This cannot be undone.
Updates one existing document in place, without re-sending the rest of it. Payload e.g. {"id":"a","metadata":{...},"metadataUpdateMode":"patch"} to merge into the existing metadata, or "overwrite" (the default) to replace it; may also carry vector, sparseVector or data to re-embed. Does nothing if the id does not exist — use vector_upsert or search_upsert to create.
Renames a namespace — for a Search database, one of its named indexes. The new name must not already be in use, and the default namespace cannot be renamed.
PERMANENTLY deletes a namespace and everything in it — for a Search database, one of its named indexes. This cannot be undone. The default namespace cannot be deleted; empty it with index_reset instead.
Queries a Vector index by vector similarity. No tokens needed. Payload per the Vector REST API, e.g. {"vector":[...],"topK":10,"includeMetadata":true} — or with useData=true, {"data":"text to embed","topK":10} for embedding-model indexes. For a Search database use search_query instead.
Upserts vectors into a Vector index. Payload e.g. [{"id":"a","vector":[...],"metadata":{...}}] — or with useData=true, [{"id":"a","data":"text to embed"}]. For a Search database use search_upsert instead.
Runs a full-text and semantic search over one named index of a Search database. No tokens needed. Payload per the Search REST API, e.g. {"query":"space odyssey","limit":5,"reranking":true}.
Upserts documents into a named index of a Search database (server-side embedding), creating the named index if it does not exist. Payload e.g. [{"id":"movie-1","content":{"title":"Star Wars"},"metadata":{...}}].
Manages Upstash Boxes — sandboxed cloud containers with a shell, a filesystem and an optional headless browser. Actions: create (set browser=true to make box_browser usable), list (optionally filtered by label or status), get, status (cheaper than get, for polling), delete (permanent, takes the workspace with it; pass box_id for one box or box_ids for several in one call), pause, resume, fork (copies an idle or paused non-ephemeral box), reset (wipes the workspace back to a fresh box; the id survives). Every action except create and list needs box_id (delete accepts box_ids instead). There is no delete-everything: to clear an account, list first and pass the ids you mean. Ephemeral boxes need no paid plan and are cleaned up when their TTL expires; keep-alive boxes require one. size and keep_alive set what a box costs and cannot be changed after create; prices per size: https://upstash.com/pricing/box.md. Confirm with the user before creating a keep-alive box, which is billed monthly.
Runs a shell command inside a box, waits for it to finish, and returns its exit code and output. Use it for file operations, package installs, builds, tests — anything a shell does. For repository work (clone, commit, push, pull request) use box_git, which also puts the GitHub credentials into the box. The command is an argv array, e.g. ['bash', '-c', 'ls -la']; an inline program is one too: ['node', '-e', code], ['python3', '-c', code] or ['npx', 'tsx', '-e', code], and content written with ['sh', '-c', 'printf %s "$1" > "$2"', 'sh', content, path] needs no quoting. `folder` defaults to /workspace/home, the workspace root; a clone sits at /workspace/home/<repo name>. To start something long-running (a dev server, say) without blocking, detach it inside the shell: ['sh', '-c', '( my-server > server.log 2>&1 & )']. A paused box is resumed first. Read-only OAuth connections cannot run commands: the box API refuses them with 403.
Drives the headless Chromium in a box created with browser=true. Actions: goto (navigate to url and return the page), content (read the current page as title/url/text/links), screenshot (PNG of the page — returned as an image unless path is given, in which case it is saved into the box at that path instead), tabs (list the open tabs), tab_new (open a tab, optionally at url), tab_close (needs tab), live_view (a view-only page a person can open to watch the tab live — frames flow out, no input goes in, so hand the URL to the user rather than trying to click in it). box_id is required for every action.
Runs git inside a box. Authentication comes from the GitHub installation linked to the Upstash account — the tool takes no token, and a private repo works only if that installation can see it. Actions: clone (needs repo), status, diff, commit (needs message), checkout (needs branch), push, create_pr (needs title), create_issue (needs title). Anything else git does (add, log, rebase) is a box_exec command such as ['git', 'log', '-1']. Clone with this tool rather than with git in box_exec: clone is what puts the GitHub credentials into the box, and without them push and create_pr fail with a 500. A clone lands at /workspace/home/<repo name>; pass that as `folder` on every other action, since the default is the workspace root, which is not a repository. create_pr opens the pull request for the branch as it exists on the remote and pushes nothing itself, so push first, and give push the branch name: without one the API pushes to a branch named after the box. Read-only OAuth connections are refused with 403 on the actions that write (clone, commit, checkout, push, create_pr, create_issue).
Manages public preview URLs for ports inside a box, so a service running in it is reachable from the internet. Actions: create (needs port; basic_auth or bearer_token add a generated credential, which is returned once and only here), list, delete (needs port). box_id is required for every action.
Reads a box's timestamped log entries — system, user and agent sources — which is how to find out what happened inside it. Filterable by source, level, free-text search and a timestamp window.
Inspects a box's run history — agent prompts, shell executions and browser runs — with their status, output, token usage and cost. Actions: list, get (needs run_id), cancel (needs run_id; only a run that is still running can be cancelled). box_id is required for every action.
Manages box snapshots — full filesystem copies a new box can be built from. Actions: create (needs box_id), list (one box's snapshots, needs box_id), list_all (every snapshot in the account), delete (needs box_id and snapshot_id), restore (needs snapshot_id; creates a NEW box from the snapshot and leaves the original alone, inheriting the snapshot's model and runtime unless they are overridden).
Manages Box API keys for the authorized account scope, the credential the Box SDK, CLI and deployed apps use. Actions: list (metadata only: id, name, prefix, never the secret), create (optional name; returns the secret once, so surface it to the user to store), delete (needs api_key_id; anything still using the key stops working immediately). A key is account-scoped and independent of this connection: it keeps working after the OAuth grant that created it is revoked, so tell the user to delete it, here or in the Upstash console, once it is no longer needed. Read-only OAuth grants get 403 on create and delete.
Cron schedules that run a shell command or an agent prompt inside a box on a UTC cron expression. Actions: create (needs cron and either command or prompt), list, get, update, pause, resume, delete (the last five need schedule_id). update changes only the fields given, so a new cron leaves the command alone. timeout is milliseconds; 0 clears it on update. Read-only OAuth connections are refused with 403 on the actions that write.
Changes a running box's configuration. Actions: get (model, MCP servers and enabled skills; labels are on box_manage get); set_model (needs model); add_label and remove_label (need label); add_skill and remove_skill (need skill, as owner/repo/skill-name); add_mcp_server (needs mcp_server) and remove_mcp_server (needs name); set_network_policy (needs network_policy); set_git_identity (needs git_user_name and git_user_email); get_init_command, set_init_command (needs init_command) and delete_init_command, which apply to keep-alive boxes only. Size, browser and keep_alive are fixed at create time. Read-only OAuth connections are refused with 403 on the actions that write.
Account-level environment variables, merged into every box created afterwards; a box's own env_vars win for the same key, and a box that already exists is not changed. Actions: list (values come back masked), set (needs key and value), set_all (needs env_vars, and replaces the whole set), delete (needs key). Not a secrets store: a value set here is visible inside every future box. Read-only OAuth connections are refused with 403 on the actions that write.
Resource and token usage for a box. Actions: current (CPU, memory and disk right now), history (a time series; range such as 1h or 24h, step such as 1m), tokens (token counts and cost over the last days), steps (the agent's commits, one per prompt, newest first), step_diff (needs sha; the diff one step made).
Account-wide views across every box. Actions: summary (each active box with its cost; status deleted lists the deleted ones instead), billing (this month's token and compute totals), logs (log lines from all boxes; limit, offset, level, source, search, start_time and end_time filter them).
Lists, gets, creates or deletes Upstash Blob buckets — object storage an agent can upload files to and link to afterwards. Blob has no plans to choose: storage, operations and bandwidth are free up to a monthly allowance and pay-as-you-go above it (https://upstash.com/pricing/blob.md). Actions: list (every bucket in the authorized account scope), get (needs bucket_id; with include_credentials the result also carries the bucket's `token`, the value `@upstash/blob` reads as UPSTASH_BLOB_TOKEN), stats (needs bucket_id; storage, bandwidth, operations and cost per day and per month, collected hourly, so today's row is partial), create (needs name), delete (needs bucket_id; permanent, and refused while the bucket still holds objects — empty it with blob_object delete first), reset_token (needs bucket_id; rotates the bucket token: the current token stops working at once, so apps need the new UPSTASH_BLOB_TOKEN from get with include_credentials; confirm with the user first). A public bucket serves its objects at a permanent URL under public_host, which is what you want for a link that has to keep working, such as an image embedded in a PR body; a private bucket has no public host and its objects are reachable only through short-lived signed URLs. The token is returned only by get with include_credentials on a read-write connection; on a read-only connection it is omitted regardless, and list, create, delete and reset_token never return it.
Mints presigned PUT URLs for paths in a Blob bucket, so files are uploaded straight to storage from wherever they already are — a `curl` inside a box, a CI job — without their bytes passing through this server. Send the returned `headers` verbatim with the PUT: they are part of the signature, so a changed, dropped or added header is a 403 from storage. A URL lives at most 10 minutes, so mint it immediately before uploading rather than up front. On a public bucket each file also comes back with `public_url`, the permanent link to use once the upload succeeds (in a PR body, say); a private bucket has none. The result's `curl_example` is the first file's real command line.
Mints short-lived presigned GET URLs for objects in a Blob bucket, so their bytes are downloaded straight from storage — a `curl` inside a box, a browser — without passing through this server. This is the way to read a **private** bucket, whose objects have no public link; on a public bucket the permanent `public_url` works too and is returned alongside. The URLs only read, so they are available on read-only connections. A URL lives at most 10 minutes; set `download_as` to have storage serve the object as an attachment with that filename. A missing object is a 404 from storage when the URL is fetched, not an error here.
Lists or deletes objects in an Upstash Blob bucket — their paths, sizes and links, never their bytes. Actions: list (needs bucket_id; optional prefix and cursor; up to 1000 objects per page, and a cursor in the result means more follow — pass it back to continue), delete (needs bucket_id and paths, up to 1000 exact keys; permanent, and a path that is already gone counts as deleted). To empty a bucket before blob_bucket delete, list a page, delete its paths, repeat until list comes back empty. Never returns bucket tokens.
Opens the Upstash console: an interactive view of the user's Redis databases and keys, QStash and Workflow schedules, logs and DLQs, Vector and Search indexes, Boxes and Blob buckets. Call it when the user asks to see, browse or open their Upstash resources rather than for a specific answer. To show one resource, pass product and resource (and a tab): the console opens on it, and the user can still navigate from there.
Console only: one SCAN page of a Redis database with each key's type and TTL.
Console only: one Redis key's type, TTL, size and a bounded read of its value.
One endpoint, the same key, whichever client you use.
~/Library/Application Support/Claude/claude_desktop_config.json (Mac) · %APPDATA%\Claude\claude_desktop_config.json (Windows)
Replace API_KEY with your own key.
Already have an "mcpServers" section in your config? Just add the server entry inside it.
Discovery, routing, credentials, tool scoping and execution logs all happen at the gateway→connections stay ACTIVE with no work from you
Upstash MCP runs through a gateway that holds the credentials, scopes the access and records every call.
Managed auth, hosted MCP servers, and every Upstash MCP tool your agent needs.
Free to start.