treeline-moneyChat with your finances from Treeline Money. Query balances, spending, budgets, and transactions.
Install via ClawdBot CLI:
clawdbot install zack-schrag/treeline-moneyChat with your finances. Ask questions like "What's my net worth?", "How much did I spend on groceries?", or "Am I over budget?" and get instant answers from your own financial data.
# 1. Install the CLI (OpenClaw handles this automatically)
# 2. Enable demo mode (sample data)
tl demo on
# 3. Try it out
tl status
For agents: If tl commands fail with "command not found", the CLI needs to be installed. OpenClaw handles installation automatically via the skill metadata. Start with demo mode so users can try queries immediately.
Verify the CLI is available with tl --version. Start with demo mode so users can try queries immediately.
Optional: Download the desktop app for visual exploration of your data.
Demo mode loads sample data so users can try queries without connecting a bank:
tl demo on
To switch to real data later:
tl demo off
Demo data is separate from real data.
tl demo on prints a success message โ if it seems to hang, wait a few seconds (first run initializes the database)tl demo status to verify demo mode is enabledtl demo on againWhen the user is ready to move beyond demo mode, direct them to set up a data source with the guides linked below.
Data source options:
Setup guides: Bank Sync ยท CSV Import
Once set up, use tl sync to pull bank transactions or tl import to load a CSV.
Treeline Money is a local-first personal finance app. All your data stays on your device in a local DuckDB database. No cloud accounts, no subscriptions required (sync services are optional), full SQL access to your financial data.
Encrypted databases not supported. If the user has enabled database encryption in Treeline, CLI commands will fail. They'll need to either:
If you see "database is encrypted" errors, explain this limitation.
Format all responses for mobile/chat:
Example good response:
Your net worth is $125k
Assets: $180k
- Retirement: $85k
- Savings: $25k
- Checking: $10k
- Home equity: $60k
Liabilities: $55k
- Mortgage: $52k
- Credit cards: $3k
Example bad response:
| Account | Type | Balance |
|---------|------|---------|
| My 401k Account | asset | 85234.56 |
...
These commands are read-only and safe to run autonomously:
tl status # Quick account summary with balances
tl status --json # Same, but JSON output
tl query "SQL" --json # Run any SQL query (database opened in read-only mode)
tl sql "SQL" --json # Same as tl query (alias)
tl backup list # List available backups
tl doctor # Check database health
tl demo status # Check if demo mode is on/off
Note:tl queryandtl sqlopen the database in read-only mode by default. They cannot modify data unless--allow-writesis passed (see write commands below).
Use tl status for quick balance checks โ it's faster than a SQL query.
These commands modify local data. Always ask the user for confirmation before running them, unless the user has explicitly allowed them in PERMISSIONS.md (see Agent Permissions).
tl query "SQL" --allow-writes --json # Run a SQL query with write access
tl sql "SQL" --allow-writes --json # Same (alias)
tl sync # Sync accounts/transactions from bank integrations
tl sync --dry-run # Preview what would sync (read-only, safe to run)
tl import FILE -a ACCOUNT # Import transactions from CSV
tl import FILE -a ACCOUNT --dry-run # Preview import without applying (read-only, safe to run)
tl import FILE -a ACCOUNT --json # JSON output for scripting
tl backup create # Create a backup
tl backup restore NAME # Restore a backup
tl compact # Compact database (reclaim space, optimize)
tl tag "groceries" --ids ID1,ID2 # Apply tags to transactions
tl demo on|off # Toggle demo mode (sample data)
Tip: --dry-run variants are read-only and safe to run without confirmation. Use them to preview before asking the user to confirm the actual operation.
Use tl compact if the user mentions slow queries โ it optimizes the database.
tl import auto-detects column mappings from CSV headers. Most bank CSVs work out of the box:
tl import bank_export.csv --account "Chase Checking"
The --account / -a flag accepts an account name (case-insensitive, substring match) or UUID.
Always preview first with --dry-run to verify columns were detected correctly:
tl import bank_export.csv -a "Checking" --dry-run --json
All import flags (all optional except --account):
| Flag | Purpose | Example |
|------|---------|---------|
| --date-column | Override date column | --date-column "Post Date" |
| --amount-column | Override amount column | --amount-column "Amt" |
| --description-column | Override description column | --description-column "Memo" |
| --debit-column | Use debit column (instead of amount) | --debit-column "Debit" |
| --credit-column | Use credit column (instead of amount) | --credit-column "Credit" |
| --balance-column | Running balance (creates snapshots) | --balance-column "Balance" |
| --flip-signs | Negate amounts (credit card CSVs) | --flip-signs |
| --debit-negative | Negate positive debits | --debit-negative |
| --skip-rows N | Skip N rows before header | --skip-rows 3 |
| --number-format | us, eu, or eu_space | --number-format eu |
| --profile NAME | Load a saved profile | --profile chase |
| --save-profile NAME | Save settings as profile | --save-profile chase |
| --dry-run | Preview without importing | --dry-run |
| --json | JSON output | --json |
Common patterns for agents:
# Step 1: Find the account UUID
tl status --json
# Step 2: Preview import
tl import transactions.csv -a "550e8400-e29b-41d4-a716-446655440000" --dry-run --json
# Step 3: Execute import
tl import transactions.csv -a "550e8400-e29b-41d4-a716-446655440000" --json
Duplicate transactions are automatically detected and skipped on re-import via fingerprinting.
Before running any write command, check for PERMISSIONS.md in this skill directory.
If it exists, read it to see which write commands the user has pre-approved. Pre-approved commands can be run without asking for confirmation. All other write commands still require explicit user confirmation before execution.
If PERMISSIONS.md does not exist, always ask before running any write command.
Template for PERMISSIONS.md:
# Treeline Agent Permissions
Commands listed here are pre-approved โ the agent can run them without
asking for confirmation each time. Remove a line to require confirmation.
## Allowed write commands
- tl sync
- tl backup create
- tl demo on|off
Before answering finance questions, check for CONTEXT.md in this skill directory.
If it exists, read it first โ it contains user-specific knowledge:
Learning new context: When you discover something about the user's setup:
See the User Context Pattern section at the end for the template.
tl query "
WITH latest AS (
SELECT DISTINCT ON (account_id) account_id, balance
FROM sys_balance_snapshots
ORDER BY account_id, snapshot_time DESC
)
SELECT
SUM(CASE WHEN a.classification = 'asset' THEN s.balance ELSE 0 END) as assets,
SUM(CASE WHEN a.classification = 'liability' THEN ABS(s.balance) ELSE 0 END) as liabilities,
SUM(CASE WHEN a.classification = 'asset' THEN s.balance ELSE -ABS(s.balance) END) as net_worth
FROM accounts a
JOIN latest s ON a.account_id = s.account_id
" --json
tl query "
WITH latest AS (
SELECT DISTINCT ON (account_id) account_id, balance
FROM sys_balance_snapshots
ORDER BY account_id, snapshot_time DESC
)
SELECT a.name, a.classification, a.institution_name, s.balance
FROM accounts a
JOIN latest s ON a.account_id = s.account_id
ORDER BY s.balance DESC
" --json
Check CONTEXT.md for internal_transfer_tags. Default pattern:
tl query "
SELECT SUM(ABS(amount)) as total_spent
FROM transactions
WHERE amount < 0
AND transaction_date >= date_trunc('month', current_date)
AND NOT (tags && ARRAY['transfer', 'savings', 'investment'])
" --json
tl query "
SELECT tags, SUM(ABS(amount)) as spent
FROM transactions
WHERE amount < 0
AND transaction_date >= '2026-01-01' AND transaction_date < '2026-02-01'
AND tags IS NOT NULL AND tags != '[]'
GROUP BY tags
ORDER BY spent DESC
" --json
tl query "
SELECT t.description, t.amount, t.transaction_date, a.name as account
FROM transactions t
JOIN accounts a ON t.account_id = a.account_id
ORDER BY t.transaction_date DESC
LIMIT 10
" --json
accounts
| Column | Description |
|--------|-------------|
| account_id | UUID primary key |
| name | Account display name |
| classification | asset or liability |
| account_type | credit, investment, Loan, other, or null |
| institution_name | Bank/institution name |
| currency | Currency code (e.g., USD) |
| is_manual | Boolean โ manually added vs synced |
sys_balance_snapshots โ Source of truth for balances
| Column | Description |
|--------|-------------|
| snapshot_id | UUID primary key |
| account_id | FK to accounts |
| balance | Balance at snapshot time |
| snapshot_time | When recorded |
| source | sync, manual, etc. |
transactions
| Column | Description |
|--------|-------------|
| transaction_id | UUID primary key |
| account_id | FK to accounts |
| amount | Signed (negative = expense) |
| description | Transaction description |
| transaction_date | When it occurred |
| posted_date | When it cleared |
| tags | Array of tags |
Tags are the primary concept in Treeline โ transactions can have multiple tags.
Categories come from the budget plugin (plugin_budget), which maps tags to budget categories. Not all users have this plugin.
Plugins have their own DuckDB schemas: plugin_
tl query "
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name LIKE 'plugin_%'
" --json
plugin_budget.categories โ Budget categories
| Column | Description |
|--------|-------------|
| category_id | UUID primary key |
| month | YYYY-MM format |
| type | income or expense |
| name | Category name |
| expected | Budgeted amount |
| tags | Array of tags to match |
plugin_goals.goals โ Savings goals
| Column | Description |
|--------|-------------|
| id | UUID primary key |
| name | Goal name |
| target_amount | Target amount |
| target_date | Target date |
| completed | Boolean |
| active | Boolean |
plugin_subscriptions โ Detected recurring charges
plugin_cashflow โ Cash flow projections
plugin_emergency_fund โ Emergency fund tracking
Check CONTEXT.md for which plugins the user has and cares about.
Always use latest snapshot:
WITH latest AS (
SELECT DISTINCT ON (account_id) account_id, balance
FROM sys_balance_snapshots
ORDER BY account_id, snapshot_time DESC
)
SELECT a.name, s.balance
FROM accounts a
JOIN latest s ON a.account_id = s.account_id
Tags are arrays:
-- Contains a specific tag
WHERE tags @> ARRAY['groceries']
-- Contains any of these tags
WHERE tags && ARRAY['food', 'dining']
-- Note: UNNEST doesn't work in all contexts in DuckDB
-- Instead, GROUP BY tags directly
-- This month
WHERE transaction_date >= date_trunc('month', current_date)
-- Specific month
WHERE transaction_date >= '2026-01-01'
AND transaction_date < '2026-02-01'
SELECT
c.name,
c.expected,
COALESCE(SUM(ABS(t.amount)), 0) as actual,
c.expected - COALESCE(SUM(ABS(t.amount)), 0) as remaining
FROM plugin_budget.categories c
LEFT JOIN transactions t ON t.tags && c.tags
AND t.amount < 0
AND t.transaction_date >= (c.month || '-01')::DATE
AND t.transaction_date < (c.month || '-01')::DATE + INTERVAL '1 month'
WHERE c.month = strftime(current_date, '%Y-%m')
AND c.type = 'expense'
GROUP BY c.category_id, c.name, c.expected
| User asks | Approach |
|-----------|----------|
| "Net worth?" | Net worth query |
| "Balances?" | Account balances query |
| "How much in [X]?" | Filter by name ILIKE '%X%' |
| "How much did I spend?" | True spending query (exclude internal moves) |
| "Spending on [tag]?" | Filter by tag |
| "Am I over budget?" | Budget vs actual (requires budget plugin) |
| "Recent transactions" | Order by date DESC, limit |
| "Savings?" | Filter accounts by name/type |
| "Retirement?" | Filter by 401k, IRA, retirement keywords |
| "Import CSV" / "Upload transactions" | Guide through tl import โ preview first with --dry-run |
| "Import from [bank name]" | Use tl import with appropriate flags for that bank's CSV format |
--json for parseable outputclassification for asset/liabilityWhen this skill is installed, create CONTEXT.md alongside it to store user-specific knowledge. This keeps the skill generic/shareable while personalizing behavior.
Template for CONTEXT.md:
# Treeline User Context
*Auto-updated by your assistant as it learns your setup*
## Account Notes
<!-- What specific accounts mean, e.g.: -->
<!-- - "Company 401k" = retirement account -->
<!-- - "Home Equity" = home value estimate (manual) -->
## Tag Conventions
<!-- How the user uses tags -->
## Cash Flow Rules
<!-- Tags to exclude from "true spending" calculations -->
internal_transfer_tags: [transfer, savings, investment]
## Income Sources
<!-- Known income sources for better reporting -->
## Active Plugins
<!-- Which plugins are installed and relevant -->
## Preferences
<!-- Reporting style, rounding, spouse-friendly mode, etc. -->
## Learned Facts
<!-- Anything else discovered about the user's financial setup -->
Maintenance:
All data is local (~/.treeline/treeline.duckdb). Never share transaction descriptions or account details outside the conversation unless explicitly asked.
Generated Mar 1, 2026
Users can quickly assess their financial status by querying net worth, spending patterns, and budget adherence. This helps individuals monitor progress toward savings goals or identify overspending in categories like dining or entertainment.
Business owners can import transaction CSVs to categorize expenses, track cash flow, and generate reports for tax preparation. This enables efficient management of operational costs without relying on cloud-based accounting software.
Advisors can use SQL queries to analyze client data locally, providing personalized insights on investment performance or debt reduction strategies. This supports secure, offline consultations while maintaining data privacy.
Instructors can enable demo mode to teach budgeting concepts using sample data, allowing students to practice queries without exposing personal information. This facilitates hands-on learning in classroom or online settings.
Freelancers can sync bank transactions to track irregular income, categorize business expenses, and estimate quarterly tax liabilities. This aids in maintaining financial stability and compliance with tax regulations.
The core app is free and local-first, with revenue generated from optional paid sync services like SimpleFIN and Lunch Flow. This model attracts users seeking privacy while monetizing convenience for automated data integration.
Licensing the CLI or app to banks or advisory firms for internal use, enabling secure client data analysis without cloud dependencies. This targets organizations prioritizing data sovereignty and compliance with financial regulations.
Collaborating with online learning platforms to integrate Treeline into finance courses, offering demo data for practical exercises. Revenue comes from partnership agreements or referral incentives for student sign-ups to paid services.
๐ฌ Integration Tip
Start with demo mode to familiarize users with queries before connecting real data, and always use --dry-run for write commands to preview changes without risk.
iMessage/SMS CLI for listing chats, history, watch, and sending.
Use when you need to control Discord from Clawdbot via the discord tool: send messages, react, post or upload stickers, upload emojis, run polls, manage threads/pins/search, fetch permissions or member/role/channel info, or handle moderation actions in Discord DMs or channels.
Use when you need to control Slack from Clawdbot via the slack tool, including reacting to messages or pinning/unpinning items in Slack channels or DMs.
Send WhatsApp messages to other people or search/sync WhatsApp history via the wacli CLI (not for normal user chats).
Build or update the BlueBubbles external channel plugin for Clawdbot (extension package, REST send/probe, webhook inbound).
OpenClaw skill for designing Telegram Bot API workflows and command-driven conversations using direct HTTPS requests (no SDKs).