One Front Door to Every Tool
TL;DR:
- At PrizePicks, delivering a 6-star customer experience runs on data scattered across a dozen tools, and wrangling it is one of our biggest engineering challenges. Rigorous performance assessment and constant data collection are how we find experience bottlenecks and decide what to build next, but that signal lives across the issue tracker, source host, error monitor, metrics stack, team chat, and more.
- The MCP Aggregator gives every app, agent, and engineer one front door to all of it. Less time hunting and interpreting data, more time on high-leverage work closer to our members.
- Because everything passes through one boundary, standards propagate by default. A new control, naming convention, or metric definition reaches every consumer the day it ships. Set the standard once, at the layer everything already passes through, and you keep the power of fast, numerous agents without losing the glue that keeps the org coherent.
Why we built an MCP aggregator, and what we learned setting the standard once, at the tool layer
Ask an AI assistant something simple, like "what's the current state of this project, and is anything on fire?", and you hit a wall that has nothing to do with how smart the model is. The answer lives in five different systems — the issue tracker, the source host, the error monitor, the metrics stack, the team chat — and the assistant can only reach the ones someone bothered to wire up.
So everyone wires the integrations on their own. The same integration gets set up a dozen times in a dozen slightly different ways across dozens of different apps. Nobody shares a view of which tools exists, who’s allowed to call them, or what happened when they were called.
The Model Context Protocol (MCP) standardized how one application talks to one tool or system. It didn’t solve how an organization manages dozens of those connections at once across many users and applications. That’s the gap we set out to close.
The MCP Aggregator is a single authenticated endpoint that sits in front of every tool we’ve integrated and gives every app, agent, and engineer the same front door, permissions model, and audit trail. Connect once, get everything.
The problem we were facing
A few pains stacked up together:
- Adoption is fragile — tools that behave non-deterministically struggle to get adopted, especially by users that aren’t intimately familiar with how they work. One confusing experience and people stop reaching for them. This is especially true since our team operates at breakneck speed in a hyper-competitive industry; time is extremely precious, and the bar to try something new has to be near zero, or it interrupts our ability to deliver.
- MCP setup is per-app and per-person — every client (desktop assistants, editors, custom agents) needs its own configuration. There is real, meaningful friction when you multiply that by every tool our team uses.
- Connections were scattered and unmanaged — people were independently wiring up the same integrations. There was no single source of truth for what existed or any central policy; there was nowhere to look when something behaved oddly.
- Information lives in silos — painting a complete picture of how a service works, or where a project actually stands, means searching across many systems. It’s slow, and it’s easy to miss something.
- And every setup was a different slice — because everyone had configured their own tools, no two agents had the same reach. One had GitHub and Linear; another had GitHub and Slack; another had something else again. Each combination gave the agent a slightly different view of the world. This is problematic since an agent has no idea what it can’t see. Hand it a few endpoints, and it answers from its slice with the same confidence it’d bring to the whole picture. Two people ask the same question and get two confident, differently-incomplete answers, with nothing flagging the gap.

The lever was obvious: one central layer that everything points at, instead of N inconsistent integrations maintained in isolation.
What we built

We created a single endpoint for any MCP-compatible client. Behind it sit all the tools across our upstream tool servers. Each consumer gets a few things for free:
- Namespaced tools so that tool names never collide
- Entitlement-scoped visibility so that you only see the tools you’re allowed to call
- An audit trail on every call and every denial
- Runtime-managed upstreams enabling us to add and remove tool sources without restarting anything
- Pass-through user credentials so the underlying application acts on behalf of the end user instead of through a shared credential
- A complete, shared view of the landscape so that every agent and underlying application sees the same map of what systems exist, so it knows where to look and, just as importantly, knows where it hasn’t checked.
Problems we solved building it
-
Not everything has an MCP — some of our business tools didn’t have MCP integrations, so we stoop our own MCPs wrapped around their APIs. We also built our own collection of useful tools, including a semantic search across all of our coding repositories, a data-warehouse connector, and an org-chart service. We self-hosted these systems as internal services so that they could live behind the same boundary as everything else.
-
Credential management became a real subsystem — for many tools, a service-account model didn’t work for a couple of reasons:
- Data access — some data (like emails) wasn’t accessible from a shared token. Relying on shared tokens would handicap the ability of the aggregator service to be maximally useful for each end user.
- Attribution — in many systems (like our task management system), we wanted user-level attribution, since service accounts would obfuscate the end user taking the action.
As such, we designed a credential management system to selectively pass through user credentials when effective tool usage required it.
-
Eval suites at the tool-fetching layer — when you slip a proxy between an app and its tools, you have to prove you didn’t quietly change the behavior. So we built tests and smoke checks at the fetch layer, verifying that calling a tool through the aggregator returns what calling it directly would. It’s a fidelity guarantee, allowing us to keep moving without wondering if the abstraction is mitigating utility.
-
Tool discovery at scale — aggregating tools creates a problem of its own: abundance. With hundreds of tools behind one endpoint (and the catalog growing every week), naively handing every tool’s full schema to the model on every request is both expensive and counterproductive. Schemas are verbose (a typical one runs about 160 tokens once you include its input definition), and burying the three tools that matter under a hundred that don’t measurably hurts the model’s reasoning. More context is not more useful context.
We designed the aggregator to select before it serves. A fast, cheap model sees a lightweight catalog (just the tool names and one-line descriptions) and picks the handful relevant to the request. Only those full schemas get loaded for the main model to act on. To keep this honest, we built a measurement harness running representative prompts through the real selection path. A typical single-system request, like “show me the recently merged pull requests” pulls three tools out of the catalog, roughly an 80% reduction in tool-schema tokens versus loading everything.
The economics get better as we grow. The cost of loading all schemas scales linearly with the catalog, while the cost of loading a well-selected subset stays roughly flat. Every tool we add widens the gap, and because selection runs inside the aggregator, every app inherits it for free, without needing to implement its own tool-routing logic.

- Observability, closing into a loop — every tool call, auth event, and policy denial is a structured event, meaning that we can see how tools are actually used, not how we assume they would be used. That visibility is the engine for everything that comes next: observe usage → build evals from it → optimize the discovery layer → surface more useful context per app → observe again.

Where this goes
A few directions we’re building toward:
- An ontology layer for tool selection — helping any app or agent pick the right tools as the catalog keeps scaling. This is the next evolution of the discovery work above.
- Consolidating the tooling layer to fight context rot — fewer, sharper tools; common multi-tool patterns promoted into reusable skills
- Standards that propagate by default — because everyone passes through one boundary, a new control or convention reaches every consumer the day it lands. Any hallucinations or tool misuse turn into measurable improvements that immediately reach every consumer.
Setting the standard once
Normally, an organizational standard (how you authenticate, how you name things, etc.) has to travel. You write it down, you tell people, and then every person re-implements it in every app they build. The standard is only as strong as the weakest copy of it, and copies drift. Alignment becomes a thing you constantly spend energy maintaining rather than something you simply have. A central tooling layer flips that; by setting the standard once, at the layer that everything already passes through, every consumer inherits it the moment it ships.

This matters as agentic applications get more capable. These tools are powerful, and they act fast and at volume. The usual cost of that power is fragmentation; more builders and more agents, each moving in a slightly different direction. Setting standards at the tool layer is how we keep the power without eroding the glue that helps keep us coherent.
Keep up with us here on how we're threading the needle between the DFS industry and innovation on @PrizePicksLabs - we’re also signing free agents across teams at PrizePicks. Come build with us.