Netision · 2026 / case 03
The MCP tool server
The shared hands of an agent platform: 49 tools in 20 packages, where tools declare what they are and credentials never become arguments.
Architect and main author, ~98% of current lines
Python · FastMCP · MCP · Streamable HTTP · Microsoft Graph · Playwright · reportlab · pytest
- first-party tools
- 49
- in 20 capability packagescount
- connectors
- 13
- across 5 providerscount
- a PDF in the tool result
- ~170k tok→~30 tok
- files by reference, not base64doc
- unused tools deleted in one pass
- 22
- commit
A Model Context Protocol server over Streamable HTTP: web research, six file generators, and 13 per-user connectors across Microsoft 365, Power BI, Google Workspace, Zoho and Databricks. And it can mount external MCP servers behind the same front door. It went through three architectures in eight months.
employer work: written up as architecture and decisions; client names, internal hosts and source stay private.
01/05Who is asking, their delegated token, the model and the turn all ride headers into context variables. A model that could set them as arguments could read someone else's account.
§ 1The motive
Every agent in the platform needs the same hands (search the web, write a deck, read a mailbox), and none of them should have to hard-code what a tool does, or hold a user's credentials. The server executes tools; it does not run conversations.
§ 2Three architectures in eight months
- February: a single-file social-media intelligence server for Claude Desktop and Cursor.
- March: a modular monolith on SurrealDB with per-agent tool permissions.
- May onwards: a plugin registry (drop a folder, get a module, zero core changes), and later the tag contract, delegated-token connectors and files by reference.
§ 3Decisions
- Tools are named by capability, not by consumer.
web_tools,pdf_tools,deck_tools. Never a folder named after the agent that happens to call it. - Codes, never wording. A tool declares which vocabulary entry it belongs to (
searching_web,web_search); the frontend owns every user-facing word. - Identity, credentials, host and turn are never tool arguments. One that could set the turn could claim the user approved something they never saw. A test pins it: no tool takes a user, a token or a host.
- Strip before you proxy. External MCP servers receive every forwarded header, so the user's token is removed before anything reaches them.
- Least privilege by construction. Drive declares read scopes only. Consent can't grant a write scope nobody asked for.
§ 4What this doesn't fix
The service check proves the caller is one of our services and says nothing about whose data it reads. User auth stays the caller's job, by design. Some connectors are built against plans that haven't met a real account yet, and they're marked that way.