# QStash MCP

> QStash (Serverless Message Queue) MCP Server lets your AI client manage background tasks and message delivery directly through natural language. Publish delayed webhooks, create reliable FIFO queues with `upsert_queue`, schedule recurring jobs (`list_schedules`), and audit failed messages in the Dead Letter Queue (DLQ). Stop relying on brittle cron jobs; run durable, serverless messaging workflows from your IDE.

## Overview
- **Category:** developer-tools
- **Price:** Free
- **Tags:** message-queue, serverless, webhooks, upstash, qstash, background-jobs

## Description

**Getting Started and Managing Queues**

When you need reliable background processing that doesn't rely on brittle cron jobs, this server connects your AI client directly to QStash. You manage the entire message lifecycle—from scheduling to failure recovery—all through natural language commands.

You can check what queues you’ve set up using `list_queues`, or create a new one or modify an existing queue's parameters and parallelism with `upsert_queue`. If you need to view the current status of any specific line, use `get_queue`.

For managing topics (URL Groups), you can list all configured groups using `list_url_groups`, then check a group’s endpoints configuration via `get_url_group`; if you gotta build one or update its destinations, use `upsert_url_group`. You can also remove specific endpoints from a topic using `remove_endpoints`.

**Sending and Controlling Messages**

You don't just send messages; you control them. To dispatch a single message with custom timing, retries, or deduplication rules, use `publish_message`. If you gotta blast out multiple destinations at once, `batch_messages` sends several messages in one request. You can also cancel specific pending transmissions using `cancel_message`, or stop a whole bunch of them by filtering and criteria for `bulk_cancel_messages`.

To ensure tasks run in strict order (FIFO) or with controlled concurrency, use `enqueue_message`. If you need to send messages to multiple locations without defining full topic groups first, you can also use `batch_messages`.

**System State and Auditing Failure**

When things go wrong, your data doesn't just vanish. Failed transmissions land in the Dead Letter Queue (DLQ). You can see a list of every message that failed delivery using `list_dlq`, grab the full details on one specific failure with `get_dlq_message`, or manually try sending it again by calling `retry_dlq_message`. If you know something's junk, you can remove one item from the DLQ with `delete_dlq_message`, or wipe out every message in the entire queue at once using `bulk_delete_dlq`.

To keep your system running smoothly, you can monitor scheduled jobs by listing them all with `list_schedules`; to check a single job's parameters, use `get_schedule`. You control these jobs directly: pause one with `pause_schedule`, or restart it when needed using `resume_schedule`.

**Advanced System Control and Maintenance**

You can manage the entire system’s throughput. Check how many keys you have configured by running `get_keys`, or review all rate limit settings with `list_flow_control_keys`. To get details on a specific key, use `get_flow_control_key`.

If usage gets too high, don't sweat it; you can temporarily suspend a key to prevent overuse using `pause_flow_control`, or reactivate it later with `resume_flow_control`. You can set permanent rules for any rate limit key using `pin_flow_control`, and remove those rules by calling `unpin_flow_control`. If you need to reset the usage counter on a key, use `reset_flow_control_rate`.

For system-wide oversight, check global concurrency limits with `get_global_parallelism`, or review all operational history using `list_logs`; for granular audit data, you can also view historical logs via `list_logs`.

**Putting It All Together: Lifecycle Management**

You control the state of every component. You can halt processing on a designated line with `pause_queue`, or restart it immediately with `resume_queue`. Similarly, if a scheduled job is running too often, you can pause it using `pause_schedule` and resume it later with `resume_schedule`. When you're done testing a queue or topic group, remember that you need to delete the entire resource using `delete_queue`, `delete_url_group`, or cleaning up a background job schedule with `delete_schedule`.

## Tools

### batch_messages
Send multiple messages to various destinations in a single request.

### bulk_cancel_messages
Cancel several pending messages by specifying filters and criteria.

### bulk_delete_dlq
Wipes all messages from the Dead Letter Queue at once.

### bulk_retry_dlq
Retries every single message currently sitting in the DLQ.

### cancel_message
Stops a specific message before it is delivered to its endpoint.

### delete_dlq_message
Removes one specific message from the Dead Letter Queue.

### delete_queue
Permanently deletes an entire message queue.

