The Zerto Docs MCP, along with the other MCP servers I’ve been running have grown in usage from a couple hits per week to over 5000 hits per week. They have been live since May of 2026, and during that time I’ve noticed a lot of things I would like to have from an MCP gateway that MetaMCP wasn’t able to provide. I also noticed that the project seems to have gone dark, with over 100 open issues and 18 pull requests. Long story short, it was time to make the cutover from MetaMCP to Torii for all my MCP servers.
The companion post to this one explains why I wrote my own MCP gateway instead of staying on MetaMCP. This one is about the part I was actually nervous about: moving live traffic for the zerto-docs mcp over while people were using it.
Because that’s the thing about going multi-user. When it’s just me, a migration is a five minute job and if I break it, I fix it. The moment colleagues and public users have a working connector in their Claude config, every change I make is a change to their tooling, and they didn’t ask for it.
The problem with the new URL
MetaMCP served my documentation servers at URLs shaped like this:
https://mcp.jpaul.io/metamcp/zerto-docs/mcp
torii serves the same server at:
https://torii.jpaul.io/zerto-docs/mcp
Different host, different path, different name (same MCP server instance behind the scene). I could have sent an email saying “please update your connector,” and some people would have, and some would have had a broken tool for three weeks and quietly stopped using it. (Or worse they wouldnt have noticed and the LLM would have just made up its own answers.)
So I taught torii about aliases instead. An old path is recorded against a server, and the gateway keeps answering it:
metamcp/zerto-docs -> zerto-docs
metamcp/zerto-docs-zsupport-> zerto-docs-zsupport
metamcp/morpheus-docs -> hpe-morpheus-docs
metamcp/hvm-docs -> hpe-hvm-docs
metamcp/opsramp-docs -> hpe-opsramp-docs
Then I repointed the mcp.jpaul.io DNS record at torii’s tunnel and stopped MetaMCP. Five old URLs, still working, now served by different software. Nobody edited anything.
The new URLs, if you would rather not go through the alias
You do not have to do anything to keep using the Zerto Docs MCP. The alias keeps the old path working, and that is the whole point of it. But if you don’t want to use the alias, and rather point straight at the real thing, here is the mapping.
| Old URL (MetaMCP) | New URL (torii) |
|---|---|
https://mcp.jpaul.io/metamcp/zerto-docs/mcp | https://torii.jpaul.io/zerto-docs/mcp |
https://mcp.jpaul.io/metamcp/morpheus-docs/mcp | https://torii.jpaul.io/hpe-morpheus-docs/mcp |
https://mcp.jpaul.io/metamcp/hvm-docs/mcp | https://torii.jpaul.io/hpe-hvm-docs/mcp |
https://mcp.jpaul.io/metamcp/opsramp-docs/mcp | https://torii.jpaul.io/hpe-opsramp-docs/mcp |
Two things that are not a straight find and replace. The Zerto docs server kept its name, but the HPE ones picked up an hpe- prefix, so you can’t just swap the hostname and keep the rest of the path. And the tool names changed: MetaMCP handed out zerto-docs__search_docs, torii hands out search_docs. If your client cached a tool list from before the move, refresh it, or remove and re-add the connector. A client that re-lists gets the short names and stays working either way.
Multi-user, concretely
“Multi-user” sounds like a feature list item. What it actually means here is two different kinds of person.
The first kind has an account. They sign in, they have a set of grants, and what their connector can reach is decided by who they are rather than which URL they typed. A key or an OAuth client can only ever narrow that, never widen it, so a credential I hand out can’t exceed what I have myself.
The second kind has no account at all. The documentation servers are useful to colleagues who are never going to create a login on my side project, so six of them are open: anyone can call them with no credential. That sounds like the absence of security but it isn’t. “Open” only decides that an anonymous caller resolves to one reserved account. What that account may actually call is still a grant, written on purpose, and if I grant nothing then an anonymous caller connects successfully and sees an empty tool list.
Right now those six open servers expose the same mcp servers that MetaMCP was exposing, along with the same list of tools.
Home grown, and what that costs
The whole thing is Python, FastAPI, Postgres, and valkey, running in containers on a server in my homelab. Cloudflare tunnels handle the public hostname so nothing on my LAN has a port open to the internet.
The project has taken several months get to where I would call it production ready, but the wave of traffic will be the real judge of that. Here is a Torii traffic radar, I think you can tell when the cutover happened.
BTW location data is ballpark, using MaxMind, but most LLM tool calls come from the datacenter where the agent is running, not someone’s home ip.
What’s next
Supply chain. Right now CI runs static analysis, a dependency advisory check and a secret scan on every push. That’s a decent start and it has two holes I can name: nothing scans the container image, so operating system level vulnerabilities in the base image are invisible, and nothing runs on a schedule, so a vulnerability published tomorrow against unchanged code never surfaces until I happen to commit something. I’m adding image scanning and a generated SBOM per build, so that “are we affected by this CVE” becomes a lookup instead of a rebuild. That’ll be its own post once Torii has been integrated into my VulnWatcher project.
![]()