FrontMCP vs Prefect's FastMCP TypeScript

FastMCP TypeScript is Prefect's TypeScript counterpart to the Python FastMCP, built on v2 of the official MCP SDK: one FastMCP object with tool(), resource() and prompt(), and in the same package a client, middleware, server composition and an apps layer. It isn't FastMCP for TypeScript, punkpeye's fastmcp package, which has its own page. FrontMCP declares tools as decorated classes and adds a container for shared services, agents, jobs and workflows, 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.

This site documents FrontMCP, so read it knowing who wrote it. Every FastMCP TypeScript fact below comes from its own README, documentation and source at 1.7.3, checked on 2026-10-20, and links to them. Every FrontMCP fact links to the page on this site that shows FrontMCP 1.10.5 doing it, or to how this was checked.

Quick answer

Choose Prefect's FastMCP TypeScript when you want the Python FastMCP's model in TypeScript, on the official SDK v2, with a client, middleware, server composition and both MCP eras over HTTP and stdio in one package. Choose FrontMCP over Prefect's FastMCP TypeScript when you want shared services, agents, jobs, workflows and MCP tasks, a test library, sessions shared between instances, or builds for Vercel, AWS Lambda and Cloudflare Workers.


What FastMCP TypeScript is

FastMCP TypeScript lives in Prefect's GitHub organization and is published on npm as @prefecthq/fastmcp-ts. Its README calls it "the official TypeScript counterpart to FastMCP for Python", built "by the same team at Prefect" (README). Its first release was 0.0.2-alpha.0 on 2026-04-23, 1.0.0 came out on 2026-07-28, and 1.7.3, the version checked here, on 2026-10-01 (npm). Its documentation is at fastmcp-ts.docs.prefect.io, from the docs/ folder that this page links to at the release tag.

Its package.json says Apache-2.0, and so does npm; the repository has no LICENSE file at v1.7.3 (package.json). The server needs Node 22 or later; the client also bundles for the browser (Installation).

It's built on v2 of the official SDK, @modelcontextprotocol/server and @modelcontextprotocol/client (README), which installed 2.3.1 on 2026-10-20, and on the frozen @modelcontextprotocol/server-legacy for its OAuth server (OAuth). Its README says that since 1.0 it "speaks both MCP protocol generations: the 2025 legacy era and the 2026-07-28 modern era. A server serves both at once, and a client negotiates one" (README).

Two names collide with punkpeye's FastMCP for TypeScript: the library's name, and its CLI, which is called fastmcp in both packages.

On 2026-10-20, FastMCP TypeScript had 78 GitHub stars (GitHub API) and 9,609 npm downloads in the week of 2026-10-12 to 2026-10-18 (npm API). FrontMCP had 146 stars and 15,574 downloads of @frontmcp/sdk in the same week.

The same tool in both

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

In FastMCP TypeScript

This is the server from the README and the Quickstart, with only its tool, as we ran it with @prefecthq/fastmcp-ts 1.7.3, zod 4.6.7 and tsx, in a project with "type": "module":

server.ts
import { FastMCP } from '@prefecthq/fastmcp-ts/server'
import { z } from 'zod'

const server = new FastMCP({ name: 'my-server', version: '1.0.0' })

server.tool(
  {
    name: 'add',
    description: 'Add two numbers',
    input: z.object({ a: z.number(), b: z.number() }),
  },
  ({ a, b }) => a + b
)

await server.run()                              // stdio (default)
// await server.run({ transport: 'http', port: 3000 })

npx fastmcp call add --file server.ts a=2 b=3, from its CLI, started the server over stdio, called the tool and printed 5. The CLI asks for 2026-07-28 first; with --json the result carried the server's info in _meta, as a 2026-07-28 result does, and with --legacy it was the same 5 after an initialize handshake. A number comes back as a text block (Return values).

With server.run({ transport: 'http', port: 3209 }) instead, the same server answered at http://127.0.0.1:3209/mcp. A client from @modelcontextprotocol/client 2.3.1 called add with its default, which opens a 2025-era session with initialize, and with versionNegotiation: { mode: "auto" }, which asks for 2026-07-28 first:

legacy 2025-11-25 {"content":[{"type":"text","text":"5"}]}
modern 2026-07-28 {"_meta":{"io.modelcontextprotocol/serverInfo":{"name":"my-server","version":"1.0.0"}},"content":[{"type":"text","text":"5"}]}

There's no build step and no configuration file: npx fastmcp run server.ts or 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.

Open
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 {}

Starting FrontMCP in your browser…

