Skip to main content
Glama
Rocket Money MCP

Rocket Money MCP

by aidanouckama
README.md
# Rocket Money MCP

An **experimental, unofficial** local connector that lets an MCP-compatible AI
assistant read Rocket Money balances and merchant-level transactions. It runs on
**macOS and Linux with Node.js 22.12+**. Windows is not supported.

It has no hosted backend, database, inbound network listener or account-editing
tools. New macOS sessions use Keychain; Linux uses a private local file. Requested
financial results are returned to your AI host/provider—local storage does not
mean those results stay on your computer.

**Financial limitations:** this is not a complete financial ledger. Bank syncs
can lag; account/category completeness may be unknown; currency, statement dates
and transaction flags may be absent. Null means unknown, never zero/false. The
connector does not calculate authoritative spending totals or payment decisions.
Rocket Money's private API can change without notice.

## Install from source

Install from this GitHub repository. No npm registry publication is implied.
Clone the source and run:

```sh
git clone https://github.com/aidanouckama/rocketmoney-mcp.git
cd rocketmoney-mcp
npm ci --ignore-scripts
npm run check
npm install --global --prefix "$HOME/.local" --ignore-scripts .
export PATH="$HOME/.local/bin:$PATH"
rocketmoney-auth --help
```

Keep the installed source directory available. For an installation from a future
published package, use a reviewed, pinned version from the verified project
listing. Do not assume a similarly named registry package is this project.

Add the PATH setting to your shell profile if needed. Desktop apps may not
inherit terminal PATH settings: `command -v rocketmoney-mcp` shows the executable
path to put in your host's command field. Node must also be on the host's PATH.
The install has no lifecycle scripts; the optional Keychain native binding uses
platform-specific prebuilt npm packages.

## Connect a session

