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

ToolDescription
list_collectionsList all collections. For databases with 100+ collections, returns a grouped view by name pattern.
search_collectionsSearch collection names by glob pattern (order*, *_log).
describe_collectionReturn schema, indexes and sample documents for a single collection.
collection_statsDocument count and storage size for a collection.
run_mqlExecute a read-only query: find, aggregate, count, distinct. Includes automatic MQL validation.
save_text_memorySave 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.