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 🙏

© 2025 – Pkg Stats / Ryan Hefner

mcp-forge

v0.2.3

Published

A high-level application framework for the Model Context Protocol (MCP)

Readme

mcp-forge

npm version License: MIT TypeScript Node.js

A high-level application framework for the Model Context Protocol (MCP). Think of it as Express.js for building MCP servers.

Why mcp-forge?

Building MCP servers with the raw SDK requires handling low-level protocol details, JSON-RPC messaging, and repetitive boilerplate. mcp-forge provides a clean, fluent API that lets you focus on your tool logic:

import { Forge } from "mcp-forge";
import { z } from "zod";

const forge = new Forge({ name: "my-server", version: "1.0.0" });

forge.tool(
  "get_weather",
  {
    schema: z.object({ city: z.string() }),
    description: "Get weather for a city",
  },
  async ({ city }) => `Weather in ${city}: 72°F, Sunny`
);

forge.start();

Features

  • 🔧 Simple API — Register tools, resources, and prompts with a fluent builder pattern
  • 📦 Plugin System — Create modular, reusable bundles that can be published to npm
  • 🔌 Built-in Middleware — Rate limiting, caching, metrics, logging, retry, timeout, and auth
  • 📐 Type Safety — Full TypeScript support with Zod schema inference
  • 🌐 Multiple Transports — Stdio (default) and HTTP/StreamableHTTP
  • 📋 Resource Templates — Dynamic URIs with parameterized paths like file:///logs/{date}
  • 📊 Progress Reporting — Report progress during long-running tool operations
  • 🔐 Pluggable Auth — Bring your own authentication with extractToken/validate hooks

Requirements

  • Node.js 18 or higher
  • TypeScript 5.0+ (recommended)

Installation

npm install mcp-forge zod

Quick Start

1. Create a Server

// server.ts
import { Forge, logging } from "mcp-forge";
import { z } from "zod";

const forge = new Forge({
  name: "demo-server",
  version: "1.0.0",
});

// Add logging middleware
forge.use(logging({ level: "info" }));

// Register a tool
forge.tool(
  "greet",
  {
    schema: z.object({ name: z.string().describe("Name to greet") }),
    description: "Greet someone by name",
  },
  ({ name }) => `Hello, ${name}!`
);

// Start the server
forge.start();

2. Run the Server

npx ts-node server.ts

3. Connect to Claude Desktop

Add to your Claude Desktop configuration:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "demo-server": {
      "command": "npx",
      "args": ["ts-node", "/absolute/path/to/server.ts"]
    }
  }
}

Restart Claude Desktop, and your tools will be available!

Core Concepts

Tools

Tools are functions that MCP clients can invoke:

forge.tool(
  "add_numbers",
  {
    schema: z.object({
      a: z.number().describe("First number"),
      b: z.number().describe("Second number"),
    }),
    description: "Add two numbers together",
  },
  ({ a, b }) => a + b
);

Progress Reporting

For long-running tools, report progress to the client:

forge.tool(
  "analyze_repo",
  {
    schema: z.object({ url: z.string() }),
    description: "Analyze a repository",
  },
  async ({ url }, ctx) => {
    await ctx.reportProgress(0.1, "Cloning repository...");
    await cloneRepo(url);

    await ctx.reportProgress(0.5, "Analyzing files...");
    const results = await analyzeFiles();

    await ctx.reportProgress(0.9, "Generating report...");
    return generateReport(results);
  }
);

Resources

Resources expose data that clients can read:

forge.resource(
  "config",
  "file:///config.json",
  { description: "Application configuration", mimeType: "application/json" },
  () => ({ text: JSON.stringify({ version: "1.0.0" }) })
);

Resource Templates

Define dynamic resources with URI parameters:

forge.resourceTemplate(
  "user-profile",
  "db://users/{userId}",
  {
    schema: z.object({ userId: z.string() }),
    description: "User profile by ID",
  },
  async ({ userId }) => {
    const user = await db.findUser(userId);
    return { text: JSON.stringify(user) };
  }
);

Prompts

Create reusable prompt templates:

forge.prompt(
  "summarize",
  {
    schema: z.object({ topic: z.string() }),
    description: "Generate a summary prompt",
  },
  ({ topic }) => ({
    messages: [{ role: "user", content: { type: "text", text: `Summarize: ${topic}` } }],
  })
);

Middleware

Add cross-cutting concerns:

forge.use(async (ctx, next) => {
  console.log(`Executing ${ctx.type}: ${ctx.name}`);
  const result = await next();
  return result;
});

Plugins

Bundle related functionality into reusable modules:

import { ForgePlugin } from "mcp-forge";

const mathPlugin: ForgePlugin = (forge) => {
  forge.tool("add", { schema: z.object({ a: z.number(), b: z.number() }) }, ({ a, b }) => a + b);
  forge.tool("multiply", { schema: z.object({ a: z.number(), b: z.number() }) }, ({ a, b }) => a * b);
};

forge.plugin(mathPlugin);

Built-in Middleware

| Middleware | Description | |------------|-------------| | rateLimit() | Token bucket rate limiting | | cache() | In-memory caching with TTL | | timeout() | Handler timeout protection | | metrics() | Execution timing and statistics | | logging() | Structured logging to stderr | | retry() | Automatic retry with exponential backoff | | auth() | Pluggable authentication |

import { rateLimit, cache, timeout, logging , auth } from "mcp-forge";

forge
  .use(logging({ level: "info" }))
  .use(rateLimit({ maxRequests: 100, windowMs: 60_000 }))
  .use(cache({ ttlMs: 300_000 }))
  .use(timeout({ ms: 30_000 }));

Authentication

Protect your HTTP endpoints with pluggable authentication:

import { Forge, auth } from "mcp-forge";

const forge = new Forge({ name: "secure-server", version: "1.0.0" });

forge.use(auth({
  extractToken: (headers) => {
    const authHeader = headers["authorization"];
    if (typeof authHeader === "string") {
      return authHeader.replace("Bearer ", "");
    }
    return undefined;
  },
  validate: async (token) => {
    // Your validation logic (database, JWT, API key, etc.)
    const user = await db.validateToken(token);
    return user ? { userId: user.id, role: user.role } : null;
  },
}));

Note: Auth is automatically skipped for stdio transport (inherently trusted).

Transport Options

Stdio (Default)

For local MCP clients like Claude Desktop:

forge.start(); // Uses stdio by default

HTTP

For remote clients:

forge.start({ transport: "http", port: 3000 });

Graceful Shutdown

process.on("SIGINT", async () => {
  await forge.stop();
  process.exit(0);
});

API Reference

See the API documentation for complete details.

Examples

Browse the examples/ directory for complete working examples:

  • basic-server.ts — Simple server with tools, resources, and prompts
  • plugin-demo.ts — Demonstrates the plugin system

Contributing

We welcome contributions! See CONTRIBUTING.md for:

  • Development setup instructions
  • Code style guidelines
  • Pull request process

License

MIT © 2025 mcp-forge contributors