{"_id":"@403fin/mcp","name":"@403fin/mcp","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@403fin/mcp","version":"1.0.0","description":"Model Context Protocol server for Forbidden Finance — a thin client over the public /v1 REST API.","type":"module","bin":{"403fin-mcp":"dist/index.js"},"engines":{"node":">=22"},"license":"MIT","author":{"name":"403 Finance, Inc."},"homepage":"https://403fin.io","repository":{"type":"git","url":"git+https://github.com/403ent/403fin-mcp.git"},"keywords":["mcp","model-context-protocol","forbidden-finance","403fin","personal-finance"],"scripts":{"build":"tsc","generate":"tsx scripts/generate-tools.ts && biome check --write src/tools/generated.ts","test":"vitest run","lint":"biome check .","format":"biome format --write .","prepublishOnly":"npm run build"},"dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","zod":"^3.25.0"},"devDependencies":{"@biomejs/biome":"^2.5.5","@types/node":"^22.13.0","tsx":"^4.23.1","typescript":"^6.0.3","vitest":"^3.2.7","yaml":"^2.9.0"},"publishConfig":{"access":"public"},"gitHead":"ec3e0f86ea0c12ee42f1000f105fc5f84a500e33","_id":"@403fin/mcp@1.0.0","bugs":{"url":"https://github.com/403ent/403fin-mcp/issues"},"_nodeVersion":"22.23.2","_npmVersion":"12.0.2","dist":{"integrity":"sha512-gcfC2653hECvgjbMCLqiw+ZAAi/wUwz9mfpjmFJT05e5pVcaoyi7KZcu+CoWbGEDOkZ0MIK7uBl8SP884DSU2A==","shasum":"ad1e0d32c04538eb123061732bc372a2e349ec4f","tarball":"https://registry.npmjs.org/@403fin/mcp/-/mcp-1.0.0.tgz","fileCount":19,"unpackedSize":94773,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDwMyrzvsu0UNurQXJ8zDnFMLc2Xzj1S7iamRiyerIEYQIhAIs4SsyyU2MUR37ya35TgPvfViE6+GCY42jy/1WFVaku"}]},"_npmUser":{"name":"403fin","email":"admin@403fin.io"},"directories":{},"maintainers":[{"name":"403fin","email":"admin@403fin.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp_1.0.0_1787470094509_0.40972132682777085"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-23T07:28:14.340Z","1.0.0":"2026-08-23T07:28:14.645Z","modified":"2026-08-23T07:28:14.874Z"},"maintainers":[{"name":"403fin","email":"admin@403fin.io"}],"description":"Model Context Protocol server for Forbidden Finance — a thin client over the public /v1 REST API.","homepage":"https://403fin.io","keywords":["mcp","model-context-protocol","forbidden-finance","403fin","personal-finance"],"repository":{"type":"git","url":"git+https://github.com/403ent/403fin-mcp.git"},"author":{"name":"403 Finance, Inc."},"bugs":{"url":"https://github.com/403ent/403fin-mcp/issues"},"license":"MIT","readme":"# @403fin/mcp\n\nThe official [Model Context Protocol](https://modelcontextprotocol.io) server for\n**Forbidden Finance**. It lets an MCP-capable AI assistant (Claude, ChatGPT,\nPerplexity, and others) read your accounts, transactions, budgets, goals, net\nworth, investments, debt, and insights — and make a few carefully-guarded\nchanges — through the Forbidden Finance public `/v1` API.\n\nIt is a thin, open-source client: every tool call is a single authenticated HTTPS\nrequest to `/v1`. There is no backend code and no data store. Your credential and\nOAuth tokens stay on your machine.\n\n- **40 tools** — 29 read-only and 11 writes: transactions\n  (`create_transaction`, `update_transaction`, `delete_transaction`,\n  `annotate_transaction`, `categorize_transactions`), categories\n  (`create_category`, `update_category`, `delete_category`), goals\n  (`update_goal`, `record_goal_contribution`), and `switch_budget_method`.\n  Writes need a connection with writes enabled and the matching `:write` scope.\n- **Two ways to authenticate** — an `ff_` API key, or an interactive OAuth 2.1\n  sign-in (PKCE) with a local loopback callback.\n- **Premium feature.** The public API is available on the Premium tier.\n\n## Quickstart\n\nRun it with `npx` (no install needed):\n\n```bash\nFF_API_KEY=ff_ak_your_key npx @403fin/mcp\n```\n\nThe server speaks MCP over stdio, so you normally don't run it by hand — you point\nyour AI app at it with one of the config snippets below.\n\n### Get an API key\n\nIn the Forbidden Finance app, go to **Settings → AI & API Connections** and create\na key. It starts with `ff_`. Keep it secret — treat it like a password.\n\n## Configure your AI app\n\n### Claude Desktop\n\nEdit `claude_desktop_config.json` (macOS:\n`~/Library/Application Support/Claude/claude_desktop_config.json`, Windows:\n`%APPDATA%\\Claude\\claude_desktop_config.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"forbidden-finance\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@403fin/mcp\"],\n      \"env\": {\n        \"FF_API_KEY\": \"ff_ak_your_key\"\n      }\n    }\n  }\n}\n```\n\n### ChatGPT (Developer Mode / MCP)\n\nAdd a **stdio** MCP server:\n\n```json\n{\n  \"mcpServers\": {\n    \"forbidden-finance\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@403fin/mcp\"],\n      \"env\": { \"FF_API_KEY\": \"ff_ak_your_key\" }\n    }\n  }\n}\n```\n\n### Perplexity\n\nIn Perplexity's MCP settings, add a local (stdio) server:\n\n```json\n{\n  \"mcpServers\": {\n    \"forbidden-finance\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@403fin/mcp\"],\n      \"env\": { \"FF_API_KEY\": \"ff_ak_your_key\" }\n    }\n  }\n}\n```\n\n## Authentication\n\nYou can authenticate two ways. The server picks based on your environment:\n\n### 1. API key (recommended, simplest)\n\nSet `FF_API_KEY` to your `ff_` key. That's it. The key is held in memory only and\nis never written to disk or logged.\n\n### 2. OAuth 2.1 sign-in (no API key)\n\nIf `FF_API_KEY` is **not** set, the first tool call starts an OAuth 2.1\nauthorization-code flow with PKCE:\n\n1. Your browser opens to the Forbidden Finance consent screen.\n2. After you approve, a one-time `127.0.0.1` loopback listener captures the\n   result.\n3. Access and refresh tokens are cached locally (see below) and refreshed\n   automatically as needed.\n\nNo client secret is involved (the client is registered dynamically as a public\nPKCE client). No scope is requested by default, which grants all read scopes and\nno writes; set `FF_SCOPES` to narrow that further. Refresh tokens are issued\neither way.\n\nTo use the write tools over OAuth, two things must both be true: request the\nwrite scopes via `FF_SCOPES` (a write scope implies its read scope), **and**\nenable **Allow changes** on the consent screen. Either one alone is not enough —\nwrites stay off until you opt in on both.\n\n| Scope | Reaches |\n|---|---|\n| `transactions.annotate:write` | `annotate_transaction`, `categorize_transactions` |\n| `transactions:write` | those two **plus** `create_transaction`, `update_transaction`, `delete_transaction` |\n| `categories:write` | `create_category`, `update_category`, `delete_category` |\n| `goals:write` | `update_goal`, `record_goal_contribution` |\n| `budgets:write` | `switch_budget_method` |\n\nThe two transaction scopes are deliberately different sizes: an assistant that\nonly sorts your spending into categories can be given\n`transactions.annotate:write` and will never be able to change an amount or\ndelete a row. Example: `FF_SCOPES=\"transactions.annotate:write categories:write\"`.\n\n**Token cache location** (keyed per base URL, file `0600` / dir `0700`):\n\n- Linux/macOS: `$XDG_CONFIG_HOME/403fin-mcp/tokens.json` (or\n  `~/.config/403fin-mcp/tokens.json`)\n- Windows: `%APPDATA%\\403fin-mcp\\tokens.json`\n\n## Environment variables\n\n| Variable      | Required | Default                 | Purpose                                                                                                              |\n| ------------- | -------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------- |\n| `FF_API_KEY`  | no\\*     | —                       | Your `ff_` API key. When set, selects API-key auth.                                                                  |\n| `FF_BASE_URL` | no       | `https://api.403fin.io` | API origin. Must be `https://`. Set this for self-hosting.                                                           |\n| `FF_SCOPES`   | no       | omitted                 | OAuth scope string (OAuth mode only). Omitted, the server grants all read scopes and no writes; set this to narrow.   |\n\n\\* Either set `FF_API_KEY`, or leave it unset to use OAuth.\n\n### Self-hosting\n\nIf you run your own Forbidden Finance instance, point the connector at it:\n\n```bash\nFF_BASE_URL=https://ff.your-domain.example FF_API_KEY=ff_ak_your_key npx @403fin/mcp\n```\n\n`FF_BASE_URL` must use HTTPS — the connector refuses plain HTTP and never disables\nTLS verification.\n\n## What the AI can and cannot do\n\n- **Reads** cover accounts, balances, connections, sync status, transactions and\n  search, categories, budgets and progress, recurring rules and upcoming bills,\n  goals (with progress, history, and contributions), net worth and its history,\n  holdings, liabilities, debt summary and payoff planning, and spending / income /\n  cash-flow insights.\n- **Writes** are limited to eleven tools, each requiring an idempotency key so a\n  retried call can't double-apply: create, edit, delete, annotate, and bulk\n  categorize transactions; create, edit, and delete custom categories; update a\n  goal's editable fields; record a goal contribution; and switch your budgeting\n  method.\n- **What writes still cannot do.** Bank-synced transactions cannot be deleted —\n  the bank is the source of truth and the next sync would bring the row back.\n  System categories (the seeded defaults) cannot be changed or deleted. A\n  transaction's currency cannot be changed. No write ever creates a merchant\n  auto-categorization rule, so an assistant sorting your spending never teaches\n  the app new habits on your behalf, and no write replaces the slices of a split\n  transaction. Switching a **shared** budget needs partner approval in the app\n  and cannot be completed here.\n\n## Privacy\n\nThis connector enforces the redaction and account/category exclusion choices you\nconfigured for the credential — hidden fields and excluded accounts are omitted or\nreported as unavailable by the API, exactly as in the app. See\n[`SECURITY.md`](https://github.com/403ent/403fin-mcp/blob/main/SECURITY.md) for the\nfull security model.\n\n## Development\n\n```bash\nnpm install\nnpm run generate   # regenerate src/tools/generated.ts from openapi.yaml\nnpm run build      # tsc → dist/\nnpm test           # vitest\nnpm run lint       # biome check\n```\n\nThe tool table (`src/tools/generated.ts`) is generated from `openapi.yaml`; a\nconformance test asserts the 40 tools match the spec, that the write set is\nexactly the eleven operations with an `Idempotency-Key`, and that the destructive\nset is exactly `delete_transaction`, `delete_category`, and\n`switch_budget_method`.\n\n## License\n\nMIT © 2026 403 Finance, Inc.\n","readmeFilename":"README.md","_rev":"1-3f47fd021e570348b58503ae050eeb60"}