{
  "markdown": "# bookie\n\n[![npm](https://img.shields.io/npm/v/bookie-mcp)](https://www.npmjs.com/package/bookie-mcp)\n[![Publish to npm](https://github.com/yuens1002/bookie/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/yuens1002/bookie/actions/workflows/npm-publish.yml)\n\n**An MCP server that keeps books for freelancers and landlords — driven from Claude or GPT instead of QuickBooks.**\n\nAsk your LLM to import a bank statement, categorize spending, reconcile a month, or generate a Schedule C. Bookie provides the correct double-entry ledger underneath — so the model reasons over real numbers, not a spreadsheet it's improvising on the fly.\n\n**This is for you if:** you're a solopreneur, freelancer, or rental property owner already living in Claude or GPT, you're comfortable with a 5-minute setup, and you want books that are actually correct.\n\n**Not for you if:** you want a dashboard UI, you need multi-user access, or you're satisfied with QuickBooks / a spreadsheet.\n\n## What you need before starting\n\n- **Node ≥ 24**\n- **[neonctl](https://neon.com/docs/reference/neon-cli)** — `npm install -g neonctl` (free [Neon](https://neon.tech) account; needed for the DB)\n- **An MCP-capable host:** Claude Desktop, Claude.ai, Cursor, VS Code, or any host supporting the MCP stdio or HTTP transport\n\n## Quick start (local, stdio)\n\n**Recommended — from source, fully automated:**\n\n```bash\ngit clone https://github.com/yuens1002/bookie\ncd bookie\nnpm install\nnpm run setup   # creates Neon DB, generates secrets, writes .env, runs db:push\nnpm run build\n```\n\n`npm run setup` opens a browser to log into Neon; new to Neon? Use the \"Sign up for an account\" link and pick GitHub/Google/Microsoft rather than email+password — it completes in the same browser round-trip, no email-verification detour that could interrupt the CLI mid-wait.\n\n`npm run setup` prints a ready-to-paste Claude Desktop config block at the end:\n\n```json\n{\n  \"mcpServers\": {\n    \"bookie\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/bookie/dist/index.js\"],\n      \"env\": {\n        \"BOOKIE_DB_URL\": \"<printed by setup>\",\n        \"BOOKIE_DB_DIRECT_URL\": \"<printed by setup>\",\n        \"BOOKIE_API_KEY\": \"<printed by setup>\"\n      }\n    }\n  }\n}\n```\n\n**Adding another machine to the same ledger — no clone needed:** stdio is a *local* process — every machine running a stdio MCP client spawns its own copy of the server, so each one otherwise needs its own checkout. Once the Neon DB is provisioned (via `npm run setup` above, on any one machine), every *other* machine just needs the same connection strings — no `git clone`, no `npm install`, no `npm run build` to keep in sync. Point that machine's MCP host at the [published package](https://www.npmjs.com/package/bookie-mcp) instead:\n\n```json\n{\n  \"mcpServers\": {\n    \"bookie\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"bookie-mcp\"],\n      \"env\": {\n        \"BOOKIE_DB_URL\": \"<same value as your first machine>\",\n        \"BOOKIE_DB_DIRECT_URL\": \"<same value as your first machine>\",\n        \"BOOKIE_API_KEY\": \"<same value as your first machine>\"\n      }\n    }\n  }\n}\n```\n\n`npx` fetches and runs the published version on demand — every machine pointed at the same `BOOKIE_DB_URL` shares one ledger, without any of them (besides the original) needing a checkout.\n\n**Bootstrapping a DB without cloning at all:** if you don't have connection strings yet from any machine (e.g. you created the Neon project manually instead of via `npm run setup`), push bookie's bundled schema directly:\n\n```bash\nmkdir bookie-mcp && cd bookie-mcp\nnpm install bookie-mcp\nBOOKIE_DB_URL=<pooled> BOOKIE_DB_DIRECT_URL=<direct> npx prisma db push --schema=node_modules/bookie-mcp/prisma/schema.prisma\n```\n\nThen use the same `npx -y bookie-mcp` config above.\n\n## Quick start (remote, HTTP — for Claude.ai mobile)\n\nDeploy to Railway with one click:\n\n[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/X2T0sN?referralCode=X2mmSS)\n\nRailway pulls the pre-built image from GHCR — no source build needed. Set the required env vars when prompted. See [docs/DEPLOYING.md](docs/DEPLOYING.md) for the full walkthrough (env var reference, Neon + Resend setup, Claude.ai OAuth connector).\n\n## Why no UI?\n\nThe host LLM already reads CSVs, sees receipt images, and writes prose. Bookie owns the things an LLM *shouldn't* improvise: a correct double-entry ledger, integer-cent money math, deterministic categorization rules, and reproducible reports. The model handles language and vision; the server handles the books.\n\n## Tools\n\nThe full, always-current tool reference lives in [`docs/TOOLS.md`](docs/TOOLS.md) (regenerate with `npm run docs:tools`). Today:\n\n| Tool | What it does |\n|------|--------------|\n| `manage_accounts` | Create/list/archive accounts (segment-scoped categories carry a tax line) |\n| `add_transaction` | Record one balanced double-entry (money flows from → to) |\n| `split_transaction` | One payment leg + N category legs (a receipt split across categories) |\n| `import_transactions` | Import a bank/card CSV as balanced entries — preview → confirm, with dedup |\n| `manage_rules` | Create/list/delete/test/suggest auto-categorization rules (categorize → account/property, or exclude) that power import-preview suggestions; `action=suggest` scans past categorizations and returns candidate rules for descriptions with 2+ occurrences |\n| `categorize_transaction` | Re-categorize the income/expense leg of an existing entry — explicit account or apply a stored rule |\n| `reconcile` | Match a bank/card statement CSV against the ledger and mark postings cleared — preview then commit |\n| `manage_receipts` | Attach, list, delete, or get a signed download URL for receipt data; optionally upload the original file (JPEG, PNG, WEBP, HEIC, or PDF) to Railway Bucket storage |\n| `generate_report` | Monthly reconciliation summary, or fiscal-year Schedule C / Schedule E tax P&L |\n| `export_report` | Render any report as markdown or CSV |\n| `send_report` | Run a report and email it via Resend |\n| `query_transactions` | List entries + postings by date range / account |\n| `account_balances` | Current balance per account |\n\n## Resources\n\nBookie exposes two MCP resources that an LLM can read without calling a tool:\n\n| Resource URI | MIME type | What it contains |\n|-------------|-----------|-----------------|\n| `bookie://accounts` | `application/json` | All active accounts with their current balances |\n| `bookie://reports/{year}` | `text/markdown` | Annual fiscal snapshot: Schedule C, Schedule E, and a one-row-per-month summary (opening balance, net income, cleared postings count) |\n\n## Prompts\n\nThree canned workflow prompts guide the LLM through common bookkeeping tasks:\n\n| Prompt | Parameters | Purpose |\n|--------|-----------|---------|\n| `monthly-close` | `year`, `month` | Step-by-step month-end close: import CSV → categorize → reconcile → report → (optional) email |\n| `categorize-uncategorized` | _(none)_ | Find journal entries with no income/expense leg and walk through categorizing each |\n| `prepare-tax-summary` | `year` | Generate Schedule C + E, export as markdown and CSV, optionally email |\n\n## Configuration\n\nSee [`.env.example`](.env.example) for the full reference. Key variables:\n\n| Variable | Purpose |\n|----------|---------|\n| `BOOKIE_TRANSPORT` | `stdio` (default) or `http` |\n| `BOOKIE_DB_URL` | Neon pooled connection string |\n| `BOOKIE_DB_DIRECT_URL` | Neon direct connection string (for `db push`) |\n| `BOOKIE_API_KEY` | Static Bearer token (Claude Desktop / direct API) |\n| `PUBLIC_URL` | Public HTTPS base URL of the deployed server (Claude.ai connector) |\n| `JWT_SECRET` | HS256 signing secret for OAuth JWT access tokens |\n| `OAUTH_CLIENT_ID` | OAuth client ID (default: `claude-ai-connector`) |\n| `OAUTH_CLIENT_SECRET` | Required when using OAuth: `/authorize` refuses all requests when unset (prevents any visitor from authorizing); `/token` also validates it. Enter this value in the Claude.ai connector settings. |\n| `RESEND_API_KEY` | Resend API key for `send_report` |\n| `RESEND_FROM` | Verified sender address for `send_report` (e.g. `Bookie <reports@yourdomain.com>`) |\n| `AWS_ENDPOINT_URL` / `AWS_S3_BUCKET_NAME` / `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_DEFAULT_REGION` | Railway Bucket credentials — auto-injected when you connect a bucket to the service (use AWS SDK Generic style); enables receipt file upload in `manage_receipts` |\n\n## Docs\n\n- [Architecture](docs/ARCHITECTURE.md) — data model, transports, layering\n- [Deploying](docs/DEPLOYING.md) — Railway + Neon + Resend setup\n- [Roadmap](docs/ROADMAP.md) — phased plan\n- [Changelog](CHANGELOG.md) — what shipped\n- [Releasing](docs/RELEASING.md) — versioning + release process\n- [Tools](docs/TOOLS.md) — generated manual\n- [Contributing](CONTRIBUTING.md) — setup, conventions, tests\n\n## Safety\n\nBookie stores financial data in your Neon Postgres database; connection strings live in `.env` (gitignored) and Railway env vars — never commit them. The HTTP transport requires auth on every `/mcp` request: either a static Bearer token (`BOOKIE_API_KEY`) or an OAuth JWT issued by the `/token` endpoint. Always set at least one before exposing the server beyond localhost. See [docs/DEPLOYING.md](docs/DEPLOYING.md) for the full Claude.ai connector OAuth setup.\n\n## License\n\nMIT\n",
  "bytes": 9340,
  "sha": "44508fbd39c84e84c336b10fc86bae76db07d527b52301ce06ae2e17cee7f48c",
  "repo_slug": "yuens1002/bookie",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_yuens1002_bookie_fcbcd26f/readme"
}