How to Filter Exposed MCP Tools for Token-Constrained Environments
Reduce LLM token consumption by exposing only specific MCP tools using the --tools CLI flag or CRG_TOOLS environment variable.
The Code Review Graph (CRG) server provides a rich set of Model Context Protocol (MCP) tools for graph-based code analysis, but full tool exposure can overwhelm token-limited LLMs. This guide explains how to filter exposed MCP tools for token-constrained environments using the built-in _apply_tool_filter mechanism in CRG's FastMCP implementation.
How the Tool Filter Works
CRG implements tool filtering in code_review_graph/main.py through the _apply_tool_filter helper, invoked during server startup. The mechanism prunes the MCP tool inventory before any client connection occurs.
Filter Execution Flow
-
Step 1: Resolve allow‑list — The filter reads
--toolsfrom CLI arguments or theCRG_TOOLSenvironment variable, normalizing the comma-separated list (whitespace stripped, empty entries removed). Source:code_review_graph/main.pylines 381‑386. -
Step 2: Iterate registered tools — CRG loops through every tool registered on the
FastMCPinstance (mcp). -
Step 3: Prune non-matching tools — Tools not in the allow‑list are removed via
mcp.remove_tool(name), eliminating their descriptions from the MCP tool inventory entirely. -
Step 4: Preserve async semantics — The underlying coroutine implementations remain intact; only the registration is dropped.
-
Step 5: Default to full exposure — If no filter is provided, all tools remain available.
This approach is token‑efficient by design: shrinking the tool inventory reduces the initial payload size, directly lowering token consumption for constrained LLMs.
Filtering Methods
CLI Flag: --tools
Pass a comma-separated list of tool names to keep:
code-review-graph serve --tools query_graph_tool,semantic_search_nodes
Only query_graph_tool and semantic_search_nodes remain exposed; all others are pruned from the MCP inventory.
Environment Variable: CRG_TOOLS
Ideal for containerized deployments or CI pipelines:
export CRG_TOOLS="embed_graph_tool,get_review_context_tool"
code-review-graph serve
The server reads CRG_TOOLS and applies identical filtering logic before accepting connections.
Programmatic Filtering
For embedded server scenarios, invoke the filter directly:
from code_review_graph.main import crg_main
# Retain minimal tool set before client connections
crg_main._apply_tool_filter("list_graph_stats,visualize")
This manipulates the FastMCP instance in-process, ensuring filtered tool exposure for all subsequent clients.
Verifying Filtered Tool Exposure
After server startup, connected MCP clients receive only the pruned tool list:
client = mcp_client.connect() # platform-specific connection
print(client.list_tools())
# Output: ['query_graph_tool', 'semantic_search_nodes']
The filtered inventory persists for the server's lifetime; restart with different parameters to adjust exposure.
Implementation Details
| Component | Location | Purpose |
|---|---|---|
_apply_tool_filter |
code_review_graph/main.py lines 381‑386 |
Core filtering logic |
| CLI argument parsing | code_review_graph/cli.py |
Bridges --tools to internal filter |
| Test coverage | tests/test_main.py lines 418‑442 |
Validates filter behavior across input methods |
The filter integrates into the serve command initialization, ensuring trimmed tool exposure from the first client handshake regardless of transport (stdio or HTTP).
Test Coverage
The test suite confirms three critical scenarios in tests/test_main.py:
-
test_no_filter_keeps_all_tools(lines 418‑425): Verifies full tool retention whencrg_main._apply_tool_filter(None)is called. -
test_filter_via_argument(lines 426‑432): Confirms CLI-based filtering withcrg_main._apply_tool_filter("query_graph_tool"). -
test_filter_via_env_var(lines 434‑442): ValidatesCRG_TOOLSenvironment variable behavior usingmonkeypatch.setenv.
Summary
- Use
--toolsfor ad-hoc filtering via command line - Set
CRG_TOOLSfor environment-based configuration in containers - Call
_apply_tool_filterprogrammatically for embedded deployments - Target
code_review_graph/main.pyfor source-level understanding of the filter mechanism
Frequently Asked Questions
What happens if I specify a tool name that doesn't exist?
The filter silently ignores non-existent names. Only matching registered tools are retained; unknown names simply result in no tools being exposed if no valid names remain in the allow‑list.
Can I change the filter without restarting the server?
No. The _apply_tool_filter runs once during server initialization. Changing exposed tools requires a server restart with new --tools or CRG_TOOLS values.
Does filtering affect tool execution performance?
No. Performance characteristics remain unchanged—the filter only removes registration metadata, not the underlying tool implementations. Async semantics for long-running tools are preserved.
How do I discover available tool names for filtering?
Check the source code in code_review_graph/main.py where tools are registered via decorators like @mcp.tool(), or run the server without filtering and query client.list_tools() to see the full inventory.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →