Skip to content

Next.js 16 DevTools: AI-Assisted Debugging with MCP

8 min read1451 words

Debugging a hydration mismatch used to mean copying error messages, pasting them into Claude, and explaining my route structure. With Next.js 16's MCP integration, Claude reads the route structure directly from my running dev server. When I ask "why is this page hydrating incorrectly?", Claude already knows the component tree, cache state, and server logs. Here's how MCP transforms the debugging workflow.

What MCP Enables

Model Context Protocol (MCP) is an open standard for connecting AI tools to application context. Next.js 16 exposes a MCP endpoint at /_next/mcp during development. This endpoint provides:

  • Route information: Your application's route structure, dynamic segments, and layouts
  • Unified logs: Browser and server logs in one stream
  • Cache state: Current caching behavior for each route
  • Rendering context: Which components render on server vs client
  • Error stack traces: Automatically captured without manual copying

AI assistants like Claude, Cursor, and others can connect to this endpoint and access real-time application state.

Setting Up MCP

Next.js 16 enables MCP by default in development mode. Start your dev server normally:

npm run dev

The MCP endpoint activates at http://localhost:3000/_next/mcp. To connect your AI tool, install the bridge package:

npm install -D next-devtools-mcp

Configure your AI client's MCP settings. For Claude Code:

{
  "mcpServers": {
    "next-devtools": {
      "command": "npx",
      "args": ["-y", "next-devtools-mcp@latest"]
    }
  }
}

The bridge auto-discovers running Next.js dev servers and forwards AI queries to them.

Debugging with Context

Without MCP, debugging a caching issue required manual context:

Without MCP:

"My /blog/[slug] page is showing stale data. Here's my page component: [pastes code] And here's my fetch: [pastes more code] The cache seems to not invalidate properly..."

With MCP, the AI already has this context:

You: "Why is /blog/[slug] showing stale data?"

AI Response:

Looking at your route configuration, I see the issue. Your generateStaticParams runs at build time, and your fetch uses the default cache. The route is configured with:

  • Cache mode: force-cache (inherited from layout)
  • Revalidation: none set
  • Dynamic: false (static generation)

The page pre-renders with stale data and never revalidates. You have two options:

  1. Add revalidation to the fetch: fetch(url, { next: { revalidate: 3600 } })
  2. Make the route dynamic: export const dynamic = 'force-dynamic'

Based on your traffic patterns visible in the logs, option 1 with hourly revalidation would balance freshness with performance.

The AI reads the actual route configuration, not a description of it.

Available MCP Tools

Next.js 16 DevTools exposes several tools through MCP:

get_routes

Returns your application's route structure:

// AI prompt: "Show me my routes"
// MCP response:
{
  routes: [
    {
      path: "/",
      type: "static",
      hasLayout: true,
      components: ["RootLayout", "HomePage"]
    },
    {
      path: "/blog/[slug]",
      type: "dynamic",
      generateStaticParams: true,
      cacheMode: "force-cache"
    }
  ]
}

get_logs

Retrieves unified browser and server logs:

// AI prompt: "What errors happened on /dashboard?"
// MCP response:
{
  logs: [
    {
      source: "server",
      level: "error",
      message: "Error in generateMetadata",
      route: "/dashboard",
      stack: "..."
    },
    {
      source: "browser",
      level: "warning",
      message: "Hydration mismatch in UserAvatar",
      component: "UserAvatar"
    }
  ]
}

get_cache_state

Shows current cache behavior:

// AI prompt: "Is /api/users cached?"
// MCP response:
{
  route: "/api/users",
  cacheStatus: "dynamic",
  lastRevalidation: null,
  dataCache: {
    entries: 0,
    strategy: "no-store"
  }
}

upgrade_nextjs_16

Automates migration tasks:

// AI prompt: "Help me upgrade to Next.js 16"
// MCP triggers codemods for:
// - Async params migration
// - PPR to cacheComponents
// - Middleware to proxy
// - Image component changes

Practical Debugging Examples

Hydration Errors

You: "I'm getting hydration errors on the home page"

AI Response:

I can see the hydration mismatch in your logs. The error occurs in the DateTime component at line 23. Looking at the component:

The issue is that you're rendering new Date().toLocaleString() without suppressHydrationWarning. The server renders at build time, the client renders at request time - different timestamps.

