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.
Use middleware when you need to wrap execution for a request. Use a plugin when you want to bundle middleware, hooks, tools, resources, or prompts into one reusable unit.
If the behavior is analytics, logging, or metrics that should happen after the response is already written, prefer onAfterResponse(...) inside the plugin over onAfterHandle(...).
Build middleware first when the behavior is request-scoped
Middleware is the fastest path when you want to:
- block or allow execution
- decorate
ctx
- time calls
- wrap
next()
import { middleware, Redop } from "@redopjs/redop";
const requestIdPrefix = middleware(async ({ ctx, next }) => {
(ctx as Record<string, unknown>).shortRequestId = ctx.requestId.slice(0, 8);
return next();
});
new Redop({ serverInfo: { name: "middleware-demo" } })
.middleware(requestIdPrefix)
.tool("hello", {
handler: ({ ctx }) => ({
requestId: ctx.requestId,
shortRequestId: (ctx as Record<string, unknown>).shortRequestId,
}),
});
Build a plugin when you want a reusable package of behavior
definePlugin(...) is the cleanest path when you want to share behavior across multiple servers.
import { definePlugin, Redop } from "@redopjs/redop";
const timingPlugin = definePlugin({
name: "timing",
version: "0.1.0",
description: "Measure tool duration",
setup() {
return new Redop()
.onBeforeHandle(({ ctx }) => {
(ctx as Record<string, unknown>).startedAt = performance.now();
})
.onAfterHandle(({ ctx, tool }) => {
const startedAt = (ctx as Record<string, unknown>).startedAt as number | undefined;
if (startedAt == null) return;
const ms = +(performance.now() - startedAt).toFixed(2);
console.log(`[timing] ${tool} finished in ${ms}ms`);
});
},
});
new Redop({ serverInfo: { name: "plugin-demo" } }).use(timingPlugin({}));
A plugin can ship more than middleware
A plugin can register:
- middleware
- hooks
- tools
- resources
- prompts
import { definePlugin, Redop } from "@redopjs/redop";
const healthPlugin = definePlugin({
name: "health",
version: "0.1.0",
setup() {
return new Redop().tool("health", {
description: "Return service health",
handler: () => ({ ok: true, ts: Date.now() }),
});
},
});
Rule of thumb
- choose middleware for one request-layer behavior
- choose a plugin when you want a reusable bundle
- use
definePlugin(...) when you want a stable, publishable plugin API
See also