### delete_schedule
Deletes a scheduled background job entirely.

### delete_url_group
Removes a configured group of endpoints (a topic).

### enqueue_message
Adds a message to a queue, guaranteeing FIFO order or controlled parallelism.

### get_dlq_message
Retrieves the full details of one specific message that failed and landed in the DLQ.

### get_flow_control_key
Gets configuration details for a single rate limit key.

### get_global_parallelism
Retrieves the overall global concurrency settings for your messaging system.

### get_keys
Fetches all QStash signing and access keys.

### get_message
Retrieves details about a message that is currently in flight or undergoing retry.

### get_queue
Gets the current status and configuration of a specific queue.

### get_schedule
Retrieves details about a single scheduled background job.

### get_url_group
Gets the current configuration and endpoints for a specific URL Group.

### list_dlq
Shows a list of all messages that have failed delivery and are waiting in the Dead Letter Queue.

### list_flow_control_keys
Lists every rate limit key configured across your messaging system.

### list_logs
Retrieves a historical record of all QStash events and operational logs.

### list_queues
Provides an overview listing every message queue you have set up.

### list_schedules
Lists all currently active and paused background job schedules.

### list_url_groups
Lists all topic groups of endpoints you've configured.

### pause_flow_control
Temporarily suspends a specific rate limit key to prevent service overuse.

### pause_queue
Halts all message processing for a designated queue until you resume it.

### pause_schedule
Stops a scheduled background job from running on its set trigger time.

### pin_flow_control
Sets permanent configuration rules for a rate limit key.

### publish_message
Sends a message to a destination URL or URL Group, setting custom timing and retries.

### remove_endpoints
Takes specified endpoints out of an existing URL Group (topic).

### reset_flow_control_rate
Resets the current usage counter for a rate limit key.

### resume_flow_control
Reactivates a flow control key that was previously paused.

### resume_queue
Restarts message processing for a queue that had been paused.

### resume_schedule
Resumes a scheduled background job, allowing it to run again on its next trigger time.

### retry_dlq_message
Attempts to resend a specific message that failed and landed in the DLQ.

### unpin_flow_control
Removes permanent configuration rules from a rate limit key.

### upsert_queue
Creates a new queue or updates an existing one with defined parameters like parallelism.

### upsert_url_group
Creates a new topic group (URL Group) or updates an existing one's endpoints.

## Prompt Examples

**Prompt:** 
```
Publish a POST request to https://api.example.com/webhook with a 1-hour delay.
```

**Response:** 
```
I've published the message to your destination. It is scheduled for delivery in 1 hour. Message ID: msg_82391.
```

**Prompt:** 
```
List all my current QStash queues and their status.
```

**Response:** 
```
I found 3 queues: 'image-processing' (Active), 'email-service' (Paused), and 'webhooks-main' (Active).
```

**Prompt:** 
```
Check the Dead Letter Queue and retry the message with ID msg_123.
```

**Response:** 
```
I've located the message in the DLQ and successfully triggered a retry for msg_123.
```

## Capabilities

### Publish Delayed Webhooks
Send messages to a destination URL or group, scheduling when it should fire, including setting up retries and preventing duplicate sends.

### Control Message Queues
Create, update, or list queues (`upsert_queue`, `list_queues`) to ensure tasks run in order (FIFO) with controlled resource parallelism.

### Manage Scheduled Jobs
List and control recurring background jobs using cron-based schedules; you can pause or resume them directly.

### Audit Dead Letter Queues (DLQ)
Inspect failed messages via `list_dlq` and manually retry specific failures with `retry_dlq_message`, ensuring no data loss.

### Monitor Flow Control
Check and adjust rate limits across your messaging system using tools like `get_flow_control_key` and `list_flow_control_keys` to prevent resource overload.

## Use Cases

### Handling a payment webhook failure.
A user needs to process a post-payment event. Instead of letting the API fail and losing the data, they prompt their agent: 'Schedule this payment confirmation hook.' The agent uses `publish_message`, setting up three retries over 30 minutes. If all attempts fail, the message lands in the DLQ for manual inspection using `list_dlq`.

### Migrating a monolithic task system.
An architect needs to break up old background jobs into reliable queues. They use `upsert_queue` multiple times, creating dedicated FIFO queues for 'image-processing' and 'email-service'. Then they tell the agent to monitor them using `list_queues`, validating that parallelism is limited correctly.

