by Sanjeya Cooray, Head of Engineering & Rosario Cannavò, Big Data Engineer Onetag
The situation
More clients and colleagues work through an AI assistant. They no longer want to open a console, hunt for the right menu entry and fill in a form: they want to ask their agent, “how much is this campaign spending?” or “activate that segment” and get the answer, or the action, inside the flow they are already working in. Making that conversation possible requires a common language between agents and the platform, and today that language is the Model Context Protocol (MCP): an open standard through which an assistant asks a service, “what tools do you have?” and then invokes them, using a message format shared by Claude, ChatGPT, Copilot and every other client that supports it.
Across every client, we consistently hear the same need: while agents built directly into platforms are valuable, organisations increasingly want to retain control in-house and establish strong, direct connectivity with technology partners like Onetag through standards such as MCP.
The catch is that Onetag is not a single service. It is a set of modules, each with its own team, its own technologies and its own release cycle. A deliberately decentralised architecture, which works well for building product but which, seen from an external agent, looks like a collection of separate front doors, each with its own MCP server. We needed a single entry point that knew how to route requests to the right module. When we started, an MCP “router” did not exist yet, neither on the market nor in the libraries we were using.
The goal
Build an MCP gateway that reconciled two apparently conflicting needs. On one side, let every team develop its own MCP server independently, with the stack it knows and the domain expertise only it has. On the other, offer the outside world a single connector, publishable in the catalogues of AI assistants, where the cross-cutting concerns are centralised once and for all: authentication, authorisation, tracing and monitoring.
What we did
Rather than starting from scratch, we extended the API gateway that already sat in front of Onetag’s public APIs, a service acting as a proxy towards the internal backends. We added an MCP server next to it, exposed on the same domain over the variant of the protocol that travels on ordinary web requests and therefore passes through existing load balancers and firewalls without trouble. The choices that mattered most:
- One identity, verified at the centre. MCP requires access to be managed through a secure authorisation flow, and it gives assistants a standard way to know where users should sign in and which permissions are available. We adapted our identity provider to this model: the user logs in with their corporate account, the assistant receives an access credential and attaches it to every request. The gateway validates the credential centrally and translates the user’s entitlements into the permissions recognised by the downstream modules. This was one of the most delicate parts of the project, because security support is still not implemented in exactly the same way across model providers and each assistant handles it with slightly different nuances.
- The gateway discovers, it does not just forward. A classic API gateway hands packets over to their destination and nothing more. Ours inspects the MCP messages in transit, which are JSON-RPC, and recognizes two operations. When a tools/list arrives, meaning “what tools do you have?”, it opens a session towards every configured module, collects their tools following pagination and presents them as a single catalogue. When a tools/call arrives, meaning an invocation, it routes it to the owning module. The interesting detail is that the tool registry in the MCP SDK is static by design, while our catalogue changes depending on who is asking: so we made it dynamic, realigning it before every response and touching only what has actually changed. If a module is not responding at that moment, its tools disappear from the list with a warning in the logs, but all the others remain available.
- Everyone sees only what they are authorised to see. Discovery happens in the context of the person asking: each module only exposes what that user is entitled to see. The catalogue the agent receives is therefore different from user to user, and the gateway keeps no copy of the permissions: there is no second source of truth to keep in sync. We do not want confidential information to leak through an assistant, not even in the form of “there is a tool that does this”.
- Routing by convention. Every exposed tool carries in its name a pattern that identifies the module it comes from. When the agent invokes it, the gateway reads that pattern, works out who owns the call and forwards it with the original name. No routing table to maintain by hand, no collisions between same-named tools from different modules, and with nested names the most specific pattern wins.
- One place to look. Since every call goes through the same point, MCP calls are counted and exported to our monitoring stack, tagged by module, tool, operation and outcome: a few dashboard panels are enough to see which tools are used and where errors pile up. Every request also carries a trace identifier that enters the gateway logs and is propagated as a header to the final module, so a problem reported by a user can be reconstructed end to end with a single search.
The hardest part was not writing code, but studying a young and moving protocol, especially on the security side, and keeping pace while the specifications and the behaviour of the different assistants changed under our feet.
The result
From a developer’s point of view, adding a new module to the world of agents is now a single configuration line on the gateway: the name and address of its MCP server. A person completes one authorisation, not one per product. Every call is attributable to a specific human being, all the way down to the module where the data lives. An outage on one module degrades only its own tools, not the whole catalogue. And every team keeps its own schemas, its own limits and its own audit trail, on its own release cycle.
For Onetag users and end customers alike, the change is even simpler to describe: add one connector to your favourite assistant, sign in with your own account, and from that moment the whole Onetag universe is available to your agent. Whether the person asking is working inside Onetag or using the platform as a final customer, the gateway takes care of everything else.
Originally Published on: LinkedIn