Next.js has two routing systems that look similar in code but behave completely differently, and most model training data blends them. An agent needs to know which router the project uses, which Next major version is installed, and where the server/client boundary sits, because almost every wrong answer in this ecosystem comes from mixing App Router and Pages Router idioms. It also needs to know that server components, route handlers, and server actions all run on the server but have different rules about caching, streaming, and input validation.
Gives the agent scoped read and write access to a directory tree.
Next.js projects lean on file-based conventions, so the agent needs to see the real shape of app/ before it decides where a route belongs.
Exposes history, diffs, and blame for the repository.
Diffs are the quickest way for an agent to tell whether this codebase migrated from the Pages Router and which files are leftovers.
Drives a real browser so the agent can navigate pages, click, and read the DOM.
Hydration mismatches and client boundary bugs only show up in a running browser, never in the source.
Lets the agent inspect schema and run read queries against your database.
Server components query the database directly, so an agent that can read the real schema stops inventing column names.
Pulls issues and stack traces from your Sentry project.
Server component and server action errors surface as opaque digest IDs in production, and Sentry is where the real trace lives.
These are the failures that repeat across sessions, so each one belongs in .mcp.json.
Agents add 'use client' at the top of a file the moment they see a hook or an onClick, and they usually add it to the page or layout rather than the leaf component. That pushes the whole subtree into the client bundle and can drag server-only imports along with it. Put a rule in your rules file: default to server components, and only add 'use client' to the smallest leaf that actually needs interactivity, never to a page or layout.
Because getServerSideProps and getStaticProps dominate older training data, agents write them inside app/ files where they do nothing at all, or they scaffold a pages/api handler in a project that uses route handlers. The code often compiles, so the bug is silent. State the router explicitly in your rules file: 'This project uses the App Router only. Never write getServerSideProps, getStaticProps, getInitialProps, or files under pages/.'
When a server-only environment variable comes back undefined in a client component, the fastest fix an agent finds is renaming it to NEXT_PUBLIC_, which inlines the value into the browser bundle. This is how API keys and database URLs leak. Write the rule as a hard stop: 'Never add or rename an env var to NEXT_PUBLIC_. If a value is needed in the browser, move the logic to a server component, route handler, or server action instead.'
Caching defaults changed between Next 14 and Next 15, so agents sprinkle force-cache, revalidate, or dynamic = 'force-dynamic' based on whichever version dominated their training data. The result is either stale pages in production or every request bypassing the cache. Record the installed major version and your caching policy in the rules file, for example: 'Next 15. fetch is uncached by default. Do not add revalidate or force-cache without an explicit instruction.'
A server action is a public HTTP endpoint with a generated ID, callable by anyone who finds it, but agents write them as if only their own form can reach them and skip both the session check and input validation. Any authorization done in the component that renders the form is not authorization at all. Add: 'Every server action must re-check the session and validate its arguments with a schema before touching the database, regardless of what the calling component checks.'
Agents replace plain img tags with next/image as a reflex, then either omit width and height on a non-fill image or point it at a remote host that is not in images.remotePatterns, which fails at runtime rather than at build. List your allowed image hosts in the rules file and add: 'When using next/image with a remote src, confirm the host exists in next.config images.remotePatterns first, and always supply width and height unless the parent is a sized container using fill.'