Performance
Source files are parsed once at boot and cached in memory. Only @requires filtering runs per request (hash lookups and can? calls). In development, caches ar...
Source files are parsed once at boot and cached in memory. Only @requires filtering runs per request (hash lookups and can? calls). In development, caches are cleared automatically on file change via the Rails reloader.
Per-request work is also scoped to what the incoming JSON-RPC method actually needs, since per-tool schema compilation is the dominant cost of an MCP request:
| Method | Tools materialized |
|---|---|
tools/list | Every permitted tool in the domain |
tools/call | Only the invoked tool |
initialize, notifications/initialized, ping, GET stream probe | None |
Unrecognized shape (e.g. a batch with no top-level method) | Full domain, so routing stays correct |
In a 140-tool domain that took a tools/call from ~2.6s to under 100ms and notifications/initialized from ~2s to ~1ms, with no change to tools/list output. What remains is the listing itself โ which is cacheable (below) and, for very large domains, groupable.
Collected from README.md in the repository. Edit it there, not here.