FrontMCP vs xmcp
xmcp is a TypeScript framework for MCP servers in which every tool is a file: put add.ts in src/tools/, and xmcp finds it, builds the server and serves it. FrontMCP declares tools as decorated classes that you list in an app, and adds a container for shared services, 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.
This site documents FrontMCP, so read it knowing who wrote it. Every xmcp fact below comes from xmcp's own documentation, repository and npm entries for 1.7.1, 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 xmcp is
xmcp is made by basement.studio and is MIT-licensed (repository, license). The runtime is the xmcp package; create-xmcp-app scaffolds a project, and @xmcp-dev/compiler builds it. Its first release was on 2025-05-17, 1.0.0 came out on 2026-08-22, and 1.7.1, the version checked here, on 2026-10-09 (npm).
xmcp is built on v2 of the official MCP TypeScript SDK, which it bundles into its build, so the xmcp package has no dependencies of its own (package.json).
On 2026-10-10, xmcp had 1,333 GitHub stars (GitHub API) and 17,014 npm downloads in the week of 2026-10-02 to 2026-10-08 (npm API). FrontMCP had 146 stars and 8,479 downloads of @frontmcp/sdk in the same week. xmcp is the more widely used of the two.
The same tool in both
One tool, add, that takes two numbers and returns their sum, called with { "a": 2, "b": 3 }.
In xmcp
We scaffolded a project with npx create-xmcp-app@1.7.1 hello -y --use-npm --http --stdio, as the installation guide describes, replaced the example tool with this file, and set the port:
import { z } from "zod";
import { type ToolMetadata, type InferSchema } from "xmcp";
export const schema = {
a: z.number(),
b: z.number(),
};
export const metadata: ToolMetadata = {
name: "add",
description: "Add two numbers",
};
export default function add({ a, b }: InferSchema<typeof schema>) {
return a + b;
}import { type XmcpConfig } from "xmcp";
const config: XmcpConfig = {
http: {
port: 3202,
},
stdio: true,
paths: {
tools: "./src/tools",
prompts: "./src/prompts",
resources: "./src/resources",
},
template: {
icons: [{ src: "./xmcp.svg" }],
}
};
export default config;npm run build (xmcp build) compiled an HTTP and a stdio server in under a second, and node dist/http.js served the HTTP one at http://127.0.0.1:3202/mcp. Calling add returned:
{"content":[{"type":"text","text":"5"}]}
The tool's name could have come from its file name alone, and a plain return value became a text block. xmcp dev runs the same project with hot reload. The built dist/ folder, 1.7 MB, ran on its own, in a folder without node_modules.
In FrontMCP
The same tool as a class, and a server that lists it in an app. The Playground runs it and calls add; the Tests tab runs the checks:
import { 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 };
}
}Starting FrontMCP in your browser…
FrontMCP starts when this example comes into view.
Both use Zod fields for the input. FrontMCP lists each tool in an app instead of finding it by its file, and returns an object, which arrives as structuredContent with a text copy (Your First Tool). frontmcp create scaffolds a project, frontmcp dev runs it with reload, and it needs Node 24 or later (Installation); xmcp needs Node 22 or later.
Side by side
| xmcp 1.7.1 | FrontMCP 1.9.4 | |
|---|---|---|
| MCP revisions served | 2024-11-05 to 2026-07-28, over HTTP and stdio (Transports) | 2024-11-05 to 2026-07-28 (Error codes) |
| Declaring a tool | A file per tool in src/tools/, exporting schema, metadata and a handler (Tools) | A @Tool class or tool() function, listed in an @App |
| Schemas | Zod fields; outputSchema for structured output (Structured Outputs); experimental schemas inferred from TypeScript types (Schema inference) | Zod 4; outputSchema checks every result (Schemas Are Contracts) |
| Shared services | No container documented. A request context, HTTP middleware and MCP middleware (Request context, Middlewares) | @Provider services, read with this.get(); hooks and plugins |
| Auth | API key and JWT middleware (API key, JWT); OAuth through plugins for Auth0, Better Auth, Clerk, Descope, Scalekit and WorkOS (Authentication) | 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); per-entry rules (Authorities) |
| Testing | No testing guide. The docs check tools with the MCPJam inspector (Tools) | @frontmcp/testing with MCP matchers, run by frontmcp test (Testing) |
| Resources, prompts, completions, elicitation | All four, plus sampling (Resources, Prompts, completion, Elicitation) | All four (@Resource, @Prompt, completers, this.elicit); this.sample() for clients that offer sampling |
| Agents, jobs, workflows | Not documented | @Agent, @Job, @Workflow |
| Widgets (MCP Apps) | A tool written as a React component or HTML gets a ui:// resource; a host bridge and @xmcp-dev/ui (MCP Apps) | A tool's ui option, for MCP Apps hosts and the OpenAI Apps SDK (Tool UI, Hosts) |
| Transports | stdio; Streamable HTTP, stateless, with no sessions (Transports) | Streamable HTTP with or without sessions, the older HTTP+SSE, stdio, a Unix socket, in-memory (FrontMcpInstance) |
| Runtimes and deployment | Node 22+; Vercel with no configuration (Vercel), Cloudflare Workers (Cloudflare); adapters for Next.js, Express, Fastify, NestJS, Hono, SvelteKit, Nuxt, React Router, Astro and TanStack Start (Next.js) | Node 24+; frontmcp build for Node, Vercel, AWS Lambda, Cloudflare Workers and a browser module (Production build); createFetchHandler() for other runtimes |
| CLI | create-xmcp-app, init-xmcp, xmcp dev, xmcp build, xmcp create tool (Installation) | frontmcp create, dev, build, test, inspector (CLI); an Nx plugin |
| License | MIT | Apache-2.0 |
What each does that the other doesn't
What xmcp documents and this site doesn't show for FrontMCP:
- Tools found by their file. Adding a file adds a tool, with no list to update (Project structure).
- Adapters for web frameworks. xmcp mounts in ten of them, and its Next.js adapter has auth helpers of its own (Next.js). FrontMCP's
createFetchHandler()can be a route in a framework that hands you aRequest, but this site has no adapter guides. - Ready-made OAuth plugins for Auth0, Clerk, WorkOS, Descope, Scalekit and Better Auth (Authentication), where FrontMCP's
remotemode takes a provider you configure. - Monetization plugins: Polar, x402, Stripe and others (Monetization).
- Input schemas inferred from TypeScript types, as an experiment (Schema inference).
- A self-contained build: the compiled server runs without
node_modules.
What FrontMCP does that xmcp's docs don't document:
- A dependency container: providers with scopes that tools, resources and prompts ask for.
- Sessions for clients before 2026-07-28, which Redis can share between instances. xmcp's HTTP transport keeps no sessions.
- Agents, jobs and workflows: agents, background jobs and workflows.
- A test library with MCP matchers and fixtures (Testing Your Server).
- An OAuth server without another library: in
localmode FrontMCP serves the sign-in page and issues the tokens, and you check the user inauthenticate(Local auth). xmcp gets this from its Better Auth plugin, which uses PostgreSQL (Better Auth). - Plugins for caching, memory, approvals, feature flags and CodeCall (Plugins and adapters). xmcp's integrations cover rate limiting, through Upstash, and error reporting, through Sentry.
- The older HTTP+SSE transport, for clients that still use it (
transport). - AWS Lambda as a build target (AWS Lambda). xmcp documents Lambda through its Fastify adapter (Fastify).
Both serve MCP Apps widgets from React components, and both deploy to Vercel and Cloudflare Workers. xmcp's docs describe importing tools from an OpenAPI spec with @xmcp-dev/cli (Import OpenAPI), a command the published CLI didn't have yet (below); FrontMCP has an OpenAPI adapter.
When to choose xmcp
- You like file-based routing: a tool is a file with a function, and the framework does the wiring.
- Your MCP server lives in a web app, such as a Next.js or Nuxt project, and you want an adapter for it.
- You deploy to Vercel and want it to work without configuration.
- You sign users in with Auth0, Clerk, WorkOS or another provider xmcp has a plugin for, or you want to charge for tools.
- You want the more widely used of the two today.
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 need sessions for 2025-era clients, or the older HTTP+SSE transport.
- You want agents, background jobs or workflows from the same framework.
- You want tests written against your server with a dedicated library.
- You want FrontMCP to be the OAuth server without adding another auth library.
How this was checked
On 2026-10-10 we scaffolded an xmcp 1.7.1 project, built it, called add over HTTP and over stdio, and ran xmcp dev. 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: both servers answered all five. xmcp sends anonymous build telemetry unless XMCP_TELEMETRY_DISABLED=true is set (Telemetry); our first build didn't set it. Commands the docs show for @xmcp-dev/cli, such as call and import-openapi, weren't in the published version (0.1.2) and answered Unknown command. The overview describes the method for every library.