Setup & developer reference
Connect Claude, ChatGPT, or any MCP-compatible client to your bank accounts. Steps 1–4 below walk through the setup; the rest of the page is the full API and SQL reference for developers building on top of FinContext.
Free during the public beta. $4.99/month per user planned after beta. No usage metering, no per-call fees.
Read-only Plaid access. Row-level isolation in Postgres. Delete your data anytime. No data resale.
Read-only bank data for analysis agents. Not for payments, transfers, or account actions.
Step 1 — Create an account
Sign up at /signup to get FinContext credentials. Step 2 covers picking the right auth model for your AI client. Building an agent that signs users up on their behalf? Use the programmatic flow below.
Programmatic signup (for agent developers)
- Call
POST /api/agent-signupto onboard a user and get back a token ready for MCP:curl -X POST https://fincontext.ai/api/agent-signup \ -H "Content-Type: application/json" \ -d '{"email": "[email protected]", "password": "securepass", "display_name": "Jane", "us_resident": true, "agent_name": "Claude Desktop tax prep"}' - Returns:
{"user_id": "...", "api_token": "fc_...", "mcp_endpoint": "https://fincontext.ai/mcp"} - User already has an account? Call
POST /api/agent-logininstead — same body shape, mints a fresh token, also returnsplan_tier:curl -X POST https://fincontext.ai/api/agent-login \ -H "Content-Type: application/json" \ -d '{"email": "[email protected]", "password": "securepass", "agent_name": "Claude Desktop tax prep"}' - Field reference:
display_name— identifies the human user. Up to 100 characters.agent_name(optional, both endpoints) — self-declared label for the agent, e.g."Claude Desktop"or"claude-cli on workstation-2". Becomes the name of the issued token so users can audit and revoke individual sessions.- Allowed
agent_namecharacters: Unicode letters and digits, spaces, and- _ . , ' ( ) :. Up to 100 chars. Reserved names (agent-default,agent-login) and HTML/control characters are rejected with a 400.
- Security notification: every successful sign-in — via
/api/agent-login(token flow) or/oauth/tokenwithgrant_type=authorization_code(OAuth flow) — emails the account owner with the agent/client name, timestamp, IP, device, and a revocation link. Token refreshes don't trigger the email.
Step 2 — Connect your AI client
Two auth models. Pick the row that matches your client, then jump to the matching setup path below.
| Auth model | Use when your client is | What you do |
|---|---|---|
| OAuth | Claude Desktop, Claude.ai, ChatGPT, Hermes Agent | Add a custom connector with the URL https://fincontext.ai/mcp and sign in. No tokens to copy. Setup steps: Claude Desktop & Web · ChatGPT · Hermes |
| Token | Claude Code (CLI), mcp-remote, OpenClaw, custom MCP clients |
Generate a token at /api-tokens (sign in first if you haven’t) and paste it into the client config. Setup steps: Claude Code · mcp-remote · OpenClaw |
Claude Desktop & Claude.ai Web (Custom Connector)
- OAuth-based. Best for most personal users.
- Added in either Claude Desktop or claude.ai, it may sync to the other when you're signed into the same Anthropic account.
Steps:
- Open Claude Desktop or claude.ai → Settings → Connectors → Add custom connector.
- Enter
https://fincontext.ai/mcpas the remote MCP server URL. - Claude opens FinContext's authorize page in your browser. If you're not signed in yet, use the email and password you set at /signup.
- Click Approve. Claude receives an
fco_access token and completes setup.
- Verify: open a new chat and ask the agent to list its tools — you should see all 10 FinContext tools (
balances,transactions,status, …). - Troubleshooting:
- Inline login fails? Confirm your credentials work against
POST /api/agent-login. fco_tokens expire after 1 hour and auto-refresh — no manual rotation.
- Inline login fails? Confirm your credentials work against
- Free tier: Claude Free includes 1 Custom Connector slot. Pro / Max / Team / Enterprise allow more.
ChatGPT (Custom Connector)
- OAuth-based. Available on all ChatGPT tiers (Free, Plus, Pro, Business, Enterprise).
- Same flow as Claude's Custom Connector.
Steps:
- In ChatGPT, open Settings → Connectors. Don't see an Add / Create option? Open Settings → Apps & Connectors → Advanced settings and enable Developer mode.
- Click Create (or Add custom connector) and enter
https://fincontext.ai/mcp. - ChatGPT opens FinContext's authorize page. Sign in, click Approve.
- ChatGPT receives an
fco_access token and completes setup.
- Verify: start a new chat and ask ChatGPT to list its FinContext tools — all 10 should appear.
- Developer mode: ChatGPT gates user-added MCP servers behind this toggle. On managed accounts (Business / Enterprise), your workspace admin may have it disabled — contact them if the option is greyed out.
- Troubleshooting:
- OAuth handshake fails? Confirm your credentials work against
POST /api/agent-login. - ChatGPT does not support static
fc_tokens. For token-header auth, use Claude Code or mcp-remote instead.
- OAuth handshake fails? Confirm your credentials work against
Claude Code (CLI)
- Best for developers and automated agents.
- Uses a static
fc_token — no browser session required.
Steps:
- Run:
claude mcp add --transport http --scope user fincontext https://fincontext.ai/mcp \ --header "Authorization: Bearer fc_..." --scope usermakes the connection available across all projects. Drop it for per-project scope.
- Verify:
claude mcp listshould showfincontextasconnected.- Call the
statustool — response should includedata.onboarding.
- Troubleshooting:
- Status shows
failed? Re-runclaude mcp addwith the correctAuthorizationheader. - Regenerated your token? Re-add the server — there's no in-place update.
- Status shows
mcp-remote Bridge (Claude Desktop fallback)
- For users who prefer file-based config or can't use Claude's Custom Connector.
- The third-party
mcp-remotenpm package injects a staticfc_token without OAuth.
Steps:
- Edit
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) or%APPDATA%\Claude\claude_desktop_config.json(Windows):{ "mcpServers": { "fincontext": { "command": "npx", "args": [ "mcp-remote", "https://fincontext.ai/mcp", "--header", "Authorization: Bearer fc_..." ] } } } - Restart Claude Desktop.
- Verify: ask the agent to call
status— response should includedata.onboarding. - Security:
- This file contains a long-lived credential.
- On macOS, run
chmod 600 ~/Library/Application\ Support/Claude/claude_desktop_config.json. - Never commit this file.
- Troubleshooting:
- Invalid JSON is the most common failure — validate with
jq . < claude_desktop_config.json. - On Windows,
mcp-remotehas a known bug parsing args with spaces (theBearerprefix). Upgrade to the latestmcp-remoteor use Claude Code.
- Invalid JSON is the most common failure — validate with
Hermes Agent (CLI)
- NousResearch's Hermes connects to remote MCP servers over streamable HTTP and supports OAuth — no token to copy.
- Hermes has no server registry; you add FinContext directly by URL.
Steps:
- Add the server with OAuth:
hermes mcp add fincontext --url https://fincontext.ai/mcp --auth oauth - Hermes opens FinContext's authorize page in your browser. Sign in with your /signup credentials and click Approve.
- Verify: Hermes probes the server on add and registers its tools — you should see all 10 FinContext tools. Ask the agent to call
status. - Prefer a static token? Edit
~/.hermes/config.yamland add anfc_token from /api-tokens underheadersinstead of using OAuth:mcp_servers: fincontext: url: "https://fincontext.ai/mcp" headers: Authorization: "Bearer fc_..." - Troubleshooting: OAuth handshake fails? Confirm your credentials work against
POST /api/agent-login, or fall back to the token config above.
OpenClaw
- OpenClaw stores MCP servers as local config — no registry, no discovery. You add FinContext by URL with a static
fc_token.
Steps:
- Generate a token at /api-tokens (sign in first), then run:
openclaw mcp set fincontext '{ "url": "https://fincontext.ai/mcp", "transport": "streamable-http", "headers": { "Authorization": "Bearer fc_..." } }' - Confirm it saved:
openclaw mcp listshould showfincontext.
- Verify: start an OpenClaw session and ask it to call
status— the response should includedata.onboarding. - Security: this config holds a long-lived credential. Don't commit it or paste it into shared chats. Rotate at /api-tokens if exposed.
- Note:
openclaw mcp setonly saves config — it doesn't test reachability. If tools don't appear, re-check the URL and token.
Step 3 — Link your bank
- Your client is connected to FinContext, but no bank accounts are linked yet.
- Ask the agent to call the
link_banktool (no arguments):{"jsonrpc": "2.0", "method": "tools/call", "params": {"name": "link_bank", "arguments": {}}} - It returns a Plaid Hosted Link URL:
{"hosted_link_url": "https://hosted.plaid.com/..."} - Open the URL in a browser, then:
- Sign in to your bank.
- Choose which accounts to share.
- Confirm.
- FinContext receives read-only access — we never see your banking credentials and can't move money.
Step 4 — Start querying
- Ask the agent to call the
statustool and wait untildata.onboarding == "ready":{"data": {"onboarding": "ready", "accounts_linked": true, "num_accounts": 3, "institutions": [...]}} - Still
"pending"? Plaid hasn't finished the initial sync yet — wait a few seconds and retry. - Once
ready, all 10 MCP tools are available. Try one of these to confirm:- "What's my balance across all accounts?" → agent calls
balances. - "How much did I spend on groceries last month?" → agent calls
statwith a SQL query. - "What are my recurring subscriptions?" → see the Subscription Audit prompt for a full workflow.
- "What's my balance across all accounts?" → agent calls
- Next:
- MCP Tools — full tool list.
- SQL Analytics — the
statquery language. - Prompt Examples — ready-to-paste agent instructions.
- Token rotation:
fc_tokens (Claude Code, mcp-remote) are long-lived — regenerate means re-paste everywhere.fco_tokens (Claude Custom Connector, ChatGPT Connector) expire hourly and auto-refresh — don't rotate manually.
MCP Tools
FinContext exposes 10 MCP tools. Each tool accepts its own arguments directly; call help to discover any tool's parameters at runtime.
balances— Get current account balancestransactions— Search and filter transactions by date, category, account, amountcategories— List all available spending categoriesupdate— Override merchant name or category for a transactionstat— Run SQL analytics queries against virtual tableshelp— Show available tools and detailed usagelink_bank— Generate a Plaid Hosted Link URL to connect a bank accountstatus— Check if bank accounts are linkedsync— Pull latest transactions and balances from Plaid (async, returns immediately)feedback— Send bug reports, feature requests, or praise to the FinContext team
MCP Handshake
MCP clients connect via a standard JSON-RPC 2.0 handshake:
1. Initialize
POST /mcp
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}}
Returns server info, protocol version, and instructions listing all available tools.
2. List tools
{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}
Returns all 10 tool definitions with their per-tool annotations (readOnlyHint, openWorldHint, etc.) and JSON Schemas.
3. Call a tool
{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {
"name": "help",
"arguments": {}
}}
Start with the help tool to discover all tools and their parameters at runtime. Pass subcommand to get details for a specific tool:
{"name": "help", "arguments": {"subcommand": "stat"}}
SQL Analytics (stat)
The stat tool lets agents run SQL SELECT queries against virtual financial tables. Write standard PostgreSQL SQL; FinContext validates, rewrites, and executes it safely within the user's RLS scope.
Virtual Tables
Use DESCRIBE to discover schemas at runtime:
{"name": "stat", "arguments": {"query": "DESCRIBE transactions"}}
transactions (excludes pending, pre-joins overrides and accounts):
date DATE Transaction date
amount NUMERIC Positive = spending, negative = income
merchant TEXT Effective merchant name (user override > Plaid)
category TEXT Plaid primary category (user override > Plaid)
detailed_category TEXT Plaid detailed category
account_name TEXT Account nickname
account_type TEXT depository, credit, loan, investment
payment_channel TEXT online, in store, etc.
month TEXT YYYY-MM (derived from date)
is_income BOOL True when category = 'INCOME'
is_transfer BOOL True for transfers and loan payments
balances (daily balance snapshots + live account balances):
snapshot_date DATE Date of balance snapshot
account_name TEXT Account nickname
account_type TEXT depository, credit, loan, investment
current_balance NUMERIC Posted balance
available_balance NUMERIC Available balance
Allowed SQL
- Statements: SELECT only (no INSERT, UPDATE, DELETE, DDL)
- Clauses: GROUP BY, HAVING, ORDER BY, LIMIT, WHERE, subqueries, UNION
- Aggregates: SUM, AVG, COUNT, MIN, MAX, STDDEV
- Functions: ROUND, ABS, date_trunc, to_char, EXTRACT, COALESCE, LOWER, UPPER, TRIM, LENGTH
- Restrictions: No CTEs (WITH), no self-joins, no system tables, no pg_* functions
- Limits: 1000 rows max, 5-second timeout, 500 KB response cap
Example Queries
-- Spending by category this month
SELECT category, SUM(amount) as total
FROM transactions
WHERE date >= date_trunc('month', CURRENT_DATE)
AND NOT is_income AND NOT is_transfer
GROUP BY category ORDER BY total DESC
-- Find recurring charges (subscriptions)
SELECT merchant, COUNT(*) as n,
ROUND(AVG(amount), 2) as avg_amt,
MIN(date) as first_seen, MAX(date) as last_seen
FROM transactions
WHERE date >= CURRENT_DATE - INTERVAL '12 months'
AND NOT is_income AND NOT is_transfer
GROUP BY merchant HAVING COUNT(*) >= 3
ORDER BY avg_amt DESC
-- Monthly income trend
SELECT month, SUM(ABS(amount)) as income
FROM transactions
WHERE is_income
GROUP BY month ORDER BY month
-- Cash flow: income vs spending by month
SELECT month,
SUM(CASE WHEN is_income THEN ABS(amount) ELSE 0 END) as income,
SUM(CASE WHEN NOT is_income AND NOT is_transfer AND amount > 0
THEN amount ELSE 0 END) as spending
FROM transactions
WHERE date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY month ORDER BY month
Example Agent Workflow
A complete workflow an AI agent follows to answer "Am I spending more than usual?":
- Initialize MCP — Send
initializeto establish the connection and receive the server's instruction text. - Discover capabilities — Call the
helptool to get the full tool list with parameter details. - Get the table schema — Call the
stattool with"DESCRIBE transactions"to learn what columns are available. -
Query this month's spending by category:
{"name": "stat", "arguments": {"query": "SELECT category, SUM(amount) as total FROM transactions WHERE date >= date_trunc('month', CURRENT_DATE) AND NOT is_income AND NOT is_transfer GROUP BY category ORDER BY total DESC" }} -
Query the 3-month average for comparison:
{"name": "stat", "arguments": {"query": "SELECT category, ROUND(SUM(amount) / 3, 2) as avg_monthly FROM transactions WHERE date >= CURRENT_DATE - INTERVAL '3 months' AND date < date_trunc('month', CURRENT_DATE) AND NOT is_income AND NOT is_transfer GROUP BY category ORDER BY avg_monthly DESC" }} - Compare and narrate — The agent compares the two result sets, identifies categories that changed, and presents the answer.
Prompt Examples
Copy these prompts into your AI assistant's custom instructions or system prompt. Each one teaches the agent a complete financial analysis workflow using FinContext's stat tool.
Before using any prompt, the agent should complete the MCP Handshake (initialize → tools/list) and call the help tool to discover available tools.
1. Monthly Spending Review
"How am I doing this month?"
You are a personal finance analyst with access to the user's bank data via FinContext MCP.
When the user asks how they're doing financially this month, follow this workflow:
Step 1: Get this month's spending by category.
Call fincontext stat: SELECT category, SUM(amount) as total FROM transactions
WHERE date >= date_trunc('month', CURRENT_DATE)
AND NOT is_income AND NOT is_transfer
GROUP BY category ORDER BY total DESC
Step 2: Get the 3-month historical average by category.
Call fincontext stat: SELECT category, ROUND(SUM(amount) / 3, 2) as avg_monthly
FROM transactions
WHERE date >= CURRENT_DATE - INTERVAL '3 months'
AND date < date_trunc('month', CURRENT_DATE)
AND NOT is_income AND NOT is_transfer
GROUP BY category ORDER BY avg_monthly DESC
Step 3: Get current balances for context.
Call fincontext balances.
Step 4: Compare and present.
For each category, compute the % change from the 3-month average.
Flag categories that are >20% above average.
Estimate the projected full-month total by scaling:
projected = (this_month_total / days_elapsed) * days_in_month.
Present: total spent so far, how it compares to average, what's driving
any increase, and whether the user is on track to end the month positive.
2. Subscription Audit
"Am I wasting money on subscriptions?"
You are a personal finance analyst with access to the user's bank data via FinContext MCP.
When the user asks about subscriptions or recurring charges, follow this workflow:
Step 1: Find all recurring merchants (3+ charges in 12 months).
Call fincontext stat: SELECT merchant, COUNT(*) as occurrences,
ROUND(AVG(amount), 2) as avg_amount,
ROUND(STDDEV(amount), 2) as amount_variance,
MIN(date) as first_seen, MAX(date) as last_seen
FROM transactions
WHERE date >= CURRENT_DATE - INTERVAL '12 months'
AND NOT is_income AND NOT is_transfer
GROUP BY merchant HAVING COUNT(*) >= 3
ORDER BY avg_amount DESC
Step 2: Classify each recurring charge.
Monthly subscriptions: ~12 occurrences, low variance (stddev/avg < 0.15).
Annual charges: 1-2 occurrences with high amounts.
Frequent purchases: high count but variable amounts (not a subscription).
Step 3: Calculate impact.
Total monthly cost = sum of avg_amount for monthly subscriptions.
Annual cost = monthly * 12 + sum of annual charges.
Step 4: Present findings.
List each subscription with: merchant, monthly cost, how long active.
Highlight any that haven't been charged recently (possibly unused).
Show total monthly and annual subscription cost.
Suggest: "Cutting [X] and [Y] would save $Z/year."
3. Affordability Check
"Can I afford a $2,000 vacation next month?"
You are a personal finance analyst with access to the user's bank data via FinContext MCP.
When the user asks if they can afford a specific expense, follow this workflow:
Step 1: Get current liquid balance.
Call fincontext balances.
Sum all depository account balances (checking + savings).
Step 2: Get average monthly income (last 6 months).
Call fincontext stat: SELECT month, SUM(ABS(amount)) as income
FROM transactions
WHERE is_income AND date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY month ORDER BY month
Step 3: Get average monthly spending (last 6 months).
Call fincontext stat: SELECT month, SUM(amount) as spending
FROM transactions
WHERE NOT is_income AND NOT is_transfer AND amount > 0
AND date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY month ORDER BY month
Step 4: Project next month.
avg_income = average of monthly income values
avg_spending = average of monthly spending values
monthly_surplus = avg_income - avg_spending
projected_balance = current_liquid + monthly_surplus - requested_expense
Step 5: Give a clear yes/no with reasoning.
If projected_balance > 0 and > 1 month of expenses as buffer: "Yes, you can
afford it. You'd have $X remaining, which covers Y months of expenses."
If projected_balance > 0 but thin: "Technically yes, but it would leave you
with only $X buffer. Consider [alternative]."
If projected_balance < 0: "Not comfortably. You'd need to reduce spending
by $X or wait N months to save up."
Always show the math.
4. Spending Diagnosis
"Why does it feel like I'm spending more?"
You are a personal finance analyst with access to the user's bank data via FinContext MCP.
When the user feels they're spending more than usual, follow this workflow:
Step 1: Get current month spending by category.
Call fincontext stat: SELECT category, SUM(amount) as total
FROM transactions
WHERE date >= date_trunc('month', CURRENT_DATE)
AND NOT is_income AND NOT is_transfer
GROUP BY category ORDER BY total DESC
Step 2: Get 3-month average by category.
Call fincontext stat: SELECT category, ROUND(SUM(amount) / 3, 2) as avg
FROM transactions
WHERE date >= CURRENT_DATE - INTERVAL '3 months'
AND date < date_trunc('month', CURRENT_DATE)
AND NOT is_income AND NOT is_transfer
GROUP BY category ORDER BY avg DESC
Step 3: For each category that increased >20%, drill into merchants.
Call fincontext stat: SELECT merchant, SUM(amount) as total,
COUNT(*) as transactions
FROM transactions
WHERE date >= date_trunc('month', CURRENT_DATE)
AND category = '[CATEGORY]'
AND NOT is_income AND NOT is_transfer
GROUP BY merchant ORDER BY total DESC LIMIT 10
Step 4: Present the diagnosis.
Lead with the total: "You've spent $X this month, which is Y% above your
3-month average of $Z."
Then break down the drivers: "Dining out is the biggest increase: $A vs
your usual $B. [Merchant] accounts for $C of that."
Distinguish one-time spikes from trend changes.
End with: "Everything else is in line."
5. Net Worth Progress
"Am I making progress?"
You are a personal finance analyst with access to the user's bank data via FinContext MCP.
When the user asks about their financial progress or net worth, follow this workflow:
Step 1: Get current balances by account type.
Call fincontext balances.
Compute: total_assets (depository + investment), total_liabilities (credit + loan),
net_worth = assets - liabilities.
Step 2: Get historical balance snapshots.
Call fincontext stat: SELECT snapshot_date, account_type,
SUM(current_balance) as balance
FROM balances
WHERE snapshot_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY snapshot_date, account_type
ORDER BY snapshot_date
Step 3: Compute net worth over time.
For each snapshot date, sum assets and subtract liabilities.
Calculate: starting net worth, current net worth, absolute change, % change.
Step 4: Identify what's contributing.
Which account types grew? Which shrank?
Is the growth from saving (depository up) or investing (investment up)?
Is debt going down (credit/loan balances decreasing)?
Step 5: Present the trajectory.
"Your net worth is $X, up $Y (+Z%) over the past 12 months."
"Most of the growth came from [account type]."
"Your [debt type] decreased by $A, which contributed $A to your net worth."
If net worth decreased: be honest, identify the cause, suggest focus areas.
MCP Transport
The /mcp endpoint supports the Streamable HTTP transport (MCP spec 2024-11-05).
Supported methods
POST /mcp— JSON-RPC 2.0 requests. Returnsapplication/jsonby default, ortext/event-stream(SSE) when the client sendsAccept: text/event-stream.GET /mcp— Returns 405 (no server-initiated notifications).DELETE /mcp— Returns 200 (sessionless).
Authentication
Bearer token: Authorization: Bearer fc_... or fco_...
Test with MCP Inspector
npx @modelcontextprotocol/inspector
Documentation
/llms.txt — Quick-reference for AI agents
/llms-full.txt — Full documentation with all endpoints and parameters