Why FrontMCP: when the MCP SDK alone isn't enough

FrontMCP is a TypeScript framework for MCP servers that are becoming applications. On top of the protocol, it adds typed Zod tools, dependency injection, sign-in, tests, plugins, apps, jobs, workflows and agents, with builds for Node.js, Vercel, AWS Lambda and Cloudflare Workers. Use it when a server is growing past a few tools. For a few tools in one file, the official MCP SDK alone is the simpler choice.

This site documents FrontMCP, so read it knowing who wrote it. The facts about other libraries come from the comparisons this page links to, each checked against that library's own documentation.


When the official SDK alone is enough

The official MCP TypeScript SDK is the protocol's reference implementation, and every library here builds on it. It's the better choice when:

  • The server is small. A handful of tools in one file, plain functions, three packages, and no build step.
  • You're building a client, a host or a gateway. The SDK's client connects to any server. FrontMCP's clients call your own server's tools in-process, or serve a remote server's tools from a FrontMCP server.
  • MCP is one route in an app you already have, in Express, Hono or Fastify, or on Bun or Deno.
  • You want a schema library other than Zod. The SDK takes any Standard Schema library.

Each of these has its sources in When the SDK alone is the better choice.

What a growing server needs

A server usually starts as a few tools, and then needs more: a database client the tools share, sign-in, rules about who may call what, limits, tests, work that runs in the background, and a second team's tools beside the first. With the SDK alone, each of these is code you write around it. In FrontMCP, each is a declaration:

A server needsFrontMCPLearn it
Tools grouped as they multiply@Tool classes in @Apps, several apps on one serverGrouping Capabilities into Apps
A service the tools share, like a database clientProviders, read with this.get()Sharing State with Providers
Sign-inFive modes, from static keys to FrontMCP as the OAuth serverAuthenticating Clients
Rules about who may call whatRules on tools, resources and promptsDeciding Who Can Call What
Rate limits, concurrency caps and timeoutsOptions on a tool or the serverLimiting and Timing Out Calls
Code around every callHooks, and plugins that package themHooking into Calls
Tests@frontmcp/testing, run by frontmcp testTesting Your Server
Work in the backgroundJobs, and workflows that chain themYour First Job
Agents@Agent, with tools of its ownYour First Agent
Tools from a REST API you already haveThe OpenAPI adapterWrapping an OpenAPI Service
A build for where it runsfrontmcp build for Node.js, Vercel, AWS Lambda and Cloudflare WorkersDeploying Your Server
Clients on older and newer protocol revisions2024-11-05 to 2026-07-28 on one endpointProtocol versions

What FrontMCP adds has the same list next to what the SDK documents for each item.

What it looks like

A help desk's search tool, with a ticket store that its tools share, a rate limit, an error the model can read, and tests. The Playground runs it and calls search_tickets, and the Tests tab runs the checks:

Open
import { PublicMcpError, Tool, ToolContext, z } from "@frontmcp/sdk";
import { TicketStore } from "./ticket-store";

@Tool({
  name: "search_tickets",
  description: "Search support tickets by a word in their title. Returns each match's id, title and status.",
  inputSchema: {
    query: z.string().min(2).describe("A word to look for in ticket titles, like login"),
    status: z.enum(["open", "closed"]).optional().describe("Only tickets with this status"),
  },
  annotations: { readOnlyHint: true },
  rateLimit: { maxRequests: 30, windowMs: 60_000 },
})
export class SearchTickets extends ToolContext {
  async execute({ query, status }: { query: string; status?: "open" | "closed" }) {
    const tickets = this.get(TicketStore).search(query, status);
    if (tickets.length === 0) this.fail(new PublicMcpError(`No ticket title mentions "${query}". Try a shorter word.`));
    return { tickets };
  }
}

Starting FrontMCP in your browser…

FrontMCP starts when this example comes into view.

With the SDK alone, the store would be an object the server's factory closes over, the rate limit would be yours to write, and the tests would run a client against the server's handler (the SDK's testing guide).

When FrontMCP is the wrong choice

  • You can't run Node 24. FrontMCP needs it; the SDK runs on Node 20.
  • You want a schema library other than Zod.
  • You want the smallest dependency tree. On 2026-10-10, npm install @frontmcp/sdk installed 126 packages, against 3 for the SDK's server.
  • You need a general-purpose MCP client or agent. The SDK and mcp-use provide one.

Other libraries fit other cases, like one-file servers, file-based routing in a web app, or MCP Apps with React views: see Which one fits.

Where to start