Deploy MCP servers to Vercel
Deploy MCP servers to Vercel
Deploy your Model Context Protocol (MCP) servers on Vercel to take advantage of features like Vercel Functions, OAuth, and efficient scaling for AI applications.
- Get started with deploying MCP servers on Vercel
- Learn how to enable authorization to secure your MCP server
Deploy a Template
HyperFrames on Vercel
Preview HTML video compositions in the browser and render MP4s server-side on Vercel Sandbox.](/content/templates/next.js/hyperframes-on-vercel/index.html)
ChatGPT app with Next.js \
Ship a ChatGPT app on Vercel with Next.js and Model Context Protocol (MCP).](/content/templates/next.js/chatgpt-app-with-next-js/index.html)
x402 AI Starter
A fullstack template for using x402 with MCP and AI SDK.](/content/templates/next.js/x402-ai-starter/index.html)
Deploy MCP servers efficiently
Vercel provides the following features for production MCP deployments:
- Optimized cost and performance: Vercel Functions with Fluid compute handle MCP servers' irregular usage patterns (long idle times, quick message bursts, heavy AI workloads) through optimized concurrency, dynamic scaling, and instance sharing. You only pay for compute resources you actually use with minimal idle time.
- Instant Rollback: Quickly revert to previous production deployments if issues arise with your MCP server.
- Preview deployments with Deployment Protection: Secure your preview MCP servers and test changes safely before production
- Vercel Firewall: Protect your MCP servers from malicious attacks and unauthorized access with multi-layered security
- Rolling Releases: Gradually roll out new MCP server deployments to a fraction of users before promoting to everyone
Deploy an MCP server on Vercel
Use mcp-handler to create an MCP server in an existing Next.js App Router application. You'll need Node.js 20 or later.
Install mcp-handler v2, the MCP server SDK v2, and Zod v4:
pnpm i mcp-handler@2.1.1 @modelcontextprotocol/server@2 zod@4
yarn add mcp-handler@2.1.1 @modelcontextprotocol/server@2 zod@4
npm i mcp-handler@2.1.1 @modelcontextprotocol/server@2 zod@4
bun add mcp-handler@2.1.1 @modelcontextprotocol/server@2 zod@4
Create a route that exposes a tool for rolling an N-sided die:
app/api/mcp/route.ts
import { createMcpHandler } from 'mcp-handler';
import { z } from 'zod';
const handler = createMcpHandler((server) => {
server.registerTool(
'roll_dice',
{
description: 'Roll an N-sided die',
inputSchema: z.object({ sides: z.number().int().min(2) }),
},
async ({ sides }) => {
const value = 1 + Math.floor(Math.random() * sides);
return {
content: [{ type: 'text', text: `🎲 You rolled a ${value}!` }],
};
},
);
});
export { handler as GET, handler as POST };
Clients connect to /api/mcp using Streamable HTTP. Your framework determines the route, so you don't need to configure a base path in mcp-handler.
Version 2 of mcp-handler uses @modelcontextprotocol/server instead of @modelcontextprotocol/sdk, changes tool registration, and removes legacy HTTP+SSE transport and Redis configuration. Follow the migration guide to update an existing server.
Test the MCP server locally
Start your Next.js development server at http://localhost:3000 before opening the MCP Inspector.
- Run the MCP inspector:
pnpm dlx @modelcontextprotocol/inspector@latest
yarn dlx @modelcontextprotocol/inspector@latest
npx @modelcontextprotocol/inspector@latest
bunx @modelcontextprotocol/inspector@latest
- Open the inspector interface:
- Browse to
http://127.0.0.1:6274where the inspector runs by default
- Browse to
- Connect to your MCP server:
- Select Streamable HTTP in the drop-down on the left
- In the URL field, use
http://localhost:3000/api/mcp - Expand Configuration
- In the Proxy Session Token field, paste the token printed in the terminal where MCP Inspector is running
- Click Connect
- Test the tools:
- Click List Tools under Tools
- Click on the
roll_dicetool - Test it through the available options on the right of the tools section
When you deploy your application on Vercel, you will get a URL such as https://my-mcp-server.vercel.app.
Configure an MCP host
Using Cursor, add the URL of your MCP server to the configuration file in Streamable HTTP transport format.
cursor/mcp.json
{
"mcpServers": {
"server-name": {
"url": "https://my-mcp-server.vercel.app/api/mcp"
}
}
}
You can now use your MCP roll dice tool in Cursor's AI chat or any other MCP client.
To call the same tool from your own application, follow the AI SDK or TanStack AI example. Explore MCP integrations for connection and authentication options, including eve.
Enabling authorization
mcp-handler includes helpers for verifying bearer tokens and publishing OAuth protected resource metadata. You provide an authorization server and the logic that validates its tokens. The package does not issue tokens or run an authorization server.
Secure your server with OAuth
Wrap your MCP handler with withMcpAuth and set required: true to require a valid token. Return the verified client's identity and scopes from verifyToken.
The following example uses a token from the MCP_DEMO_TOKEN environment variable for local testing. Set that variable in .env.local before starting your development server. For production, replace the comparison with your authorization server's token verification, including issuer, audience, expiration, and granted scopes.
Replace your MCP route with the following code:
app/api/mcp/route.ts
import type { AuthInfo } from '@modelcontextprotocol/server';
import { createMcpHandler, withMcpAuth } from 'mcp-handler';
import { z } from 'zod';
const verifyToken = async (
_req: Request,
bearerToken?: string,
): Promise<AuthInfo | undefined> => {
if (!bearerToken || bearerToken !== process.env.MCP_DEMO_TOKEN) {
return undefined;
}
return {
token: bearerToken,
scopes: ['read:dice'],
clientId: 'demo-client',
};
};
const authHandler = withMcpAuth(handler, verifyToken, {
required: true,
requiredScopes: ['read:dice'],
resourceMetadataPath: '/.well-known/oauth-protected-resource',
});
export { authHandler as GET, authHandler as POST };
With this configuration, requests without a valid token receive 401. If a verified token lacks a required scope, the handler returns 403.
Expose OAuth metadata endpoint
To comply with the MCP specification, your server must expose a metadata endpoint that provides OAuth configuration details.
How to add OAuth metadata endpoint
- In your
app/directory, create a.well-knownfolder. - Inside this directory, create a subdirectory called
oauth-protected-resource. - In this subdirectory, create a
route.tsorroute.jsfile with the following code. - Replace the
https://example-authorization-server-issuer.comURL with your own Authorization Server (AS) Issuer URL. - Set
resourceUrlto the public URL of your MCP route, including/api/mcp.
app/.well-known/oauth-protected-resource/route.ts
import {
protectedResourceHandler,
metadataCorsOptionsRequestHandler,
} from 'mcp-handler';
const handler = protectedResourceHandler({
authServerUrls: ['https://example-authorization-server-issuer.com'],
resourceUrl: 'https://my-mcp-server.vercel.app/api/mcp',
});
const corsHandler = metadataCorsOptionsRequestHandler();
export { handler as GET, corsHandler as OPTIONS };
To view the full list of values available to be returned in the OAuth Protected Resource Metadata JSON, see the protected resource metadata RFC.
MCP clients that are compliant with the latest version of the MCP spec can now securely connect and invoke tools defined in your MCP server, when provided with a valid OAuth token.