MCP security & privacy


1. Token model

Monetia issues two types of bearer tokens for MCP access:

Type Prefix Lifetime Notes
OAuth access token oat_… 1 hour Issued after OAuth 2.0 + PKCE consent flow. Claude.ai refreshes automatically.
OAuth refresh token (internal) 30 days (rotated) Issued alongside the access token. Rotated on every use — presenting an already-used refresh token revokes the entire grant family (OAuth 2.1 §6.1). No silent recovery; re-authorization is required.
Personal API token mnt_… Never expires (revocable) Minted via Settings → Developer. Treat as a password. Revoke immediately if leaked.

All tokens are stored hashed (SHA-256 + server-side pepper). Monetia cannot recover a token value; if lost you must mint a new one.


2. Scope catalog

Scopes follow the <resource>:<verb> pattern. Granting *:write implies *:read. There is no "grant everything" meta-scope — each resource must be opted in explicitly on the consent screen.

Scope What Claude can do
profile:read Read your name, language, timezone, default currency, and 2FA-enabled flag. Always-on in the consent UI; cannot be unchecked.
accounts:read List and read bank account details and balances.
accounts:write Create and update bank accounts. Implies accounts:read.
cards:read List and read credit card details, statements, and balances.
cards:write Create and update credit cards. Implies cards:read.
loans:read List loans, payment schedules, and payoff summaries.
loans:write Create and update loans. Implies loans:read.
assets:read List assets, valuations, and net asset values.
assets:write Create assets and record valuations. Implies assets:read.
transactions:read Search, filter, and read income/expense transactions. Also implies transfers:read.
transactions:write Create, update, void, split, and delete transactions. Implies transactions:read. Does not grant transfers:write.
transfers:read Read transfer transactions between entities.
transfers:write Move money between your accounts (the highest-privilege write scope). Granted independently of transactions:write.
recurring:read List and read recurring transaction templates.
recurring:write Create, update, and trigger recurring transactions. Implies recurring:read.
categories:read List income/expense categories.
categories:write Create and update categories. Implies categories:read.
tags:read List transaction tags.
tags:write Create and attach tags. Implies tags:read.
budgets:read Read budget definitions and spending status.
budgets:write Create and update budgets. Implies budgets:read.
reports:read Run net worth, dashboard, spending-by-category, and income-vs-expense reports.
quick_transactions:read List pending quick transactions (bank-sync inbox).
quick_transactions:write Approve or dismiss quick transactions. Requires transactions:write for approval.
currencies:write Currently grants no tools. Manual exchange-rate overrides were removed, because rates are shared by every user.

Highlighted risk: transfers:write authorizes Claude to move money between your accounts. It is presented separately on the consent screen with an explicit warning. Do not grant it unless you intend to let Claude initiate transfers.


3. What MCP can never do

Regardless of which scopes are granted, the Monetia MCP server enforces these hard limits:

  • Cannot read or change your password — password changes go through the web UI with current-password verification.
  • Cannot enable, disable, or rotate 2FA — 2FA management is UI-only, forever.
  • Cannot register new OAuth clients on your behalf — dynamic client registration is available to developers but the resulting client still requires your consent before accessing any data.
  • Cannot access another user's data — every tool is scoped to the authenticated user.
  • Cannot bypass rate limits — 60 calls/minute/token, 1,000 calls/hour/user. Destructive tools (delete_transaction, process_due_recurring) have lower per-tool caps.

4. Audit log

Every MCP call — successful, denied, or errored — is written to an append-only audit log with:

  • Tool name called
  • OAuth client or personal token identifier
  • IP address of the request
  • SHA-256 hash of the request payload (for non-repudiation)
  • Duration in milliseconds
  • Outcome: ok, denied, or error
  • For transfers, the source and destination amounts and currencies

The log itself isn't shown in Monetia; the connected apps list (Settings → AI Assistant access (MCP)) shows when each app last used your account, taken from it.

Retention: each row is kept for 90 days and then deleted automatically (a daily job). There is no archive: once deleted, a row is gone. Deleting your account unlinks the rows from it; they keep each call's IP address until those 90 days are up.


5. Revocation paths

Action Where Effect
Revoke one connected app Settings → AI Assistant access (MCP) → Connected apps → Revoke All access and refresh tokens of that app stop working immediately; other apps are unaffected. Also DELETE /api/v1/users/mcp-grants/{client_id}/ (not callable with an MCP OAuth token).
Revoke one personal token Settings → Developer → API Tokens That specific mnt_… token is invalidated.
Disable MCP entirely Settings → AI Assistant access (MCP) → turn the switch off Every OAuth access and refresh token is revoked at once. Personal tokens are not revoked, but /mcp rejects every token type, personal ones included, while MCP access is off.
Change your password Settings → Security OAuth connections and personal tokens are not revoked and keep working; revoke them as above if you need to.

If you suspect a token has been leaked, change your password AND revoke the connected apps and any personal tokens you have minted.


6. Reporting issues

Security vulnerabilities: security@monetia.carlosmart.dev

Please include a description of the issue, steps to reproduce, and your assessment of impact. We aim to acknowledge reports within 48 hours.