npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@redopjs/redop

v0.1.10

Published

Runtime-agnostic TypeScript framework for production MCP servers

Readme

@redopjs/redop

Deploy to Railway Deploy to Fly.io Docs: Deploy to Production

Redop is a runtime-agnostic TypeScript framework for building production MCP servers with typed tools, resources, prompts, middleware, hooks, plugins, and HTTP or stdio transports.

Define the server once, then deploy on Bun, Node, Cloudflare Workers, or Vercel.

Install

bun add @redopjs/redop zod

If you want a ready-to-run starter instead:

bun create redop-app my-redop-app

Quick start

import { Redop } from "@redopjs/redop";
import { z } from "zod";

new Redop({
  serverInfo: {
    name: "my-mcp-server",
    version: "0.1.0",
    description: "Search docs and return answers",
  },
})
  .tool("search_docs", {
    description: "Search docs",
    inputSchema: z.object({
      query: z.string().min(1),
    }),
    handler: ({ input }) => ({
      query: input.query,
      results: [],
    }),
  })
  .listen(3000);

For a hosted server, the MCP endpoint will be available at http://localhost:3000/mcp.

What Redop gives you

  • Typed tool handlers with schema-driven parsing.
  • Resources and prompts alongside tools in one server.
  • Global middleware and lifecycle hooks across tools, resources, and prompts.
  • Reusable plugins with typed request context.
  • Explicit feature-module composition with .use(...).
  • HTTP and stdio transports from one API, plus portable fetch adapters for Cloudflare, Vercel, and Node.
  • MCP 2026-07-28 support: stateless HTTP, server/discover, header routing, list cache hints, MRTR (requireInput), and the tasks extension.
  • Post-response hooks for analytics, logging, and other best-effort work.
  • Built-in auth and logging plugins.

Core ideas

Redop is built around a small set of explicit primitives:

  • new Redop(...) creates the server.
  • .tool(...) registers an MCP tool.
  • .resource(...) registers a readable MCP resource.
  • .prompt(...) registers reusable prompt material.
  • .middleware(...) wraps execution.
  • .use(...) composes feature modules or plugins.
  • .listen(...) starts HTTP or stdio transport (Bun default for HTTP).
  • .handler(...) returns a portable fetch handler for Cloudflare, Vercel, Node, and similar runtimes.

Redop does not rely on file-system routing. You compose MCP surface area directly in code.

Runtime adapters

Bun .listen() is the default local HTTP path. For other runtimes:

import { Redop, cloudflare } from "@redopjs/redop/cloudflare";
import { vercel } from "@redopjs/redop/vercel";
import { listenNode } from "@redopjs/redop/node";

const app = new Redop({ serverInfo: { name: "demo", version: "0.1.0" } });

// Cloudflare Workers
export default cloudflare(app);

// Vercel / Edge (pass waitUntil in serverless)
// export default vercel(app, { waitUntil });

// Node.js
// listenNode(app, { port: 3000, hostname: "0.0.0.0" });

Package exports: @redopjs/redop/cloudflare, @redopjs/redop/vercel, @redopjs/redop/node.

Tools, resources, and prompts

Redop supports all three main MCP surface types:

  • Tools for actions and workflows.
  • Resources for readable data addressed by URI.
  • Prompts for reusable prompt material with arguments and messages.

That means one server can expose action-oriented behavior and read-only context from the same composition model.

Typed schemas

Redop keeps runtime parsing and MCP metadata close to the tool definition.

You can define schemas with:

  • Zod
  • Standard Schema-compatible libraries
  • JSON Schema

The same schema definition drives input validation and MCP discovery metadata.

Lifecycle and middleware

Redop exposes a visible execution lifecycle instead of hiding everything in handlers.

For tools, the request flow is:

derive -> onTransform -> schema parse -> onParse ->
onBeforeHandle -> tool.before -> middleware -> handler ->
tool.after -> onAfterHandle -> response written ->
tool.afterResponse -> onAfterResponse

Resources and prompts use the same high-level model, minus schema parsing.

Use this model when you need:

  • auth or request policy in middleware
  • shared setup in derive(...)
  • observability in hooks
  • post-response work in afterResponse(...)

