Skip to content
Back to notes
June 6, 2026·5 min read

Custom MCP servers — teaching AI to understand your own software

A plain-language take on what an MCP server is, why a custom one beats generic prompting, and how to set boundaries so a coding agent gets deterministic, safe access to your system.

MCPcontext engineeringAIdeveloper experienceguardrails

When I bring AI into a developer workflow today, the most common barrier isn't the model. It's context. A coding agent knows the public internet up to its training cutoff, but it doesn't know your internal system — your APIs, your data models, your business rules. With generic prompting you patch that by hand, over and over, and still only get it half right. This is where an MCP server comes in.

In this piece I explain what an MCP server is, why it's worth building your own instead of relying on prompts, and — most importantly — where the boundaries are: what AI is allowed to do and what it isn't.

What an MCP server is, without the hype

MCP (Model Context Protocol) is a standardized protocol that lets a coding agent connect to an external source. Think of it as a bridge between AI and your system — your API, database, internal docs, deploy pipeline.

Instead of AI guessing how your application works, it gets a clearly defined set of tools: "here's what you can call, here are the parameters, here's what you get back." No magic. It's an RPC layer with a description the model can understand.

What matters is what an MCP server isn't: it's not a model, it's not an "agent," and it's not a replacement for your logic. It's an adapter. All the intelligence stays where it was — in your code and in how you design your tools.

Why a custom server beats generic prompting

A generic prompt like "our API has an /orders endpoint, returns JSON with fields..." has three problems. It's fragile (the format drifts), it's expensive on tokens (context stuffed with descriptions), and above all it's non-deterministic — AI interprets it slightly differently every time.

A custom MCP server solves this by giving AI deterministic, safe access to your context:

  • Determinism — the get_order(id) tool returns structured data in the same shape every time. The model doesn't guess the schema, it's handed it.
  • Safety — you define what's exposed. AI doesn't see the whole database, only what you've given it as a tool.
  • Context savings — the tool description is short and unambiguous. You don't have to paste documentation into every prompt.
  • Auditability — every call goes through your server, so you can log it, throttle it, and inspect it.

In practice, what I do is encapsulate the business knowledge I'd otherwise repeat in a prompt once, into a tool. That's the move from software engineering to context engineering — the work isn't writing more code, it's giving AI properly shaped, bounded context.

Concrete use cases

Where a custom MCP server genuinely pays off for me:

  • Driving your own applications — AI can trigger a deploy, create a feature flag, or read out an environment's state through tools you've approved. Not through a shell where it can do anything.
  • Faster changes — when the agent knows what your entities look like and how they're validated, it generates edits that fit on the first try. Fewer review rounds.
  • Reading internal sources — internal wiki, ADRs, the database schema, runbooks. AI gets the answer from your source of truth, not from its memory.

The common thread: AI stops guessing and starts working with your actual system.

What a tool definition looks like

Here's an illustrative (generic, not from a real product) definition of a single read-only tool. Deliberately simple:

tool:
  name: get_order_status
  description: Returns the current status of an order by ID. Read-only.
  input:
    order_id:
      type: string
      required: true
  returns:
    status: enum[new, paid, shipped, cancelled]
    updated_at: datetime
  permissions:
    scope: read
    rate_limit: 60/min

The key thing is that the tool has a narrow contract: one purpose, clear inputs, clear outputs, explicit permissions. No generic run_query(sql) that would let AI reach anywhere.

Security and boundaries — what AI may not do

This is the part you don't skip. An MCP server puts AI's hands inside your system, so guardrails are part of the design, not an add-on.

The rules I stick to:

  • Default is read-only. Write and destructive operations are separate tools with explicit approval, ideally with human-in-the-loop confirmation.
  • No generic "run anything." Don't expose raw SQL, raw shell, or free-form HTTP. Every capability is a named tool with a narrow contract.
  • Least privilege. The server runs under an identity that sees only what it genuinely needs. Not under an admin token.
  • Log and rate-limit. Every call auditable. When something goes wrong, you want to know what and when.
  • Don't let sensitive data out. The server is where you mask PII and secrets before they reach the model's context.

The goal fits in one line: deterministic, fast, safe. Determinism gives it shape, speed comes from AI not guessing, and safety comes from the boundaries being hard-coded into the server — not from hoping a prompt will keep the model in line.

If you're dealing with regulation, this isn't extra work: auditable calls and scope limits are exactly what you'll want when arguing your case around the EU AI Act and for internal compliance.

In closing

A custom MCP server isn't a fad. It's a practical layer that turns AI from a clever guesser into a tool with deterministic, bounded access to your system. You don't have to build ten servers at once — start with one read-only tool over the source your people reach for most, and mind the boundaries from the first commit. It's worth investing more in tool and guardrail design than in longer prompts. That's where the real work of context engineering lives.