FrontMCP vs ViteMCP
ViteMCP is a TypeScript framework for stateless MCP servers, written for MCP 2026-07-28 by the author of FastMCP for TypeScript, whose API and history it continues: one ViteMCP object holds the whole server, with addTool(), addResource(), addPrompt(), then start(). FrontMCP declares the same things with decorators and adds a container for shared services, sessions for older clients, agents and jobs, widgets, 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 ViteMCP fact below comes from ViteMCP's own README, source and npm entry at 1.9.5, 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 ViteMCP when you want the one-object API of punkpeye's FastMCP on MCP 2026-07-28: one file, no build step, any Standard Schema library, and stateless servers on Node, Cloudflare Workers or Deno Deploy. Choose FrontMCP over ViteMCP when your clients on MCP 2025-11-25 or earlier need sessions, or when you want shared services, agents, jobs, widgets and a test library in the same framework.
What ViteMCP is
ViteMCP is published on npm as @vitemcp/server, which names Frank Fiegel as its author and, like fastmcp, has punkpeye as its maintainer. It's MIT-licensed (LICENSE). Its first release was 1.0.0 on 2026-08-06; 1.9.5, the version checked here, came out on 2026-10-17, after 33 versions (npm). Its documentation is the README and two guides in docs/, for OAuth and OpenAPI.
Its README calls it "a TypeScript framework for building stateless MCP servers", and says it "targets MCP revision 2026-07-28, which made the protocol stateless" (README). It "continues FastMCP, whose commit history this repository carries" (Acknowledgements): FastMCP's commits from December 2024 are in both repositories, and FastMCP's own README points to ViteMCP for 2026-07-28 (FastMCP README). The API is FastMCP's, without what 2026-07-28 removed: sessions, ping, roots, sampling, streamContent, and an elicit() that waits for the answer (Migrating from the session-based API).
ViteMCP is built on the official SDK, v2: its package.json asks for @modelcontextprotocol/server ^2.0.0, which installed 2.3.1 on 2026-10-20, and for Node 24 or later (package.json). Its HTTP server is Hono (Custom HTTP Routes).
On 2026-10-20, ViteMCP had 16 GitHub stars (GitHub API) and 509 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. ViteMCP is under three months old as a package, though the code it continues has been released since December 2024.
The same tool in both
One tool, add, that takes two numbers and returns their sum, called with { "a": 2, "b": 3 }.
In ViteMCP
This is ViteMCP's Quickstart, as we ran it with @vitemcp/server 1.9.5, zod 4.6.7 and tsx, in a project with "type": "module". It's FastMCP's Quickstart with FastMCP renamed:
import { ViteMCP } from "@vitemcp/server";
import { z } from "zod"; // Or any validation library that supports Standard Schema
const server = new ViteMCP({
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 @vitemcp/server dev server.ts --tool add --args '{"a":2,"b":3}' (Test with mcp-cli) ran it and called the tool:
{
"content": [
{
"type": "text",
"text": "5"
}
]
}
With start({ transportType: "httpStream", httpStream: { port: 3206 } }) instead, the same server answered at http://127.0.0.1:3206/mcp. A client from @modelcontextprotocol/client 2.3.1 called add twice: with its default, which opens a 2025-era connection 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"}]}
The 2025-era call worked although the README says that the server "serves only 2026-07-28" and that clients which don't opt in "will be rejected", unless you pass httpStream: { legacy: "stateless" } (README). In the source, "stateless" is the default when legacy isn't set (ViteMCP.ts), and the server answered initialize for every 2025-era revision without issuing an Mcp-Session-Id. With legacy: "reject", those requests got 400 and -32022 Unsupported protocol version.
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.
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). Both need Node 24 or later; FrontMCP also needs TypeScript's decorator settings (Installation), and frontmcp dev runs it. npm install @vitemcp/server installed 57 packages on 2026-10-20, and npm install @frontmcp/sdk 126.
Side by side
| ViteMCP 1.9.5 | FrontMCP 1.10.5 | |
|---|---|---|
| MCP revisions served | 2024-11-05 to 2026-07-28 over HTTP and stdio in our run, with no session for the older four over HTTP; the README says it serves only 2026-07-28 (README). legacy: "reject" serves 2026-07-28 only | 2024-11-05 to 2026-07-28 over Streamable HTTP and stdio, with a session for the older four (Protocol versions) |
| Declaring a tool | server.addTool({ name, parameters, execute }) (Tools) | A @Tool class, or the tool() function |
| Schemas | Standard Schema: Zod, ArkType, Valibot, or JSON Schema through jsonSchemaAdapter; outputSchema, checked before the result is sent (Tools, Structured Tool Output) | Zod 4; outputSchema checks every result (Schemas Are Contracts, Shaping Tool Results) |
| Shared services | No container documented. Tools get a per-request context with auth, logging and progress (Migrating from the session-based API) | @Provider services, read with this.get(); hooks and plugins |
| Auth | An authenticate(request) hook for keys or tokens; an OAuth proxy with Google, GitHub, Azure and generic providers, client ID metadata documents and discovery endpoints; per-tool canAccess with requireScopes and requireRole (Authentication, OAuth guide) | 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); client ID metadata documents |
| Asking the client for input | A tool returns ctx.inputRequired(), and the client sends the call again with the answers; sampling and roots were removed (Multi round-trip requests) | this.elicit(), which becomes input_required for 2026-07-28 clients; this.sample() and this.listRoots() for clients that offer them |
| Testing | server.connect() with the SDK's InMemoryTransport, vitemcp dev, vitemcp inspect (Unit testing) | @frontmcp/testing with MCP matchers, run by frontmcp test (Testing) |
| Resources, prompts, completions | Resources and templates, prompts, completion of prompt arguments and template parameters (Resources, Prompts, completion) | Resources and templates, prompts, completion of template parameters (@Resource, @Prompt, completers) |
| Agents, jobs, workflows, tasks | Not documented | @Agent, @Job, @Workflow; background tasks |
| Widgets (MCP Apps) | Not documented | A tool's ui option, for MCP Apps hosts and the OpenAI Apps SDK (Tool UI, Hosts) |
| Transports | stdio; Streamable HTTP, stateless; in-memory (HTTP Streaming) | Streamable HTTP with or without sessions, the older HTTP+SSE, stdio, a Unix socket, in-memory (FrontMcpInstance, transport) |
| Runtimes and deployment | Node 24+; EdgeViteMCP for Cloudflare Workers and Deno Deploy, over HTTP only and without built-in auth (Edge Runtime Support) | 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()) |
| CLI | vitemcp dev and vitemcp inspect (Testing and Debugging), and vitemcp validate in vitemcp --help; no project generator | frontmcp create, dev, build, test, inspector (CLI); an Nx plugin |
| License | MIT | Apache-2.0 |
What each does that the other doesn't
What ViteMCP documents, or did in our run, and this site doesn't show for FrontMCP:
- A choice of schema library. Any Standard Schema library works, ArkType and Valibot included, and so does plain JSON Schema. FrontMCP's pages use Zod 4 only.
- Ready-made OAuth providers.
GoogleProvider,GitHubProviderandAzureProviderset up the OAuth proxy for those sign-ins. FrontMCP'sremotemode takes an OpenID Connect provider you configure; a plain OAuth provider such as GitHub, whose users have nosub, can't be used. - Completion of prompt arguments, including from an
enum(Prompt argument auto-completion). This site shows FrontMCP completing resource template parameters only. - HTTPS and mutual TLS on the built-in server, from certificate files (HTTPS Support).
- Deno Deploy is named as a runtime. This site shows a fetch handler for such runtimes but no deployment guide for it.
- A smaller install: 57 packages against FrontMCP's 126, on 2026-10-20.
What FrontMCP does that ViteMCP's README doesn't document:
- Sessions for clients on 2025-11-25 and earlier, which Redis can share between instances. ViteMCP answers those clients without a session.
- Requests from the server to the client:
this.sample()andthis.listRoots()for clients that offer them. ViteMCP's migration table says to "call your LLM provider directly" instead of sampling, and replaces roots with nothing (Migrating from the session-based API). - 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.
- Widgets. A tool's
uioption renders an HTML or React widget for MCP Apps hosts and the OpenAI Apps SDK (Your First Widget). - Plugins for caching, memory, approval, feature flags and CodeCall (Plugins and adapters).
- Sign-in without an upstream provider: in
localmode FrontMCP is the OAuth server and serves the sign-in page, and you check the user inauthenticate(Local auth). ViteMCP's OAuth proxy signs users in through a provider. - Project scaffolding and platform builds:
frontmcp create, andfrontmcp buildfor Vercel, AWS Lambda and Cloudflare Workers (Deploying Your Server). - A test library with MCP matchers and fixtures (Testing Your Server).
Both import tools from an OpenAPI spec: ViteMCP's fromOpenAPI() and FrontMCP's OpenAPI adapter. Both accept clients that identify themselves with a client ID metadata document (FrontMCP).
When to choose ViteMCP
- You use FastMCP for TypeScript and want MCP 2026-07-28: the API is the same, and the README has a migration table for what changed.
- You want the smallest setup that works: one file, no decorators, no build, run with
tsx, and 57 packages installed. - Every request can stand on its own, and you deploy where that matters: serverless platforms, Cloudflare Workers or Deno Deploy.
- You want ArkType, Valibot or plain JSON Schema rather than Zod, or you sign users in with Google, GitHub or Azure and want the provider preset.
When to choose FrontMCP
- Your clients use MCP 2025-11-25 or earlier and need a session: a server that asks them for sampling or roots, or several instances that share sessions.
- 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).
- You want agents, background jobs, workflows, tasks or widgets from the same framework.
- You want tests written against your server with a dedicated library, or a build for Vercel, AWS Lambda or Cloudflare Workers.
- You want the more widely used of the two today: in the week of 2026-10-12 to 2026-10-18, npm counted 15,574 downloads of
@frontmcp/sdkand 509 of@vitemcp/server.
How this was checked
On 2026-10-20 we installed @vitemcp/server 1.9.5, with Node 24.18.1 and npm 11.16.0, 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, 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 the 2025-era initialize answers carried no Mcp-Session-Id, and server/discover listed only 2026-07-28 in supportedVersions. With legacy: "reject", the four older revisions got 400 and -32022. We didn't deploy EdgeViteMCP to Cloudflare Workers or Deno Deploy.
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.