The problem
The client is a Series C software company with a fast-growing engineering organization, where every team had quietly built its own one-off integration for letting an AI assistant touch internal systems. One team had a custom script for querying deployment logs, another had a Slack bot wrapping the feature-flag service, and a third was pasting database query results into a chat window by hand. None were reusable, none were consistently secured, and every new AI-assisted workflow meant building another bespoke integration from scratch.
Leadership wanted a standard way for AI agents (Claude, an internal agent framework, and eventually customer-facing agents) to access internal systems safely, instead of a sprawl of ad hoc scripts, each with its own undocumented access pattern and permission model.
Why this was a permissions problem before it was an integration problem
The instinct when a company has this problem is to jump straight to building connectors. We pushed the client to define an access and permission model first. The real risk wasn't "can an agent call our API?" It was "what happens when an agent with a production write tool gets a subtly wrong instruction?" Two of the existing integrations had unscoped write access to systems (feature flags, a customer-facing config service), and that was the problem to solve before adding more tools, not after.
Architecture
A single MCP server, not one per team
Rather than each team building and maintaining its own MCP server, we built one centrally owned server exposing tools across deployment logs, feature flags, the internal ticketing system, a read-only customer data lookup service, and a handful of other internal systems. Each tool's schema and permission scope is defined and reviewed centrally. That avoided recreating the original sprawl with a standardized protocol in place of ad hoc scripts.
Scoped, typed tool schemas
Every tool has a narrowly defined schema. The deployment-log tool can query and filter logs but can't trigger a deployment or rollback. The feature-flag tool can read flag states and toggle flags explicitly marked safe for AI-assisted changes, but it can't touch flags tagged high-risk (payment processing, auth), whatever an agent is instructed to do. We designed this scoping with each system's own team rather than imposing it, because they understood their own blast radius best.
Permission and access-scoping per caller
Tool access is scoped by which team and which agent context is calling, not a single flat permission level for every MCP client. An agent running in the on-call engineer's context has broader deployment and log access than one in a company-wide internal chat assistant, and this is enforced at the tool-invocation layer rather than trusted to prompt instructions.
Multi-agent tool orchestration for cross-system tasks
Some internal workflows span multiple tools (investigating an incident might mean checking deployment logs, then recent feature-flag changes, then filing a ticket). We built explicit hand-off patterns for these multi-step flows rather than relying on an agent to improvise the sequence of tool calls each time, which proved less reliable in early testing.
Testing and evaluation of tool-use reliability
Before rolling out to each new team, we ran a dedicated evaluation pass testing whether an agent correctly recognized when not to use a tool, not just whether it could use one correctly. A write-capable tool called with plausible but wrong arguments is the real production incident risk, so the evaluation weighted this heavily.
Challenges and tradeoffs
- Getting six different teams to agree on tool schemas took real negotiation, not just engineering. Each team had opinions about what its system's tool should expose, shaped by how it had been using its own ad hoc integration. We ran a schema review with each team individually rather than mandating a template. It took longer, but it earned real buy-in instead of teams working around a schema they didn't trust.
- Centralizing the server created a single point of operational responsibility that needed real ownership. Moving from "everyone has their own thing" to "one shared server" meant someone had to own its uptime and on-call. We helped the client make this a platform-team responsibility with defined SLAs, rather than an afterthought once teams already depended on it.
- The evaluation harness for "correctly declining to use a tool" was harder to build than testing correct usage. Most tool-use evaluation tests whether an agent calls a tool correctly, not whether it avoids calling a write-capable tool when the situation is ambiguous. We built a specific adversarial test set of ambiguous instructions for this, because it was the risk surface that mattered most.
Results
Six engineering teams moved onto the shared MCP server within two months of launch, replacing their one-off integrations. Fourteen internal tools are exposed with scoped, reviewed permissions, and there have been no write-access incidents in the five months since the first team's rollout. The client's platform lead attributes that to the tool-use evaluation process, which caught several risky agent behaviors in testing before they reached production.
The client's engineering leadership now uses this as the reference architecture for any new agent-facing internal tooling, instead of each team defaulting back to a one-off script.
What we'd do differently
We'd establish the platform-team ownership model for the shared server before the first team's rollout rather than in parallel with it. It worked out, but ownership was genuinely ambiguous for the first few weeks, which could have caused real friction if an incident had happened then.