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

# Runtime Adapters

> Reference for Redop's portable fetch handler and Bun, Node, Cloudflare, and Vercel adapters.

Redop is runtime-agnostic. Define the server once, then choose how to host it:

* Bun: `.listen()` starts a long-running HTTP server (default local DX)
* Cloudflare / Vercel / Node: `app.handler()` plus a thin adapter

## `app.handler(opts?)`

Returns a Web-standard fetch function:

```ts theme={null}
type HttpFetch = (
  request: Request,
  runtime?: {
    waitUntil?: (promise: Promise<unknown>) => void;
    disableIdleTimeout?: (req: Request) => void;
  }
) => Promise<Response>;
```

`HandlerOptions` accepts the HTTP knobs from `ListenOptions` without bind fields: `path`, `health`, `cors`, `debug`, `sessionTimeout`, `listCache`, `maxBodySize`.

## Package exports

| Export                      | Purpose                                   |
| --------------------------- | ----------------------------------------- |
| `@redopjs/redop`            | Full API + Bun `.listen()`                |
| `@redopjs/redop/cloudflare` | `cloudflare(app)` Workers handler         |
| `@redopjs/redop/vercel`     | `vercel(app)` / `vercelEdge(app)`         |
| `@redopjs/redop/node`       | `listenNode`, `nodeListener`, `nodeFetch` |

Compat aliases: `toCloudflare`, `toVercel`, `toVercelEdge`, `toNodeListener`, `toNodeHandler`, `toNodeFetch`.

## After-response scheduling

| Runtime                 | How `afterResponse` is kept alive                                           |
| ----------------------- | --------------------------------------------------------------------------- |
| Bun / Node (long-lived) | `queueMicrotask`                                                            |
| Cloudflare Workers      | `ctx.waitUntil(...)` via `cloudflare`                                       |
| Vercel / Edge           | pass `waitUntil` from `@vercel/functions` into `vercel(app, { waitUntil })` |

## Capability matrix

| Capability                      | Bun `.listen()` | Node | Cloudflare      | Vercel / Edge   |
| ------------------------------- | --------------- | ---- | --------------- | --------------- |
| Stateless MCP `2026-07-28`      | yes             | yes  | yes             | yes             |
| Reliable `afterResponse`        | yes             | yes  | via `waitUntil` | via `waitUntil` |
| Legacy sessions + GET SSE       | yes             | yes  | limited         | limited         |
| Long `subscriptions/listen` SSE | yes             | yes  | hard            | hard            |

## Examples

```ts theme={null}
// Cloudflare
import { Redop, cloudflare } from "@redopjs/redop/cloudflare";
export default cloudflare(app);

// Vercel
import { Redop, vercel } from "@redopjs/redop/vercel";
import { waitUntil } from "@vercel/functions";
export default vercel(app, { waitUntil });

// Node
import { Redop } from "@redopjs/redop";
import { listenNode } from "@redopjs/redop/node";
listenNode(app, { port: 3000, hostname: "0.0.0.0" });
```

On Cloudflare / Vercel, import `Redop` from the adapter entry (`@redopjs/redop/cloudflare` or `@redopjs/redop/vercel`) so the worker bundle does not pull the Bun `.listen()` path.
