# FrontMCP vs xmcp

> How FrontMCP and xmcp differ in protocol support, tool declaration, auth, widgets and deployment, and when to choose each.

Source: https://frontmcp.dev/compare/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](https://frontmcp.dev/compare).

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](https://xmcp.dev) is made by basement.studio and is MIT-licensed ([repository](https://github.com/basementstudio/xmcp), [license](https://github.com/basementstudio/xmcp/blob/c8f41e16adba244d2989137ba2d559f72e401ee2/license.md)). The runtime is the [`xmcp`](https://www.npmjs.com/package/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](https://www.npmjs.com/package/xmcp?activeTab=versions)).

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`](https://github.com/basementstudio/xmcp/blob/c8f41e16adba244d2989137ba2d559f72e401ee2/packages/xmcp/package.json)).

On 2026-10-10, xmcp had 1,333 GitHub stars ([GitHub API](https://api.github.com/repos/basementstudio/xmcp)) and 17,014 npm downloads in the week of 2026-10-02 to 2026-10-08 ([npm API](https://api.npmjs.org/downloads/point/last-week/xmcp)). 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](https://xmcp.dev/docs/getting-started/installation) describes, replaced the example tool with this file, and set the port:

```ts src/tools/add.ts
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;
}
```

```ts xmcp.config.ts
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:

