Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Tool-Plaidsync my checking account transactions from the last 30 days"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Tool-Plaid: MCP Server for Plaid
MCP (Model Context Protocol) server tool that exposes two tools for interacting with Plaid's financial data API:
sync_transactions- Retrieve and sync transaction dataget_balance- Get account balances
Installation
Development Installation
# Clone the repository
git clone https://github.com/reilly3000/tool-plaid.git
cd tool-plaid
# Install in development mode
pip install -e .
# Or with uv (recommended)
uv pip install -e .Production Installation
pip install tool-plaid
# or with uv
uv pip install tool-plaidConfiguration
Environment Variables
Create a .env.agent file in the project root (ignored by git) or set environment variables:
# Plaid Configuration
PLAID_ENV=sandbox|production
PLAID_CLIENT_ID=<your_client_id>
PLAID_SECRET=<your_secret>
# Security
ENCRYPTION_KEY=<your_32_byte_encryption_key>
# Storage
STORAGE_MODE=file|postgres
DATABASE_URL=postgresql://user:pass@host:port/dbname # required if STORAGE_MODE=postgres
# MCP Server
MCP_TRANSPORT=stdio|streamable-http
MCP_PORT=8000
# Caching (optional)
BALANCE_CACHE_TTL=300 # seconds, default: 300 (5 minutes)Example .env File
# Sandbox Environment
PLAID_ENV=sandbox
PLAID_CLIENT_ID=62eacf714206f30013d6e722
PLAID_SECRET=6f85aa5808d484246313470945c515
# Generate a random 32-byte key
ENCRYPTION_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
# Start with file storage
STORAGE_MODE=fileUsage
Running the Server
Local Development (STDIO)
# Set environment
export PLAID_ENV=sandbox
export PLAID_CLIENT_ID=<your_client_id>
export PLAID_SECRET=<your_secret>
export STORAGE_MODE=file
# Run with uv
uv run plaid-tool
# Or directly
python -m tool_plaidProduction (Streamable HTTP)
export PLAID_ENV=production
export DATABASE_URL=postgresql://...
export STORAGE_MODE=postgres
export MCP_TRANSPORT=streamable-http
# Run HTTP server
plaid-toolConfiguration with Claude Desktop
Add this to your MCP configuration file (e.g., claude_desktop_config.json):
{
"mcpServers": {
"plaid": {
"command": "plaid-tool",
"env": {
"PLAID_ENV": "sandbox"
}
}
}
}Tools
sync_transactions
Sync transactions from Plaid using cursor-based incremental updates.
Parameters:
item_id(required): Plaid item identifierforce_refresh(optional, default=False): Trigger Plaid refreshdays_requested(optional, default=90, range 1-730): Days of history
Returns:
{
"added": [
{
"transaction_id": "string",
"account_id": "string",
"amount": 100.50,
"date": "2025-01-15",
"merchant_name": "Merchant Name",
"category": "Food and Drink",
"pending": false
}
],
"modified": [...],
"removed": ["transaction_id_1", "transaction_id_2"],
"next_cursor": "cursor_string",
"has_more": false,
"item_status": "HISTORICAL_UPDATE_COMPLETE",
"summary": "Added 10, modified 2, removed 1 transactions"
}get_balance
Get account balances with intelligent caching.
Parameters:
item_id(required): Plaid item identifieraccount_ids(optional, default=None): Filter specific accountsforce_refresh(optional, default=False): Bypass cache
Returns:
{
"balances": [
{
"account_id": "string",
"name": "Plaid Checking",
"mask": "0000",
"type": "depository",
"available": 1000.00,
"current": 1250.00,
"iso_currency_code": "USD"
}
],
"cached": true,
"timestamp": "2025-01-15T10:30:00Z"
}Architecture
Storage Modes
File Storage (Development)
JSONL files for transactions
Simple key-value cursor tracking
Text-based balance snapshots
Directory:
data/items/{item_id}/
PostgreSQL (Production)
Async PostgreSQL with asyncpgres
Tables:
access_tokens,transactions,balances,cursorsConnection pooling
Migrations via alembic
Security
AES-256 encryption for access tokens at rest
Encryption key from environment variable
No logging of sensitive data (tokens, raw responses)
Audit logging without sensitive data
Development
Running Tests
# Unit tests
pytest tests/ -v
# With coverage
pytest --cov=tool_plaid --cov-report=htmlEnd-to-End Testing (Sandbox)
Open
tests/plaid_link_test.htmlin a browserLink a test bank using credentials:
user_good/pass_goodCopy the public token and run:
python tests/test_e2e.py <PUBLIC_TOKEN>Note: Public tokens expire after ~30 minutes.
Quick Verification
# Check config loads
python -c "from tool_plaid.config import Config; c = Config.load(); print(c.PLAID_CLIENT_ID)"
# Test encryption
python -c "from tool_plaid.utils.encryption import Encryptor; from tool_plaid.config import Config; e = Encryptor(Config.load().ENCRYPTION_KEY); print(e.decrypt(e.encrypt('test')))"Code Quality
# Format code
black tool_plaid
# Lint
ruff check tool_plaid
# Type check
mypy tool_plaidLicense
MIT
Support
For issues and questions, please open an issue on GitHub.