When interacting with intelligent agents (like Claude Desktop) that have access to multiple tools, you might observe a phenomenon called Tool Bypass.
For example, if the LLM is asked to delete a user (DELETE FROM customers), it will read the execute_safe_query description, realize that only SELECT and SHOW are allowed, and might attempt to bypass the MCP entirely by using its terminal execution tool (e.g., trying to run mysql -h 127.0.0.1 -u user -p -e "DELETE..." directly).
TokenLite MCP is designed with a Defense in Depth strategy to guarantee absolute safety against rogue LLM actions:
-
Layer 1: The AST Limiter The
execute_safe_querytool passes every LLM query throughnode-sql-parser. It forcefully injects aLIMIT 500(or whatever limit is configured) directly into the Abstract Syntax Tree, making it mathematically impossible for the LLM to request a massive payload that crashes the node process. -
Layer 2: The EXPLAIN Guardrail Before executing the query, the server runs an
EXPLAINplan on MySQL. If the optimizer detects that the query requires a Full Table Scan on a table with more estimated rows thanMCP_EXPLAIN_MAX_SCAN_ROWS(default 1000), the query is hard-blocked and the LLM is instructed to use an index. This threshold is independent ofMCP_QUERY_ROW_LIMIT, which caps how many rows are returned. -
Layer 3: Hardened
explain_queryTheexplain_querytool validates SQL through the same AST pipeline asexecute_safe_query. OnlySELECTstatements are allowed.ANALYZE(which executes the query in MySQL 8) and non-SELECT statements are blocked. All EXPLAIN calls are subject toMYSQL_QUERY_TIMEOUT. -
Layer 4: Write Scope Guardrail When write operations are enabled (
ALLOW_UPDATE_OPERATION,ALLOW_DELETE_OPERATION),UPDATEandDELETEstatements without aWHEREclause are rejected to prevent accidental mass modifications. -
Layer 5: Database User Permissions (Engine Level) To protect against Tool Bypass, TokenLite strongly mandates connecting to the database using a restricted, read-only user. As seen in our
docker/init.sqlsetup:GRANT SELECT, SHOW VIEW ON your_database.* TO 'mcp_user'@'%';
If the LLM attempts to circumvent the MCP by executing raw terminal commands, the MySQL engine itself will immediately block the destructive action with an
ERROR 1142 (42000): DELETE command deniedmessage. -
Layer 6: Environment Isolation In a production setup, the database credentials (
DB_PASSWORD) should be loaded in the environment of the MCP process internally, without explicitly printing them in the prompt. If the LLM never sees the password, it cannot build the raw terminal command to attempt a bypass. -
Layer 7: Rate Limiting A sliding-window rate limiter restricts tool invocations to
MCP_RATE_LIMIT_RPMrequests per minute (default: 60). This prevents aggressive agents from overwhelming the database with high-frequency requests. Set to0to disable. -
Layer 8: Input Validation All tool inputs are validated with strict bounds:
execute_safe_query: SQL limited to 10,000 characters max.search_schema: search query limited to 200 characters max.- Table names are sanitized against
^[a-zA-Z0-9_]+$before use in any dynamic SQL (SHOW CREATE TABLE). Names with spaces, backticks, semicolons, dots, dashes, or unicode are rejected.
-
Layer 9: Connection Hardening
multipleStatements: falseis enforced at the pool level to block stacked queries even if the AST parser is bypassed.- Optional TLS via
DB_SSL=truefor encrypted connections to managed MySQL instances.
-
Layer 10: Sanitized Error Responses Database errors returned to the LLM are sanitized to avoid leaking internal paths, raw MySQL error codes, or stack traces. Actionable hints (e.g.
refresh_schema, timeout guidance) are preserved.
If you notice the LLM trying to bypass the MCP, you can add a system prompt instruction to your agent's configuration:
"You are strictly a read-only agent for this database. Do not attempt to bypass the MCP using terminal commands, as the database engine will block any write operations."