Plugins and typed request context

Plugins in Redop are packaged Redop instances.

They can contribute:

  • middleware
  • lifecycle hooks
  • tools
  • resources
  • prompts

The important part is data flow: plugin middleware can write request-scoped data to ctx, and handlers can read that data later in the same request.

import { definePlugin, Redop } from "@redopjs/redop";

const tenantPlugin = definePlugin({
  name: "tenant",
  version: "0.1.0",
  setup() {
    return new Redop<{ tenantId: string }>().middleware(
      async ({ ctx, request, next }) => {
        const tenantId = request.headers["x-tenant-id"];

        if (!tenantId) {
          throw new Error("Missing x-tenant-id header");
        }

        ctx.tenantId = tenantId;
        return next();
      }
    );
  },
});

new Redop({
  serverInfo: {
    name: "tenant-demo",
    version: "0.1.0",
  },
})
  .use(tenantPlugin({}))
  .tool("whoami", {
    handler: ({ ctx }) => ({
      tenantId: ctx.tenantId,
    }),
  });

Compose larger servers with .use(...)

When your server grows, split it into feature modules.

Each feature folder can export its own Redop instance, and the root server can attach those modules with .use(...).

import { Redop } from "@redopjs/redop";

const notes = new Redop()
  .tool("notes.list", {
    handler: () => ({ notes: [] }),
  })
  .resource("notes://{id}", {
    name: "Note",
    handler: ({ params }) => ({
      type: "text",
      text: JSON.stringify({ id: params.id }),
    }),
  });

const users = new Redop().tool("users.get", {
  handler: ({ input }) => ({
    id: input.id,
    name: "Ada Lovelace",
  }),
  inputSchema: {
    type: "object",
    properties: {
      id: { type: "string" },
    },
    required: ["id"],
  },
});

new Redop({
  serverInfo: {
    name: "app",
    version: "0.1.0",
  },
})
  .use(notes)
  .use(users)
  .listen(3000);

Error handling

Redop resolves errors by MCP operation type:

  • tools/call failures are returned as tool results with isError: true
  • resources/read failures are returned as JSON-RPC errors
  • prompts/get failures are returned as JSON-RPC errors

onError(...) hooks can observe failures for logging, metrics, or tracing, but transport behavior is still normalized by Redop.

Built-in plugins

Redop ships with built-in helpers for common concerns:

  • logger(...)
  • apiKey(...)
  • jwt(...)
  • oauth(...)

These use the same plugin model available to application code.

Transports

Redop supports:

  • HTTP for hosted MCP servers
  • stdio for local or process-based MCP integration

You define the server once and choose the transport at startup.

Local examples

Documentation

  • Docs: https://redop.useagents.site/docs
  • Installation: https://redop.useagents.site/docs/getting-started/installation
  • First server: https://redop.useagents.site/docs/getting-started/first-server
  • Tools: https://redop.useagents.site/docs/documentation/tools
  • Resources: https://redop.useagents.site/docs/documentation/resources
  • Prompts: https://redop.useagents.site/docs/documentation/prompts
  • Plugins: https://redop.useagents.site/docs/documentation/plugins
  • Error handling: https://redop.useagents.site/docs/documentation/error-handling
  • Compose features with use(...): https://redop.useagents.site/docs/guides/compose-features-with-use
  • Build a plugin or middleware: https://redop.useagents.site/docs/guides/build-plugin-or-middleware
  • API reference: https://redop.useagents.site/docs/reference/redop

Deploy

Start with:

  • Railway: https://redop.useagents.site/docs/guides/deploy/railway
  • Fly.io: https://redop.useagents.site/docs/guides/deploy/fly-io
  • Docker: https://redop.useagents.site/docs/guides/deploy/docker
  • Cloudflare Workers: https://redop.useagents.site/docs/guides/deploy/cloudflare
  • Vercel: https://redop.useagents.site/docs/guides/deploy/vercel
  • Node.js: https://redop.useagents.site/docs/guides/deploy/node
  • Runtime adapters: https://redop.useagents.site/docs/reference/runtime-adapters

License

MIT © UseAgents