monzo-mcp
monzo-mcp
Servidor MCP para la API bancaria de Monzo. Acceso de solo lectura a cuentas, saldos, pots, transacciones y análisis de gastos, todo a través de Claude Code o de cualquier cliente MCP.
A diferencia de otras implementaciones de MCP de Monzo que usan tokens bearer en crudo (que caducan en 6 horas), este servidor gestiona OAuth completo con renovación automática de tokens.
Características
7 herramientas de solo lectura: sin operaciones de escritura, sin movimiento de dinero.
OAuth con renovación automática: los tokens se renuevan automáticamente, sin regeneración manual.
Caché local de transacciones: la base de datos SQLite sobrevive a la ventana SCA de 90 días de Monzo.
Autosincronización bajo demanda: las herramientas que leen la caché ejecutan automáticamente una sincronización incremental si la caché no se ha sincronizado hoy, por lo que rara vez necesitarás llamar a
monzo_synca mano.Análisis de gastos: desglose por categorías, principales comercios, comparación mes a mes.
Búsqueda de transacciones: busca por comercio, beneficiario (contraparte), descripción o notas en el historial almacenado en caché.
Detalles de la contraparte: las transferencias bancarias (pagos rápidos, p2p, Bacs) se almacenan en caché con el nombre del beneficiario, su sort code y su número de cuenta.
Related MCP server: monzo-mcp
Herramientas
Herramienta | Descripción | Fuente de datos |
| Lista las cuentas con tipos e IDs | API en vivo |
| Saldo actual y gasto de hoy | API en vivo |
| Pots de ahorro y saldos | API en vivo |
| Sincroniza las transacciones en la caché local | API en vivo -> SQLite |
| Lista/filtra transacciones en caché | Caché local (se autosincroniza si está obsoleta) |
| Busca por comercio/beneficiario/descripción/notas | Caché local (se autosincroniza si está obsoleta) |
| Análisis de gastos con desglose por categorías | Caché local (se autosincroniza si está obsoleta) |
Requisitos previos
Python 3.13+
uv (recomendado) o pip
Una cuenta de Monzo con un cliente OAuth registrado en developers.monzo.com
Instalación
git clone https://github.com/partymola/monzo-mcp.git
cd monzo-mcp
uv venv --python 3.13 .venv
uv pip install -e .Este paquete no está en PyPI: el nombre pertenece a un proyecto no relacionado. En su lugar se publica una imagen de contenedor; consulta Docker.
Configuración inicial
1. Registra un cliente OAuth de Monzo
Ve a developers.monzo.com y crea un cliente OAuth:
Configura la URL de redirección en
http://localhost:6600/callback.Anota tu Client ID y Client Secret.
2. Autentícate
monzo-mcp authEsto abre tu navegador para el OAuth de Monzo. Después de autorizar, aprueba el inicio de sesión en tu app de Monzo en un plazo de 5 minutos para acceder al historial completo de transacciones (la ventana SCA de Monzo).
3. Regístrate en Claude Code
claude mcp add -s user monzo -- /path/to/monzo-mcp/.venv/bin/monzo-mcpEn Windows, el script de consola se encuentra en .venv\Scripts\monzo-mcp.exe.
4. Primera sincronización
Dentro de Claude Code, ejecuta monzo_sync para rellenar la caché local de transacciones. Hazlo inmediatamente después de autenticarte para aprovechar la ventana SCA (hasta ~11 meses de historial).
Docker
Las imágenes se publican en ghcr.io/partymola/monzo-mcp. Las etiquetas llevan el prefijo v (:vX.Y.Y.Z.Y) y :latest sigue el último lanzamiento.
El contenedor necesita un volumen. Las credenciales y la caché de transacciones se guardan en /data; si no hay nada montado ahí, el contenedor arranca pero todas las herramientas informan de que no está configurado, y cualquier cosa que autorices se pierde en cuanto se reemplaza el contenedor.
Primero registra un cliente OAuth como se describe en Pas 1 de Configuración: auth pide el Client ID y el Client Secret, y no hay forma de proporcionarlos más adelante. La URL de redirección es http://localhost:6600/callback, igual que en la instalación desde el código fuente.
Autentícate una vez, en un volumen con nombre. Decide antes de ejecutarlo si prefieres un bind mount; si lo cambias después, tendrás que autorizarte de nuevo:
docker volume create monzo-mcp-data
docker run --rm -it \
-v monzo-mcp-data:/data \
-p 127.0.0.1:6600:6600 \
ghcr.io/partymola/monzo-mcp:latest authEl puerto publicado solo se necesita para este paso, para que la redirección de OAuth pueda llegar al contenedor. Enlazarlo a 127.0.0.1 mantiene el listener de callback fuera de tu red. No se abre ningún navegador (el contenedor no tiene uno), así que copia la URL que imprime. A continuación, aprueba el inicio de sesión en tu app de Monzo en menos de 5 minutos (véase la ventana SCA de Monzo).
Después, registra el servidor usando el mismo volumen:
claude mcp add -s user monzo -- \
docker run --rm -i -v monzo-mcp-data:/data ghcr.io/partymola/monzo-mcp:latest-i es obligatorio: el servidor habla JSON-RPC por stdin y stdout.
Sincroniza de inmediato. El retrofill de 11 meses se cierra a los 5 minutos de aprobar en la app de Monzo (ver la Ventana SCA de Monzo), y este camino es más largo que una instalación desde el código; por tanto, ejecuta monzo_sync en cuanto esté registrado el servidor. Si lo pierdes, obtienes silenciosamente 90 días en su lugar, sin ningún error.
Para dejar los archivos en un lugar que puedas leer, usa un bind mount en lugar de un volumen nominado. El contenedor se ejecuta como root y escribe las credenciales solo para el propietario; por eso, sin --user, quedan en propiedad de root:
mkdir -p ~/monzo-mcp-data/config
docker run --rm -it \
-v ~/monzo-mcp-data:/data \
--user $(id -u):$(id -g) \
-p 127.0.0.1:6600:6600 \
ghcr.io/partymola/monzo-mcp:latest authPasa el mismo -v y --user al comando del servidor. Crea el directorio primero; --user contra un volumen nombrado falla, porque el volumen se inicializa con propiedad de root desde la imagen.
CLI
monzo-mcp Start the MCP server (stdio transport)
monzo-mcp auth Interactive OAuth setup (opens the browser)
monzo-mcp --version Print the installed package versionConfiguración
Toda la configuración se realiza mediante variables de entorno (opcionales):
Variable | Valor por defecto | Descripción |
|
| Directorio para credenciales y tokens de OAuth |
|
| Ruta a la caché de transacciones SQLite |
|
| Interfaz a la que se vincula el servido de callbacks de |
La imagen del contenedor define las dos primeras en /data, porque los valores por defecto relativos al paquete se resuelven en el directorio lib del intérprete ahí, que no puede montarse. Establece la tercera en 0.0.0.0, porque un puerto publicado llega a la interfaz bridge del contenedor y un bind en localhost lo rechaza.
Archivos de credenciales (generados por monzo-mcp auth):
config/monzo_client.json: cliente y secreto de OAuth.config/monzo_tokens.json: tokens de acceso y de renovación (renovación automática).
Ventana SCA de Monzo
La Autenticación Reforzada del Cliente (SCA) de Monzo limita el acceso al historial de transacciones:
Dentro de 5 minutos tras la aprobación: hasta ~11 meses de historial.
Cuando la ventana caduca: solo los últimos 90 días.
La caché SQLite local conserva permanentemente todas las transacciones sincronizadas, así que ejecuta monzo_sync justo después de hacer monzo-mcp auth.
Para un retrofill de un intervalo posterior, pase since a monz_sync: una fecha ISO (2026-01-01) o fecha con hora (2026-01-01T14:30:00Z). Retroceder más de ~90 días funciona solo dentro de la ventana SCA; fuera de ella se devuelven solo los últimos 90 días.
Las transacciones antiguas en la caché se agregan campos añadidos en versiones más recientes (por ejemplo, detalles de contraparte/beneficiario en transferencias bancarias) cuando se vuelven a recuperar; eso lo hace una sincronización completa posterior a la autenticación para el historial que vuelve a obtener.
Seguridad
No todas las herramientas de escritura: no se puede enviar dinero, mover fondos entre catalysts (potso) ni modificar transacciones.
La API de Monzo en sí misma no puede enviar dinero a cuentas externas.
Los tokens se almacenan como JSON en el directorio
config/(ignorado por texto).Todas las llamadas a la API son GET con autenticación mediante token bearer.
Solución de problemas
“SCA required” o solo 90 días de historial: vuelve a ejecutar
monzo-mcp authy aprueba el inicio de sesión en la app de Monzo dentro de los 5 minutos; a continuación, sincroniza de inmediato (ver la ventana SCA más arriba).Token caducado / sin renovación: vuelve a ejecutar
monzo-mcp authpara volver a autorizar.“No transaction data available”: la caché está vacía; llama a
monzo_sync(o a cualquier herramienta de lectura, una sincronización automática) una vez tras autenticación.En Docker todas las herramientas informan de “not configured” o la autorización no sobrevive a un reinicio: no hay ningún volumen montado en
/data. Ver Docker; el mismo volumen debe pasarse a la ejecución deauthy al servidor.authse queda en “Waiting for callback...” tras aprobar: el callback no se entregó. Presiona Ctrl-C y vuelve a ejecutarlo. En Docker, confirma que el puerto esté publicado (-p 127.0.0.1:6600:6600).
Contributing
Consulta CONTRIBUTING.md para el entorno de desarrollo, el flujo de pruebas y el hook de pre-commit. Los cambios se registran en CHANGELOG.md.
Licencia
GPL-3.0-or-later. Ver LICENSE.
Available Tools
7 toolsmonzo_get_balanceA
Get current balance for a Monzo account.
Args: account_type: "personal" or "joint" (default: "personal")
Returns balance, spend today, and currency. Also records a balance snapshot.
| Name | Required | Description | Default |
|---|---|---|---|
| account_type | No | personal |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It usefully discloses return fields and a side effect: 'Also records a balance snapshot.' However, it omits details about authorization, whether the balance is live/cached, or consequences of the snapshot, leaving material ambiguity for a side-effecting read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the core action, and structured into Args and Returns sections. Every sentence earns its place and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with an output schema, the description is mostly sufficient to invoke correctly. It covers the parameter, the return, and a side effect. However, it lacks usage context and enough detail about the snapshot side effect to feel fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description restates the only parameter and its allowed values, which are already present in the schema as an enum with a default. It provides no deeper meaning about what distinguishes personal from joint or how selection works, so it only partially compensates for the absence of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get current balance for a Monzo account.' This clearly distinguishes it from siblings like monzo_list_transactions, monzo_list_accounts, and monzo_spending.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use or when-not-to-use guidance is provided. It mentions the account_type default but does not explain how to choose between personal and joint, nor does it point to an alternative sibling for cases where a different tool would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monzo_list_accountsA
List all Monzo accounts with their types and IDs.
Returns account details including whether each is personal or joint, and whether it is open or closed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations present. The description states it returns account details, but does not explicitly confirm it is read-only or disclose potential side effects. For a simple list, default behavior is assumed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no wasted words, front-loaded with purpose and key return details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter list tool with an output schema, the description sufficiently explains what is returned (type and status), making it complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters: schema coverage is 100% trivially, and the description adds no param info (as none needed). Baseline of 4 is appropriate per rubric.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'List' and resource 'Monzo accounts', specifying returned details (type, status) that distinguish it from siblings like transaction or balance tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or alternatives are provided. Usage is implied from context, but the description lacks direct guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monzo_list_potsA
List all pots (savings buckets) for a Monzo account.
Args: account_type: "personal" or "joint" (default: "personal")
Returns the account the pots belong to, plus pot names and balances. Also records balance snapshots.
| Name | Required | Description | Default |
|---|---|---|---|
| account_type | No | personal |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden. It discloses what the tool returns (account, pot names, balances) and notes an important side effect: "Also records balance snapshots." It does not discuss authentication or rate limits, but for a simple list tool the disclosure is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: purpose comes first, followed by the single argument, then return behavior and side effect. Every sentence earns its place and there is no extraneous content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one optional parameter and an output schema, the description covers purpose, argument semantics, return contents, and the snapshot side effect. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description restates the schema's enum and default values for account_type without adding deeper meaning, such as when to choose personal versus joint. Since it is the only optional parameter and the schema already defines it clearly, this is sufficient but not additive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: "List all pots (savings buckets) for a Monzo account." This clearly distinguishes the tool from the sibling tools, none of which target pots, and the parenthetical clarifies the domain-specific term.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on what the tool does and documents the account_type choice of personal or joint. It does not explicitly name alternatives or exclusions, but no sibling tool overlaps with listing pots, so the guidance is sufficient for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monzo_list_transactionsA
List transactions from the local cache.
Auto-syncs if the cache is stale (last sync before today).
Queries the synced transaction database, not the live API. Bank transfers
(faster payments, p2p, bacs) include a counterparty object with the payee
name and, where the scheme provides them, sort code and account number.
Returns {"account_type": ..., "transactions": [...]}, where account_type
echoes the filter applied and is null when unfiltered.
Args: account_type: "personal" or "joint" (default: all) since: Start date, e.g. "2026-01-01" (inclusive) before: End date, e.g. "2026-02-01" (exclusive) category: Exact category match, e.g. "groceries", "eating_out", "transport" merchant: Merchant name search (case-insensitive, partial match) limit: Max results (default 50)
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| since | No | ||
| before | No | ||
| category | No | ||
| merchant | No | ||
| account_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden, and it discloses the most important behaviors: cached-not-live data access, the auto-sync side effect with its staleness threshold, the counterparty enrichment for bank transfers, and the shape of the response envelope. It stops short of a 5 because it does not state what happens if the auto-sync fails (stale data served? error?) or whether results are paginated beyond the limit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: purpose front-loaded in the first line, followed by the cache/sync behavior, the counterparty caveat, the return envelope, and a clean Args block. Every sentence earns its place, and the parameter documentation is scannable rather than prose-heavy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, the description is not obligated to explain return values in detail, yet it still provides the top-level envelope. All six optional parameters are fully documented, and the tool's complexity is moderate. The only material gap is failure behavior during the auto-sync path and the absence of pagination semantics, which keeps this from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must document the parameters itself — and it does, exhaustively and with added meaning. It specifies inclusive/exclusive semantics for since/before, exact-match semantics for category, case-insensitive partial-match semantics for merchant, allowed values plus default for account_type, and the max-results behavior for limit, all with concrete examples. This fully compensates for the empty schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first line — 'List transactions from the local cache' — pairs a specific verb (list) with a specific resource (transactions) and a scope qualifier (local cache), immediately distinguishing it from siblings such as monzo_get_balance, monzo_list_pots, and monzo_search_transactions. The follow-up 'not the live API' further sharpens the boundary, making the tool's identity unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when the tool is appropriate: it reads from the synced database rather than the live API, and it 'auto-syncs if the cache is stale (last sync before today)', which tells an agent when a prior sync step is unnecessary. It does not explicitly name an alternative tool for cases where live or search-level data is required (e.g., monzo_sync or monzo_search_transactions), so the when-not guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monzo_search_transactionsA
Search cached transactions by merchant, counterparty (payee), description, or notes.
Auto-syncs if the cache is stale (last sync before today).
Case-insensitive partial match across merchant_name, counterparty_name, description, and notes fields. Counterparty matching finds bank transfers (faster payments, p2p, bacs) by payee name.
Returns {"account_type": ..., "transactions": [...]}, where account_type
echoes the filter applied and is null when unfiltered.
Args: query: Search term account_type: "personal" or "joint" (default: all) since: Start date, e.g. "2026-01-01" (inclusive) before: End date, e.g. "2026-02-01" (exclusive) limit: Max results (default 30)
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| since | No | ||
| before | No | ||
| account_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses case-insensitive partial matching, the exact fields searched, counterparty behavior for bank transfers, cache auto-sync behavior, and the response shape. This is unusually transparent for a search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first sentence, followed by compact, high-value behavioral details and a clean Args list. Every sentence adds information; there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with five parameters and no annotations, the description covers search matching, cache staleness behavior, date-range semantics, account filtering, result limits, and the returned JSON shape. Nothing essential is missing for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, but the description lists every parameter with meaningful detail: query semantics, account_type values, since/before inclusivity with examples, and the limit default. This fully compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb-resource pair: 'Search cached transactions by merchant, counterparty (payee), description, or notes.' This clearly distinguishes it from sibling tools like monzo_list_transactions or monzo_sync by focusing on search across cached transaction fields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context: search by named fields, with automatic sync when the cache is stale ('last sync before today'). It stops short of explicitly naming alternatives or saying when not to use the tool, but the intended scenarios are easy to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monzo_spendingA
Analyse spending from cached Monzo transactions.
Auto-syncs if the cache is stale (last sync before today).
Every result carries account_type, echoing the filter applied and null
when unfiltered, so a zero total says which account it measured.
Args: month: Month in YYYY-MM format (default: current month) category: Filter by category, e.g. "groceries", "eating_out", "transport" account_type: "personal" or "joint" (default: all) detail: If true, return individual transactions instead of category summary
| Name | Required | Description | Default |
|---|---|---|---|
| month | No | ||
| detail | No | ||
| category | No | ||
| account_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It discloses the auto-sync side effect, the output behavior (account_type echo, null when unfiltered), and the detail switch affecting the return format. This goes beyond the schema and provides useful context, though it does not mention potential side effects like rate limits or error handling. The disclosure is substantial and does not contradict any annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: a clear summary sentence, a brief note on caching, an explanation of output behavior, and a concise Args list. It is front-loaded with the core purpose, and every sentence adds value. It is appropriately sized for a tool with four parameters and behavioral nuances, with no redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose, caching behavior, output characteristics, and all parameter semantics. It does not explicitly detail the return schema, but an output schema is available, so that is acceptable. It lacks explicit guidance on when to use this versus siblings, but the purpose is clear enough. Overall, it is nearly complete for an analysis tool, with only minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. The Args section provides format (YYYY-MM for month), examples (category values), default behavior (current month, all accounts), and the effect of detail (individual transactions vs summary). This adds rich meaning beyond the bare schema titles and types, fully satisfying the requirement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Analyse spending from cached Monzo transactions,' which states a specific verb (analyse), a resource (spending from Monzo transactions), and the caching behavior. This clearly distinguishes it from siblings like monzo_list_transactions (which would list raw transactions) and monzo_get_balance (which reads a balance). The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the tool does and mentions auto-sync when the cache is stale, but it does not explicitly state when to prefer this tool over alternatives like monzo_search_transactions or monzo_list_transactions. The usage context is implied by the purpose (spending analysis) but not directly contrasted with siblings, leaving some room for ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monzo_syncA
Sync transactions, balances, and pots from the Monzo API into the local cache.
Fetches up to 11 months of history (within SCA window) or falls back to the last-synced timestamp / 90 days. Handles pagination and auth-hold deduplication automatically.
Args: account_type: "personal", "joint", or None to sync all accounts since: Optional ISO date ("2026-01-01") or datetime ("2026-01-01T14:30:00Z") to start the backfill from, overriding last-sync resumption. Reaching beyond ~90 days only works inside the post-auth SCA window.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | ||
| account_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It transparently covers the 11-month fetch window, the fallback to last-synced timestamp or 90 days, automatic pagination, auth-hold deduplication, and the SCA constraint on deep backfills. It does not address side effects on the local cache or auth prerequisites in detail, but it is substantially transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a purpose statement, a behavior summary, and a clear parameter list. Every sentence adds substantive value, and the most important constraints are front-loaded. There is no redundant restatement of schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a tool with two optional parameters and an output schema. It explains what the tool fetches, the sync window behavior, pagination/deduplication, parameter semantics, and edge cases around the SCA window. Return values are reasonably covered by the output schema, so no extra explanation is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does. It explains account_type values ('personal', 'joint', or None to sync all accounts') and gives precise since formats (ISO date or datetime) plus its override behavior and SCA limitation. This goes well beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Sync') and resource ('transactions, balances, and pots from the Monzo API into the local cache'), clearly distinguishing it from sibling read/list/search tools. It also adds concrete scope details like history depth, pagination, and deduplication.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for refreshing or backfilling a local cache, but it does not explicitly state when to prefer this over sibling tools like monzo_list_transactions or monzo_search_transactions. It gives helpful context around backfill windows and last-sync resumption, but no exclusions or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.9.0- Changed
monzo_get_balance1 field changed- added
Input schema / properties / account_type / enumAdded value: +[ + "personal", + "joint" +]
- Changed
monzo_list_pots1 field changed- added
Input schema / properties / account_type / enumAdded value: +[ + "personal", + "joint" +]
- Changed
monzo_list_transactions1 field changed- changed
Input schema / properties / account_type / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "personal", + "joint" + ], + "type": "string" + }, + { + "type": "null" + } +]
- Changed
monzo_search_transactions1 field changed- changed
Input schema / properties / account_type / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "personal", + "joint" + ], + "type": "string" + }, + { + "type": "null" + } +]
- Changed
monzo_spending1 field changed- changed
Input schema / properties / account_type / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "personal", + "joint" + ], + "type": "string" + }, + { + "type": "null" + } +]
- Changed
monzo_sync1 field changed- changed
Input schema / properties / account_type / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "personal", + "joint" + ], + "type": "string" + }, + { + "type": "null" + } +]
1 tool update
v0.2.1- Changed
monzo_sync1 field changed- added
Input schema / properties / sinceAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Since" +}
7 tool updates
v0.1.0- First observed
monzo_get_balance - First observed
monzo_list_accounts - First observed
monzo_list_pots - First observed
monzo_list_transactions - First observed
monzo_search_transactions - First observed
monzo_spending - First observed
monzo_sync
TDQS
Scored across 7 tools
Tools are mostly distinct, but monzo_search_transactions and monzo_list_transactions both query cached transactions, differing mainly in search vs filter semantics; users could confuse which to use. Spending analysis is distinct as it provides aggregated insights.
All tools follow the monzo_ prefix with snake_case and mostly verb_noun pattern (get_balance, list_pots, search_transactions). However, 'monzo_sync' lacks a noun and 'monzo_spending' uses a noun as the action, deviating slightly from the pattern.
Seven tools is well-scoped for a personal finance MCP covering balance, pots, accounts, transactions, and spending analysis. Each tool serves a clear purpose without redundancy.
Covers core read-only banking operations: balance, accounts, pots, transaction listing/search, spending analysis, and data synchronization. Missing features like pot transfers or transaction details by ID, but these are beyond typical read-only scope.
Maintenance
Related MCP Connectors
Read-only bank & investment accounts via Plaid: balances, holdings, transactions, SQL analytics.
Read-only access to your bank, investment, and crypto accounts: balances, transactions, holdings.
Chat with your bank data: balances, transactions, budgets, bills. Reads only, never moves money.
Read-only Lunch Money accounts, transactions, categories and budgets. Unofficial connector.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceProvides an MCP server for querying and managing Monarch Money personal finance data through a local SQLite mirror with read-only SQL access. It enables users to sync transaction history from the Monarch API and analyze accounts, categories, and tags.1MIT
- AlicenseNot gradedqualityCmaintenanceRead-only Monzo banking integration for Claude Code that allows querying balances, transactions, pots, and spending analysis through natural conversation.4MIT
- -licenseNot gradedqualityNot gradedmaintenanceEnables interaction with Monzo bank accounts for balance checking, transaction management, pot operations, and reconciliation through natural language.-
- AlicenseNot gradedqualityBmaintenanceEnables local read-only exploration of Quicken Simplifi financial data through MCP, with tools for searching transactions, categories, tags, and merchants, using a local SQLite cache and token-based authentication.1MIT