payloadcms/payload · error · APIError
Missing request URL
Error message
Missing request URL
What it means
The mcpEndpoint handler requires req.url because it parses query parameters (overrideAccess). If req.url is falsy it throws APIError 400. This normally only happens for synthetic/programmatic requests, not real HTTP requests which always carry a URL.
Source
Thrown at packages/plugin-mcp/src/endpoint/index.ts:16
import type { PayloadHandler, PayloadRequest } from 'payload'
import {
createMcpHandler,
isLegacyRequest,
WebStandardStreamableHTTPServerTransport,
} from '@modelcontextprotocol/server'
import { APIError } from 'payload'
import { buildMcpServer } from '../mcp/buildMcpServer.js'
import { getPluginConfig } from '../utils/getPluginConfig.js'
import { getAuthorizedMCP } from './access.js'
export const mcpEndpoint: PayloadHandler = async (req) => {
if (!req.url) {
throw new APIError('Missing request URL', 400)
}
req.payloadAPI = 'MCP' as const
const pluginConfig = getPluginConfig({ config: req.payload.config })
const overrideAccessParam = new URL(req.url).searchParams.get('overrideAccess')
if (overrideAccessParam !== null && process.env.NODE_ENV !== 'development') {
throw new APIError('MCP overrideAccess is only available in development.', 400)
}
let overrideAccess = false
if (overrideAccessParam === 'true') {
overrideAccess = true
} else if (overrideAccessParam !== null && overrideAccessParam !== 'false') {
throw new APIError('MCP overrideAccess must be "true" or "false".', 400)
}
View on GitHub (pinned to 00c58b35c0)
Solutions
- Ensure req.url is set (e.g. 'http://localhost/api/mcp') before invoking the handler.
- In tests, build the request through Payload's normal HTTP path or a complete mock.
- If writing a custom adapter, populate url from the incoming request line.
Defensive patterns
Strategy: validation
Validate before calling
if (!req.url) {
// in tests/adapters, set a URL before invoking the handler
req.url = 'http://localhost/api/mcp'
} Type guard
const hasUrl = (req: PayloadRequest): boolean => typeof req.url === 'string' && req.url.length > 0
Prevention
- In tests, build requests via Payload's HTTP path or a complete mock including url.
- Custom adapters must populate url from the request line.
- Don't call mcpEndpoint with a hand-built minimal request object.
When it happens
Trigger: Invoking the handler directly in tests without setting req.url; a request adapter that strips the url; a job/programmatic context constructing a PayloadRequest manually.
Common situations: Unit tests calling mcpEndpoint(req) with a minimal mock; a custom server adapter that fails to populate url; integration harness building requests by hand.
Related errors
- Unauthorized, you must be logged in to make this request.
- MCP overrideAccess is only available in development.
- MCP overrideAccess must be "true" or "false".
- Content-Type expected to be application/json
- Invalid upload instructions request
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/f1138e53f3c1a452.
Report an issue: GitHub.