Skip to main content
Glama
wilderfield

plaid-mcp

by wilderfield

plaid-mcp

Persistenter Plaid-MCP-Server für einen KI-Assistenten (Elowen), der in einem ephemeren Container läuft.

plaid-mcp ist ein langlebiger, extern gehosteter Dienst, der das Plaid- Geheimnis und die verschlüsselten Zugriffstoken für jede verknüpfte Institution besitzt. Der Assistent ruft zur Laufzeit mcp__plaid__*-Tools auf; er sieht niemals die rohen Zugriffstoken, sondern nur undurchsichtige item_id- und account_id-Werte, die Plaid bereits als öffentlich betrachtet.

Elowen (ephemeral container)
  └─ calls mcp__plaid__* tools
        └─ plaid-mcp (persistent, nanoclaw-hosted)
              ├─ Plaid SDK + PLAID_SECRET (never leaves this service)
              ├─ access_token store (SQLite, AES-256-GCM at rest)
              └─ /link/start, /link/callback (HTTPS, browser-facing)
                    └─ Plaid REST API / Plaid Link JS

Oberflächen

Ein einzelner Node.js-Prozess stellt zwei völlig getrennte Oberflächen bereit:

  1. MCP-Server. Entweder stdio (der Agent startet diese Binärdatei als Subprozess) oder http (Streamable HTTP unter POST /mcp, mit Bearer-Token-Schutz). Wählen Sie dies mit MCP_TRANSPORT. Für den oben beschriebenen Anwendungsfall des Familienbudgets wollen Sie http, damit eine Flotte ephemerer Agenten-Container einen persistente Server gemeinsam nutzen kann.

  2. HTTPS-Link-Mini-App unter /link/*. Wird nur während des einmaligen Bankverknüpfungsprozesses verwendet — der Benutzer öffnet eine URL, die der Assistent ihm gibt, meldet sich innerhalb von Plaid Link bei seiner Bank an und ist fertig. Danach wird der Browser für diese Institution nie wieder benötigt.

Related MCP server: plaid-mcp

MCP-Tools

Tool

Was es tut

list_linked_institutions()

Jedes verknüpfte Element, mit needs_relink-Gesundheitsflag (ruft /item/get pro Element auf).

list_accounts(item_id?)

Zwischengespeicherte Kontenliste (Typ, Untertyp, Maske, letzter Saldo) für eine oder alle Institutionen.

get_balances(account_ids?)

Echtzeitsalden über /accounts/balance/get (kostenpflichtiger Plaid-Endpunkt).

get_transactions(start_date, end_date, account_ids?, cursor?)

Transaktionen im Datumsbereich, ca. 250 pro Seite, undurchsichtiger Paginierungs-Cursor.

search_transactions(query, since?, until?, min_amount?, max_amount?, category?)

Serverseitig gefilterte Transaktionssuche. Gibt kompakte Zeilen zurück.

get_monthly_summary(month, group_by?)

Voraggregierte Monatssummen, gruppiert nach category oder merchant. Hält den LLM-Kontext klein.

get_investment_holdings(account_ids?)

Positions-Snapshot (Ticker, Menge, Marktwert, Kostenbasis).

get_investment_transactions(start_date, end_date, account_ids?)

Käufe/Verkäufe/Dividenden in einem Zeitfenster.

get_liabilities(account_ids?)

Kreditkarten-APRs/Auszüge, Studienkredite, Hypothekendetails.

initiate_link(institution_hint?)

Gibt { url, session_id, expires_at } zurück — geben Sie die URL an den Benutzer weiter.

link_status(session_id)

Abfragen bis succeeded (mit neuer item_id), failed oder expired.

remove_institution(item_id)

Widerruft das Plaid-Element und löscht das lokale Token.

Alle Tool-Antworten sind JSON innerhalb eines einzelnen text-Inhaltselements (funktioniert auf jedem MCP-Client, einschließlich solcher, die structuredContent nicht anzeigen).

Einmaliger Verknüpfungsprozess

  1. Elowen ruft initiate_link({ institution_hint: "Chase" }) auf. Der Server:

    • ruft Plaid /link/token/create auf,

    • speichert eine link_sessions-Zeile (Status pending),

    • gibt { url: "https://<LINK_BASE_URL>/link/start?s=<uuid>&sig=<hmac>", session_id, expires_at } zurück.

  2. Elowen sendet die URL an den Benutzer.

  3. Der Benutzer öffnet sie in einem Browser. Die Seite lädt Plaid Link JS vom offiziellen CDN mit diesem link_token und präsentiert einen "Open Plaid Link"-Button.

  4. Plaid Links onSuccess sendet { public_token, institution } plus die signierte Session-ID per POST zurück an /link/callback.

  5. /link/callback tauscht public_tokenaccess_token + item_id aus, verschlüsselt das Zugriffstoken mit AES-256-GCM, speichert es dauerhaft und markiert die Session als succeeded.

  6. Elowen fragt link_status(session_id) ab, sieht succeeded mit der item_id und fährt fort.

Die signierten URL-Parameter (s, sig) sind HMAC-SHA256-geschlüsselt durch LINK_SESSION_SECRET. Die DB-Zeile ist die Quelle der Wahrheit — der HMAC lehnt einfach und kostengünstig fehlerhafte Anfragen ab, bevor wir SQLite berühren.

Konfiguration

Die gesamte Konfiguration erfolgt über Umgebungsvariablen (geladen aus .env).

Variable

Erforderlich

Standard

Beschreibung

PLAID_CLIENT_ID

Ja

Vom Plaid-Dashboard

PLAID_SECRET

Ja

Vom Plaid-Dashboard. Verlässt diesen Dienst niemals.

PLAID_ENV

Nein

sandbox

sandbox

development

production

PLAID_API_VERSION

Nein

2020-09-14

Fixierte API-Version

PLAID_PRODUCTS

Nein

transactions

Kommagetrennte Liste. Häufig: transactions,investments,liabilities

PLAID_COUNTRY_CODES

Nein

US

Kommagetrennte Liste von ISO-Ländercodes

PLAID_USER_ID

Nein

family-default

Stabiles client_user_id, das an Plaid gesendet wird

PLAID_ENCRYPTION_KEY

Ja

32 Bytes hex (openssl rand -hex 32). AES-256-GCM-Schlüssel für ruhende Token.

LINK_SESSION_SECRET

Ja

≥ 32 Bytes hex. HMAC-Schlüssel für signierte Link-URLs.

LINK_SESSION_TTL_SECONDS

Nein

900

Lebensdauer der Link-Session

LINK_BASE_URL

Ja

Öffentliche HTTPS-Basis-URL, die der Browser aufruft (z. B. https://plaid.example.com)

PORT

Nein

3333

HTTP-Port. TLS wird vorgelagert bei nanoclaw terminiert.

ADMIN_TOKEN

Nein

Falls gesetzt, schützt dies /link/admin/* Introspektionsrouten

MCP_TRANSPORT

Nein

http

stdio

http

MCP_BEARER_TOKEN

Ja, wenn MCP_TRANSPORT=http

Bearer-Token erforderlich bei POST /mcp

DB_PATH

Nein

./data/plaid-mcp.sqlite (Docker: /data/plaid-mcp.sqlite)

SQLite-Pfad. Mounten Sie hier ein persistentes Volume.

LOG_LEVEL

Nein

info

Pino-Log-Level. Alle Logs gehen an stderr.

Generieren Sie Geheimnisse mit:

make keys

Speicherung

SQLite (better-sqlite3) unter $DB_PATH. Zwei Tabellen sind wichtig:

  • itemsitem_id PK, verschlüsseltes access_token_blob BLOB, Institution Name/ID, Status, Ablauf der Zustimmung.

  • link_sessions — kurzlebig, laufen automatisch ab, wenn sie nach ihrem expires_at und während eines 60-sekündigen Hintergrund-Sweeps gelesen werden.

Zugriffstoken werden gespeichert als [1-Byte Version][12-Byte IV][16-Byte GCM Tag][N-Byte Ciphertext]. Die Entschlüsselung schlägt fehl, wenn das GCM-Tag nicht verifiziert werden kann.

Sicherheitsmodell

  • Der MCP-HTTP-Transport erfordert Authorization: Bearer $MCP_BEARER_TOKEN bei jeder Anfrage. Ohne dies würde die Agentenflotte jedes verknüpfte Bankkonto dem Internet preisgeben.

  • Die browserseitigen /link/*-Routen sind signiert (HMAC) und an eine kurzlebige, DB-gestützte Session gebunden.

  • TLS wird erwartet, vorgelagert (bei nanoclaw / Caddy / was auch immer Ihr Edge ist) zu terminieren. Der Container spricht intern einfaches HTTP; stellen Sie ihn nur über den Proxy bereit.

  • Jedes Plaid-Token ist im Ruhezustand verschlüsselt. Selbst mit der SQLite-Datei in der Hand kann ein Angreifer ohne PLAID_ENCRYPTION_KEY die Token nicht verwenden.

  • Die MCP-Tools geben niemals Zugriffstoken an den Agenten zurück. Nur undurchsichtige item_id / account_id-Strings überschreiten die MCP-Grenze.

Lokale Entwicklung

npm install
make setup           # creates .env from env.example
make keys >> .env    # append fresh PLAID_ENCRYPTION_KEY / LINK_SESSION_SECRET / MCP_BEARER_TOKEN
# edit .env: PLAID_CLIENT_ID, PLAID_SECRET, LINK_BASE_URL
npm run dev          # tsx with hot reload

Für lokale Link-Tests benötigen Sie einen HTTPS-Tunnel (Plaid Link onSuccess funktioniert nicht von http://localhost). cloudflared, ngrok oder ein echter Caddy-Reverse-Proxy funktionieren alle; welcher öffentliche Hostname auch immer Ihnen gegeben wird, kommt in LINK_BASE_URL.

Docker

make build
make up
make logs

Die Compose-Datei mountet ./data:/data, damit die SQLite-DB Neustarts überlebt. Ersetzen Sie in einer nanoclaw-Bereitstellung diesen Bind-Mount durch das cluster-verwaltete persistente Volume.

Anbindung des Agenten an eine gehostete Instanz

Innerhalb der MCP-Client-Konfiguration des Agenten-Containers:

{
  "mcpServers": {
    "plaid": {
      "url": "https://plaid-mcp.your-domain.example/mcp",
      "headers": {
        "Authorization": "Bearer <MCP_BEARER_TOKEN>"
      }
    }
  }
}

Der Agent erhält das Bearer-Token über den Mechanismus zur Geheimnis-Injektion, den nanoclaw bereits für seine anderen Agenten-Geheimnisse verwendet. Er sieht niemals PLAID_SECRET oder irgendein Zugriffstoken.

Lizenz

Intern.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Self-hosted MCP server enabling Claude to query bank accounts, balances, and transactions through Plaid with OAuth and TLS.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A local MCP server that provides read-only SQL access to financial accounts via Plaid, enabling natural language queries about transactions, balances, and holdings.
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Personal finance MCP server that integrates Plaid bank data with local SQLite memory for conversational budgeting, goal tracking, and transaction management.
    15
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that exposes banking data (connections, accounts, balances, transactions) and agent skills, allowing AI agents to query and refresh financial data via stdio.
    139
    6
    Apache 2.0