```json
{"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:

```ts add.tool.ts active
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 };
  }
}
```

```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");
});
```

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](https://frontmcp.dev/learn/your-first-tool#returning-results-and-errors)). [`frontmcp create`](https://frontmcp.dev/reference/cli#frontmcp-create) scaffolds a project, [`frontmcp dev`](https://frontmcp.dev/reference/cli#frontmcp-dev) runs it with reload, and it needs Node 24 or later ([Installation](https://frontmcp.dev/learn/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](https://xmcp.dev/docs/configuration/transports)) | 2024-11-05 to 2026-07-28 ([Error codes](https://frontmcp.dev/reference/errors)) |
| Declaring a tool | A file per tool in `src/tools/`, exporting `schema`, `metadata` and a handler ([Tools](https://xmcp.dev/docs/core-concepts/tools)) | A [`@Tool`](https://frontmcp.dev/reference/sdk/tool) class or `tool()` function, listed in an `@App` |
| Schemas | Zod fields; `outputSchema` for structured output ([Structured Outputs](https://xmcp.dev/docs/core-concepts/tools#structured-outputs)); experimental schemas inferred from TypeScript types ([Schema inference](https://xmcp.dev/docs/configuration/schema-inference)) | Zod 4; `outputSchema` checks every result ([Schemas Are Contracts](https://frontmcp.dev/learn/schemas-are-contracts)) |
| Shared services | No container documented. A request context, HTTP middleware and MCP middleware ([Request context](https://xmcp.dev/docs/core-concepts/request-context), [Middlewares](https://xmcp.dev/docs/core-concepts/middlewares)) | [`@Provider`](https://frontmcp.dev/reference/sdk/provider) services, read with `this.get()`; [hooks](https://frontmcp.dev/reference/sdk/hooks) and [plugins](https://frontmcp.dev/reference/sdk/plugin) |
| Auth | API key and JWT middleware ([API key](https://xmcp.dev/docs/authentication/api-key), [JWT](https://xmcp.dev/docs/authentication/jwt)); OAuth through plugins for Auth0, Better Auth, Clerk, Descope, Scalekit and WorkOS ([Authentication](https://xmcp.dev/docs/guides/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](https://frontmcp.dev/reference/auth/modes)); per-entry rules ([Authorities](https://frontmcp.dev/reference/auth/authorities)) |
| Testing | No testing guide. The docs check tools with the MCPJam inspector ([Tools](https://xmcp.dev/docs/core-concepts/tools#elicitation)) | `@frontmcp/testing` with MCP matchers, run by `frontmcp test` ([Testing](https://frontmcp.dev/reference/testing)) |
| Resources, prompts, completions, elicitation | All four, plus sampling ([Resources](https://xmcp.dev/docs/core-concepts/resources), [Prompts](https://xmcp.dev/docs/core-concepts/prompts), [completion](https://xmcp.dev/docs/core-concepts/resources#resource-template-completion), [Elicitation](https://xmcp.dev/docs/core-concepts/tools#elicitation)) | 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()`](https://frontmcp.dev/reference/sdk/contexts#thissample-and-thislistroots) for clients that offer sampling |
| 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) | A tool written as a React component or HTML gets a `ui://` resource; a host bridge and `@xmcp-dev/ui` ([MCP Apps](https://xmcp.dev/docs/core-concepts/mcp-apps)) | 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, stateless, with no sessions ([Transports](https://xmcp.dev/docs/configuration/transports)) | Streamable HTTP with or without sessions, the older HTTP+SSE, stdio, a Unix socket, in-memory ([`FrontMcpInstance`](https://frontmcp.dev/reference/sdk/frontmcp-instance)) |
| Runtimes and deployment | Node 22+; Vercel with no configuration ([Vercel](https://xmcp.dev/docs/deployment/vercel)), Cloudflare Workers ([Cloudflare](https://xmcp.dev/docs/deployment/cloudflare)); adapters for Next.js, Express, Fastify, NestJS, Hono, SvelteKit, Nuxt, React Router, Astro and TanStack Start ([Next.js](https://xmcp.dev/docs/adapters/nextjs)) | Node 24+; `frontmcp build` for Node, Vercel, AWS Lambda, Cloudflare Workers and a browser module ([Production build](https://frontmcp.dev/reference/deployment/production-build)); [`createFetchHandler()`](https://frontmcp.dev/reference/sdk/create-fetch-handler) for other runtimes |
| CLI | `create-xmcp-app`, `init-xmcp`, `xmcp dev`, `xmcp build`, `xmcp create tool` ([Installation](https://xmcp.dev/docs/getting-started/installation)) | `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/basementstudio/xmcp/blob/c8f41e16adba244d2989137ba2d559f72e401ee2/license.md) | [Apache-2.0](https://github.com/agentfront/frontmcp/blob/main/LICENSE) |

## 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](https://xmcp.dev/docs/getting-started/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](https://xmcp.dev/docs/adapters/nextjs)). FrontMCP's [`createFetchHandler()`](https://frontmcp.dev/reference/sdk/create-fetch-handler) can be a route in a framework that hands you a `Request`, but this site has no adapter guides.
- **Ready-made OAuth plugins** for Auth0, Clerk, WorkOS, Descope, Scalekit and Better Auth ([Authentication](https://xmcp.dev/docs/guides/authentication)), where FrontMCP's [`remote` mode](https://frontmcp.dev/reference/auth/remote) takes a provider you configure.
- **Monetization plugins**: Polar, x402, Stripe and others ([Monetization](https://xmcp.dev/docs/guides/monetization)).
- **Input schemas inferred from TypeScript types**, as an experiment ([Schema inference](https://xmcp.dev/docs/configuration/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](https://frontmcp.dev/learn/sharing-state-with-providers) with scopes that tools, resources and prompts ask for.
- **Sessions for clients before 2026-07-28**, which [Redis](https://frontmcp.dev/reference/deployment/redis) can share between instances. xmcp's HTTP transport keeps no sessions.
- **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).
- **A test library** with MCP matchers and fixtures ([Testing Your Server](https://frontmcp.dev/learn/testing-your-server)).
- **An OAuth server without another library**: in `local` mode FrontMCP serves the sign-in page and issues the tokens, and you check the user in `authenticate` ([Local auth](https://frontmcp.dev/reference/auth/local#checking-users-yourself)). xmcp gets this from its Better Auth plugin, which uses PostgreSQL ([Better Auth](https://xmcp.dev/docs/integrations/better-auth)).
- **Plugins for caching, memory, approvals, feature flags and CodeCall** ([Plugins and adapters](https://frontmcp.dev/reference/plugins)). 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`](https://frontmcp.dev/reference/sdk/frontmcp#transport)).
- **AWS Lambda as a build target** ([AWS Lambda](https://frontmcp.dev/reference/deployment/aws-lambda)). xmcp documents Lambda through its Fastify adapter ([Fastify](https://xmcp.dev/docs/adapters/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](https://xmcp.dev/docs/guides/import-openapi)), a command the published CLI didn't have yet ([below](#how-this-was-checked)); FrontMCP has an [OpenAPI adapter](https://frontmcp.dev/reference/adapters/openapi).

## 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](https://frontmcp.dev/learn/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](https://xmcp.dev/docs/configuration/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](https://frontmcp.dev/compare#how-this-was-checked) describes the method for every library.
