Skip to content
aimcpsql-serverazurecoding-agents

Scoped Database Context: An MCP Pattern for Large Azure SQL Schemas

Matt Hammond 7 min read
One drawer pulled open in a wall of labelled wooden index drawers, like a single schema slice from a large database

On a database with hundreds of tables, connecting a coding agent to the whole schema causes three problems at once. The schema uses up context on every request, the model picks the wrong table among hundreds of similar names, and broad access gives the agent an oversized blast radius. We use a scoped, read-only Model Context Protocol (MCP) server driven by a versioned module-to-schema mapping instead. The agent asks for the slice that matches the module it is working on, gets the five tables it needs, and every call is logged.

  • Scope by module rather than per request, and treat the mapping as a reviewed, versioned artefact.
  • Keep the server read-only, least-privilege, and logged, as with any production MCP server.
  • Microsoft’s official SQL MCP tooling handles connectivity, and you add the scoping layer yourself.

This builds on the patterns in our MCP patterns for production agents guide.

Teams that put coding agents to work on large SQL Server estates run into the same problem early. The database has hundreds of tables, and the agent needs schema context to write correct queries and data access code. Pasting schema fragments into prompts by hand cannot be maintained. Connecting the agent to the database and letting it explore is expensive, inaccurate, and hard to defend in a security review.

This post describes the pattern we use instead: scoped schema context served through a small Model Context Protocol (MCP) server.

Why whole-schema access fails

Token cost. A schema dump for a large database runs to tens of thousands of tokens, and agentic sessions re-send context repeatedly. Prompt caching reduces the cost without removing it, and it does nothing for the second problem. Our token cost guide covers the budgeting side.

Accuracy. Give a model Customer, Customers_Legacy, CustomerV2, tblCustomer, and Customer_Staging in the same context, and some of the time it will choose the wrong one. Large legacy schemas are full of near-duplicates, deprecated tables, and misleading names. A smaller, well-chosen context gives more reliable results than a larger one.

Security. An agent holding a broad database credential raises an obvious question about blast radius (how much a mistake or a compromise could reach). Even with read-only access, the whole schema plus reference data is more of your estate than any single task needs. ‘The agent can read everything’ is also a difficult position to defend in a supplier assessment.

The pattern: a module map plus a scoped server

The design has two parts. The first is knowledge about the system written down, and only the second is software.

1. A module-to-schema mapping, versioned in the repository. Someone who knows the system records which tables, views, and relationships belong to each functional module, such as Orders, Billing, and Membership. On a well-structured estate, part of this mapping may already exist as schemas or naming conventions. On a legacy estate, producing it is useful archaeology in its own right, and agent-assisted dependency mapping (as used in our stored procedure modernisation guide) speeds it up. The mapping is a reviewed artefact, so any change to it goes through a pull request.

2. A read-only MCP server that serves slices. Three tools cover most needs:

  • list_modules() returns the module names and one-line descriptions, so the agent can orient cheaply.
  • get_module_schema(module) returns the schema slice for one module: tables with columns, types, keys, and the relationships that cross into other modules. Those relationships arrive as stubs, so the agent knows an edge exists without pulling the neighbour’s full schema.
  • get_reference_values(table) optionally returns the rows of small, enumeration-style lookup tables, because ‘what are the valid status codes?’ is the question agents ask most after structure.

The server connects with a least-privilege, read-only credential, serves metadata rather than business data, and logs every call. These follow the standard disciplines in our MCP patterns guide: read-only data servers, least-privilege scoping, and per-call audit logging.

The agent’s workflow then follows from the module it is working on. For a change to billing, get_module_schema("Billing") puts twelve tables in context instead of hundreds, correctly named and current, for a fraction of the tokens.

Where the official tooling fits

You do not need to build connectivity from scratch. Microsoft ships SQL MCP Server capabilities built on Data API builder and Azure SQL tools in the Azure MCP Server, and community servers exist for direct SQL Server access. These handle the plumbing: safe connections, query execution, and schema inspection.

None of them knows your module boundaries, and no generic tool could. The scoping layer (the mapping plus the slice-serving tools) is thin and specific to your system. You can implement it as configuration over Microsoft’s tooling, since Data API builder’s entity model can express a good part of it, or as a small custom server in front of the database.

What scoping gives you

Any one of these benefits would justify the afternoon of work, and together they change how agents fit into database-heavy delivery:

  • Cheaper sessions, because the context carries the slice rather than the whole estate.
  • Better code, because the agent cannot choose a deprecated table it never saw.
  • A security position that survives review: read-only, module-scoped, logged, and versioned.
  • A reusable asset: the same server serves development agents, support tooling, and any future agent workload against the same estate, and the module map gives the team documentation it may never have had.

The same approach works for any large structured source, not only SQL Server. In each case we would give agents curated context shaped by the system’s own boundaries, rather than raw access shaped by the vendor’s API.

If you are pointing coding agents at a large database estate, we would build this early. For the wider harness thinking, see harness engineering for coding agents. If your agents run in Claude Code on a .NET codebase, our Claude Code for .NET developers guide covers the project setup a server like this sits alongside. Book a consultation if you want it built with you.

Frequently asked questions

Why not just connect the agent to the whole database?
It causes three problems at once. A schema dump covering hundreds of tables consumes context on every request, and models pick the wrong table when hundreds of similar names are in view. An agent holding broad database access has an oversized blast radius. Scoping the context addresses all three with one design decision.
What does a scoped schema MCP server expose?
Small, curated tools instead of a raw connection: list the modules, fetch the schema slice for one module (its tables, columns, keys, and relationships), and optionally fetch reference values for enumeration-style lookup tables. It is read-only, driven from a versioned module-to-schema mapping, and logs every call.
Is there an official SQL Server MCP server?
Microsoft publishes SQL MCP Server capabilities built on Data API builder, plus Azure SQL tools in the Azure MCP Server, and community servers exist. They solve connectivity and safe query execution. You add the scoping layer, which decides which slice of a large schema an agent sees for a given task, because it encodes your module boundaries.
Does this pattern apply beyond modernisation work?
Yes. Any agent workload against a large database benefits, including support tooling that answers data questions, agents drafting reports, and development agents writing queries or data access code. Wherever the schema is bigger than the task, scoping improves cost, accuracy, and the security position at the same time.

Ready to transform your software?

Let's talk about your project. Contact us for a free consultation and see how we can deliver a business-critical solution at startup speed.