Case study
MCP servers over real internal systems
Three internal MCP servers — PulseOne, ProjectOne, SignalOne — that give AI agents governed access to live company systems, running in production.
- The constraint
- Live internal systems, an evolving protocol, no established playbook
- Outcome
- Agents working against real internal state, daily
- Time to first value
- First useful output within the first sprint
The situation
An AI assistant is only as useful as what it can see and touch. Ours could see nothing: the state that matters day to day — project delivery, team goals, operational signals — lived in internal systems no model could reach. Instead of waiting for vendors to integrate with tools they've never heard of, I built the bridge myself: MCP servers over the systems we already run.
The constraints
- Real systems, real data. These aren't sandboxes. A wrong answer or a careless write is visible to the whole team, so access had to be shaped deliberately, not granted wholesale.
- A protocol still settling. MCP is young and moving. Spec revisions, SDK churn, evolving client behaviour — the ground shifts while you build on it.
- No playbook. There is no established pattern library for exposing line-of-business systems to agents. Most decisions had to be made from first principles and revised in use.
- The same trust problem as any AI tool. An agent that does something wrong once, in front of the team, loses the room. Guardrails weren't a compliance afterthought; they were the adoption strategy.
- Part-time attention, built alongside tech-lead responsibilities.
What I built
Three servers, each wrapping a live internal system:
- PulseOne — goals and people. Agents can read state broadly, but every change is a proposal that a human reviews and approves. Nothing writes directly.
- ProjectOne — project and delivery state, readable by agents in the same governed way.
- SignalOne — operational signals, so an agent can notice what a human would otherwise have to go looking for.
The design rule across all three: reads are broad, writes are proposals. An agent can always answer "what's the current state?"; it can never silently change it. Structurally each server is small — scoped tools over the system's own API, with the access model designed before the tool list.
These run in production and back real daily work: assistants and agent sessions that answer questions about live internal state and draft actions for humans to approve.
Time to first value
First useful output within the first sprint — the first server earned its keep the day an agent could correctly answer one real question about live state without anyone opening the underlying systems.
What changed
Questions that used to mean logging into internal systems and assembling an answer by hand can now be asked in plain language, mid-task, by anyone working with an agent. Proposed changes arrive pre-drafted with a human decision at the end, instead of being typed from scratch.
I haven't instrumented usage across the servers, so I won't claim adoption figures. The observable fact is that they are in production, wired into daily agent workflows, and that the propose-and-approve pattern has so far kept the failure mode that kills these tools — one bad autonomous action — from happening.
What I'd do differently
On the first server I designed the tool list first and the access model second, then had to walk back two tools that exposed more than an agent needed. The lesson stuck: the guardrail model is the design, and the tools fall out of it. The second and third servers were built access-model-first and were both faster to ship and easier to reason about.
I'd also pin protocol and SDK versions from day one and upgrade on my own schedule. Early on I chased the spec as it moved, which meant repeated small breakages at unpredictable times — exactly the kind of silent maintenance load a side-of-desk system can't afford.