Rajveer Mahida
← blog

Exposing an internal tool registry as an MCP server

Reusing 13 tools for both the chat assistant and external MCP clients, safely.

1 min read#ai#mcp#node

One tool registry feeding both the chat loop and an MCP server

We'd already built 13 read-only tools for our Claude-powered support assistant — things like "look up a document's seal status" or "list a user's pending signatures." When we needed to let external MCP clients call the same platform data, the obvious move was reusing that exact tool registry instead of writing a second integration layer.

One registry, two surfaces

The tool definitions are Zod schemas, converted to JSON Schema at startup. The chat assistant's agentic loop calls them directly. The MCP server wraps the same functions behind a Streamable HTTP transport — no duplicated business logic, no drift between what the chatbot can do and what an external MCP client can do.

The isolation problem

The tricky part wasn't the protocol — it was making sure one user's MCP session couldn't see another user's data. We solved it by forwarding the end user's own JWT on every tool call, so each downstream service applies its own authorization exactly as it would for a normal API request. Cross-user access isn't filtered after the fact; it's structurally impossible, because the tool never has more authority than the token it's carrying.

What I'd change

Right now, MCP clients authenticate the same way the chat assistant does. A larger deployment would issue scoped, shorter-lived tokens specifically for MCP sessions instead of reusing the platform's general-purpose JWTs.