### Auditing a production outage.
An ops engineer notices processing stopped. They ask their agent: 'What queues are paused, and what failed messages do we have?' The agent runs `list_queues` and then `list_dlq`. The engineer uses `get_dlq_message` to confirm the payload of a single bad message before triggering a mass retry with `bulk_retry_dlq`.

### Testing rate limit impact.
A developer wants to test if their new feature overwhelms an external API. They run `get_flow_control_key` first to see the current limits, then use `pause_flow_control` before running a high-volume test. Once done, they use `resume_flow_control` and `reset_flow_control_rate`.

## Benefits

- Guaranteed delivery paths: Instead of just publishing a webhook, you use `publish_message` to set specific retries and delays. If the first attempt fails, the system handles the backoff, so your code doesn't need complex retry logic.
- Full state visibility: You can list every queue (`list_queues`) and get detailed status reports for any single one using `get_queue`. This means you see if a service is backed up or paused immediately.
- Zero data loss management: Failed messages don't vanish. Use `list_dlq` to audit them, and when you confirm the fix, use `retry_dlq_message` to put the message back on track. It’s built-in failure recovery.
- Concurrency control: If one service gets hammered, it can slow down all your services. Tools like `get_global_parallelism` let you monitor and adjust rate limits (`reset_flow_control_rate`) before hitting a hard wall.
- Automated job lifecycle: Stop worrying about cron jobs failing silently. You list schedules with `list_schedules`, and if something breaks, you can pause or resume the job directly via the agent.

## How It Works

The bottom line is: it turns complex API calls for message queuing into natural language commands that execute reliably from anywhere.

1. First, you subscribe to the server and input your unique QStash Token from the Upstash Console.
2. Next, you tell your AI client what you want done—for example, 'Schedule a webhook for 2 hours from now' or 'List all queues'.
3. The agent executes the necessary tools (`publish_message`, `list_queues`) and reports the result back to your chat, giving you confirmation and IDs.

## Frequently Asked Questions

**How do I schedule a message using publish_message?**
You specify the target destination URL or URL Group, and then define the delay time. The agent handles the formatting of that request for you, letting you set precise timing rules.

**What is the difference between list_queues and get_queue?**
`list_queues` gives you a high-level inventory—a list of every queue name. `get_queue` dives deep into one specific queue, providing its current status, configuration details, and capacity metrics.

**If I use bulk_retry_dlq, does it delete the message after retrying?**
No. The `bulk_retry_dlq` tool just attempts to resend all messages in the DLQ. If they fail again, they will remain or move to another failure state; you still need to monitor the logs.

**Can I pause a queue using the agent?**
Yes. You prompt your agent with the queue name and ask it to pause the processing. It executes `pause_queue` and immediately confirms that message intake has stopped for that specific service.

**How do I ensure messages are processed in order?**
You must use `enqueue_message` with the appropriate parameters to guarantee FIFO (First-In, First-Out) processing. This ensures sequential execution where order matters.

**What happens if I exceed my rate limit when using `publish_message`?**
The system handles excess traffic by throttling your request automatically. You can check and adjust these limits by running `list_flow_control_keys`. This ensures service stability during high-volume sends.

**If I call `delete_queue`, are the messages currently waiting in that queue also deleted?**
Yes, calling `delete_queue` removes all associated message data and records from that queue. Use this tool with caution; it’s permanent cleanup.

**How can my agent retrieve the necessary signing keys before calling tools like `enqueue_message`?**
Your AI client must first use `get_keys`. This action provides the required credentials and signatures needed for all subsequent write operations, securing your workflow.

**How can I schedule a message to be sent later?**
Use the `publish_message` tool and provide the `delay` parameter (e.g., '10m' for 10 minutes) or a `not_before` Unix timestamp.

**What happens if a message fails all retry attempts?**
The message is moved to the Dead Letter Queue (DLQ). You can use `list_dlq` to find it and `retry_dlq_message` to attempt delivery again.

**Can I manage recurring tasks like cron jobs?**
Yes! You can use `list_schedules` to see existing ones, and `pause_schedule` or `resume_schedule` to control them.