FrontMCP starts when this example comes into view.

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). An argument of the wrong type is a tool error in FrontMCP, as the second test shows, which the model reads as a result. In FastMCP TypeScript it's a JSON-RPC error: { "a": "2", "b": 3 } got -32602 Validation failed in our run, as its docs say (Schemas). FrontMCP needs Node 24 or later and TypeScript's decorator settings (Installation); FastMCP TypeScript needs Node 22. npm install @prefecthq/fastmcp-ts installed 149 packages on 2026-10-20, and npm install @frontmcp/sdk 126.

Side by side

FastMCP TypeScript 1.7.3FrontMCP 1.10.5
MCP revisions served2024-11-05 to 2026-07-28 on one endpoint, over Streamable HTTP and stdio; the older four with a session, unless stateless mode is on (Protocol eras, Running your server)2024-11-05 to 2026-07-28 over Streamable HTTP and stdio, with a session for the older four (Protocol versions)
Declaring a toolserver.tool({ name, description, input }, handler) (Tools)A @Tool class, or the tool() function
SchemasStandard Schema: Zod, Valibot, ArkType; output checked after the handler; JSON Schema generated, or set by hand (Schemas)Zod 4; outputSchema checks every result (Schemas Are Contracts, Shaping Tool Results)
Shared servicesNo container documented. Handlers get an ambient context from server.getContext(), with logging, progress, request state and session state (Context)@Provider services, read with this.get()
Code around every callMiddleware: logging, caching per caller, rate limiting, size limits, error normalization, cancellation (Middleware)Hooks and plugins; rate limits, concurrency caps and timeouts (Guard options)
AuthToken verifiers: JWTs against a JWKS, introspection, static tokens, several at once, or headers from a trusted proxy; oauthProvider and oauthProxy, which the docs call "a supported interim"; requireScopes and per-component checks (Auth overview, OAuth, Authorization)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); per-entry rules (Authorities)
TestingAn in-process Client.connect(server), stdio stream overrides, and fastmcp call, list and inspect (Transports, Running your server); no test matchers documented@frontmcp/testing with MCP matchers, run by frontmcp test (Testing)
Resources, prompts, completions, elicitationAll four, with resource subscriptions on both eras; elicitation, sampling and roots as requests on a 2025-era session, or a returned inputRequired() on both eras (Resources, Prompts, Context)All four (@Resource, @Prompt, completers, this.elicit, which serves both eras); this.sample() and this.listRoots() for clients that offer them
Agents, jobs, workflows, tasksNot documented; MCP tasks are "planned" (Tasks)@Agent, @Job, @Workflow; background tasks
Widgets (MCP Apps)FastMCPApp: screens built from a server-side component library, ready-made approval, choice, file upload and form providers, and generative UI (Apps overview)A tool's ui option with HTML or React, for MCP Apps hosts and the OpenAI Apps SDK (Tool UI, Hosts)
Combining serversmount() with a prefix, createProxy() for remote servers, and transforms that rename, filter or namespace what's listed (Composition, Transforms)Several apps on one server, or one endpoint per app (Apps, discovery and splitting); remote servers served as apps (Remote servers)
ClientClient for any server, with multi-server connections and sampling adapters for Anthropic, OpenAI and Google (README)connect() to your own server, in-process
TransportsStreamable HTTP, with sessions or stateless; stdio; no standalone SSE (Running your server)Streamable HTTP with or without sessions, the older HTTP+SSE, stdio, a Unix socket, in-memory (FrontMcpInstance, transport)
Runtimes and deploymentNode 22+; server.fetch() serves a web-standard Request, statelessly; a health endpoint and custom routes (Installation, FastMCP, Running your server)Node 24+; frontmcp build targets for Node, Vercel, AWS Lambda, Cloudflare Workers and a browser module (Production build); a fetch handler for other runtimes (createFetchHandler())
CLIfastmcp run, inspect, call, list, dev inspector, install for Claude Code, Cursor and Claude Desktop, discover; no project generator (CLI)frontmcp create, dev, build, test, inspector (CLI); an Nx plugin
LicenseApache-2.0 in package.json; no LICENSE file in the repositoryApache-2.0

What each does that the other doesn't

