Deploy MCP servers to Vercel

Deploy your Model Context Protocol (MCP) servers on Vercel to take advantage of serverless functions, OAuth authentication, and efficient scaling for AI applications.

Use the mcp-handler package and create the following API route to host an MCP server that provides a single tool that rolls a dice.

app/api/mcp/route.ts
import { z } from 'zod';
import { createMcpHandler } from 'mcp-handler';
 
const handler = createMcpHandler(
  (server) => {
    server.tool(
      'roll_dice',
      'Rolls an N-sided die',
      { 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}!` }],
        };
      },
    );
  },
  {},
  { basePath: '/api' },
);
 
export { handler as GET, handler as POST, handler as DELETE };

This assumes that your MCP server application, with the above-mentioned API route, runs locally at http://localhost:3000.

  1. Run the MCP inspector:
terminal
npx @modelcontextprotocol/inspector@latest http://localhost:3000
  1. Open the inspector interface:
    • Browse to http://127.0.0.1:6274 where the inspector runs by default
  2. 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 from the terminal where your MCP server is running
    • Click Connect
  3. Test the tools:
    • Click List Tools under Tools
    • Click on the roll_dice tool
    • 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.

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.

The mcp-handler provides built-in OAuth support to secure your MCP server. This ensures that only authorized clients with valid tokens can access your tools.

To add OAuth authorization to the MCP server you created in the previous section:

  1. Use the withMcpAuth function to wrap your MCP handler
  2. Implement token verification logic
  3. Configure required scopes and metadata path
app/api/[transport]/route.ts
import { withMcpAuth } from 'mcp-handler';
import { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
 
const handler = createMcpHandler(/* ... same configuration as above ... */);
 
const verifyToken = async (
  req: Request,
  bearerToken?: string,
): Promise<AuthInfo | undefined> => {
  if (!bearerToken) return undefined;
 
  const isValid = bearerToken === '123';
  if (!isValid) return undefined;
 
  return {
    token: bearerToken,
    scopes: ['read:stuff'],
    clientId: 'user123',
    extra: {
      userId: '123',
    },
  };
};
 
const authHandler = withMcpAuth(handler, verifyToken, {
  required: true,
  requiredScopes: ['read:stuff'],
  resourceMetadataPath: '/.well-known/oauth-protected-resource',
});
 
export { authHandler as GET, authHandler as POST };

To comply with the MCP specification, your server must expose a metadata endpoint that provides OAuth configuration details. Among other things, this endpoint allows MCP clients to discover, how to authorize with your server, which authorization servers can issue valid tokens, and what scopes are supported.

  1. In your app/ directory, create a .well-known folder.
  2. Inside this directory, create a subdirectory called oauth-protected-resource.
  3. In this subdirectory, create a route.ts file with the following code for that specific route.
  4. Replace the https://example-authorization-server-issuer.com URL with your own Authorization Server (AS) Issuer URL.
app/.well-known/oauth-protected-resource/route.ts
import {
  protectedResourceHandler,
  metadataCorsOptionsRequestHandler,
} from 'mcp-handler';
 
const handler = protectedResourceHandler({
  authServerUrls: ['https://example-authorization-server-issuer.com'],
});
 
export { handler as GET, metadataCorsOptionsRequestHandler 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.

By using Vercel to deploy your MCP server, you take advantage of Vercel Functions with Fluid compute to optimize your cost and usage. MCP servers often experience irregular usage patterns with a combination of long idle times, quick succession of messages and heavy AI workloads.

With Fluid compute's optimized concurrency and dynamic scaling, you only pay for the compute resources you actually use with the minimum amount of idle time. If your MCP server function needs to process AI heavy workloads, Fluid compute's ability to share instances increases performance efficiently.

Learn how to deploy MCP servers on Vercel, connect to them using the AI SDK, and explore curated lists of public MCP servers.

Last updated on August 14, 2025