copilot-money-cli

Use when querying Copilot Money for finances, transactions, net worth, and holdings.

9 stars

Best use case

copilot-money-cli is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when querying Copilot Money for finances, transactions, net worth, and holdings.

Teams using copilot-money-cli should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/copilot-money-cli/SKILL.md --create-dirs "https://raw.githubusercontent.com/exiao/skills/main/external-services/copilot-money-cli/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/copilot-money-cli/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How copilot-money-cli Compares

Feature / Agentcopilot-money-cliStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when querying Copilot Money for finances, transactions, net worth, and holdings.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Copilot Money CLI

Use the Rust CLI (`copilot` binary at `/usr/local/bin/copilot`). The Python `copilot-money` CLI is deprecated.

> **Note:** Unofficial tool, not affiliated with Copilot Money.

## Auth

Token stored at `~/.config/copilot-money-cli/token`. Firebase JWT, expires every ~1 hour.

```bash
copilot auth status          # Check if token is valid
copilot auth login           # Interactive browser login
copilot auth refresh         # Refresh expired token (needs playwright)
```

If `copilot auth refresh` fails ("token refresh helper not found"), grab a fresh token from the web app session instead (see Bulk Export below).

## Commands

```bash
# Transactions
copilot transactions list                                    # Last 25
copilot transactions list --limit 50 --pages 10             # 500 txns (paginated)
copilot transactions list --all                             # Everything (slow, 25/page)
copilot transactions list --sort date-desc --output json
copilot transactions list --unreviewed
copilot transactions list --category "Groceries"
copilot transactions list --name-contains "uber"
copilot transactions list --date 2026-03-01
copilot transactions list --date-after 2026-01-01 --date-before 2026-03-31

# Categories
copilot categories list --output json                       # {id, name}

# Write (require --yes in scripts)
copilot transactions set-category <id> --category "Food"
copilot transactions set-notes <id> --notes "..."
copilot transactions review <ids...>
```

## Bulk Transaction Download

### Option A: CSV Export (fastest, all transactions in one request)

The GraphQL API has an `ExportTransactions` operation that generates a signed GCS URL to a complete CSV. No pagination, no limits. This is what the web app's "Download transactions" button uses.

```bash
TOKEN=$(cat ~/.config/copilot-money-cli/token)
EXPORT_URL=$(curl -s -X POST https://app.copilot.money/api/graphql \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "operationName": "ExportTransactions",
    "variables": {
      "sort": [{"direction": "DESC", "field": "DATE"}]
    },
    "query": "query ExportTransactions($filter: TransactionFilter, $sort: [TransactionSort!]) { exportTransactions(filter: $filter, sort: $sort) { expiresAt url } }"
  }' | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['exportTransactions']['url'])")

curl -s "$EXPORT_URL" -o transactions.csv
```

CSV columns: `date, name, amount, status, category, parent category, excluded, tags, type, account, account mask, note, recurring`

The `filter` variable accepts `TransactionFilter` (same as the paginated query) so you can filter server-side before export.

**Note:** The signed URL expires (check `expiresAt` timestamp). Download immediately.

### Option B: CLI with date-range chunking (for JSON + programmatic filtering)

The server hard-caps pagination at **25 results per page** regardless of `--limit`. For large datasets, chunk by date range to reduce total pages:

```bash
# Monthly chunks, JSON output
for MONTH in 01 02 03; do
  copilot transactions list \
    --date-after "2026-$MONTH-01" \
    --date-before "2026-$MONTH-31" \
    --all --output json \
    >> txns_2026.jsonl
done
```

Or use `--pages` to control how many pages to fetch per chunk:
```bash
copilot transactions list \
  --date-after 2026-01-01 --date-before 2026-03-31 \
  --limit 25 --pages 40 --sort date-desc --output json
```

### When to use which

| Method | Speed | Format | Filtering | Best for |
|--------|-------|--------|-----------|----------|
| Option A (Export) | Fast (1 request) | CSV | Server-side via filter | Full dumps, spreadsheet analysis |
| Option B (CLI chunks) | Slow (25/page) | JSON | CLI flags + post-processing | Programmatic analysis, category resolution |

## API Details (discovered)