What FastMCP TypeScript documents, or did in our run, and this site doesn't show for FrontMCP:

  • The official SDK v2 underneath. Its protocol code is the SDK's, and its docs say it runs the MCP conformance suite on every pull request (Migration). FrontMCP is built on v1 of the SDK and implements 2026-07-28 itself (FrontMCP vs the official SDK).
  • A client for any MCP server, in Node or the browser, with connections to several servers at once and sampling adapters for Anthropic, OpenAI and Google (README).
  • Transforms: a view of what's listed that renames tools, filters them by tag or version, prefixes every name, or adds a tool that lists resources or prompts (Transforms).
  • UI from server-side components: screens described as a JSON component tree, ready-made approval, choice, file upload and form screens, and generative UI that lets the model build a screen (Apps overview). FrontMCP's widgets are HTML or React that you write.
  • A choice of schema library. Any Standard Schema library works. FrontMCP's pages use Zod 4 only.
  • Completion of prompt arguments (Prompts). This site shows FrontMCP completing resource template parameters only.
  • Installing a server file into Cursor and Claude Desktop with fastmcp install (CLI). A FrontMCP server built with the cli target installs itself into Claude Code and Codex (CLI).
  • The Python FastMCP's conventions: the same entrypoint exports for the CLI (CLI), and OpenAPI generation that matches Python's output (OpenAPI).
  • Node 22. FrontMCP needs Node 24.

What FrontMCP does that FastMCP TypeScript's docs don't document:

  • Sessions shared between instances, through Redis. FastMCP TypeScript keeps a 2025-era session in the memory of the instance that answered initialize, and its answer for several instances is stateless mode, which turns off session state and requests from the server (Stateless mode).
  • One this.elicit() for both eras: on a session it waits for the answer, and for a 2026-07-28 client it becomes input_required (How an elicitation travels). In FastMCP TypeScript, ctx.elicit() throws on a 2026-07-28 request, and a handler that serves both returns inputRequired() (Context).
  • A dependency container: providers with scopes, which tools, resources and prompts get with this.get().
  • Agents, jobs, workflows and tasks: agents that run a model loop on the server, jobs that run in the background, workflows that chain them, and tools that run as MCP tasks, which FastMCP TypeScript lists as planned.
  • A test library with MCP matchers and fixtures (Testing Your Server).
  • An OAuth server with client ID metadata documents: in local mode FrontMCP serves the sign-in page and issues the tokens (Local auth), and accepts clients identified by a metadata URL (CIMD). FastMCP TypeScript's oauthProvider and oauthProxy register clients with Dynamic Client Registration, which 2026-07-28 deprecates, from the frozen server-legacy package (OAuth).
  • Plugins for memory, approvals, feature flags and CodeCall (Plugins and adapters), next to the cache that both have.
  • Project scaffolding and platform builds: frontmcp create, and frontmcp build for Vercel, AWS Lambda and Cloudflare Workers (Deploying Your Server). FastMCP TypeScript's server runs on Node.
  • The older HTTP+SSE transport, for clients that still use it (transport).

Both import tools from an OpenAPI spec (FastMCP TypeScript, FrontMCP), both serve tools from other MCP servers (FastMCP TypeScript, FrontMCP), and both cache results per caller (FastMCP TypeScript, FrontMCP).

When to choose FastMCP TypeScript

  • You use the Python FastMCP, or run Python and TypeScript servers side by side, and want the same model and CLI conventions in both.
  • You want the official SDK v2 underneath, with both protocol eras over HTTP and stdio from one server.
  • You also need a client: for several servers at once, in the browser, or with sampling handled by Anthropic, OpenAI or Google.
  • You assemble a gateway from other servers, with prefixes, proxies and transforms.
  • You want UI screens from a component library, or generated by the model, rather than HTML you write.
  • You want Valibot or ArkType rather than Zod, or you're on Node 22.

When to choose FrontMCP

  • The server is growing, and you want shared services, several apps, hooks and plugins to organise it (Structuring a Server).
  • You want agents, background jobs, workflows or MCP tasks from the same framework.
  • You run several instances behind a load balancer and want 2025-era sessions to work on all of them (Running Several Instances).
  • You want tests written against your server with a dedicated library, or a build for Vercel, AWS Lambda or Cloudflare Workers.
  • You want FrontMCP to be the OAuth server, with client ID metadata documents.

How this was checked

On 2026-10-20 we installed @prefecthq/fastmcp-ts 1.7.3, with Node 24.18.1 and npm 11.16.0, ran the server above over stdio, with its CLI and with tsx, and over 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, with the MCP-Protocol-Version: 2026-07-28 header and the revision in _meta. Over stdio and over HTTP, all five answered and returned 5; over HTTP each older revision got an Mcp-Session-Id, and none did with stateless: true. server/discover listed only 2026-07-28 in supportedVersions. We didn't try the OAuth server, the apps layer or the client's sampling adapters.

FrontMCP serves all five revisions over Streamable HTTP and stdio. Its stdio router returns discovery and resultType results for 2026-07-28, and keeps initialize sessions for older clients. Changed in 1.10.5: before, server/discover over stdio returned -32601 and a 2026-07-28 call received an older-revision result. The overview describes the method for every library.