AI agents

Financial data an agent can discover on its own.

Most financial APIs assume a human reads the docs and writes the client. This one publishes an MCP server with 15 tools, an OpenAPI 3.1 document, an llms.txt and two .well-known descriptors — so the model finds the surface, and you spend your time on the agent instead of on tool wrappers.

who this is for

The hard part isn't the model. It's grounding.

Teams shipping an agent that has to reason about somebody's money

An assistant that talks about money without seeing any is a liability. It invents balances, misremembers what recurs, and answers “can I afford this” with vibes. The fix is not a bigger context window — it is a connection to the real account and a set of tools the model can call with confidence.

That normally means building the whole aggregation stack first: provider integrations, a Link flow, token storage, normalization, a sync loop, then a tool wrapper for each read your agent might want. Weeks of work before the agent says anything true.

Here the tool layer is the product surface. Point an MCP client at one URL with your key and the tools are already defined, typed and metered. If your framework prefers OpenAPI, the same endpoints are described in an OpenAPI 3.1 document you can hand to a generator. If it prefers plain text, there is an llms.txt.

what you'd call

The endpoints this actually uses.

An agent usually lives in the MCP tools, but they are a facade over the same REST endpoints — so anything an agent can do, your backend can do the same way.

Endpoints used by ai agents and assistants integrations
POST/mcpMCP server over Streamable HTTP; GET returns the descriptor
POST/v1/institutions/searchFind the institution before the hand-off
POST/v1/link/token/createMint the URL the user completes in a browser
POST/v1/link/token/exchangepublic_token → access_token, once they finish
POST/v1/transactions/syncCursor deltas the agent can call repeatedly
POST/v1/ai/cashflowA grounded forecast rather than a guess
POST/v1/ai/purchase-analysisCan they afford this, and what it costs them
POST/v1/ai/health-score0–100 with explainable subscores to quote

in code

What the integration looks like.

Three ways in, all authenticated by the same secret key: an MCP client config, raw JSON-RPC over HTTP, and the Node SDK when the agent runs behind your own server.

jsonmcp-client-config.json
{  "mcpServers": {    "feelconnect": {      "type": "http",      "url": "https://connect.feels.money/mcp",      "headers": {        "Authorization": "Bearer fc_sk_test_…"      }    }  }}
bashJSON-RPC over Streamable HTTP
# List the tools. Streamable HTTP speaks JSON-RPC 2.0 over one URL,# and the same secret key authenticates it as authenticates /v1.curl https://connect.feels.money/mcp \  -H "Authorization: Bearer $FEELCONNECT_SECRET_KEY" \  -H "Content-Type: application/json" \  -H "Accept: application/json, text/event-stream" \  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' # Then call one. Nothing here is FeelConnect-specific plumbing —# it is the MCP call your framework already knows how to make.curl https://connect.feels.money/mcp \  -H "Authorization: Bearer $FEELCONNECT_SECRET_KEY" \  -H "Content-Type: application/json" \  -H "Accept: application/json, text/event-stream" \  -d '{    "jsonrpc": "2.0",    "id": 2,    "method": "tools/call",    "params": {      "name": "sync_transactions",      "arguments": { "access_token": "fc_at_…", "count": 100 }    }  }'
tsagent-tools.ts
import { FeelConnect } from "@feelconnect/node"; const fc = new FeelConnect({  apiKey: process.env.FEELCONNECT_SECRET_KEY!,  baseUrl: "https://connect.feels.money/v1",}); // The two calls that turn "can it see my money" into a yes.// Step 1 happens on your server; the user completes Link in a browser.const { link_token } = await fc.link.createToken({  user: { client_user_id: userId },  products: ["transactions", "balances", "recurring"],  client_name: "Your assistant",}); // Step 2, after Link returns a public_token to your callback.const { access_token } = await fc.link.exchangeToken({ public_token }); // From here the agent has grounded facts instead of guesses.const { forecast, engine } = await fc.ai.cashflow({  access_token,  horizon_days: 30,}); // engine is "rules" | "ai" | "ai+rules" — so the agent can tell the user// whether a number came from arithmetic or from a model.console.log(engine, forecast);

what you get

Mechanisms, in the order you would meet them.

  1. 15 tools, already typed

    search_institutions, create_link_url, exchange_public_token, get_item, list_accounts and 10 more — each with a described argument list, so a model picks the right one without you writing a schema.
  2. Discovery without documentation

    /mcp, /openapi.json, /llms.txt, /llms-full.txt, /.well-known/mcp.json, /.well-known/ai-plugin.json — every one of them a live route, not a PDF.
  3. Credentials never reach the agent

    The Link hand-off happens in the user's browser. Your agent gets an opaque fc_at_… token and nothing else, and the token is stored as a SHA-256 hash on our side.
  4. Answers that can cite themselves

    Every AI response carries an engine field, and the rules-first design means a model outage degrades to deterministic answers instead of an error.
  5. Metered like everything else

    MCP calls count as API requests; AI tools also consume the AI quota. No separate agent SKU, no separate key, no surprise.
  6. The sandbox is agent-shaped

    Deterministic data means an eval suite that does not drift: the same connection returns the same 24 months every time you run it.

questions

Straight answers.

Give the model something true to work with.

Point your MCP client at one URL with a sandbox key and watch it search institutions, connect an account and read two years of transactions — before you write a line of tool code.

The sandbox needs no approval and no card. You can have the shapes in front of you in a few minutes and decide from there.