Documentation

A Vercel adapter for the Model Context Protocol (MCP), enabling real-time communication between your applications and AI models.

Next.js Support
TypeScript
Real-time

Installation

Terminal
npm install mcp-handler @modelcontextprotocol/sdk zod@^3

# or with yarn
yarn add mcp-handler @modelcontextprotocol/sdk zod@^3

# or with pnpm  
pnpm add mcp-handler @modelcontextprotocol/sdk zod@^3

# or with bun
bun add mcp-handler @modelcontextprotocol/sdk zod@^3

Next.js Usage

Create an API route to handle MCP requests. The route should be placed at app/api/[transport]/route.ts.

app/api/[transport]/route.ts
import { createMcpHandler } from "mcp-handler";
import { z } from "zod";

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}!` }],
        };
      }
    );
  },
  {
    // Optional server options
  },
  {
    // Optional configuration
    basePath: "/api", // this needs to match where the [transport] is located
    maxDuration: 60,
    verboseLogs: true,
  }
);

export { handler as GET, handler as POST };

Client Integration

Connect your MCP server to various AI clients and development environments.

Claude Desktop
Add your MCP server to Claude Desktop's configuration file.

Configuration file locations:

  • • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • • Windows: %APPDATA%\Claude\claude_desktop_config.json
"remote-example": {
  "command": "npx",
  "args": [
    "-y",
    "mcp-remote",
    "http://localhost:3000/api/mcp"
  ]
}
Cursor
Configure Cursor to use your MCP server (supports SSE directly as of v0.48.0).

Configuration file: ~/.cursor/mcp.json

"remote-example": {
  "url": "http://localhost:3000/api/mcp"
}
Windsurf
Connect Windsurf to your MCP server for enhanced AI capabilities.

Configuration file: ~/.codeium/windsurf/mcp_config.json

Configuration Options

The createMcpHandler function accepts the following configuration options:

interface Config {
  redisUrl?: string;        // Redis connection URL for pub/sub
  basePath?: string;        // Base path for MCP endpoints
  maxDuration?: number;     // Maximum duration for SSE connections in seconds
  verboseLogs?: boolean;    // Log debugging information
}

Authorization

The MCP adapter supports the MCP Authorization Specification through the withMcpAuth wrapper.

Basic Authorization Example
import { createMcpHandler, withMcpAuth } from "mcp-handler";
import type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";

// Create your handler as normal
const handler = createMcpHandler((server) => {
  server.tool(
    "echo",
    "Echo a message",
    { message: z.string() },
    async ({ message }, extra) => {
      // Access auth info in your tools via extra.authInfo
      return {
        content: [{
          type: "text",
          text: `Echo: ${message}${
            extra.authInfo?.token 
              ? ` for user ${extra.authInfo.clientId}`
              : ""
          }`,
        }],
      };
    }
  );
});

// Token verification function
const verifyToken = async (
  req: Request,
  bearerToken?: string
): Promise<AuthInfo | undefined> => {
  if (!bearerToken) return undefined;
  
  // Replace with actual token verification logic
  const isValid = bearerToken.startsWith("__TEST_VALUE__");
  
  if (!isValid) return undefined;
  
  return {
    token: bearerToken,
    scopes: ["read:stuff"],
    clientId: "user123",
    extra: { userId: "123" },
  };
};

// Wrap with authorization
const authHandler = withMcpAuth(handler, verifyToken, {
  required: true,
  requiredScopes: ["read:stuff"],
});

export { authHandler as GET, authHandler as POST };
OAuth Protected Resource Metadata
Create the required OAuth metadata endpoint for authorization.

Create app/.well-known/oauth-protected-resource/route.ts:

import {
  protectedResourceHandler,
  metadataCorsOptionsRequestHandler,
} from "mcp-handler";

const handler = protectedResourceHandler({
  authServerUrls: ["https://auth-server.com"],
});

export { 
  handler as GET, 
  metadataCorsOptionsRequestHandler as OPTIONS 
};
Features
  • Framework Support: Next.js (more coming soon)
  • Multiple Transport Options: HTTP & SSE
  • Redis Integration for SSE resumability
  • Full TypeScript Support
Requirements
  • Next.js 13 or later
  • Node.js 18 or later
  • Redis (optional, for SSE transport)
Built with v0