RWA MCP Server

A production MCP server splitting typed, audited tool access into separate customer and authoring surfaces.

  • 2026–present
  • Professional · RWA

Why there is no measurement

Measured internally at RWA — not mine to publish

No measurement

Why not

This ran in production and its effect was measured internally, but those numbers are RWA's rather than mine and are not mine to publish. I would rather show the gap than publish a figure I cannot let anyone check, or quietly leave the project off the site because the result is inconvenient to evidence.

Problem

AI assistants were being wired to company systems one integration at a time. Every new tool meant another bespoke client, another auth path and another place for a model to be handed more access than the task needed. The cost was not novelty — it was that nobody could answer, in one place, what an assistant could actually reach, or whether a customer-facing assistant and an internal one were reaching through the same door.

Approach

A single MCP server as the boundary, split into two entry points from one tool registry: a customer-facing surface carrying only read/query tools, and a separate authoring surface carrying the write and review tools, so the write path cannot be attached to the customer build by a registration mistake. Tools are declared with typed schemas so a model's call is validated before it reaches a system rather than after, access is scoped per tool and fails closed if unconfigured, and calls are logged so "what did it do" has an answer that does not depend on the model's own account of itself.

Components

  1. Tool registry

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    The list of what an assistant can reach. Capability is added by declaring a tool rather than by writing another client with its own auth story.

  2. Customer / authoring split

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    One registry, two entry points: a customer server with only read/query tools, an authoring server for writes — so the write path cannot reach the customer build by mistake.

  3. Typed schema validation

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    Validates a model's tool-call arguments at the boundary, so a malformed call fails locally as a validation error instead of reaching the downstream system and failing there.

  4. Per-tool scoping

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    Scope is a property of the tool rather than of the caller, so an agent cannot reach past its allowed surface regardless of what the prompt says.

  5. Fail-closed access gate

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    An unconfigured scope does not default to open. If the allowlist for a given caller is unset, every tool behind it refuses rather than falling back to unrestricted.

  6. Metadata-first query gate

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    A downstream source's schema must be read through the server before a query tool against it will run, so a call uses real field names instead of guessed ones.

  7. Guarded query execution

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    Query and export tools carry their own guardrails — response size caps and output validation — rather than trusting the caller to ask for something reasonable.

  8. Demo sites as a proving ground

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    New capabilities are exercised on demo sites first — a staging ground ahead of the real customer sites they'll eventually reach.

  9. Call audit log

    Evidence: MEASURED INTERNALLY — NOT PUBLISHABLE

    Records what was called so that "what did it do" has an answer that does not depend on the model's own account of itself.

Why a server rather than more integrations

The failure mode with assistant tooling is not that any single integration is hard. It is that the tenth one is written the same way as the first, and by then no one person can enumerate what the assistants can reach. Access ends up described by whichever engineer last touched a client.

Putting one MCP server in front of the systems moves that question to a place where it can be answered. The set of tools is a list. The scope on each tool is a property of the tool, not of the caller. Adding capability is an edit to a declaration rather than a new code path with its own auth story.

Two entry points, one registry

The server is not one process with a flag. There is a customer-facing entry point and a separate authoring entry point, and the tools that write or review anything live only behind the second one. Both entry points register through the same function, which is the point — a write tool cannot end up on the customer build through a call site someone forgot to remove, because there is only one place tools get attached and the customer path never calls into the half of it that holds write tools.

The typed boundary

Tool schemas are the part that earns its place. A model producing arguments for a tool call is producing structured output under exactly the conditions that make structured output unreliable — long context, ambiguous instructions, a plausible-looking wrong answer available.

Validating at the boundary means a malformed call fails as a validation error with a message the model can act on, instead of reaching the downstream system and failing there as something harder to attribute. It converts a class of silent misbehaviour into a loud, local one.

What is deliberately absent here

No client names, no internal metrics, no architecture diagram of an RWA system. The employer boundary in this site’s content rules is not a formality: this is a live production system belonging to my employer, and the interesting details are exactly the ones that are not mine to give away.