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, orerror - 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.