Fix: Add suppressHydrationWarning: <time suppressHydrationWarning>{new Date().toLocaleString()}</time>

Or use a client-only rendering pattern with useEffect.

Performance Issues

You: "/products is loading slowly"

AI Response:

Analyzing the route, I see several issues:

  1. Your generateStaticParams fetches all 10,000 products at build time
  2. Each product page makes 3 sequential database calls
  3. No caching is configured - every request hits the database

Current metrics from dev logs:

  • Average response time: 2.3s
  • Database queries per request: 3

Recommendations:

  1. Limit generateStaticParams to top 100 products
  2. Use Promise.all for parallel database calls
  3. Add revalidation: { next: { revalidate: 3600 } }

Want me to generate the optimized code?

Cache Debugging

You: "My API route should cache but doesn't seem to"

AI Response:

Looking at your route handler, the issue is the cookies() call:

export async function GET() {
  const session = cookies().get('session'); // This opts out of caching
  const data = await fetchData();
  return Response.json(data);
}

Reading cookies makes the route dynamic. If you need session-based data but want caching, split the routes:

  • /api/data (cached, no auth)
  • /api/user-data (dynamic, with auth)

Or use a Request object to read cookies without calling cookies():

export async function GET(request: Request) {
  const session = request.cookies.get('session');
  // ...
}

Migration Assistance

MCP includes tools for automated upgrades. When migrating from Next.js 15 to 16:

You: "Upgrade my app to Next.js 16"

AI Response:

I'll run the upgrade codemods. Scanning your project...

Found changes needed:

  1. 12 files use sync params - converting to async
  2. middleware.ts needs migration to proxy.ts
  3. next.config.js has deprecated options

Running migrations...

✓ Converted params to async (12 files) ✓ Renamed middleware.ts to proxy.ts ✓ Updated proxy function export ✓ Migrated experimental.ppr to cacheComponents

Manual steps remaining:

  1. Run npx next typegen for updated types
  2. Test async params in dynamic routes
  3. Verify proxy behavior matches middleware

Would you like me to explain any of these changes?

The AI doesn't just suggest changes it applies codemods through the MCP connection.

Multi-Project Support

For teams running multiple Next.js apps, the MCP bridge discovers all dev servers:

{
  "mcpServers": {
    "next-devtools": {
      "command": "npx",
      "args": [
        "-y",
        "next-devtools-mcp@latest",
        "--port", "3000,3001,3002"
      ]
    }
  }
}

AI queries route to the appropriate server based on context:

You: "Why is the API response different between main app and admin?"

AI Response:

Comparing the /api/users route on both apps:

Main app (port 3000):

  • Returns 20 users
  • Cached for 1 hour
  • Filters: role != 'admin'

Admin app (port 3001):

  • Returns all 150 users
  • No caching
  • No filters

The admin app includes users that the main app filters out. The cache difference explains why main app shows old data after user changes - it needs up to an hour to reflect updates.

Configuration Options

Fine-tune MCP behavior in next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  devIndicators: {
    buildActivity: true,
    buildActivityPosition: 'bottom-right',
  },
  experimental: {
    // MCP is enabled by default in dev, but can be configured
    mcpServer: {
      enabled: true,
      // Limit log history to reduce memory
      maxLogEntries: 1000,
      // Expose additional context
      exposeEnv: ['NODE_ENV', 'NEXT_PUBLIC_*'],
    },
  },
};
 
module.exports = nextConfig;

Security Considerations

MCP only runs in development mode. Production builds don't include the endpoint. However, be aware:

  • The endpoint exposes application internals
  • Don't run dev servers on public networks
  • MCP access isn't authenticated by default

For team environments, consider running dev servers behind VPN or using the bridge's built-in access controls.

The Debugging Workflow Shift

Before MCP, debugging meant context switching: run the app, reproduce the issue, copy logs, paste into AI, explain the setup, wait for suggestions that might not fit your actual configuration.

With MCP, the AI sees what you see. It knows your route structure, your cache configuration, your logs. Questions get answers grounded in your actual application state, not generic advice.

The productivity gain compounds with complexity. Simple issues save a few minutes. Complex debugging sessions the ones that used to take hours of context building now take minutes. The AI assistant becomes genuinely assistive because it has genuine context.