# Using xmcp with Next.js

**Author:** Ben Sabic

---

[xmcp](https://vercel.com/docs/frameworks/backend/xmcp) is a TypeScript-first framework for building MCP (Model Context Protocol) servers. It handles registering tools, prompts, and resources automatically, so you can focus on writing tool logic instead of protocol plumbing. With the Next.js adapter, you can add an MCP endpoint to an existing Next.js app and expose your application's functionality to AI agents and MCP clients. When you deploy to Vercel, the endpoint runs as a Vercel Function with Fluid compute by default, with no extra configuration.

In this guide, you'll add xmcp to an existing Next.js project and expose an MCP endpoint through a Next.js route handler. You'll create a tool with a typed schema and metadata, add authentication to your MCP server, then run the server locally and deploy it to Vercel.

## Prerequisites

Before you begin, make sure you have:

- A [Vercel account](https://vercel.com/signup)
  
- Node.js 20+ and a package manager (e.g., npm)
  
- An existing Next.js project using the App Router
  
- Vercel CLI installed (`npm i -g vercel`)
  

## How it works

xmcp discovers tools, prompts, and resources from dedicated directories in your project and compiles them into a generated `.xmcp` folder. The `@xmcp/adapter` package exposes this compiled server as a standard Next.js route handler, so MCP requests flow through your app like any other API route. Because the adapter runs inside Next.js, xmcp's own `middleware.ts` and `xmcp/headers` features are not supported. Next.js already provides equivalents, and on Vercel, you can also use [Routing Middleware](https://vercel.com/docs/routing-middleware) to run code before a request reaches your app.

## Steps

### 1\. Initialize xmcp in your project

Run the initializer from the root of your Next.js project:

`npx init-xmcp@latest`

The CLI detects your framework and package manager, then prompts you for directory paths:

`? Tools directory path: (tools) ? Prompts directory path: (prompts) ? Resources directory path: (resources) ? Route directory path: (app/mcp)`

Accept the defaults unless your project has a different structure. The initializer creates the tools, prompts, and resources folders, adds the MCP route to your app, and updates your `package.json` scripts to run xmcp alongside Next.js:

`{ "scripts": { "dev": "xmcp dev & next dev", "build": "xmcp build && next build" } }`

### 2\. Configure the TypeScript path mapping

The `@xmcp/adapter` import resolves against the generated `.xmcp` folder, which doesn't exist until the first build. Generate it now:

`npx xmcp build`

Then add the path mapping to your `tsconfig.json`:

`{ "compilerOptions": { "paths": { "@xmcp/*": ["./.xmcp/*"] } } }` After both steps, TypeScript resolves the adapter import without errors. ### 3\. Review the MCP route handler The initializer creates a route handler at the path you chose (default `app/mcp`). It exports the xmcp handler for both `GET` and `POST` requests: `import { xmcpHandler } from "@xmcp/adapter"; export { xmcpHandler as GET, xmcpHandler as POST };` This makes your MCP server available at `/mcp` on your app's domain. MCP clients connect to this endpoint over HTTP. ### 4\. Create a tool Each tool lives in its own file inside the tools directory. A tool file exports three things, including a Zod schema for parameters, a metadata object, and a default function that implements the logic: ``import { z } from "zod"; import { type InferSchema } from "xmcp"; export const schema = { location: z.string().describe("City name"), }; export const metadata = { name: "get-weather", description: "Get current weather for a location", }; export default async function getWeather({ location, }: InferSchema<typeof schema>) { // Your implementation here return `Weather in ${location}: 72°F, Sunny`; }`` xmcp registers the tool automatically based on the file. To add more tools, create additional files in the same directory with the same structure. The `.describe()` calls on schema fields become parameter descriptions that MCP clients show to users and AI models, so write them as you would API documentation. ### 5\. Run the server locally Start the development server: `npm run dev` This runs `xmcp dev` and `next dev` together. Your MCP endpoint is available at `http://localhost:3000/mcp`, and tool changes hot-reload as you edit files. You can connect any MCP client to this URL to test your tools. If you deploy through Vercel, you can also use [Vercel CLI](https://vercel.com/docs/cli/dev) for local development:

`vercel dev`

### 6\. Add authentication

To protect your MCP server, wrap the handler with `withAuth` and supply a token verification function. The function receives the request and bearer token, and returns auth information for valid tokens or `undefined` to reject the request:

`import { xmcpHandler, withAuth, VerifyToken } from "@xmcp/adapter"; const verifyToken: VerifyToken = async (req: Request, bearerToken?: string) => { if (!bearerToken) return undefined; // Validate the token against your auth service const isValid = await checkToken(bearerToken); if (!isValid) return undefined; return { token: bearerToken, scopes: ["read:messages", "write:messages"], clientId: "example-client", }; }; const handler = withAuth(xmcpHandler, { verifyToken, required: true, requiredScopes: ["read:messages"], resourceMetadataPath: "/.well-known/oauth-protected-resource", }); export { handler as GET, handler as POST };` Set `required: true` to reject unauthenticated requests, and use `requiredScopes` to enforce scope checks on every call. The `resourceMetadataPath` option exposes OAuth-protected resource metadata so compliant clients can discover your auth requirements. ### 7\. Deploy to Vercel Deploy by [connecting your Git repository](https://vercel.com/new) or with Vercel CLI:

`vercel deploy`

Your MCP endpoint runs as a [Vercel Function](https://vercel.com/docs/functions) and uses [Fluid compute](https://vercel.com/docs/fluid-compute) by default. Fluid compute lets multiple requests share a single instance, which suits MCP workloads well since tool calls are often I/O-bound while waiting on APIs or databases.

Once deployed, your server is available at `https://your-project.vercel.app/mcp`.

## Troubleshooting

### TypeScript can't resolve `@xmcp/adapter`

The `.xmcp` folder hasn't been generated yet, or the path mapping is missing. Run `npx xmcp build` to generate the folder, then confirm your `tsconfig.json` includes the `@xmcp/*` path mapping from step 2.

### Middleware isn't running

The Next.js adapter doesn't support xmcp's `middleware.ts` or `xmcp/headers`. Use Next.js middleware for request processing in your app, or [Routing Middleware](https://vercel.com/docs/routing-middleware) on Vercel for rewrites, redirects, and headers before a request reaches your application.

## Next steps

- Explore the full [xmcp documentation](https://xmcp.dev/docs) for prompts, resources, and configuration options
  
- Read the [Next.js adapter reference](https://xmcp.dev/docs/adapters/nextjs) for adapter-specific details
  
- Learn how [xmcp runs on Vercel](https://vercel.com/docs/frameworks/backend/xmcp), including standalone (non-Next.js) projects
  
- Understand how [Vercel Functions](https://vercel.com/docs/functions) and [Fluid compute](https://vercel.com/docs/fluid-compute) execute your MCP endpoint

---

[View full KB sitemap](/kb/sitemap.md)
