tools/list into the model’s context before the first user message. This page records what that costs for levelrail-mcp in each mode, which tools overlap, and the tests that stop the listing growing unnoticed.
Numbers are estimates: the serialized tools/list JSON length divided by 4 (no tokenizer is in go.mod). They are good for comparing modes and catching regressions, not for billing. They are a snapshot of the 156 registered tools and drift as tools are added, so rerun the commands below for current figures.
MCP tool surface counts each tool’s name, description and input schema per toolset. This page measures the whole serialized tools/list response a client receives, which also carries output schemas and annotations, so its totals are larger.
Tools and tokens per mode
Measured bygo test -run TestToolListTokenBudget -v ./internal/mcptools (or scripts/mcp-token-budget.sh).
Modes are defined in
internal/mcptools/modes.go and driven by the class table in internal/mcptools/classes.go: 118 read, 28 mutating and 10 destructive tools. read-only registers read tools, standard adds mutating tools, and full adds destructive ones. The API token’s own abilities still apply on top of the mode.
The agent-core profile
Theagent-core profile lists 15 tools and omits output schemas from tools/list (results are still returned as text and structured content). Its full listing is about 2,600 estimated tokens against about 66,700 for full mode. The tools are listed in MCP tool surface. A test holds the listing under a budget (default 3,500, override with APP_MCP_TOKEN_BUDGET_AGENT_CORE).
Use this profile for autonomous agents, which rarely need more than these 15 tools: levelrail-mcp --tool-profile agent-core or APP_MCP_TOOL_PROFILE=agent-core.
Overlapping tools
Annotations
- Every registered tool carries a title,
readOnlyHint,openWorldHintand, for non-read tools,destructiveHint.TestEveryToolClassifiedininternal/mcptools/modes_test.gofails the build if a tool is unclassified. idempotentHintis set only for tools whose name starts withset_. Tools such asapprove_*,reject_deploy_approval,expire_alert_silenceandrestart_appare also safe to repeat but are marked non-idempotent.- Sensitive and untrusted-output tools carry
_metaflags (levelrail/sensitiveand its untrusted counterpart), set from the class table.
Where tokens go
Output schemas take up most of the space. Typed handlers derive them from the Go result struct, so the same large result schema repeats across tools (for example the app resource inget_app, list_apps and restart_app, and the deploy result in deploy_app, rollback_app and approve_deploy_approval). Input schemas and descriptions are the next largest parts. The cheapest fix is a smaller listing, which is what the agent-core profile and the APP_MCP_TOOLSETS filter give you.
Regression tests
internal/mcptools/budget_test.go serializes tools/list for each mode over an in-memory MCP session and fails when the estimate exceeds that mode’s budget.
Run it with a report of the heaviest tools:
scripts/mcp-token-budget.sh
Raise a budget only with a reason in the PR that changes it.