Poke Bank
FastMCP server exposing Open Banking (Enable Banking) as MCP tools β get_auth_url, exchange_code, list_accounts, get_transactions, get_balances
Ask AI about Poke Bank
Powered by Claude Β· Grounded in docs
I know everything about Poke Bank. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
poke-bank
An MCP server that exposes Enable Banking (EU/Nordic) and Teller (US) as MCP tools for Poke. Provides AI agents with tools to connect bank accounts, list accounts, fetch transactions, and check balances.
Features
- Dual provider support: Enable Banking for EU/Nordic banks, Teller for US banks
- 5 MCP tools: authorize bank connections, list accounts, get transactions, get balances, create sessions
- Automatic callback: Bank redirects back to
/callbackwhich auto-completes the session β no manual code copying - Teller Connect widget: Embedded JS widget at
/connect/tellerfor US bank enrollment (100 free enrollments) - Encrypted session store: AES-256-GCM encrypted SQLite database for session metadata
- Bearer token auth: Secure the server with
MCP_API_KEYso only you can use it - Poke webhook: Automatically notifies Poke when a bank account is connected
Quick Start
Prerequisites: Python 3.10+ and Node.js 18+ (which includes npx and npm).
git clone https://github.com/kacperkwapisz/poke-bank.git
cd poke-bank
If you haven't logged into Poke yet, do that first β start.sh will pick up your token automatically:
npx poke login
Then just run:
./start.sh
On the first run, start.sh automatically handles the full setup:
- Creates a Python virtualenv and installs dependencies
- Copies
.env.exampleβ.env - Reads your Poke API key from
poke logincredentials and injects it into.env - Generates a random
MCP_API_KEYandSESSION_ENCRYPTION_KEYand saves them to.env - Prompts you for your
ENABLE_BANKING_APP_ID(or you can set it manually in.envlater) - Immediately starts the server and tunnel
After the first run, open .env and fill in your provider credentials β Enable Banking (ENABLE_BANKING_APP_ID, ENABLE_BANKING_PRIVATE_KEY, ENABLE_BANKING_REDIRECT_URI) for EU/Nordic banks and/or Teller (TELLER_APP_ID, TELLER_CERT, TELLER_KEY) for US banks β then run ./start.sh again.
On subsequent runs, start.sh skips setup and goes straight to starting the server and tunnel.
AI coding agent setup
Copy this prompt into your AI coding agent (Claude Code, Cursor, etc.):
Set up poke-bank (https://github.com/kacperkwapisz/poke-bank) for me β clone the repo, run 'npx poke login' so I can authenticate with Poke (wait for me to confirm), then run './start.sh' which will automatically wire up my Poke API key, generate an MCP_API_KEY and SESSION_ENCRYPTION_KEY, set up the virtualenv, and start the server and tunnel. Before configuring bank providers, ask me: "Do you want to connect US banks, EU/Nordic banks, or both?" Then only set up what I choose. For EU/Nordic banks (Enable Banking): guide me to https://enablebanking.com to create an application, generate an RSA key pair (openssl genrsa -out private.pem 2048 && openssl rsa -in private.pem -pubout -out public.pem), upload the public key to the dashboard, copy the Application ID into ENABLE_BANKING_APP_ID, and set ENABLE_BANKING_REDIRECT_URI to https://<my-domain>/callback. For US banks (Teller): guide me to https://teller.io to create an application, copy the Application ID into TELLER_APP_ID, and download the mTLS certificate (teller.zip) β extract certificate.pem and private_key.pem and set TELLER_CERT and TELLER_KEY to their paths (not needed for sandbox mode). Do NOT type passwords or secrets, tell me to enter those myself and confirm when done; if the server fails due to missing credentials, have me update .env and run './start.sh' again.
Enable Banking Setup
To use poke-bank, you need credentials from Enable Banking:
- Create an account at enablebanking.com and create a new application
- Generate an RSA key pair for JWT signing:
openssl genrsa -out private.pem 2048 openssl rsa -in private.pem -pubout -out public.pem - Upload
public.pemto the Enable Banking dashboard under your application - Copy the Application ID (a UUID) β this is your
ENABLE_BANKING_APP_ID - Set the redirect URI in the dashboard to
https://<your-domain>/callbackβ this must matchENABLE_BANKING_REDIRECT_URIin.env - Add credentials to
.env:ENABLE_BANKING_APP_ID=<your-application-uuid> ENABLE_BANKING_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY----- ENABLE_BANKING_REDIRECT_URI=https://your-domain.com/callback
Note: You can also point
ENABLE_BANKING_PRIVATE_KEYto the PEM file path instead of inlining the key.
Teller Setup (US Banks)
To connect US bank accounts, you need a Teller application:
- Create an account at teller.io and create a new application
- Copy your Application ID β this is your
TELLER_APP_ID - Download your mTLS certificate β
teller.zipwas downloaded when you signed up (containscertificate.pemandprivate_key.pem). If lost, regenerate from the Certificates section of the Teller Dashboard. - Add credentials to
.env:TELLER_APP_ID=app_xxxxx TELLER_ENV=sandbox # sandbox | development | production TELLER_CERT=/path/to/certificate.pem # required for development/production TELLER_KEY=/path/to/private_key.pem # required for development/production
Note: Sandbox mode works without mTLS certificates and provides test data. You get 100 free enrollments on the developer plan.
Note: You can also inline the PEM strings directly in
TELLER_CERTandTELLER_KEYinstead of pointing to file paths (use\nfor newlines).
Manual Setup
1. Configure .env
cp .env.example .env
Edit .env with your Enable Banking credentials, then generate the required keys:
# MCP_API_KEY
openssl rand -hex 32
# SESSION_ENCRYPTION_KEY (64 hex chars)
python3 -c "import secrets; print(secrets.token_hex(32))"
2. Install dependencies
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
3. Run
source .venv/bin/activate
python3 src/server.py
4. Test
npx @modelcontextprotocol/inspector
Open http://localhost:6274 and connect to http://localhost:3000/mcp using "Streamable HTTP" transport. Pass Authorization: Bearer <your-MCP_API_KEY> header.
Authentication
Set MCP_API_KEY to secure the server. All requests must include Authorization: Bearer <MCP_API_KEY>.
When running via start.sh (which uses poke tunnel), set POKE_TUNNEL=1 to make MCP_API_KEY optional β the tunnel handles authentication. start.sh sets this automatically.
If MCP_API_KEY is not set and POKE_TUNNEL is not 1, the server runs unauthenticated (with a warning). Always set it in non-tunnel deployments.
Enable Banking uses JWT-based authentication (not OAuth2 client credentials). Your application signs short-lived JWTs with the RSA private key registered in the Enable Banking dashboard. These JWTs are sent as Bearer tokens on every API request.
Docker
docker compose up -d
Or use the pre-built image from GitHub Container Registry:
docker run -d \
-p 3000:3000 \
--env-file .env \
-v poke-bank-data:/data \
ghcr.io/kacperkwapisz/poke-bank:main
Resource Limits
The server is mostly idle (lightweight HTTP + on-demand banking API calls). Recommended limits for container orchestrators:
| Resource | Reservation | Limit |
|---|---|---|
| Memory | 64 MB | 256 MB |
| CPU | 0.1 | 0.5 |
Routes
| Path | Method | Description |
|---|---|---|
/mcp | GET | Health check β returns {"status": "ok"} |
/mcp | POST | MCP protocol endpoint |
/callback | GET | Enable Banking redirect β auto-completes the authorization flow |
/connect/teller | GET | Serves the Teller Connect widget page for US bank enrollment |
/callback/teller | POST | Receives enrollment data from the Teller Connect widget |
All other paths return 404.
MCP Tools
| Tool | Description |
|---|---|
get_auth_url | Start the authorization flow β returns a URL for the user to open and a session_id. Use provider='teller' for US banks, provider='enable_banking' (default) for EU/Nordic. |
create_session | Exchange the authorization code for a banking session (returns accounts) |
list_accounts | List all bank accounts linked to a session |
get_transactions | Get transactions for an account (optional date range filter) |
get_balances | Get current balances for an account |
Environment Variables
| Variable | Required | Description |
|---|---|---|
MCP_API_KEY | Yes | Bearer token for MCP clients. Optional when POKE_TUNNEL=1. |
ENABLE_BANKING_APP_ID | Yes | Application UUID from the Enable Banking dashboard (JWT kid) |
ENABLE_BANKING_PRIVATE_KEY | Yes | RSA private key PEM string or path to PEM file (signs API JWTs) |
ENABLE_BANKING_REDIRECT_URI | Yes | Redirect URL registered with Enable Banking |
SESSION_ENCRYPTION_KEY | Yes | 64 hex chars (32 bytes) for AES-256-GCM session encryption |
ENABLE_BANKING_BASE | No | API base URL β defaults to https://api.enablebanking.com |
CONSENT_VALIDITY_DAYS | No | Fallback consent validity in days when ASPSP lookup fails (default: 90). By default the maximum validity supported by the bank is used. |
DB_PATH | No | SQLite path β defaults to /data/sessions.db |
RATE_LIMIT_GET_RPM | No | GET rate limit per IP (default: 30) |
RATE_LIMIT_POST_RPM | No | POST rate limit per IP (default: 120) |
POKE_WEBHOOK_URL | No | Webhook URL to notify Poke when a bank account is connected |
POKE_API_KEY | No | API key for Poke webhook authentication |
TELLER_APP_ID | No | Teller application ID (enables US bank support via Teller) |
TELLER_ENV | No | Teller environment: sandbox, development, or production (default: sandbox) |
TELLER_CERT | No | Teller mTLS certificate β file path or inline PEM string (required for development/production) |
TELLER_KEY | No | Teller mTLS private key β file path or inline PEM string (required for development/production) |
POKE_TUNNEL | No | Set to 1 when using the Poke tunnel (disables MCP_API_KEY requirement) |
HOST_PORT | No | Exposed port on the host (default: 3000) |
PORT | No | Server port inside the container (default: 3000) |
Authorization Flow
Enable Banking (EU/Nordic)
- Call
get_auth_urlwith the bank name and country code - Open the returned
auth_urlin a browser and authorize - The bank redirects to
/callbackwhich auto-completes the session β no manual code copying needed - Use
list_accounts,get_transactions,get_balanceswith thesession_id
Fallback: If the callback redirect doesn't work, you can also manually copy the
codefrom the redirect URL and callcreate_sessionwith thecodeandsession_id.
Teller (US)
- Call
get_auth_urlwithprovider='teller' - Open the returned
auth_urlβ the Teller Connect widget loads in the browser - User authenticates with their bank through the widget
- On success, the page POSTs enrollment data to
/callback/tellerand shows "Connected" - Use
list_accounts,get_transactions,get_balanceswith thesession_id
If POKE_WEBHOOK_URL and POKE_API_KEY are set, a webhook is sent to Poke when a bank account is successfully connected (for both providers).
Session Store
Session metadata (authorization IDs, account lists) is stored in an encrypted SQLite database at /data/sessions.db inside the container (or ./sessions.db when running locally via start.sh). The poke-bank-data Docker volume persists this across restarts.
All session data is encrypted with AES-256-GCM using the SESSION_ENCRYPTION_KEY. The key never leaves your server.
Poke Setup
Connect your MCP server to Poke at poke.com/settings/connections. Add the bearer token (MCP_API_KEY) in the connection auth settings.
When a bank account is connected, poke-bank can automatically notify Poke via webhook. Set POKE_WEBHOOK_URL and POKE_API_KEY in .env to enable this.
License
MIT
