Plaid MCP server for AI agents

Live

API KEY

BANKING DATA

Accounting & Finance

Plaid gives your agent banking data for the Items your app has linked: read accounts and real-time balances, sync and pull transactions, check identity and account numbers, and read investments, liabilities, and statements.

  • Per-user credentials: each call uses the actual user's API key, never a shared bot.
  • Encrypted per-tenant vault: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: pre-call scope check, 90-day SIEM-exportable audit chain.
Plaid
agent · Acme Q3
Run
What recurring payments show up on this customer's checking account?
S
plaid_transactions_recurring_get
141ms
Banking data agent
8 recurring outflows, including $2,150 rent and 4 subscriptions totaling $63 a month. Salary arrives every 2 weeks.
Sources: 1 Item, recurring streams
plaid
8 streams
18:29
Message Claude...

Tools your banking data agent reaches for on Plaid, scoped per user.

CALL ANY TOOL
27 tools for banking data on Plaid: read accounts, balances, and account numbers, sync and refresh transactions, check identity, read investments, liabilities, and statements, and manage Items and Link tokens.
plaid_accounts_balance_get
Get accounts balance
Get real-time balances for an Item's accounts by fetching fresh data from the institution. Returns accounts with balances (available, current, limit, iso_currency_code, last_updated_datetime) and item. Use plaid_accounts_balance_get before moving money or whenever balances must be current. Each call is billed and usually takes under 10 seconds, sometimes 30 or more. Use plaid_accounts_get for free cached balances.
Parameters
Name
Type
Required
Description
access_token
string
Required
The Item's access_token, returned by plaid_item_public_token_exchange after the end user links an account with Plaid Link. It starts with access-production-. Example: access-production-de3ce8ef-33f8-452c-a685-8671031fc0f6.
account_ids
array
Optional
Limit the accounts returned to these account_ids, from plaid_accounts_get. Leave empty for all of the Item's accounts. Plaid returns an error if an id does not belong to the Item. Example: ["BxBXxLj1m4HMXBm9WZZmCWVbPjX16EHwv99vp"].
min_last_updated_datetime
string
Optional
Oldest acceptable balance time, ISO 8601 (YYYY-MM-DDTHH:mm:ssZ). Only needed for institutions that do not return real-time balances (for example Capital One); Plaid returns an error if its balance is older. Example: 2026-10-20T00:00:00Z.
plaid_accounts_get
Get accounts
plaid_auth_get
Get auth
plaid_identity_get
Get identity
plaid_identity_match
Identity match
plaid_institutions_get
Get institutions
plaid_institutions_get_by_id
Institutions get by id
plaid_institutions_search
Search institutions
plaid_investments_holdings_get
Get investments holdings
plaid_investments_refresh
Refresh investments
plaid_investments_transactions_get
Get investments transactions
plaid_item_access_token_invalidate
Item access token invalidate
plaid_item_get
Get item
plaid_item_public_token_exchange
Item public token exchange
plaid_item_remove
Remove item
plaid_item_webhook_update
Update item webhook
plaid_liabilities_get
Get liabilities
plaid_link_token_create
Create link token
plaid_link_token_get
Get link token
plaid_statements_list
List statements
plaid_statements_refresh
Refresh statements
plaid_transactions_get
Get transactions
plaid_transactions_recurring_get
Get transactions recurring
plaid_transactions_refresh
Refresh transactions
plaid_transactions_sync
Sync transactions
plaid_user_create
Create user
plaid_user_remove
Remove user
Build your Agent
Same auth pattern across LangChain, OpenAI, Anthropic, and Google ADK.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

// Plaid tools scoped to this user
const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["plaid"], toolNames: [
    "plaid_accounts_balance_get",
    "plaid_transactions_sync",
    "plaid_transactions_recurring_get"] },
  pageSize: 100,
});

const agent = createReactAgent({ llm, tools });
await agent.invoke({ messages: [{ role: "user", content: "Get this Item's balances, sync new transactions, and list its recurring payments" }] });
import OpenAI from "openai";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["plaid"] }, pageSize: 100,
});

const res = await openai.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Get this Item's balances, sync new transactions, and list its recurring payments" }],
  tools,
});

// Execute the tool call with the user's vaulted Plaid API key
await sk.tools.executeTool(res.choices[0].message.tool_calls[0], "user_123");
import Anthropic from "@anthropic-ai/sdk";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["plaid"] }, pageSize: 100,
});

