# FrontMCP vs FastMCP for TypeScript

> How FrontMCP and FastMCP for TypeScript (punkpeye/fastmcp) differ in protocol support, tools, auth, testing and deployment, and when to choose each.

Source: https://frontmcp.dev/compare/fastmcp-typescript

FastMCP for TypeScript is a framework for MCP servers in which one `FastMCP` object holds the whole server: `addTool()`, `addResource()`, `addPrompt()`, then `start()`. FrontMCP declares the same things with decorators and adds a container for shared services, auth modes, agents and jobs, widgets, a test library and a build 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 FastMCP fact below comes from FastMCP's own README and repository at **4.22.4**, checked on **2026-10-10**, and links to it. Every FrontMCP fact links to the page on this site that shows FrontMCP 1.9.4 doing it.

---

## What FastMCP is

[FastMCP](https://github.com/punkpeye/fastmcp) is written by Frank Fiegel (`punkpeye` on GitHub and npm) and is MIT-licensed. It's published on npm as [`fastmcp`](https://www.npmjs.com/package/fastmcp) and on JSR as [`@punkpeye/fastmcp`](https://jsr.io/@punkpeye/fastmcp). Its first release was 1.0.0 on 2024-12-23; 4.22.4, the version checked here, came out on 2026-10-04, after 238 versions across four major versions ([npm](https://www.npmjs.com/package/fastmcp?activeTab=versions)). Its documentation is the [README](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md) and a few guides in [`docs/`](https://github.com/punkpeye/fastmcp/tree/v4.22.4/docs).

It isn't the Python FastMCP. Its README says it's [inspired by](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#acknowledgements) Jonathan Lowin's Python implementation, and its OAuth proxy is described as a [port of the Python one](https://github.com/punkpeye/fastmcp/blob/v4.22.4/docs/oauth-python-typescript.md).

FastMCP is [built on the official SDK](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#when-to-use-fastmcp-over-the-official-sdk), v1: its `package.json` asks for `@modelcontextprotocol/sdk` `^1.24.3`, which installed 1.32.1 on 2026-10-10. Its HTTP transport comes from the author's `mcp-proxy` package, and its HTTP server is Hono.

On 2026-10-10, FastMCP had 3,274 GitHub stars ([GitHub API](https://api.github.com/repos/punkpeye/fastmcp)) and 709,121 npm downloads in the week of 2026-10-02 to 2026-10-08 ([npm API](https://api.npmjs.org/downloads/point/last-week/fastmcp)). FrontMCP had 146 stars and 8,479 downloads of `@frontmcp/sdk` in the same week. FastMCP has been released for a year longer and is far 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 FastMCP

This is FastMCP's [Quickstart](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#quickstart), as we ran it with `fastmcp` 4.22.4, `zod` 4.6.5 and `tsx`, in a project with `"type": "module"`:

```ts server.ts
import { FastMCP } from "fastmcp";
import { z } from "zod"; // Or any validation library that supports Standard Schema

const server = new FastMCP({
  name: "My Server",
  version: "1.0.0",
});

server.addTool({
  name: "add",
  description: "Add two numbers",
  parameters: z.object({
    a: z.number(),
    b: z.number(),
  }),
  execute: async (args) => {
    return String(args.a + args.b);
  },
});

server.start({
  transportType: "stdio",
});
```

`npx fastmcp dev server.ts --tool add --args '{"a":2,"b":3}'` ran it and called the tool:

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

With `start({ transportType: "httpStream", httpStream: { port: 3204 } })` instead, the same server answered at `http://localhost:3204/mcp`, and a client built with `@modelcontextprotocol/sdk` got the same result. There's no build step and no configuration file: `npx tsx server.ts` runs it.

### In FrontMCP

The same tool, in a one-app FrontMCP server. The Playground runs it and calls `add`; the **Tests** tab runs the checks below it.

```ts main.ts active
import { App, FrontMcp, Tool, ToolContext, z } from "@frontmcp/sdk";

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

@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 FrontMCP version is longer: a tool class, an app that lists it, and a server that lists the app. It returns an object, which arrives as `structuredContent` with a text copy ([Your First Tool](https://frontmcp.dev/learn/your-first-tool#returning-results-and-errors)). FrontMCP needs Node 24 or later ([Installation](https://frontmcp.dev/learn/installation)) and TypeScript's decorator settings, and [`frontmcp dev`](https://frontmcp.dev/reference/cli#frontmcp-dev) runs it.

## Side by side

| | FastMCP 4.22.4 | FrontMCP 1.9.4 |
| --- | --- | --- |
| MCP revisions served | 2024-11-05 to 2025-11-25. The README says it [doesn't support 2026-07-28](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md?plain=1#L5-L7); over HTTP, our 2026-07-28 requests got `400` | 2024-11-05 to 2026-07-28 ([Error codes](https://frontmcp.dev/reference/errors)) |
| Declaring a tool | `server.addTool({ name, parameters, execute })` ([Tools](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#tools)) | A [`@Tool`](https://frontmcp.dev/reference/sdk/tool) class, or the `tool()` function |
| Schemas | Standard Schema: Zod, ArkType, Valibot, or JSON Schema through an adapter; `outputSchema` for structured output ([Tools](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#tools), [Structured Tool Output](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#structured-tool-output)) | Zod 4; `outputSchema` checks every result ([Schemas Are Contracts](https://frontmcp.dev/learn/schemas-are-contracts), [Shaping Tool Results](https://frontmcp.dev/learn/shaping-tool-results)) |
| Shared services | No container documented. Tools get a `context` with the session, logging and progress ([Sessions](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#sessions)) | [`@Provider`](https://frontmcp.dev/reference/sdk/provider) services, read with `this.get()` |
| Auth | An `authenticate()` hook for keys or tokens; an OAuth proxy with Google, GitHub, Azure and generic providers; discovery endpoints; per-tool `canAccess` ([Authentication](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#authentication)) | Five modes: public, static keys, JWTs from your identity provider, and FrontMCP as the OAuth server, with its own sign-in page or an upstream provider's ([Auth modes](https://frontmcp.dev/reference/auth/modes)); per-entry rules ([Authorities](https://frontmcp.dev/reference/auth/authorities)) |
| Testing | `server.connect()` with the official SDK's `InMemoryTransport`, `fastmcp dev`, `fastmcp inspect` ([Unit testing](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#unit-testing-with-an-in-memory-transport)) | `@frontmcp/testing` with MCP matchers, run by `frontmcp test` ([Testing](https://frontmcp.dev/reference/testing)) |
| Resources, prompts, completions, elicitation | All four, plus sampling and roots ([Resources](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#resources), [Prompts](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#prompts), [completion](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#prompt-argument-auto-completion), [Elicitation](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#elicitation)) | Resources and templates, prompts, completion of template parameters, `this.elicit()` ([`@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 | [`@Agent`](https://frontmcp.dev/reference/sdk/agent), [`@Job`](https://frontmcp.dev/reference/sdk/job), [`@Workflow`](https://frontmcp.dev/reference/sdk/workflow) |
| Widgets (MCP Apps) | Not documented. The source passes a tool's `_meta.ui.resourceUri` through to `tools/list` ([`FastMCP.ts`](https://github.com/punkpeye/fastmcp/blob/v4.22.4/src/FastMCP.ts)) | 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; Streamable HTTP with an SSE endpoint beside it; a stateless mode; in-memory ([HTTP Streaming](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#http-streaming), [Stateless mode](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#stateless-mode)) | 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), [`transport`](https://frontmcp.dev/reference/sdk/frontmcp#transport)) |
| Runtimes and deployment | Node, Bun; `EdgeFastMCP` for Cloudflare Workers and Deno Deploy, stateless and without built-in auth ([Edge Runtime Support](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#edge-runtime-support)) | Node 24 or later; `frontmcp build` targets for Node, Vercel, AWS Lambda, Cloudflare Workers and a browser module ([Production build](https://frontmcp.dev/reference/deployment/production-build)); a fetch handler for other runtimes ([`createFetchHandler()`](https://frontmcp.dev/reference/sdk/create-fetch-handler)) |
| CLI | `fastmcp dev`, `fastmcp inspect`, `fastmcp validate`; no project generator ([Running Your Server](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#running-your-server)) | `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/punkpeye/fastmcp/blob/v4.22.4/LICENSE) | [Apache-2.0](https://github.com/agentfront/frontmcp/blob/main/LICENSE) |

## What each does that the other doesn't

What FastMCP documents and this site doesn't show for FrontMCP:

- **A choice of schema library.** Any [Standard Schema](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#tools) library works, ArkType and Valibot included, and so does plain JSON Schema. FrontMCP's pages use Zod 4 only.
- **Ready-made OAuth providers.** `GoogleProvider`, `GitHubProvider` and `AzureProvider` set up the [OAuth proxy](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#oauth-with-pre-configured-providers) for those sign-ins. FrontMCP's [`remote` mode](https://frontmcp.dev/reference/auth/remote) takes an OpenID Connect provider you configure, like Auth0, Okta or Keycloak; a plain OAuth provider such as GitHub, whose users have no `sub`, [can't be used](https://frontmcp.dev/reference/auth/remote#pointing-frontmcp-at-your-providers-endpoints).
- **Completion of prompt arguments**, including from an `enum` ([Prompt argument auto-completion](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#prompt-argument-auto-completion)). This site shows FrontMCP completing resource template parameters only.
- **Streaming partial tool output** with `streamContent`, which the README marks as a FastMCP extension that isn't in the MCP specification ([Streaming Output](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#streaming-output)).
- **HTTPS, mutual TLS and CORS options** on the built-in server ([Remote Server Options](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#remote-server-options)), and custom routes on its Hono app.
- **Deno Deploy and Bun** are named as runtimes. This site shows a [fetch handler](https://frontmcp.dev/reference/sdk/create-fetch-handler) for such runtimes but no deployment guide for them.

What FrontMCP does that FastMCP's README doesn't document:

- **MCP 2026-07-28.** FastMCP's README says it serves 2025-11-25 and earlier, and points to another framework for 2026-07-28. FrontMCP [serves both eras](https://frontmcp.dev/reference/errors) on one endpoint.
- **A dependency container**: [providers](https://frontmcp.dev/learn/sharing-state-with-providers) with scopes, which tools, resources and prompts get with `this.get()`.
- **Agents, jobs and workflows**: [agents](https://frontmcp.dev/learn/your-first-agent) that run a model loop on the server, [jobs](https://frontmcp.dev/learn/your-first-job) that run in the background, and [workflows](https://frontmcp.dev/learn/chaining-jobs-into-workflows) that chain them.
- **Widgets.** A tool's `ui` option renders an HTML or React widget for MCP Apps hosts and the OpenAI Apps SDK ([Your First Widget](https://frontmcp.dev/learn/your-first-widget)).
- **Plugins** for caching, memory, approval, feature flags and CodeCall ([Plugins and adapters](https://frontmcp.dev/reference/plugins)).
- **Sign-in without an upstream provider**: in `local` mode FrontMCP is the OAuth server and serves the sign-in page, and you check the user in `authenticate` ([Local auth](https://frontmcp.dev/reference/auth/local#checking-users-yourself)). FastMCP's OAuth proxy signs users in through a provider.
- **Project scaffolding and platform builds**: `frontmcp create`, and `frontmcp build` for Vercel, AWS Lambda and Cloudflare Workers ([Deploying Your Server](https://frontmcp.dev/learn/deploying-your-server)).
- **A test library** with MCP matchers and fixtures ([Testing Your Server](https://frontmcp.dev/learn/testing-your-server)).

Both have an OpenAPI importer: FastMCP's [`fromOpenAPI()`](https://github.com/punkpeye/fastmcp/blob/v4.22.4/README.md#openapi) and FrontMCP's [OpenAPI adapter](https://frontmcp.dev/reference/adapters/openapi).

## When to choose FastMCP

- You want the smallest setup that works: one file, no decorators, no build, run with `tsx`. FastMCP's README describes its audience as people who want to build MCP servers quickly without dealing with low-level details.
- Your clients speak MCP 2025-11-25 or earlier, and you don't need 2026-07-28 yet.
- You want ArkType, Valibot or plain JSON Schema rather than Zod.
- You sign users in with Google, GitHub or Azure and want the provider preset.
- You want a library that many more people use today, with a longer release history.

## When to choose FrontMCP

- You need MCP 2026-07-28 next to the older revisions.
- The server is growing past a handful of tools, and you want shared services, several apps, plugins and hooks to organise it ([Structuring a Server](https://frontmcp.dev/learn/structuring-a-server)).
- You want agents, background jobs, workflows or widgets from the same framework.
- You deploy to Vercel, AWS Lambda or Cloudflare Workers and want a build for each.

## How this was checked

On 2026-10-10 we installed `fastmcp` 4.22.4, ran the Quickstart above over stdio and Streamable HTTP, and called `add`. 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`, and over HTTP the 2026-07-28 requests got `400` with `server_missing_modern_protocol_support`. Stateless mode answered the same. The [overview](https://frontmcp.dev/compare#how-this-was-checked) describes the method for every library.
