Overview
Every tool is a Python async function decorated with@tool. The decorator auto-generates the Claude API tool schema from the function signature and docstring.
Step 1: Choose the right file
| Domain | File |
|---|---|
| Spending, income, budgets | backend/tools/cashflow_tools.py |
| Portfolio, holdings, prices | backend/tools/investment_tools.py |
| Credit cards, loans, debts | backend/tools/debt_tools.py |
| Net worth, accounts, health | backend/tools/wealth_tools.py |
| Live prices, forex | backend/tools/market_tools_v2.py |
| Cross-domain / utility | backend/tools/shared_tools.py |
Step 2: Write the tool
- Always scope queries to
user_id— never fetch data without it - Return a
dict— Claude will receive it as JSON - No
defaultvalues in the function signature for required parameters (causes schema issues) - Keep tool names snake_case and globally unique
Step 3: Register the tool
In the relevant domain specialist file (backend/orchestrator/specialist.py), add your tool to the domain’s tool list:
Step 4: Add a loading label (Flutter)
Inlib/features/ai_agent/providers/chat_provider.dart, add your tool name to the _toolLabels map: