# FrontMCP vs mcp-framework

> How FrontMCP and mcp-framework differ in protocol support, tool classes, auth, testing and deployment, and when to choose each.

Source: https://frontmcp.dev/compare/mcp-framework

mcp-framework is a TypeScript framework in which each tool is a class in its own file, found by scanning a folder: extend `MCPTool`, set a name, a description and a Zod schema, and write `execute()`. FrontMCP also declares tools as classes, with a decorator, and adds a container for shared services, more auth modes, agents and jobs, a test library and builds for several platforms. This page shows the same tool in both and compares them on the criteria of the [comparison overview](https://frontmcp.dev/compare).

This site documents FrontMCP, so read it knowing who wrote it. Every mcp-framework fact below comes from its own documentation, repository and npm entry for **0.2.22**, checked on **2026-10-10**, and links to them. Every FrontMCP fact links to the page on this site that shows FrontMCP 1.9.4 doing it.

---

## What mcp-framework is

[mcp-framework](https://mcp-framework.com) is written by Alex Andru (`QuantGeekDev` on GitHub), with documentation at [mcp-framework.com](https://mcp-framework.com/docs/introduction). The repository's [LICENSE](https://github.com/QuantGeekDev/mcp-framework/blob/mcp-framework-v0.2.22/LICENSE) is MIT, and its docs [say the same](https://mcp-framework.com/docs/why-mcp-framework); the npm entry has no `license` field. It's published as [`mcp-framework`](https://www.npmjs.com/package/mcp-framework), first on 2024-12-08; 0.2.22, the version checked here, is the latest, published on 2026-04-16 ([npm](https://www.npmjs.com/package/mcp-framework?activeTab=versions)). The project is at 0.x and makes no stability claim, and an [open issue](https://github.com/QuantGeekDev/mcp-framework/issues/95) from June 2025 asks for maintainers.

It's built on v1 of the official MCP TypeScript SDK: it asks for `@modelcontextprotocol/sdk` `^1.29.0` as a peer dependency, and for Zod 3 ([`package.json`](https://github.com/QuantGeekDev/mcp-framework/blob/mcp-framework-v0.2.22/package.json)). Its docs describe it as "an independent framework that uses `@modelcontextprotocol/sdk`" ([Why mcp-framework](https://mcp-framework.com/docs/why-mcp-framework)).

On 2026-10-10, mcp-framework had 930 GitHub stars ([GitHub API](https://api.github.com/repos/QuantGeekDev/mcp-framework)) and 51,963 npm downloads in the week of 2026-10-02 to 2026-10-08 ([npm API](https://api.npmjs.org/downloads/point/last-week/mcp-framework)). FrontMCP had 146 stars and 8,479 downloads of `@frontmcp/sdk` in the same week. mcp-framework has been released for a year longer and is more widely used.

## The same tool in both

One tool, `add`, that takes two numbers and returns their sum, called with `{ "a": 2, "b": 3 }`.

### In mcp-framework

We created a project with the CLI, as the [README](https://github.com/QuantGeekDev/mcp-framework/blob/mcp-framework-v0.2.22/README.md#creating-a-repository-with-mcp-framework) shows (`npx -p mcp-framework@0.2.22 mcp create add-server`, and `mcp create add-server-http --http --port 3203` for HTTP), added a tool with `mcp add tool add`, and wrote it like the README's [Quick Start](https://github.com/QuantGeekDev/mcp-framework/blob/mcp-framework-v0.2.22/README.md#quick-start):

```ts src/tools/AddTool.ts
import { MCPTool, MCPInput } from "mcp-framework";
import { z } from "zod";

const schema = z.object({
  a: z.number().describe("First number to add"),
  b: z.number().describe("Second number to add"),
});

class AddTool extends MCPTool {
  name = "add";
  description = "Add two numbers";
  schema = schema;

  async execute(input: MCPInput<this>) {
    return input.a + input.b;
  }
}

export default AddTool;
```

The server is the scaffold's `src/index.ts`, unchanged. For HTTP:

```ts src/index.ts
import { MCPServer } from "mcp-framework";

const server = new MCPServer({
  transport: {
    type: "http-stream",
    options: {
      port: 3203
    }
  }});

server.start();
```

`npm run build` compiles the project and checks that every schema field has a description, and `npm start` serves the tools it finds in `dist/tools`. Over stdio and over HTTP, calling `add` returned:

```json
{"content":[{"type":"text","text":"5"}]}
```

> **Note**
On 2026-10-10, with npm 11, the scaffold didn't build as generated. Its `package.json` lists no `zod`, so `import { z } from "zod"` found Zod 4 (installed for the MCP SDK) while mcp-framework uses Zod 3: `mcp create` stopped with `Property 'message' does not exist on type 'MCPInput<this>'`, and a server built anyway answered every call with `keyValidator._parse is not a function`. Running `npm install zod@3` in the project fixed both. We created the HTTP project with `--no-example`, which skips the example tool, and installed `zod@3` in it before adding `add`.

### In FrontMCP

The same tool as a decorated class, and a server that lists it in an app. The Playground runs it and calls `add`; the **Tests** tab runs the checks:

```ts add.tool.ts active
import { Tool, ToolContext, z } from "@frontmcp/sdk";

@Tool({
  name: "add",
  description: "Add two numbers",
  inputSchema: {
    a: z.number().describe("First number to add"),
    b: z.number().describe("Second number to add"),
  },
})
export class Add extends ToolContext {
  async execute({ a, b }: { a: number; b: number }) {
    return { sum: a + b };
  }
}
```

```ts main.ts
import { App, FrontMcp } from "@frontmcp/sdk";
import { Add } from "./add.tool";

@App({ id: "calc", name: "Calculator", tools: [Add] })
export class CalcApp {}

@FrontMcp({ info: { name: "calc", version: "1.0.0" }, apps: [CalcApp] })
export default class Server {}
```

```ts add.test.ts
import { test, expect } from "@frontmcp/testing";

test("adds two numbers", async ({ mcp }) => {
  const result = await mcp.tools.call("add", { a: 2, b: 3 });
  expect(result).toBeSuccessful();
  expect(result.json()).toEqual({ sum: 5 });
});

test("rejects a string where a number belongs", async ({ mcp }) => {
  const result = await mcp.tools.call("add", { a: "2", b: 3 });
  expect(result).toBeError("INVALID_INPUT");
});
```

The two look alike: a class per tool, a name, a description, a Zod schema and an `execute()` method. mcp-framework finds tool classes by scanning a folder; FrontMCP lists them in an app. FrontMCP uses Zod 4, returns an object as `structuredContent` with a text copy ([Your First Tool](https://frontmcp.dev/learn/your-first-tool#returning-results-and-errors)), and needs Node 24 or later ([Installation](https://frontmcp.dev/learn/installation)); mcp-framework needs Node 18.19 or later.

## Side by side

| | mcp-framework 0.2.22 | FrontMCP 1.9.4 |
| --- | --- | --- |
| MCP revisions served | 2024-11-05 to 2025-11-25; the docs say "MCP 2025-11-25 Compliant" ([Introduction](https://mcp-framework.com/docs/introduction)). Our 2026-07-28 requests failed | 2024-11-05 to 2026-07-28 ([Error codes](https://frontmcp.dev/reference/errors)) |
| Declaring a tool | A class extending `MCPTool`, one per file, found in `dist/tools` ([Tools](https://mcp-framework.com/docs/tools/overview)) | A [`@Tool`](https://frontmcp.dev/reference/sdk/tool) class or `tool()` function, listed in an `@App` |
| Schemas | Zod 3, with a description required on every field; `outputSchemaShape` for structured output ([Advanced features](https://mcp-framework.com/docs/tools/advanced-features)) | Zod 4; `outputSchema` checks every result ([Schemas Are Contracts](https://frontmcp.dev/learn/schemas-are-contracts)) |
| Shared services | Not documented | [`@Provider`](https://frontmcp.dev/reference/sdk/provider) services, read with `this.get()` |
| Auth | API key, JWT (HS256), and an OAuth 2.1 resource server that checks tokens against a JWKS or by introspection; custom providers ([Authentication](https://mcp-framework.com/docs/authentication/overview), [OAuth](https://mcp-framework.com/docs/authentication/oauth)) | Five modes: public, static keys, JWTs from your identity provider, FrontMCP as the OAuth server with its own sign-in or an upstream provider's ([Auth modes](https://frontmcp.dev/reference/auth/modes)); per-entry rules ([Authorities](https://frontmcp.dev/reference/auth/authorities)) |
| Testing | The MCP Inspector ([Debugging](https://mcp-framework.com/docs/debugging)); no test helpers documented | `@frontmcp/testing` with MCP matchers, run by `frontmcp test` ([Testing](https://frontmcp.dev/reference/testing)) |
| Resources, prompts, completions, elicitation | Resources, prompts and elicitation, plus sampling, roots and progress ([Resources](https://mcp-framework.com/docs/resources/overview), [Prompts](https://mcp-framework.com/docs/prompts/overview), [Elicitation](https://mcp-framework.com/docs/tools/elicitation)); completion is in the [changelog](https://github.com/QuantGeekDev/mcp-framework/blob/mcp-framework-v0.2.22/CHANGELOG.md), not the docs | All four ([`@Resource`](https://frontmcp.dev/reference/sdk/resource), [`@Prompt`](https://frontmcp.dev/reference/sdk/prompt), [completers](https://frontmcp.dev/reference/sdk/resource-template#completing-parameters), [`this.elicit`](https://frontmcp.dev/reference/sdk/elicit)); [`this.sample()` and `this.listRoots()`](https://frontmcp.dev/reference/sdk/contexts#thissample-and-thislistroots) for clients that offer them |
| Agents, jobs, workflows | Not documented; MCP tasks are experimental ([Advanced features](https://mcp-framework.com/docs/tools/advanced-features)) | [`@Agent`](https://frontmcp.dev/reference/sdk/agent), [`@Job`](https://frontmcp.dev/reference/sdk/job), [`@Workflow`](https://frontmcp.dev/reference/sdk/workflow) |
| Widgets (MCP Apps) | An `MCPApp` class or an `app` property on a tool, with React scaffolding ([MCP Apps](https://mcp-framework.com/docs/apps/overview)) | A tool's `ui` option, for MCP Apps hosts and the OpenAI Apps SDK ([Tool UI](https://frontmcp.dev/reference/ui), [Hosts](https://frontmcp.dev/reference/ui/hosts)) |
| Transports | stdio (the default); HTTP Stream with sessions, which the README calls experimental; SSE, deprecated; several at once ([Transports](https://mcp-framework.com/docs/transports/overview)) | Streamable HTTP with or without sessions, the older HTTP+SSE, stdio, a Unix socket, 2026-07-28 HTTP, in-memory ([`FrontMcpInstance`](https://frontmcp.dev/reference/sdk/frontmcp-instance)) |
| Runtimes and deployment | Node 18.19+; AWS Lambda with `createLambdaHandler()`, and a `handleRequest()` for Cloudflare Workers and Vercel Edge ([Serverless](https://mcp-framework.com/docs/transports/serverless)) | Node 24+; `frontmcp build` for Node, Vercel, AWS Lambda, Cloudflare Workers and a browser module ([Production build](https://frontmcp.dev/reference/deployment/production-build)) |
| CLI | `mcp create`, `mcp add` for tools, prompts, resources and apps, `mcp build`, `mcp validate` ([README](https://github.com/QuantGeekDev/mcp-framework/blob/mcp-framework-v0.2.22/README.md#cli-usage)) | `frontmcp create`, `dev`, `build`, `test`, `inspector` ([CLI](https://frontmcp.dev/reference/cli)); an [Nx plugin](https://frontmcp.dev/reference/nx) |
| License | [MIT](https://github.com/QuantGeekDev/mcp-framework/blob/mcp-framework-v0.2.22/LICENSE) | [Apache-2.0](https://github.com/agentfront/frontmcp/blob/main/LICENSE) |

## What each does that the other doesn't

What mcp-framework documents and this site doesn't show for FrontMCP:

- **Tools found by scanning a folder**, so adding a file adds a tool.
- **Generators for each kind of component**: `mcp add tool`, `mcp add prompt`, `mcp add resource` and `mcp add app`.
- **A check, at build time, that every schema field has a description**, so the model never sees an undocumented argument (`mcp build`, `mcp validate`).
- **stdio and HTTP from one process**, each transport with its own auth ([Multi-transport](https://mcp-framework.com/docs/transports/multi-transport)).
- **Node 18.19 or later.** FrontMCP needs Node 24.

What FrontMCP does that mcp-framework's docs don't document:

- **MCP 2026-07-28**, next to the older revisions, on one endpoint ([Error codes](https://frontmcp.dev/reference/errors)).
- **A dependency container**: [providers](https://frontmcp.dev/learn/sharing-state-with-providers) with scopes.
- **Hooks and plugins** around every call, with official plugins for caching, memory, approvals and feature flags ([Plugins and adapters](https://frontmcp.dev/reference/plugins)).
- **Agents, jobs and workflows**: [agents](https://frontmcp.dev/learn/your-first-agent), [background jobs](https://frontmcp.dev/learn/your-first-job) and [workflows](https://frontmcp.dev/learn/chaining-jobs-into-workflows).
- **An OAuth server**: FrontMCP can issue the tokens itself, with its own sign-in page and your check of the user, or after a sign-in at an upstream provider ([Local auth](https://frontmcp.dev/reference/auth/local#checking-users-yourself), [Remote and proxied auth](https://frontmcp.dev/reference/auth/remote)), and checks per-entry [authorities](https://frontmcp.dev/reference/auth/authorities).
- **A test library** with MCP matchers and fixtures ([Testing Your Server](https://frontmcp.dev/learn/testing-your-server)).
- **Sessions shared between instances** through [Redis](https://frontmcp.dev/reference/deployment/redis). mcp-framework keeps HTTP sessions in the process, which an [open issue](https://github.com/QuantGeekDev/mcp-framework/issues/187) says stops it scaling across instances.
- **Builds for Vercel and Cloudflare Workers** from the CLI ([Deploying Your Server](https://frontmcp.dev/learn/deploying-your-server)).

## When to choose mcp-framework

- You want a class per tool, discovered from a folder, with generators and a build that checks your descriptions, and little else to learn.
- You're on Node 18 or 20, and your clients speak MCP 2025-11-25 or earlier.
- You want the more widely used of the two today.

## When to choose FrontMCP

- You need MCP 2026-07-28, or Zod 4.
- The server is growing, and you want shared services, several apps, hooks and plugins to organise it ([Structuring a Server](https://frontmcp.dev/learn/structuring-a-server)).
- You want agents, background jobs, workflows or tests from the same framework.
- You run several instances of the server behind a load balancer ([Running Several Instances](https://frontmcp.dev/learn/running-several-instances)).

## How this was checked

On 2026-10-10 we created two mcp-framework 0.2.22 projects with its CLI, one for stdio and one for HTTP, made the fix in the note above, and called `add` over each. We then sent each server an `initialize` request for every MCP revision from 2024-11-05 to 2025-11-25, and the 2026-07-28 `server/discover` and `tools/call` requests. The four older revisions answered and returned `5`. 2026-07-28 didn't: over stdio, `server/discover` got `-32601` `Method not found`, and over HTTP both requests got `400`, `No valid session ID provided` from the HTTP Stream transport and `Unsupported protocol version: 2026-07-28` from the documented `handleRequest()`. The [overview](https://frontmcp.dev/compare#how-this-was-checked) describes the method for every library.
