Skip to content

Repository files navigation

finary-mcp

A local MCP server (stdio) that gives Claude access to your Finary net-worth and banking data — reading accounts, transactions, cash flow and portfolio, and writing back transaction categories and auto-categorization rules.

Ask "what did I spend on groceries last month?" or "recategorize every Amex payment" and Claude answers from your real data. 10 tools, no network calls in the test suite, stdio only — nothing leaves your machine except the calls to Finary itself.

Unofficial project, not affiliated with Finary; it uses their internal API, so it can break at any time. Read the status and disclaimer before using it. Documentation below is in French — open an issue if you'd like it translated.


Serveur MCP local (stdio) exposant vos données Finary à Claude — lecture et écriture (recatégorisation, règles intelligentes).

⚠️ Finary n'a pas d'API publique : ce serveur utilise l'API interne (reverse-engineered, cf. finary_uapi). Elle peut casser à tout moment.

Statut et avertissement

Projet non officiel, sans aucun lien avec Finary. Il s'adresse à un utilisateur qui accède à ses propres données, avec ses propres identifiants.

Conséquences à accepter avant de l'utiliser :

  • Aucune stabilité garantie. L'API interne n'a pas de contrat public : un déploiement Finary peut renommer un champ ou déplacer un endpoint sans préavis. Ça s'est déjà produit pendant le développement (operation_date → date, amount → value).
  • Le transport peut cesser de fonctionner. Le login dépend d'une impersonation TLS qui passe aujourd'hui le bot management de Clerk. Si la détection se durcit, npm run verify:transport le signalera, mais le login échouera.
  • Vérifiez les conditions d'utilisation de Finary avant de vous en servir : automatiser l'accès à un service via son API interne peut les enfreindre. C'est votre responsabilité, pas celle de ce dépôt.
  • Les tools d'écriture mutent un vrai compte. Voir la section Écritures et son piège documenté sur la suppression de règles.

Installation

npm install && npm run build
cp .env.example .env   # remplir FINARY_EMAIL / FINARY_PASSWORD
chmod 600 .env

Premier login (MFA)

set -a; source .env; set +a
npm run login          # demande le code TOTP, persiste la session dans ~/.finary-mcp/

Transport : impersonation TLS

Finary délègue son auth à Clerk, protégé par le bot management Cloudflare. Clerk répond 403 bot_detected au POST /v1/client/sign_ins dès que la requête part du fetch natif de Node : le discriminant n'est pas les headers (les envoyer tous à l'identique d'un navigateur ne change rien) mais l'empreinte TLS/HTTP2 du client. Les autres endpoints (refresh de token, api.finary.com) ne sont pas filtrés.

Le login passe donc par impit (binaire natif précompilé, zéro dépendance runtime), qui négocie le TLS avec l'empreinte de Chrome. C'est le transport par défaut de tous les appels ; il se charge paresseusement, au premier appel réseau seulement.

npm run verify:transport   # sans credentials : identifiant volontairement invalide

Verdict OK: TLS impersonation accepted by Clerk → le transport passe. Si Clerk durcit sa détection, c'est ce script qui le dira le premier (FAIL: still bot_detected), avant même d'avoir à tenter un login.

FINARY_SESSION_TOKEN reste supporté (JWT récupéré dans DevTools sur app.finary.com → header authorization d'un appel à api.finary.com), mais ces JWT Clerk expirent en ~60 s : c'est utilisable pour un test ponctuel, pas comme mode de fonctionnement.

Config Claude Code

claude mcp add finary -- node /path/to/finary-mcp/dist/index.js

Ou dans la config JSON :

{
  "mcpServers": {
    "finary": {
      "command": "node",
      "args": ["/path/to/finary-mcp/dist/index.js"],
      "env": { "FINARY_EMAIL": "...", "FINARY_PASSWORD": "..." }
    }
  }
}

Tools

Tool Description
finary_get_accounts Comptes + soldes + type
finary_get_transactions Transactions d'une période (filtres catégorie/compte/recherche)
finary_get_cashflow Agrégats IN/OUT par catégorie
finary_get_portfolio Allocation et valorisation invest
finary_export_transactions_csv Export CSV d'une période
finary_get_categories Catégories de transactions (racines + sous-catégories, avec ids)
finary_get_rules Règles intelligentes de catégorisation existantes
finary_create_rule Crée une règle (écriture — aperçu dry_run disponible)
finary_delete_rule Supprime une règle (écriture — nécessite confirm: true)
finary_set_transaction_category Recatégorise une transaction (écriture)

Écritures

Les tools d'écriture (finary_create_rule, finary_delete_rule, finary_set_transaction_category) mutent le compte Finary réel. Garde-fous intégrés : finary_create_rule retourne toujours un aperçu (dry_run: true pour prévisualiser sans créer), et finary_delete_rule exige confirm: true.

Sémantique des règles (vérifiée en conditions réelles) :

  • Le pattern est un tableau de tokens en AND (tous doivent figurer dans le libellé, insensible à la casse). Aucune condition sur le montant ou le compte.
  • Une règle s'applique rétroactivement aux transactions passées.
  • Re-créer une règle sur un pattern identique remplace la règle existante (upsert).
  • ⚠️ Piège : supprimer une règle ne restaure PAS les catégories d'origine, contrairement à ce qu'affirme la modale Finary. Les transactions affectées restent dans la catégorie de la règle supprimée. Pour revenir en arrière : recréer une règle sur le même pattern avec la bonne catégorie, ou recatégoriser transaction par transaction. finary_delete_rule exige confirm: true et répète cet avertissement dans son résultat.

Sécurité

  • Session dans ~/.finary-mcp/session.json (0600, écriture atomique). Credentials uniquement via env.
  • Aucune donnée financière dans les logs (stderr technique uniquement : méthode, path, status — jamais de corps de requête, de libellé, de montant, de cookie ni de JWT).
  • Transport stdio uniquement : aucun port ouvert, aucune donnée envoyée ailleurs qu'à Finary.

Développement

npm test        # typecheck (src + tests) puis vitest
npm run build

Les tests n'appellent jamais le réseau : le transport est injecté (fetchImpl) et les fixtures de tests/fixtures/api-shapes.ts reproduisent la forme réelle de l'API avec des valeurs inventées. C'est volontaire : un champ renommé côté Finary casse un test au lieu de produire silencieusement des montants null.

Licence

MIT.

About

MCP server (stdio) exposing Finary data to Claude

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages