Tools
Tools are the actions the LLM can take. Every tool call is executed by Mango and the result is fed back to the LLM.
Built-in tools
Register all built-in MongoDB tools with one call:
from mango.tools import build_mongo_tools
from mango.tools.base import ToolRegistry
tools = ToolRegistry()
for tool in build_mongo_tools(db):
tools.register(tool)
Available tools
| Tool | Description |
|---|---|
list_collections | List all collections. For databases with 100+ collections, returns a grouped view by name pattern. |
search_collections | Search collection names by glob pattern (order*, *_log). |
describe_collection | Return schema, indexes and sample documents for a single collection. |
collection_stats | Document count and storage size for a collection. |
run_mql | Execute a read-only query: find, aggregate, count, distinct. Includes automatic MQL validation. |
save_text_memory | Save free-form knowledge about the database. |
run_mql in detail
This is the main query tool. The LLM constructs a QueryRequest and passes it as JSON arguments:
# find — filter + projection + sort + limit
run_mql(
operation="find",
collection="orders",
filter={"status": "delivered"},
projection={"_id": 0, "order_id": 1, "total": 1},
sort={"created_at": -1},
limit=20,
)
# aggregate — full pipeline
run_mql(
operation="aggregate",
collection="orders",
pipeline=[
{"$match": {"created_at": {"$gte": "2026-01-01"}}},
{"$group": {"_id": "$user_id", "total": {"$sum": "$amount"}}},
{"$sort": {"total": -1}},
{"$limit": 10},
],
)
# count
run_mql(operation="count", collection="users", filter={"active": True})
# distinct
run_mql(operation="distinct", collection="orders", distinct_field="status")
Allowed operations: find, aggregate, count, distinct. Everything else is rejected.
MQL Validation
Every call to run_mql is automatically validated before reaching the database. The validator checks:
- The target collection exists
- Field names in filters and pipelines are present in the schema
- MQL operators are valid (e.g.
$match,$group,$sum) - JSON syntax is well-formed
If validation fails, the LLM receives a structured error message with a hint (e.g. did you mean 'order_total'?) and corrects the query without user intervention.
To disable validation (not recommended):
from mango.tools.mongo_tools import RunMQLTool
tool = RunMQLTool(backend, validate=False)
Error Recovery
When a tool call fails with a query-level error (wrong field path, bad operator, missing $unwind), Mango automatically retries up to max_retries times. The exact error is injected back into the LLM context with correction rules, so the model can fix and resubmit.
agent = MangoAgent(
...
max_retries=2, # default: 2
)
Infrastructure errors (connection refused, auth failure, timeout) are not retried — they are surfaced to the user immediately.
The ask() result includes a retries_made counter so you can track how often recovery was needed.
Optional tools
These tools are not included in build_mongo_tools(). Register them manually when needed.
ExplainQueryTool
Explains a query step by step in natural language, plus execution stats from MongoDB explain(). The LLM calls this automatically when the user asks to "walk me through", "explain this query", "show the query plan", or "is this using an index?".
from mango.tools.mongo_tools import ExplainQueryTool
tools.register(ExplainQueryTool(backend))
Example output:
1. $match → filter orders where created_at ≥ 2026-01-01
2. $group → group by user_id, sum amount → total
3. $sort → order by total desc
4. $limit → first 10 results
Execution stats:
documents examined: 42,381
index used: created_at_1
total time: 14ms
DeleteLastMemoryEntryTool
Lets the user correct the agent in natural language — "that was wrong, delete it" — without any UI. The tool removes the last auto-saved memory entry from the vector index.
Because it references the agent's internal state, it must be registered after the agent is created:
from mango.tools.memory_tools import DeleteLastMemoryEntryTool
agent = MangoAgent(...)
tools.register(DeleteLastMemoryEntryTool(memory, lambda: agent._last_memory_entry_id))
The LLM calls delete_last_memory_entry when the user says things like "that was wrong", "delete that", "forget the last query", or "don't save that". It does nothing unless the user explicitly asks.
ToolResult
Every tool returns a ToolResult:
@dataclass
class ToolResult:
success: bool
data: Any # the actual result data
error: str | None # error message if success=False
def as_text(self) -> str:
"""Serialize result to text for the LLM."""
ToolRegistry
The registry manages tool lookup and execution:
from mango.tools.base import ToolRegistry
tools = ToolRegistry()
# Register a tool
tools.register(my_tool)
# Get all tool definitions (for the LLM)
definitions = tools.get_definitions()
# Execute a tool by name
result = await tools.execute("run_mql", operation="count", collection="users")
Next step
→ Custom Tools — build your own tools and register them alongside the built-ins.