Wenn du nach "Next.js MCP server" suchst, landest du bei zwei verschiedenen Aufgaben, die sich einen Namen teilen. Die einen wollen, dass ihr Coding-Agent in die Next.js-App hineinschauen kann, die sie gerade bauen: die Fehler auf der Seite, die Routen, die Build-Probleme. Die anderen wollen ihre Next.js-App in einen MCP server verwandeln, damit Claude oder ChatGPT Tools aufrufen können, die ihre Seite bereitstellt. Die meisten Seiten, die wir gelesen haben, behandeln nur eine der beiden und verwischen die andere, und viele zeigen für die zweite Aufgabe noch die alte Version der Library.
Dieser Guide deckt beides ab. Wir haben jeden Befehl und jedes Codebeispiel unten am 14. November 2026 ausgeführt, mit Next.js 16.4.6, next-devtools-mcp 0.4.0, mcp-handler 2.4.0, @modelcontextprotocol/server 2.4.0 und zod 4.6.7, auf macOS. Wo das Ergebnis von der Doku abwich, sagen wir es.
Welches brauchst du?
| Du willst | Nutze | Läuft | Die KI bekommt |
|---|---|---|---|
| Claude Code, Cursor oder Codex beim Debuggen der App helfen lassen, die du gerade schreibst | Eingebautes /_next/mcp plus next-devtools-mcp |
Deine Maschine, nur next dev |
Live-Fehler, Routen, Logs, Compile-Checks, versionspassende Docs |
| KI-Apps Tools aus deinem Produkt geben (Suche, Bestellungen, Docs) | Deine eigene Route mit mcp-handler |
Wo auch immer die App deployed ist | Die Tools, die du schreibst, sonst nichts |
| Beides | Beides, sie kollidieren nicht |
Wenn du unsicher bist, willst du wahrscheinlich das erste. Es braucht einen Befehl und keinen Code.
Teil 1: Verbinde deinen Coding-Agent mit einer laufenden Next.js-App
Was Next.js 16 unter /_next/mcp bereitstellt
Seit Next.js 16 beantwortet next dev MCP-Anfragen unter /_next/mcp. Das ist standardmäßig aktiv. Wir haben tools/list per curl dorthin geschickt und neun Tools zurückbekommen:
| Tool | Was es zurückgibt | Benötigt |
|---|---|---|
get_errors |
Aktuelle Fehler: next.config-Validierung, Browser-Runtime-Fehler, Build-Fehler mit source-gemappten Stacks |
Die im Browser geöffnete Seite für Runtime-Fehler |
get_logs |
Pfad zur Dev-Log-Datei mit Browser-Konsole und Server-Ausgabe | |
get_page_metadata |
Was zum aktuellen Seiten-Render beigetragen hat | Die im Browser geöffnete Seite |
get_project_metadata |
Projektpfad und Dev-Server-URL | |
get_routes |
Jede Route gruppiert nach appRouter und pagesRouter, dynamische Segmente als [param] |
|
get_server_action_by_id |
Quelldatei und Exportname einer Server Action | |
get_compilation_issues |
Resolve-Fehler, fehlende Module, Transform-Fehler über alle Routen | Turbopack |
compile_route |
Eine Route kompilieren, ohne sie anzufragen | Turbopack |
get_request_insights |
Aktuelle Request-Timelines, Fetches und Cache-Verhalten | experimental.requestInsights |
Der Server nannte sich selbst "Next.js MCP Server" in Version 0.2.0. In unserer Test-App mit zwei Seiten gab get_routes genau das zurück, was wir hatten: / und /api/mcp.
Die Compile-Tools sind der stille Gewinn. Ein Agent, der gerade drei Dateien bearbeitet hat, kann den laufenden Dev-Server fragen, ob sie kompilieren, statt einen kompletten next build zu starten, während der Code halb fertig ist.
Zwei Einschränkungen solltest du kennen, bevor du dich darauf verlässt. Es existiert nur in der Entwicklung: Wir haben dieselbe App gebaut und next start ausgeführt, und /_next/mcp gab 404 zurück. Und es braucht Next.js 16. Auf 15 gibt es unter diesem Pfad nichts; npx @next/codemod@latest upgrade latest ist der Upgrade-Weg, den das Tooling selbst vorschlägt.
Um es abzuschalten, setzt du experimental.mcpServer in next.config auf false.
next-devtools-mcp installieren
Dein Agent spricht nicht direkt mit /_next/mcp. Das Paket next-devtools-mcp ist ein kleiner stdio-Server, der laufende Dev-Server findet und Aufrufe an sie weiterleitet. Seit Version 0.4.0 ist es ein schlanker Connector mit vier Tools:
nextjs_indexlistet die laufenden Next.js-Dev-Server und die Tools auf, die jeder bereitstellt.nextjs_callführt eines dieser Tools auf einem Server aus, gegeben dessenportundtoolName.nextjs_docsverweist den Agent auf die Docs, die in deinem installierten Next.js unternode_modules/next/dist/docs/mitgeliefert werden, damit die Antworten zu deiner Version passen.browser_evalverweist den Agent auf dieagent-browserCLI, um Seiten in einem echten Browser zu prüfen.
Es braucht Node.js 20.19 oder neuer. Wähle deinen Client:
Claude Code
claude mcp add next-devtools npx next-devtools-mcp@latest
Codex
codex mcp add next-devtools -- npx next-devtools-mcp@latest
Unter Windows 11 braucht Codex laut README außerdem env = { SystemRoot="C:\\Windows", PROGRAMFILES="C:\\Program Files" } und startup_timeout_ms = 20_000 in .codex/config.toml.
Gemini CLI
gemini mcp add next-devtools npx next-devtools-mcp@latest
Füge -s user hinzu, um es für jedes Projekt statt nur für das aktuelle zu installieren.
VS Code mit Copilot
code --add-mcp '{"name":"next-devtools","command":"npx","args":["-y","next-devtools-mcp@latest"]}'
Cursor oder jeder Client, der eine JSON-Datei liest
{
"mcpServers": {
"next-devtools": {
"command": "npx",
"args": ["-y", "next-devtools-mcp@latest"]
}
}
}
Lege sie in .mcp.json im Projekt-Root ab, um sie über git mit dem Team zu teilen, oder in ~/.cursor/mcp.json nur für Cursor.
Alle Agents auf einmal
npx add-mcp next-devtools-mcp@latest
add-mcp schreibt den Eintrag für jeden Coding-Agent, den es auf der Maschine findet.
Prüfen, ob es funktioniert
Starte zuerst den Dev-Server. Öffne dann die Seite, an der du arbeitest, im Browser, denn get_errors und get_page_metadata lesen aus laufenden Browser-Sessions. Frage den Agent jetzt etwas, das nur die laufende App weiß:
- "Welche Fehler hat die App gerade?"
- "Liste die Routen auf und sag mir, welche dynamisch sind."
- "Kompiliert
/blog/[slug]?"
In Claude Code siehst du Aufrufe wie nextjs_index und dann nextjs_call mit toolName: "get_errors". Wenn der Agent stattdessen aus deinen Dateien antwortet, hat er sich nicht verbunden.
Du kannst den Endpoint auch ohne Agent prüfen:
curl -s -X POST http://localhost:3000/_next/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
Eine Liste von Tools bedeutet, dass Next.js in Ordnung ist und jedes Problem zwischen dem Agent und next-devtools-mcp liegt.
Was uns begegnet ist: Dev-Server auf anderen Ports
Unsere Test-App lief auf Port 3417, weil Port 3000 belegt war. nextjs_index hat sie nicht gefunden. Es hat ein anderes Projekt gefunden, das zufällig auf 3000 lief.
Ein Blick in den Paket-Quellcode erklärte, warum. Unter macOS und Linux sucht next-devtools-mcp 0.4.0 zuerst nach Prozessen, die genau next-server heißen. Auf unserem Mac heißt der Prozess next-server (v16.4.6), also schlug dieser Abgleich fehl, und das Paket fiel darauf zurück, die Ports 3000 bis 3010 abzuklopfen. Ein Dev-Server auf einem anderen Port ist für es unsichtbar.
Der Fix ist einfach. nextjs_call nimmt den Port direkt, und es funktionierte auf 3417, sobald wir ihn übergaben:
{ "port": 3417, "toolName": "get_routes" }
Wenn du also mehr als ein Projekt laufen hast oder einen eigenen Port verwendest, sag es dem Agent einmal: "der Dev-Server läuft auf Port 3417". Er ruft das Tool dann mit diesem Port auf. Projekte innerhalb von 3000 bis 3010 zu halten vermeidet das Problem ebenfalls.
Teil 2: eigenen MCP server in einer Next.js-App bauen
Das ist die andere Bedeutung: Deine Next.js-App wird zu etwas, mit dem sich Claude, Cursor oder ChatGPT per URL verbinden können. Typische Tools sind eine Suche über deine Inhalte, ein Lookup in deiner Datenbank oder eine Aktion wie das Anlegen eines Support-Tickets.
Vercls mcp-handler erledigt die Protokollarbeit. Er macht aus einer Server-Definition eine einfache (Request) => Response-Funktion, und genau das exportiert ein Next.js Route Handler.
Version 2 hat viel verändert
Die meisten Tutorials zeigen noch Version 1, mit Redis, einem SSE-Endpoint und einer dynamischen Route [transport]. Version 2 ist einfacher, und die alten Snippets laufen darauf nicht:
| mcp-handler 1.x | mcp-handler 2.x | |
|---|---|---|
| SDK-Paket | @modelcontextprotocol/sdk 1.x |
@modelcontextprotocol/server 2.x |
| zod | 3 | 4.2 oder neuer |
| Node.js | 20 oder neuer | |
| Transports | Streamable HTTP und SSE | Nur Streamable HTTP, stateless |
| Redis | Für SSE nötig | Wird nicht verwendet |
| Routing-Optionen | basePath, maxDuration, redisUrl und mehr |
Entfernt: mounte den Handler an der Route, die du willst |
Wenn du auf 1.x bleibst, halte @modelcontextprotocol/sdk bei 1.26.0 oder neuer. Das mcp-handler README markiert frühere SDK-Versionen wegen einer Sicherheitslücke.
Installation
npm install mcp-handler@^2 @modelcontextprotocol/server@^2 zod@^4
Die Route
Erstelle app/api/mcp/route.ts. Diese hier gibt AI-Clients eine Suche über Blog-Posts. Tausch das Array gegen deine Datenbank oder dein CMS.
import { createMcpHandler } from "mcp-handler";
import { z } from "zod";
const posts = [
{ slug: "edge-caching", title: "Caching at the edge", body: "How we cache HTML at the edge for 10 minutes." },
{ slug: "image-sizes", title: "Picking image sizes", body: "Three widths cover most layouts." },
];
const handler = createMcpHandler(
(server) => {
server.registerTool(
"search_posts",
{
title: "Search posts",
description: "Find blog posts whose title or body contains the query.",
inputSchema: z.object({ query: z.string().min(2) }),
},
async ({ query }) => {
const q = query.toLowerCase();
const hits = posts.filter((p) => `${p.title} ${p.body}`.toLowerCase().includes(q));
return {
content: [{ type: "text", text: hits.length ? hits.map((p) => `${p.title} (/blog/${p.slug})`).join("\n") : "No posts found." }],
};
},
);
},
{ serverInfo: { name: "my-blog", version: "1.0.0" } },
);
export { handler as GET, handler as POST };
/api/mcp ist nur eine Konvention. Der Handler schaut nie auf den Pfad, also funktioniert app/mcp/route.ts genauso gut. Gib Clients die vollständige URL der Route, die du wählst.
Setz serverInfo. Ohne das hat sich unser Server bei Clients als "mcp-typescript server on vercel" vorgestellt, und das sehen Nutzer in der Server-Liste ihres Clients.
Mit curl testen
Mit laufendem npm run dev sind diese drei Requests ein vollständiger Round Trip. Wir haben sie gegen die Route oben laufen lassen:
curl -s -X POST http://localhost:3000/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
Die Antwort kam als ein Server-Sent Event mit "serverInfo":{"name":"my-blog","version":"1.0.0"} zurück. Ersetz den Body durch {"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}, um search_posts mit seinem JSON Schema zu sehen, und durch diesen hier, um das Tool auszuführen:
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_posts","arguments":{"query":"edge"}}}
Wir bekamen Caching at the edge (/blog/edge-caching). Ein einfaches GET auf die Route antwortete mit 405, was zu erwarten ist: Version 2 ist stateless und hat keinen langlebigen Stream zum Öffnen.
Für eine Klick-Ansicht statt curl funktioniert auch der MCP Inspector: npx @modelcontextprotocol/inspector, dann verbinde dich mit dem Streamable HTTP Transport zu http://localhost:3000/api/mcp.
Einen Client verbinden
Clients, die Streamable HTTP sprechen, verbinden sich per URL.
Claude Code
claude mcp add --transport http my-blog http://localhost:3000/api/mcp
Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"my-blog": { "url": "http://localhost:3000/api/mcp" }
}
}
VS Code (.vscode/mcp.json)
{
"servers": {
"my-blog": { "type": "http", "url": "http://localhost:3000/api/mcp" }
}
}
Claude Desktop liest Remote-Server aus Settings › Connectors. Für eine lokale URL in claude_desktop_config.json brückst du sie mit mcp-remote:
{
"mcpServers": {
"my-blog": { "command": "npx", "args": ["-y", "mcp-remote", "http://localhost:3000/api/mcp"] }
}
}
Nach dem Deploy tauschst du die localhost-URL gegen die echte, etwa https://your-app.vercel.app/api/mcp. Unser Config-Builder schreibt diese Snippets für 15 Clients, wenn du deinen Server dort einträgst.
Absichern, bevor du deployst
Eine deployte Route ist öffentlich. Jeder, der die URL findet, kann deine Tools aufrufen, also füg Auth hinzu, bevor du das erste Mal deployst, nicht danach.
withMcpAuth wrappt den Handler. Hier ist die Version, die wir getestet haben, mit einem geteilten Token aus einer Umgebungsvariable:
import { createMcpHandler, withMcpAuth } from "mcp-handler";
// createMcpHandler(...) as above
const verifyToken = async (_req: Request, bearerToken?: string) => {
if (!bearerToken || bearerToken !== process.env.MCP_TOKEN) return undefined;
return { token: bearerToken, clientId: "team", scopes: ["posts:read"] };
};
const authed = withMcpAuth(handler, verifyToken, { required: true });
export { authed as GET, authed as POST };
required: true ist wichtig. Ohne das geht ein Request ohne gültiges Token trotzdem durch. Mit dem Flag bekam unser unauthentifizierter Aufruf:
HTTP/1.1 401 Unauthorized
www-authenticate: Bearer error="invalid_token", error_description="No authorization provided", resource_metadata="http://localhost:3417/.well-known/oauth-protected-resource"
und derselbe Aufruf mit Authorization: Bearer <token> bekam 200.
Über diesen resource_metadata-Link finden OAuth-fähige Clients deinen Sign-in. Servier ihn aus app/.well-known/oauth-protected-resource/route.ts:
import { metadataCorsOptionsRequestHandler, protectedResourceHandler } from "mcp-handler";
const handler = protectedResourceHandler({ authServerUrls: ["https://auth.example.com"] });
const corsHandler = metadataCorsOptionsRequestHandler();
export { handler as GET, corsHandler as OPTIONS };
Er antwortete mit {"resource":"http://localhost:3417","authorization_servers":["https://auth.example.com"]}. Zeig authServerUrls auf deinen echten Identity Provider. Für echte Nutzer ersetzt du das geteilte Token durch die Verifikation der Tokens dieses Providers und prüfst requiredScopes pro Route. Die aktuelle Spec-Revision, 2026-07-28, verschiebt die Client-Registrierung von Dynamic Client Registration zu Client ID Metadata Documents; diese Arbeit passiert in deinem Authorization Server, und deine Next.js-Route ändert sich nicht.
Innerhalb eines Tools liegt die verifizierte Identität auf ctx.http?.authInfo, sodass ein Tool Ergebnisse nach dem Account des Aufrufers filtern kann.
Probleme und Lösungen
| Was du siehst | Ursache | Lösung |
|---|---|---|
[error] No server info found von next-devtools-mcp |
Kein Next.js 16 Dev-Server läuft, oder er liegt außerhalb der Ports 3000 bis 3010 | Starte npm run dev; bei einem anderen Port gibst du dem Agent den Port für nextjs_call |
ERR_MODULE_NOT_FOUND für next-devtools-mcp/dist |
Veralteter npx-Cache | Leere den npx-Cache und starte den Client neu |
404 auf /_next/mcp |
Next.js 15 oder älter, next start, oder experimental.mcpServer: false |
Upgrade, nutze next dev, oder entferne das Flag |
| Agent antwortet aus Dateien, ruft nie Tools auf | Client hat den Server nicht geladen | Starte den Client neu und prüfe seine MCP-Liste; in Claude Code führst du /mcp aus |
405 auf GET /api/mcp |
Normal für mcp-handler 2 | Nichts zu beheben; Clients nutzen POST |
401 mit einem WWW-Authenticate-Header |
withMcpAuth mit required: true und ohne Token |
Sende Authorization: Bearer ... oder melde dich über den OAuth-Flow des Clients an |
Alter Tutorial-Code scheitert an redisUrl oder basePath |
Für mcp-handler 1 geschrieben | Entferne diese Optionen und mounte die Route dort, wo du sie willst |
| "The module was automatically converted to an EcmaScript module" in einem frischen Projekt | npm init hat "type": "commonjs" zu package.json hinzugefügt |
Lösche das type-Feld; Next.js kümmert sich selbst um Module |
Das letzte hat uns fünf Minuten in einem leeren Testprojekt gekostet. Bei create-next-app tritt das Problem nicht auf.
Next.js MCP server in unserem Verzeichnis
Am 14. November 2026 enthielt der HostedMCP-Katalog 19 aktive Server mit Next.js im Namen, und 4 davon haben unsere Index-Regeln bestanden. Die zwei, die für diese Anleitung relevant sind:
| Server | Stars | Checks score | Was es ist |
|---|---|---|---|
| vercel/next-devtools-mcp | 836 | 89 | Der Connector aus Teil 1 |
| vercel-labs/mcp-handler | 699 | 86 | Die Library aus Teil 2 |
Die Star-Zahlen stammen von GitHub aus unserem letzten Refresh; der Checks score ist unser automatisierter Review von Repository, Lizenz, Maintenance, Supply Chain und Tool-Beschreibungen, mit den Belegen im Checks-Bericht des jeweiligen Servers. Die meisten der anderen 17 sind Starter-Templates oder Single-Purpose-Tools mit wenigen Stars. Prüf sie auf dieselbe Weise, bevor du einen installierst.
Sicherheitshinweise
Der Dev-Endpoint ist nur für die Entwicklung gedacht, aber er ist nicht privat. Solange next dev läuft, kann jeder Prozess, der den Port erreicht, deinen Projektpfad, deine Routen und den Speicherort des Logs lesen. Binde den Dev-Server nicht an eine gemeinsam genutzte Netzwerkadresse, während Secrets in seiner Umgebung liegen.
Deine eigene Route ist ab dem Tag, an dem du sie deployst, eine öffentliche API. Behandle jedes Tool wie einen Endpoint: Validiere Eingaben mit dem Schema, gib nur zurück, was der Aufrufer sehen darf, und pack niemals Secrets oder interne URLs in Tool-Beschreibungen, denn das Modell liest diese Beschreibungen – und jeder, der deine Tools auflistet, liest sie ebenfalls. Unser MCP-Sicherheitsleitfaden geht die Risiken der Reihe nach durch.
Wie es weitergeht
Wenn du die Protokolldetails hinter der Route willst, baut how to build an MCP server einen in reinem TypeScript und Python. Wenn dein Server live ist, reichst du das Repository ein, und HostedMCP listet es mit Install-Snippets für jeden Client und führt seine Checks aus.