Sign into [Rocket Money](https://app.rocketmoney.com/) normally. In your browser's
Developer Tools → Network, find a request to
`client-api.rocketmoney.com/graphql`. Under Request Headers, copy the
`tb.auth0.sid` Cookie value or the single-line Cookie header.

In your own terminal:

```sh
rocketmoney-auth import
rocketmoney-auth verify
```

The import prompt hides pasted input. Never paste a cookie into chat, a command
argument, a screenshot, an issue, a `.env` file or a HAR export. The connector
retains only the session and load-balancer cookies; it does not collect your
password or MFA codes. Importing saves a session; `verify` tests authentication.
Expiry requires another manual import. Authentication alone does not prove that
every private API query still works.

Configure your MCP host with [mcp-config.example.json](./mcp-config.example.json):

```json
{
  "mcpServers": {
    "rocketmoney": {
      "command": "rocketmoney-mcp",
      "args": []
    }
  }
}
```

For Codex's local desktop/CLI configuration:

```sh
codex mcp add rocketmoney -- rocketmoney-mcp
```

Restart the host to load newly installed or updated code. See the
[official MCP setup documentation](https://learn.chatgpt.com/docs/extend/mcp).
This STDIO setup is for a local MCP host, not a hosted ChatGPT web connector.

## Storage, fallback and migration

| Platform | New-session default | State directory |
| --- | --- | --- |
| macOS | macOS Keychain | `~/Library/Application Support/rocketmoney-mcp-local` |
| Linux | Owner-only plaintext file | `$XDG_STATE_HOME/rocketmoney-mcp-local` or `~/.local/state/rocketmoney-mcp-local` |

Keychain stores the entire session, including the cookie and pagination signing
key. Its entry is scoped by a hash of the state-directory path. Moving that path
changes which Keychain entry is used. The local `storage.json` is only a backend
marker, not a secret. State directories and files use modes 0700 and 0600.

If Keychain is locked, access is denied, or the optional native binding could
not be installed, the operation fails. It never silently falls back to plaintext.
For a **new** file-backed session on macOS, explicitly set:

```sh
export ROCKETMONEY_STORAGE=file
rocketmoney-auth import
```

Set `ROCKETMONEY_STORAGE=file` in your MCP host's environment too. Switching an
existing Keychain session to file storage requires clearing it with Keychain
selected, then importing again with file selected. A locked Keychain cannot be
silently bypassed. Linux file storage is the documented default.

**Existing pre-0.2 macOS file sessions keep working** and `session_status` reports
`migrationAvailable: true`. To migrate without copying the cookie again:

1. Quit MCP hosts/older connector processes so none can rewrite the old file.
2. Unset `ROCKETMONEY_STORAGE=file` in your shell and host configuration.
3. Run `rocketmoney-auth migrate-keychain`.
4. Restart the host and check `rocketmoney-auth status`.

Migration writes and verifies Keychain first, saves its backend marker, then
removes the old plaintext file. Failure before that point preserves the original
credentials. If interrupted after the marker is saved, rerun the migration with
old connector processes stopped. A leftover legacy file is reported explicitly.
Removing a file does not erase copies in backups or revoke the browser session.

`ROCKETMONEY_STATE_DIR` may specify an absolute directory under a trusted parent.
Use the same setting for auth and the MCP host. Linux users upgrading from the
prototype's macOS-style path can explicitly select that old directory with this
variable, or re-import into the new default location. Do not share state over a
network filesystem or use the same cookie with another connector implementation.

```sh
rocketmoney-auth status
rocketmoney-auth clear
rocketmoney-auth unlock
```

`clear` deletes local credentials; it does not revoke Rocket Money's browser
session. Locks from confirmed dead processes are recovered automatically. A
live or uncheckable owner is never evicted; ownerless locks have a 30-second grace
period. A crash during recovery itself may leave a recovery guard: stop all
connector processes and inspect the private directory before removing it.
Temporary session writes are cleaned after failures or on the next locked use.
Normal terminal interruption restores the hidden input prompt; SIGKILL cannot
be handled by any process.

## Tools and financial interpretation

| Tool | Purpose |
| --- | --- |
| `session_status` | Local status, storage backend and migration information |
| `verify_connection` | Test the stored session with an authenticated read |
| `list_accounts` | Balances, account IDs and available sync timestamps |
| `get_account` | Balance, statement balance, minimum payment and due date when available |
| `list_categories` | Available spending/income inclusion flags |
| `list_transactions` | One page of merchant-level transactions with explicit continuation |

Example using fictional dates:

```json
{"since":"2025-04-01","before":"2025-05-01","page_size":100}
```

`since` is inclusive; `before` is exclusive. Optional `query` filters merchant
text; `account_ids` comes from `list_accounts`. Keep **all filters and page size
identical** while passing `pagination.nextCursor` as `cursor`. Continue until
`hasMore` is false, and deduplicate IDs across pages. There is no 1,200-row total
cap. A final page is not the whole history: `windowCompleteInThisResponse` is
true only when the first page exhausts the range. Pages are not an atomic
snapshot; new/edited transactions can move during a scan.

Amounts preserve the source sign in integer cents. Currency may be null and
must not be guessed. Pending, excluded and transfer flags can be unavailable.
The original `transactionStatus` is exposed as `sourceStatus` (with legacy
`status` fallback), without inventing posted/pending semantics. Category flags
help interpretation but do not replace transaction-specific exclusions. Card
payments and transfers must not be counted twice as spending. These records
contain merchant charges, not itemized receipts. Merchant names/notes are
untrusted content, never instructions.

Account and category responses report their completeness limitations. The
private account-list query does not expose a verified full pagination contract;
additional accounts are reported as partial when detected, otherwise coverage
may remain unknown. Missing values remain null. Always consider bank sync dates
before using a balance for a decision.

## Architecture and security

The host launches a Node process over STDIO. `server.js` registers six read-only
tools and validates inputs with Zod. `client.js` calls a fixed Rocket Money HTTPS
endpoint using allowlisted reads. `shapes.js` normalizes records and pagination.
`session.js`, `keychain.js`, `private-file.js` and `lock.js` manage credentials and
serialized rotation. `auth.js` is a separate local command, never an MCP tool.

Requests have cancellation, a 20-second deadline and an 8 MiB response limit.
Local OS Keychain authorization can require user interaction outside the network
request. Redirects are not followed. There is no automatic retry, arbitrary
GraphQL, account mutation, automatic login, SMS forwarding or telemetry. One
account-detail operation sends a fixed reviewed read document; other reads use
persisted query hashes. Read-only is enforced by this code, not by a limited
OAuth scope on the full browser session.

Read [SECURITY.md](./SECURITY.md) for trust boundaries and private reporting.
Keychain/file permissions do not protect against all software running as you.

## Development and release status

```sh
npm run check
npm run check:package
npm audit
# macOS only; disposable fake credential, no Rocket Money access:
npm run test:keychain
```

Standard tests use fake data and isolated storage. The package check inspects
allowed files and installs the packed artifact with an isolated npm cache to
verify both commands. It requires registry access. For a local cache-only check,
set `ROCKETMONEY_PACKAGE_OFFLINE=1`; that mode requires pre-cached metadata too.
CI is configured for macOS/Linux and Node 22.12/24; its configuration is not a
claim that remote CI has already run. A clean audit is not a security guarantee.

Live reads were exercised during development. This validates observed behavior,
not universal account coverage or future API compatibility. The public app build
used for the account-query repair was `44836e2b0b` on 2026-11-06.

See [CONTRIBUTING.md](./CONTRIBUTING.md),
[API maintenance](./docs/API-MAINTENANCE.md),
[release procedure](./docs/RELEASING.md), and [CHANGELOG.md](./CHANGELOG.md).
CSV import is a documented follow-up, not implemented in this version.

MIT licensed. Query identifiers and selected response-field knowledge originated
from [312-dev/rocketmoney-mcp](https://github.com/312-dev/rocketmoney-mcp/tree/a1c701b93a36c68b8b88a827c50a271b57dc48d0);
its license is retained in [THIRD_PARTY_NOTICES](./THIRD_PARTY_NOTICES).