const msg = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Get this Item's balances, sync new transactions, and list its recurring payments" }],
  tools,
});

// Tool call runs with the user's vaulted Plaid API key
await sk.tools.executeTool(msg.content, "user_123");
import { Agent } from "@google/adk/agents";
import { ScalekitClient } from "@scalekit-sdk/node";

const sk = new ScalekitClient(env.SCALEKIT_ENV_URL, env.SCALEKIT_CLIENT_ID, env.SCALEKIT_CLIENT_SECRET);

const { tools } = await sk.tools.listScopedTools("user_123", {
  filter: { connectionNames: ["plaid"] }, pageSize: 100,
});

const agent = new Agent({
  name: "banking_data_agent",
  model: "gemini-2.5-pro",
  instruction: "Plaid tools scoped to this user",
  tools,
});

await agent.run("Get this Item's balances, sync new transactions, and list its recurring payments");
Try these prompts
Copy any prompt into your agent. Each maps directly to a Plaid tool. Click to copy, paste into your agent, done.
Accounts and balances
Copy the prompt
Copied
Get real-time balances for this Item's accounts.
Copy the prompt
Copied
Show the account and routing numbers for this Item's checking account.
Copy the prompt
Copied
Does this applicant's name and address match the bank's records?
Transactions
Copy the prompt
Copied
Sync new transactions for this Item since the last cursor.
Copy the prompt
Copied
List this Item's transactions from the last 90 days.
Copy the prompt
Copied
Find the recurring deposits and payments on this Item.
Items and Link
Copy the prompt
Copied
Create a Link token so a new user can connect their bank.
Copy the prompt
Copied
Check the status of this Item.
Copy the prompt
Copied
Search Plaid's supported institutions for Chase.
SEE HOW AUTH WORKS
Each user connects their own Plaid API key once, and Scalekit sends it with every call. Keys stay vaulted, every call is scope checked, and every action is logged.
1
Authorize
Your user connects
Plaid
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
Plaid
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
Plaid
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
Plaid
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
See the same per-user auth pattern across other accounting and finance connectors.
GTM and RevOps Teams
Revenue forecast commentary
Pulls open pipeline from Salesforce and HubSpot, calculates coverage against quota, flags at-risk stages, posts commentary to Slack, and logs every snapshot to Google Sheets.
Test other agents
See the same per-user auth pattern across other accounting and finance connectors.
GTM
Revenue forecast agent
Score pipeline coverage against quota across Salesforce and HubSpot, post forecast commentary to Slack, log snapshots to Sheets.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared Plaid API key looks fine in a demo. In production every balance check and transaction sync looks like one service account, and you cannot tell which user triggered it. Scalekit resolves the credential of the actual user who triggered the agent, never a shared bot.
// shared key
audit → bot_service_account

// scalekit
audit → user_abc ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
Plaid today. Ten connectors tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent access Plaid as the user or through a shared API key?
As the user. Each user connects their own Plaid API key once, and Scalekit sends it with every call. Audit logs attribute every balance check and transaction sync to that user, not a shared service account.
Where is the Plaid API key stored?
In Scalekit's managed AES-256 token vault, namespaced per tenant. To rotate it, the user reconnects with a new API key. Revocation is a single dashboard action. Credentials never appear in prompts, logs, or LLM context.
Can I limit what the agent does in Plaid?
Yes. Filter by tool name in listScopedTools to expose only what you want, for example the account, balance, and transaction tools without plaid_item_remove, which removes an Item for good, or plaid_user_remove, which deletes a Plaid user and every Item linked to it. Scalekit also enforces scope checks before every API call.
What happens when a user revokes Plaid access?
The connection is invalidated on the next tool call. Subsequent requests for that user fail closed with a clear error. Other users in the tenant remain unaffected. The event is logged for audit.
Does the Plaid connector use real bank data?
Yes. It uses your Plaid client ID and Production secret and calls Plaid's Production environment, so your Plaid team needs Production approval from Plaid. The tools read and manage Items your app has already linked through Plaid Link.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""plaid"": {
""url"": ""https://mcp.scalekit.com/plaid"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.plaid]
url = ""https://mcp.scalekit.com/plaid""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""plaid"": {
""url"": ""https://mcp.scalekit.com/plaid"",
""type"": ""http""
}
}
}