The Next.js drop-in lets you colocate an MCP server inside an existing Next.js app — same repo, sameDocumentation Index
Fetch the complete documentation index at: https://mcp-use.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
@/* aliases, same shared components, same .env files
— without spinning up a separate project. Your Next.js routes keep working, and
a single mcp-use dev (or build / start) runs the MCP server beside them.
Quick Start
Inside an existing Next.js app (App Router,src/ layout):
Project Layout
The convention for a drop-in:src/mcp/index.ts is auto-discovered when you pass --mcp-dir src/mcp. You
can override the entry with --entry src/mcp/server.ts.
Widgets in src/mcp/resources/ are picked up by mcp-use build / dev
automatically — they can import "@/components/..." and those aliases resolve
through your app’s tsconfig.json.
How It Works
Three problems come up when you run an MCP server inside a Next.js project, and the drop-in solves each automatically:1. Path aliases (@/lib/...)
When your tool imports @/lib/auth, that alias is defined in the host app’s
tsconfig.json. The CLI registers tsx with the project’s tsconfig, so
transitive imports like @/lib/auth resolve through the same paths config
Next.js uses.
2. Next.js server-runtime modules
A helper likesrc/lib/auth.ts typically contains:
next in your package.json, it installs
runtime shims that replace the following specifiers with inert stand-ins:
| Module | Stub behavior |
|---|---|
server-only | No-op (the import itself is the whole side effect in the real pkg). |
client-only | No-op. |
next/cache | revalidatePath/revalidateTag no-op, unstable_cache returns fn. |
next/headers | headers() returns empty Headers, cookies() returns empty store. |
next/navigation | redirect()/notFound() still throw, so callers fail loudly. |
next/server | Minimal NextResponse/NextRequest stubs. |
module.register() loader) and the
CJS side (via a Module._resolveFilename patch), so require("server-only")
and import "server-only" both route to the stub. No user configuration
needed.
3. Environment variables
The CLI mirrors Next.js’s env-file cascade intoprocess.env before your
server boots:
DATABASE_URL from .env.local shows
up the same way Next.js sees it.
Widgets inside a Next.js app
Widgets run in a browser iframe and cannot use server APIs, even though they live inside the Next.js tree. The drop-in enforces this at build time — if a widget (or a module it transitively imports) pulls inserver-only,
next/headers, etc., the build fails with an actionable error:
src/mcp/index.ts
<project>/src/ when it exists, so widgets that
import shared components pick up the same design tokens your app uses.
CLI Flags
These work ondev, build, and start:
| Flag | Description |
|---|---|
--mcp-dir <dir> | Folder holding the MCP entry + resources/ (e.g. src/mcp). |
--entry <file> | Explicit entry file, relative to project root. Overrides --mcp-dir discovery. |
--widgets-dir <dir> | Widgets directory (defaults to <mcp-dir>/resources). |
--mcp-dir mode tries, in order:
<dir>/index.ts, <dir>/index.tsx, <dir>/server.ts, <dir>/server.tsx.
Build semantics
mcp-use build --mcp-dir is intentionally lighter than the standalone
build:
- No esbuild transpile step. The host Next.js app owns its build; trying
to transpile every
.ts/.tsxin a Next project blows up on files liketailwind.config.tsand RSC-only files. The manifest records the.tssource path andmcp-use startruns it throughtsxdirectly. - No
tsc --noEmittypecheck.next buildalready does this for you. - Widget builds still run — they produce static assets in
dist/resources/widgets/<name>/.
Running alongside Next.js
The MCP server andnext dev are two separate processes. Give them different
ports:
package.json
Requirements
- Next.js 13+ (App Router or Pages Router — the shims cover both).
- A project-root
tsconfig.jsonwith your@/*paths. The drop-in picks these up via Vite’sresolve.tsconfigPaths(for widgets) andtsx’s tsconfig support (for the server). tailwindcssin yourdependenciesif you use it in widgets (@tailwindcss/vitealone is not enough — the widget pipeline needstailwindcssdirectly resolvable from the project).
Example
A complete working example lives in the repo: examples/server/features/nextjs-drop-in. It demonstrates@/* aliases, server-only + next/headers via a shared
src/lib/server-data.ts, and a widget that reuses a shared
@/components/card component.