- **GraphQL endpoint:** `POST https://app.copilot.money/api/graphql`
- **Auth:** Firebase JWT in `Authorization: Bearer <token>` header
- **Pagination hard cap:** 25 items/page (server ignores `first` values above 25)
- **Export:** `ExportTransactions` returns a signed Google Cloud Storage URL (no pagination)
- **Firebase project:** `copilot-production-22904`

## Analysis pattern

```python
import subprocess, json, csv
from collections import defaultdict

# Option A: CSV (fast, complete)
# Run the export curl commands above, then:
with open('transactions.csv') as f:
    txns = list(csv.DictReader(f))
# Category already resolved as text in CSV

# Option B: JSON via CLI
cats = {c['id']: c['name'] for c in json.loads(
    subprocess.check_output(['copilot', 'categories', 'list', '--output', 'json'])
)}

raw = json.loads(subprocess.check_output([
    'copilot', 'transactions', 'list',
    '--all', '--sort', 'date-desc', '--output', 'json'
]))['transactions']

for t in raw:
    t['category'] = cats.get(t.get('categoryId', ''), 'Uncategorized')
```

## JSON output fields (transactions)

```json
{
  "id": "...",
  "date": "2026-03-03",
  "name": "Trader Joe's",
  "amount": 28.88,
  "categoryId": "K4Ij...",
  "type": "REGULAR",
  "isReviewed": false
}
```

## Security

- Calls only `app.copilot.money`. No telemetry.
- Token stored in plaintext at `~/.config/copilot-money-cli/token`.

Related Skills

writer

9
from exiao/skills

Write content in Eric's voice — articles, blog posts, tweets, social media posts, marketing copy, newsletter drafts. Loads WRITING-STYLE.md and enforces kill phrases.

positioning-angles

9
from exiao/skills

Use when defining product positioning, choosing strategic angles, crafting value propositions, competitive positioning, product messaging, differentiation strategy, or go-to-market angles. Also use for 'how should I position my app', 'what angle should I use', 'painkiller vs vitamin', or 'market positioning'.

outline-generator

9
from exiao/skills

Use when generating outlines, article structures, content outlines, blog outlines, planning article sections, structuring posts, breaking down topics into sections, or organizing ideas for long-form content. Also use for 'outline this', 'structure this article', or 'plan the sections'.

last30days-open

9
from exiao/skills

Use only when the user explicitly asks for the open variant of last30days, including watchlists, briefings, and history queries. Sources: Reddit, X, YouTube, web.

last30days

9
from exiao/skills

Use when researching what happened in the last 30 days on a topic. Also triggered by 'last30'. Sources: Reddit, X, YouTube, web. Produces expert-level summary with copy-paste-ready prompts.

hooks

9
from exiao/skills

Use when generating hooks, headlines, titles, and scroll-stopping openers for content. Also use when analyzing viral posts, Reels, TikToks, YouTube Shorts, or successful social examples to extract reusable hook patterns and improve hook guidance.

evaluate-content

9
from exiao/skills

Use when judging content quality OR editing/improving existing copy: shareability, readability, voice, cuttability, angle, copy sweeps.

editor-in-chief

9
from exiao/skills

Use when a first draft is complete and all Phase 1 gates are done: topic selected (seo-research), title approved (hooks), outline approved (outline-generator), draft written (writer). Runs autonomous diagnosis-prescribe-rewrite loop before Substack.

copywriting

9
from exiao/skills

Write or improve marketing copy for any surface: pages, ads, app stores, landing pages, TikTok/Meta scripts, push notifications, UGC. Combines page copy frameworks with direct response principles.

content-strategy

9
from exiao/skills

Use when building content strategy: hooks, angles, and ideas from what's trending now. Covers organic and paid creative across TikTok, X, YouTube, Meta, LinkedIn.

content-pipeline

9
from exiao/skills

Orchestrator for the 3-article content pipeline — runs research phase, spawns parallel article sub-agents, creates Typefully drafts. Use when running the full content pipeline (usually via cron at 3am).

yt-dlp

9
from exiao/skills

Download audio/video from YouTube and other sites using yt-dlp. Use when the user asks to download music, songs, albums, podcasts, or video from YouTube or similar platforms. Triggers on 'download song', 'get mp3', 'yt-dlp', 'youtube download', 'rip audio'.