Example Use Case: a University MCP System
The testbed both plug-ins were built and validated against — a fictional university management system, not a requirement of either package.
Everything on this page is specific to example/. tool_curator and multilingual_normalizer have no knowledge of universities, students, or any of the tool names below — see the Reusability Guide for what carries over to a different domain unchanged versus what you'd rebuild.
The testbed
An in-memory mock database (mock_db/university_mock_database.py) sits behind 8 FastMCP servers exposing 191 tools total:
| Server | Tools |
|---|---|
academic |
23 |
student_services |
45 |
faculty |
44 |
finance |
18 |
infrastructure |
22 |
admin_analytics |
20 |
placement |
10 |
library |
9 |
Roles
Four personas, defined in example/orchestrator/persona_access_policy.py, see different slices of the 191 tools:
- student — roughly 87 tools
- faculty — roughly 65 tools
- executive — roughly 27 tools (mostly read-only dashboards)
- admin — all 191
About 55 of the 191 tools are state-mutating “action tools,” intercepted for user confirmation by example/orchestrator/mutation_guard.py regardless of persona.
Three generations, one test suite
The same 281-case hand-labeled suite (see Evaluation & Results) was run against three successive versions:
- No curator — every tool the role permits goes to the model at session start. This is the accuracy ceiling and the token floor’s opposite: maximum accuracy, maximum cost.
- TF-IDF curator — keyword-only retrieval, with a blanket “always include all action tools” augmentation added once top-k alone proved unreliable for action-triggering queries.
- Hybrid curator — BGE + FAISS + BM25 + RRF + the anchor, compound splitting, and dependency expansion described in Tool Curator Architecture.
The description-refinement finding
The single most generalizable result from this deployment has nothing to do with retrieval technique. The original 191 tool descriptions were written “for a person” — roughly 80 words each, most of it a “use this tool when…” section restating the description in different words. With no curator at all, that phrasing scored roughly 80% correct against the 281-case suite.
Rewriting all 191 descriptions into a tighter contract format — parameters and return shape only, dropping the restated “when to use this” section — took the same no-curator baseline to 281/281 (100%), with zero code changes anywhere. The extra prose seems to compete for the model’s attention with the part of the description that actually distinguishes one tool from another, and it roughly halves every tool’s token footprint on top of whatever the curator saves.
Every accuracy number reported anywhere in this documentation is measured against the refined descriptions — this is worth internalizing before tuning anything else: check description quality before touching top_k, the anchor threshold, or the synonym file. See Lessons Learned for the fuller version of this point.