A Next.js middleware library for handling MCP (Model Context Protocol) server with OAuth2 authorization. This package provides utilities to help developers integrate MCP OAuth2-related processes into their Next.js applications.
- 🛡️ MCP OAuth2 authorization flow support
- ⚡️ Compatible with Next.js 15.5+ middleware mechanism
- 🧩 Extensible middleware architecture for customization
- 🪝 Built-in authentication, registration, and token validation middleware
- 🔧 Flexible token verification with custom endpoints
- Next.js 15.5.2 or higher (required for MCP middleware compatibility)
- Node.js runtime (middleware must use
runtime: 'nodejs'
configuration)
pnpm add nextjs-mcp-middleware
# or
npm install nextjs-mcp-middleware
# or
yarn add nextjs-mcp-middleware
⚠️ We recommend using pnpm for the best dependency compatibility.
Ensure your project has @modelcontextprotocol/sdk
properly installed and configured.
// src/middleware.ts
import { nextMcpMiddleware } from 'nextjs-mcp-middleware'
import type { NextRequest } from 'next/server'
// Token verification function
async function verifyToken(req: Request, bearerToken?: string): Promise<AuthInfo | undefined> {
if (!bearerToken)
return undefined
// MCP client verification logic
return {
token: bearerToken,
scopes: ['profile'], // Add relevant scopes
clientId: '', // Add user/client identifier
extra: {
// Optional extra information
userId: '',
},
}
}
const { middlewareGenerator, matcher } = nextMcpMiddleware({
mcpHandlerParams: {
mcpServer: (server) => {
useMcp(server)
registerTools()
},
mcpHandlerOptions: {},
mcpHandlerConfig: {
basePath: '/api',
maxDuration: 60,
verboseLogs: true,
},
verifyToken,
},
metadata: {
clientId: process.env.SSO_CLIENT_ID || '',
clientSecret: process.env.SSO_CLIENT_SECRET || '',
scopesSupported: ['profile'],
responseTypesSupported: ['code', 'token'],
},
needAuth: true,
authConfig: {
async customAuthEndpoint(params: authCallParams, request: NextRequest) {
const { responseType, clientId, redirectUri, scope, state } = params
return `${process.env.SSO_HOST}/v1/oauth/authorize?response_type=${responseType}&client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}&state=${state}`
},
async customToken(params: tokenCallParams, _request) {
const { code, grantType } = params
const response = await ssoServer.post(
`/v1/oauth/token?code=${code}&grant_type=${grantType}`,
{
headers: {
'Content-Type': 'application/json',
},
}
)
return await response.json()
},
},
})
export const middleware = middlewareGenerator
export const config = {
runtime: 'nodejs', // Required: Must use nodejs runtime
// matcher, // Optional: Use generated matcher or define your own
}
SSO_CLIENT_ID=your_client_id
SSO_CLIENT_SECRET=your_client_secret
SSO_HOST=https://your-sso-server.com
To use your MCP server with Cursor or VSCode Copilot, add the following configuration to your MCP settings:
Add to your Cursor MCP settings:
{
"mcp-remote": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://your-next-server.com/api/mcp",
"9696"
]
}
}
Add to your VSCode MCP settings:
{
"mcp-remote": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://your-next-server.com/api/mcp",
"9696"
]
}
}
Note: Replace
https://your-next-server.com/api/mcp
with your actual Next.js server URL and MCP endpoint. The port9696
is the default MCP port, adjust as needed. This configuration is compatible with both Cursor and VSCode Copilot.
Main function to create MCP middleware with OAuth2 support.
mcpHandlerParams
: MCP server configurationneedAuth
: Enable/disable authentication requirementmetadata
: OAuth2 client metadata,be required withneedAuth: true
clientId
: OAuth2 client_id value, or a function returning itclientSecret
: OAuth2 client_secret value, or a function returning itissuer?
: Authorization server issuer URL (optional)authorizationEndpoint?
: OAuth2 authorization endpoint URL (optional)tokenEndpoint?
: OAuth2 token endpoint URL (optional)registrationEndpoint?
: Dynamic client registration endpoint URL (optional)userinfoEndpoint?
: UserInfo endpoint URL (optional)tokenEndpointAuthMethodsSupported?
: Supported token endpoint auth methods, e.g.['client_secret_basic','client_secret_post']
(optional)scopesSupported
: Supported OAuth2 scopes, e.g.['profile']
responseTypesSupported
: Supported OAuth2 response types, e.g.['code','token']
authConfig
: Custom authentication endpoints configuration be required withneedAuth: true
customAuthEndpoint
: Custom authorization endpoint. Supports two forms:- String: a fixed URL or an intermediate relay URL. You can point this to a relay URL which then performs a second redirect to your final
redirectUri
(e.g./api/relay-auth?redirect_uri=...
). - Function:
(params: authCallParams, request: NextRequest) => Promise<string> | string
for fully dynamic URL construction based onresponseType
,clientId
,redirectUri
,scope
,state
, and the currentrequest
.
- String: a fixed URL or an intermediate relay URL. You can point this to a relay URL which then performs a second redirect to your final
customToken
: Custom token endpoint
AuthInfo
: Token verification result interfaceauthCallParams
: Authorization endpoint parameterstokenCallParams
: Token endpoint parameters
Important: Your middleware configuration must specify runtime: 'nodejs'
:
export const config = {
runtime: 'nodejs', // Required for MCP middleware
}
This package requires Next.js 15.5.2 or higher for proper MCP middleware support.
You can enable verbose middleware logs using the debug
package namespace mcp:middleware
.
Run with environment variable:
# Enable only middleware logs
DEBUG=mcp:middleware pnpm dev
# Enable all mcp-related logs
DEBUG=mcp:* pnpm dev
# Multiple patterns
DEBUG=mcp:middleware,other:debug pnpm dev
During tests (Vitest):
DEBUG=mcp:middleware pnpm test
In the example app (workspace):
pnpm -F example dev:debug
pnpm -F example dev:debug:all
- Fatal error: Error: client_secret_basic authentication requires a client_secret
- This usually means your OAuth client is configured to use
client_secret_basic
but theclient_secret
is missing or not being sent. - Quick fixes:
- Ensure
SSO_CLIENT_SECRET
is set in your environment and correctly loaded by your Next.js app. - If you recently changed credentials or scopes in local development, clear the local MCP auth cache:
rm -rf ~/.mcp-auth
- Restart your MCP client (Cursor/VSCode Copilot) and your Next.js server, then retry.
- Ensure
- This usually means your OAuth client is configured to use
For Chinese documentation, see
docs/README.zh-CN.md
.