Skip to content

TanStack Start

Integrate xmcp tools, prompts, and resources into TanStack Start server routes.

For the complete documentation index, see llms.txt. Markdown variants of every page are available by appending .md to the URL.

The TanStack Start adapter serves MCP requests through your React Start application's server routes. It supports Node.js and Cloudflare Workers and uses the same file-based tools, prompts, and resources as other xmcp transports.

Automatic setup

From an existing React TanStack Start project, run:

The initializer detects @tanstack/react-start, creates xmcp.config.ts, adds example tools, prompts, and resources, and creates src/routes/mcp.ts. It updates your build and development scripts so the adapter exists before TanStack starts.

Use --yes for noninteractive setup. --route-path src/routes/api creates src/routes/api/mcp.ts, served at /api/mcp. For a custom routes root, supply its directory and check that the generated createFileRoute path matches your router configuration. Existing MCP route files are preserved: use --skip-route to integrate the handler yourself.

If @cloudflare/vite-plugin is installed, the initializer uses Workers builds. You can also select them explicitly:

This configures xmcp's adapter build. Your TanStack app still owns its Vite plugins, Worker entry point, and Wrangler configuration.

Manual setup

Install xmcp and its compiler in your existing app:

xmcp.config.ts

Set a discovery path to false if you do not use that kind of handler. Run pnpm exec xmcp build to generate .xmcp/adapter, then add the route:

src/routes/mcp.ts

The relative import works without adding a Vite alias. Adjust it if you move the route. The adapter is server code: import it only from server handlers, never from a component or client entry.

src/tools/greet.ts

Development and Node.js builds

Keep your host application's build command and run xmcp first:

package.json

The initial build generates the adapter before Vite loads your routes. The xmcp watcher updates discovery as handlers are added or removed; TanStack compiles application modules and their imports. Keep .xmcp/ in .gitignore and run both builds in CI.

For a Node production server, configure your TanStack hosting integration, such as Nitro, as described in the TanStack hosting guide. The Node example includes a complete Vite/Nitro configuration and a start command. The examples require Node 22.12 or newer.

Cloudflare Workers

Configure the app with @cloudflare/vite-plugin and Wrangler following TanStack's Cloudflare instructions. Use nodejs_compat for xmcp's request context storage:

wrangler.jsonc
package.json

With adapter: "tanstack", --cf emits the Workers-compatible adapter in .xmcp/adapter. TanStack builds and serves the Worker. xmcp does not create a standalone worker.js or replace your Wrangler configuration.

Tools and their dependencies must support Workers. Avoid Node-only filesystem APIs in Worker tools. See the Workers example for the complete app and local preview workflow.

Authentication and CORS

Use TanStack server-route middleware or a route-level handler to authenticate requests. Once your application has verified the credentials, pass its MCP authentication information to the adapter:

verifiedToken, verifiedClientId, and verifiedScopes come from your application's credential verification. The adapter forwards this information to tool handlers as extra.authInfo; passing the option does not verify a token. Reject unauthorized requests before calling the adapter.

Configure browser CORS and OPTIONS handling on the TanStack route. The adapter handles the MCP request and leaves application HTTP middleware to TanStack. Existing xmcp MCP middleware remains available for tool-level behavior.

Stateless requests

Each request gets a fresh MCP server. Initialization does not establish a server-side session, and subsequent calls must include their own authentication and client metadata. Modern clients send metadata in the protocol request envelope; older clients can repeat x-mcp-client-name and x-mcp-client-version headers on each call.

The SDK controls protocol responses, including streaming responses and unsupported HTTP methods. Registering GET and DELETE forwards those methods to the SDK; it does not enable persistent sessions.

On this page

One framework to rule them all