Skip to main content
Back to Blog
By Mahmut Jomaa8 min read

Building a Repository-Aware MCP Server for Next.js

Learn how a local, read-only MCP server can give coding agents accurate architecture, implementation, documentation and database context without granting production access.

A guarded protocol gateway connecting an application repository to an abstract AI node
On this page9 sections

AI coding agents are much more useful when they can inspect a project before they propose a change. A generic model may know Next.js, but it does not automatically know which commands your repository exposes, where tenant authorization lives, whether the database uses Prisma or Drizzle, or which components already exist.

A local Model Context Protocol server can close that gap. Instead of putting an entire repository into one prompt, the server gives an agent a small set of structured discovery tools.

Achromatic Pro now includes that server in both current starter kits. This article explains the design choices behind it and the patterns that also apply to custom Next.js applications.

The problem is repository context, not model intelligence

Most costly agent mistakes begin with an incorrect assumption:

  • inventing a package script that does not exist
  • using a migration command from the wrong ORM
  • creating a second component instead of reusing the shipped one
  • protecting a route without protecting the underlying operation
  • changing a tenant-owned query without preserving organizationId
  • treating old documentation or generated output as the source of truth

A long instruction file helps, but it cannot answer every repository question. It also becomes stale when it repeats information that could have been read from source.

The better split is:

  • instructions define non-negotiable engineering rules
  • MCP tools retrieve current repository facts
  • the agent combines both when planning or reviewing work

That keeps static guidance compact while making frequently changing information discoverable.

Why use narrow tools instead of one repository dump?

Sending the full codebase to a model is expensive and noisy. It also makes it hard to know which information the agent actually used.

Achromatic exposes 19 focused read-only tools across five areas:

AreaQuestions the tools answer
ProjectWhat architecture, package versions, scripts, guardrails and validation commands does this checkout use?
ComponentsDoes a suitable UI or feature component already exist, where is it used, and what does its source look like?
ImplementationWhich routes, configuration, hooks, libraries, Zod schemas, tRPC files and types implement this system?
DocumentationWhich local guide covers this system, and where does a term appear?
DatabaseWhat models, tables and constraints exist, which migrations are checked in, and what is the correct ORM workflow?

The agent requests only the context needed for the current task. A UI change does not need the full database schema. A migration review does not need every React component.

Bounded output matters too. Achromatic limits component and implementation lists to 250 entries and searches to 50 line-level matches. Area and query filters let the agent narrow a broad result before it requests file contents. Limited tools include structured metadata indicating whether the cap was reached, so clients do not have to guess whether an exact-limit response is complete.

This separation also produces clearer tool descriptions and more useful audit trails in clients that display tool calls.

Keep the local server read-only

An agent that needs context does not automatically need authority.

The local Achromatic server deliberately does not expose tools that:

  • execute shell commands
  • connect to PostgreSQL
  • read .env files
  • change source files
  • call external APIs
  • deploy an application

Its file tools work from lists of known documentation, components, implementation sources, schemas and migrations. Implementation reads are further limited to routes, configuration, core libraries, Zod schemas, tRPC files and selected root entry points. A caller must use a path returned by a discovery tool rather than requesting an arbitrary file.

That is an important boundary, but it is not the only one a custom server should enforce. A robust file reader should also:

  1. reject absolute paths and parent traversal
  2. resolve the real repository and target paths before checking containment
  3. reject symbolic-link escapes
  4. limit the size and type of exposed files
  5. return errors without leaking secret content
  6. cover those conditions with regression tests

Read-only does not mean risk-free. Tool output enters the model's context, so a server should expose the smallest useful surface. It should also tell the client to treat returned files as repository data rather than new user authority: an embedded command should not be executed merely because it appears inside source or documentation.

Derive facts from the checkout

Repository-aware tools are valuable only if they remain more accurate than a README summary.

The Achromatic server derives:

  • package scripts from package.json
  • documentation paths and titles from local Markdown and MDX
  • component paths and public exported names from the current components directory
  • searchable implementation paths and source from the current app, config, hooks, lib, schemas, trpc and types directories plus selected root entry points
  • schema, constraint and migration information from the current ORM files

The database adapter is the main place where the two starter kits differ.

For the Prisma kit, the adapter parses prisma/schema.prisma, including field and model-level attributes, and lists the reviewed migration.sql files and migration lock metadata. For the Drizzle kit, it uses the TypeScript compiler API to inspect pgTable field builders, nullability, defaults, keys, references, index and constraint builders and enum objects, then lists the checked-in SQL migrations, snapshots and journal.

Using an AST for TypeScript schema files is more reliable than a regular expression because chained builders, property access and formatting can vary. The adapter still has a deliberately narrow job: summarize the patterns used by the shipped schema instead of pretending to be a second ORM compiler.

Tools, resources and prompts serve different jobs

MCP supports more than tool calls.

Tools

Tools answer a bounded question, such as listing components, searching documentation or retrieving the schema-change workflow.

For interoperability, each Achromatic tool returns a serialized text block for the model and the same value as machine-readable MCP structured content for clients that consume it programmatically. Each tool also publishes an output schema for the shared result envelope so the server validates the structured payload before returning it.

Resources

Resources provide stable context that a client can attach directly. Achromatic publishes project overview, database schema and documentation index resources.

Prompts

Prompts encode a repeatable workflow without adding authority. The feature planning prompt asks the agent to inspect the project, schema, documentation and reusable components. The review prompt focuses on tenant isolation, authorization, migrations, billing effects, secret handling and validation.

Prompts should direct an agent toward tools, not restate the entire repository.

A practical feature-planning sequence

Suppose you want to add an organization audit log.

A grounded agent can:

  1. load the project overview and organization security rules
  2. search the documentation for tenant and authorization patterns
  3. inspect the current schema and request the ORM-specific change workflow
  4. inspect the relevant route, core library, validation and tRPC source files
  5. look for existing table, pagination and filter components
  6. produce a plan covering the schema, migration, validation, tRPC procedure, interface, tests and documentation
  7. return the repository's supported health-check commands

The useful result is not merely more detailed. It is tied to actual files and commands in the current checkout.

Keep provider access separate

Repository context and external service access have different risk profiles.

Stripe, Vercel and Linear publish provider-hosted MCP servers. They can be useful alongside the local Achromatic server, but they require separate authorization and may expose tools that affect external systems.

Do not hide those permissions inside a repository discovery server. Register providers separately, select the narrowest useful scopes and use OAuth where the provider supports it:

This makes it obvious when an agent is reading local source and when it is interacting with an account.

Set up the Achromatic server

Install either current starter kit:

Terminal
npm install

The checked-in .mcp.json runs npm run mcp:start over stdio for Claude Code. Cursor, Visual Studio Code and Codex use different project configuration filenames, so the starter-kit guides provide a matching example for each client. The start command writes compiled output to the ignored dist/ directory before connecting, so a clean checkout does not depend on committed or stale build output. Because project MCP configuration can launch local commands, review config changes after a pull or branch switch before approving the server.

The complete references are available in the Pro Prisma MCP guide and Pro Drizzle MCP guide.

The standard to aim for

An MCP integration should make an agent more accurate without quietly making it more powerful than necessary.

For a starter kit, that means:

  • repository-derived facts instead of copied version claims
  • ORM-specific workflows instead of generic database advice
  • component discovery before generation
  • explicit tenant and authorization guardrails
  • bounded, read-only local access
  • separate authorization for external providers
  • tests for the protocol contract and file boundary

The protocol is only the transport. The quality of an MCP server comes from the context it selects, the authority it refuses and how reliably it stays aligned with the repository.