{"id":49295044,"url":"https://github.com/evan-moon/firma","last_synced_at":"2026-05-09T07:12:00.716Z","repository":{"id":353813787,"uuid":"1220435400","full_name":"evan-moon/firma","owner":"evan-moon","description":"Local-first CLI portfolio tracker for overseas investors, with built-in MCP server for Claude","archived":false,"fork":false,"pushed_at":"2026-05-06T22:26:46.000Z","size":3244,"stargazers_count":29,"open_issues_count":1,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-07T00:33:48.272Z","etag":null,"topics":["claude","cli","finnhub","local-first","mcp","personal-finance","portfolio","sqlite","stock","typescript"],"latest_commit_sha":null,"homepage":"https://firma-cli.vercel.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/evan-moon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-24T22:37:39.000Z","updated_at":"2026-05-06T22:26:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/evan-moon/firma","commit_stats":null,"previous_names":["evan-moon/firma"],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/evan-moon/firma","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evan-moon%2Ffirma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evan-moon%2Ffirma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evan-moon%2Ffirma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evan-moon%2Ffirma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evan-moon","download_url":"https://codeload.github.com/evan-moon/firma/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evan-moon%2Ffirma/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32810459,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude","cli","finnhub","local-first","mcp","personal-finance","portfolio","sqlite","stock","typescript"],"created_at":"2026-04-26T03:04:31.013Z","updated_at":"2026-05-09T07:12:00.694Z","avatar_url":"https://github.com/evan-moon.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/evan-moon/firma/main/assets/og-image.png\" alt=\"firma\" width=\"560\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003efirma\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eYou earned well this year.\u003cbr/\u003eDo you know where it went?\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Drop your trade history into Claude.\u003cbr/\u003e\n  Get back a full financial picture — portfolio, net worth, cash flow — stored in a local SQLite file.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@evan-moon/firma\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@evan-moon/firma.svg?style=flat\u0026color=cb3837\u0026logo=npm\" alt=\"npm version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/evan-moon/firma/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/evan-moon/firma?style=flat\u0026logo=github\u0026color=ffd700\" alt=\"GitHub stars\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://nodejs.org/\"\u003e\u003cimg src=\"https://img.shields.io/badge/node-%3E%3D22-339933?style=flat\u0026logo=node.js\u0026logoColor=white\" alt=\"Node \u003e= 22\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://glama.ai/mcp/servers/evan-moon/firma\"\u003e\u003cimg src=\"https://glama.ai/mcp/servers/evan-moon/firma/badges/score.svg\" alt=\"firma MCP server\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://modelcontextprotocol.io\"\u003e\u003cimg src=\"https://img.shields.io/badge/MCP-ready-7c3aed?style=flat\" alt=\"MCP-ready\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ccode\u003enpm install -g @evan-moon/firma\u003c/code\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/evan-moon/firma/main/assets/demo_short.gif\" alt=\"Claude MCP visualizing finance data\" width=\"700\" /\u003e\n\u003c/p\u003e\n\n---\n\n```\nYou:    Here's my IBKR trade history [trades.csv]. Set up firma.\nClaude: I see 47 transactions. Logging in chronological order... done.\n        Syncing prices and FX history... your portfolio: $179K, +61% all-time. TSLA is 78%.\n\nYou:    My portfolio feels really volatile lately. Should I be worried?\nClaude: TSLA is 74% of your equity — a 10% TSLA move is a 7% net worth move.\n        Cash flow is solid at $6.4k/month saved. The volatility is market, not lifestyle.\n\nYou:    That July expense spike looks alarming.\nClaude: That was $57k in TSLL — a leveraged bet, not spending.\n        Strip it out: expenses flat at ~$7k/month, savings rate 47.8%.\n\nYou:    Give me a full overview with charts.\nClaude: Net worth: $294k → $490k in 8 months, pulled back to $427k with TSLA's Q1 dip.\n        [builds net worth trend, income vs expenses, portfolio allocation, unrealized P\u0026L]\n```\n\n---\n\n## Why firma\n\n- **Talks to Claude natively.** `firma mcp install` wires firma into Claude Desktop. Every command you can run in the terminal, Claude can call through MCP — log trades, sync prices, render charts, reason about your data.\n- **Local-first, no exceptions.** Everything lives in `~/.firma/firma.db`. No server, no sync, no account. Your financial data never leaves your machine.\n- **Built for US market investors.** Multi-currency (USD, KRW, EUR, JPY, and more) with historical FX rates from FRED — so a 2018 balance shows the 2018 exchange rate, not today's.\n- **Transactions as source of truth.** No holdings table to drift out of sync. Portfolio, cost basis, and P\u0026L are always derived live from your trade log.\n- **Daily brief with world context.** `get_brief` bundles holdings, macro signals, commodity prices, dividend calendar, global macro (World Bank), and active disaster alerts (GDACS) in one call — no extra API keys needed for the global data.\n- **Developer-friendly.** `--json` on every read command. Three clean verb groups: `add`, `show`, `report`.\n\n---\n\n## Get started\n\n```bash\n# 1. Install\nnpm install -g @evan-moon/firma\n\n# 2. Set API keys (both free)\nfirma config set finnhub-key YOUR_KEY   # finnhub.io — prices, news, earnings\nfirma config set fred-key YOUR_KEY      # fred.stlouisfed.org — macro \u0026 FX history\n\n# 3. Connect Claude Desktop\nfirma mcp install\n# Restart Claude Desktop — firma tools will appear in the toolbar.\n```\n\n**4. Drop your data into Claude.** Paste a CSV, brokerage export, or plain text — Claude logs everything and syncs prices automatically.\n\n\u003e Prefer the terminal? Every MCP tool has a matching `firma` command — see [CLI reference](#cli-reference).\n\n\u003e If firma helps you track your money, please [⭐ star the repo](https://github.com/evan-moon/firma/stargazers) — it's the cheapest way to help others find it.\n\n---\n\n## CLI reference\n\n`--json` is available on every read command. Alias: `firma rm` = `firma delete`.\n\n### Portfolio\n\n| Command | What it does |\n|---|---|\n| `firma show portfolio` | Holdings with P\u0026L, avg cost, market value |\n| `firma show txns [ticker]` | Transaction history with running avg cost |\n| `firma show dividend` | Estimated annual income + per-ticker yield |\n| `firma show concentration` | HHI concentration by ticker, currency, sector, country |\n| `firma show snapshot [ticker]` | Portfolio value history; `--from`/`--to` for date range |\n| `firma show benchmark` | Portfolio return vs SPY/QQQ (or custom benchmarks via `-b`) |\n| `firma show risk` | Volatility, drawdown, Sharpe, Sortino, beta — requires snapshots |\n| `firma profile` | Set up your goals (birth year, retirement target, target net worth, risk tolerance, notes) — every field optional |\n| `firma show profile` | Show the stored profile |\n\n### Balance \u0026 Cash Flow\n\n| Command | What it does |\n|---|---|\n| `firma add balance [-p YYYY-MM]` | Monthly asset \u0026 liability snapshot |\n| `firma add flow [-p YYYY-MM]` | Monthly income \u0026 expense entry |\n| `firma add monthly [-p YYYY-MM]` | Balance + flow in one call (month-end) |\n| `firma show balance [-p YYYY-MM]` | Stored balance entries for a period |\n| `firma show flow [-p YYYY-MM]` | Stored cash flow entries for a period |\n| `firma report` | Net worth trend + cash flow charts (combined) |\n| `firma report balance / flow / settle` | Targeted views |\n| `firma report -c USD` | Display in USD, EUR, JPY, CNY, or GBP |\n\n### Transactions\n\n| Command | What it does |\n|---|---|\n| `firma add txn` | Record a transaction (buy / sell / deposit / dividend / tax) |\n| `firma edit txn [id]` | Edit a transaction |\n| `firma delete txn [id]` | Delete a transaction |\n\n### Snapshots\n\n| Command | What it does |\n|---|---|\n| `firma add snapshot` | Sync prices and record today's portfolio snapshot |\n| `firma edit snapshot` | Edit a snapshot entry (interactive picker) |\n| `firma delete snapshot [date]` | Delete all entries for a date |\n\n### Research (Finnhub)\n\n| Command | What it does |\n|---|---|\n| `firma show news \u003cticker\u003e` | Recent company news |\n| `firma show insider \u003cticker\u003e` | Insider buy/sell transactions |\n| `firma show financials \u003cticker\u003e` | SEC-reported quarterly financials (income, cash flow, balance sheet) |\n| `firma show valuation \u003cticker\u003e` | PEG ratio, P/S, FCF yield — computed from 8 quarters of SEC filings |\n| `firma show earnings [ticker]` | Earnings calendar + EPS history |\n\n### Macro (FRED)\n\n| Command | What it does |\n|---|---|\n| `firma show macro` | VIX, 10Y yield, yield curve, USD index, HY spread, inflation, fed funds, FX |\n| `firma show stress` | Economic Stress Index (0–100) from 5 FRED series |\n| `firma show regime` | Macro regime bias — Risk-on / Mixed / Risk-off |\n| `firma show fx [currency]` | Inspect cached FX history with `--from`/`--to`/`--limit` |\n\n### Global Intelligence (no API key)\n\n| Command | What it does |\n|---|---|\n| `firma show world-intel` | World Bank macro (GDP, inflation, unemployment) + GDACS active disaster alerts in one view |\n\n### Daily Brief \u0026 Actions\n\n| Command | What it does |\n|---|---|\n| `firma brief` | Daily intelligence brief: movers, news, earnings, macro, commodities, dividend calendar, world macro, disaster alerts (cached per day; `--refresh` to regenerate) |\n| `firma sync` | Fetch latest prices (Finnhub) + FX rate history (FRED) |\n| `firma sync fx` | FX history only — incremental backfill from your earliest entry date |\n| `firma doctor` | Check setup status — API keys, data, FX cache |\n| `firma mcp install` | Register MCP server in Claude Desktop |\n| `firma config set finnhub-key KEY` | Set Finnhub API key |\n| `firma config set fred-key KEY` | Set FRED API key |\n| `firma config set currency CODE` | Set home currency (KRW, USD, JPY, …) |\n\n---\n\n## Claude integration (MCP)\n\nAfter `firma mcp install`, Claude has full read/write access to your data through conversation. Two tools are available only via MCP:\n\n| Tool | What it does |\n|---|---|\n| `fetch_fred_series` | Fetch any FRED time series by ID (800K+ series) |\n| `search_fred_series` | Search the FRED catalog by keyword |\n\n`get_brief` is the primary entry point for any daily check-in or market question. In a single call it returns:\n\n- **Portfolio** — holdings with weights, daily P\u0026L, total cost vs market value\n- **Concentration** — HHI by ticker, sector, currency, country\n- **Movers** — top winners and losers for the day\n- **News** — recent headlines per holding\n- **Earnings** — upcoming earnings dates with EPS estimates\n- **Economic calendar** — high/medium-impact events for the week\n- **Macro** — FRED snapshot (VIX, 10Y yield, credit spread, fed funds, FX impact in home currency)\n- **Stress \u0026 Regime** — Economic Stress Index + Risk-on / Mixed / Risk-off bias\n- **Commodities** — WTI oil, gold, copper (via FRED — no extra key)\n- **Dividend calendar** — upcoming ex-dates and estimated income for held positions\n- **World macro** — GDP growth, inflation, unemployment across major economies (World Bank — no extra key)\n- **Disaster alerts** — active GDACS Orange/Red events (no extra key)\n- **Insights** — cross-referenced observations that tie portfolio exposure to macro context\n\nIf today's snapshot is missing, `get_brief` records one automatically before assembling the brief, so daily history accrues even when you forget to run `firma add snapshot`.\n\n`show_valuation` and `show_world_intel` are available for deeper drill-downs after reading the brief.\n\n**Prompts** — type `/` in Claude Desktop to access guided workflows:\n\n| Prompt | What it does |\n|---|---|\n| `import-trades` | Confirms column mapping then bulk-inserts every row in a single `add_txns` call — handles 100s of rows in one shot |\n| `import-balance` | Same flow for a net-worth spreadsheet (rows = months, columns = balance categories) → bulk `add_balances` |\n| `import-flow` | Same flow for an income/expense spreadsheet → bulk `add_flows` |\n| `month-end` | Walks through balance + cash flow entry for the period, submits in one batch |\n| `morning` | Calls `get_brief` and surfaces only what needs attention |\n| `analyst` | Activates a financial-analyst persona — Claude leads with concentration risk, frames every number against net worth or runway, and combines portfolio + cash flow + macro into a single view |\n| `setup-profile` | Captures your goals (birth year, retirement target, target net worth, risk tolerance, notes) so all future analysis is anchored to them — every field optional |\n| `pre-mortem` | Five plausible ways a position could go wrong over 12 months — concrete failure modes tied to actual data, with portfolio impact in dollars |\n| `rebalance` | Compares current allocation against your stated target, flags drift, suggests specific trades while accounting for tax cost and wash-sale risk |\n| `tax-harvest` | Scans unrealized losses, checks 30-day wash-sale rule, suggests similar-but-not-identical replacements, estimates tax savings by bracket |\n| `scenario` | Models a market shock or macro shift on your actual portfolio with explicit beta assumptions you can override |\n\n`setup_status` (called by Claude at the start of any conversation) also returns an `analyst_context` block — a lightweight version of the analyst persona that influences every reply without a manual prompt invocation.\n\nHistorical FX note: `firma sync fx` backfills daily KRW/JPY/EUR/CNY/GBP rates from FRED starting at your earliest transaction date. Subsequent runs are increment-only. This means a 2018 balance in KRW uses the 2018 rate — not today's.\n\n---\n\n## Development\n\nRequires Node.js 22+ and Yarn Berry.\n\n```bash\ncorepack enable\nyarn install\n\nyarn dev:cli show portfolio    # CLI dev mode\nyarn typecheck                 # Full type check\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for architecture overview and extension points.\n\n---\n\n## Works with Herald\n\nFirma is the financial intelligence layer of the [Herald](https://ai-herald.vercel.app) ambient voice assistant stack. When connected, Herald can:\n\n- report your portfolio performance and net worth by voice\n- answer \"how much did I spend on fees this quarter?\" without opening a spreadsheet\n- surface market context mid-conversation alongside your own position data\n\nHerald + Firma + [Memex](https://github.com/evan-moon/memex) — ambient voice, financial intelligence, and persistent memory in one personal AI stack.\n\n---\n\n## License\n\nMIT © [Evan Moon](https://github.com/evan-moon)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevan-moon%2Ffirma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevan-moon%2Ffirma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevan-moon%2Ffirma/lists"}