Build a fund data app with Cursor or Claude Code in ten minutes
Use an AI coding agent to build a fund comparison page from ISINs. What an AGENTS.md for a financial data API must contain, and the prompts that work.Published 2 September 2026 · 7 min read · by FundFacts APIAI coding agents are good at gluing APIs together and bad at guessing what an API means. Give Cursor or Claude Code a fund data endpoint with no context and it will invent field names, hammer the quota, treat a two-minute cold request as a failure, and put the key in a React component. Give the same agent a well-written AGENTS.md and it builds the right thing on the first prompt. This post shows what that file must contain for a financial data API, then walks through building a fund comparison page with it. We use FundFacts API, whose Pro and Scale plans ship a ready-made AI companion kit, but the structure applies to any API you want agents to use well.
Why agents fail on data APIs
Three things go wrong repeatedly:
- Semantics. The agent sees
"ter": "0.20%"and writesparseFloat(ter) / 100in one place andNumber(ter)in another. It does not know that empty strings mean "not disclosed", that weights are already in percent, or thatprofile.categoryis a stable classification whilekeyFacts.subAssetis display text. - Operational rules. Rate limits, rolling windows, a first request that legitimately takes 15 seconds to 3 minutes, a 24-hour freshness cycle: none of this is visible from a JSON sample, so the agent sets a 10 s timeout, retries in a loop and burns the quota.
- Design choices. Asked for "a comparison page", the agent needs to know which fields belong in a comparison and which do not. Without guidance it shows the first ten keys it finds.
An AGENTS.md fixes all three by being the document the agent reads before writing code. Most agents pick it up automatically from the project root: Cursor, Claude Code, OpenAI Codex, GitHub Copilot's coding agent, Windsurf and Gemini CLI all look for it.
What a good AGENTS.md for a data API contains
The kit's AGENTS.md is about 500 lines, generated from the same field reference that renders the documentation. Its sections, in the order an agent should read them:
| Section | What it settles |
|---|---|
| What the API is, and is not | One endpoint, ISIN in, factsheet out. No search, no bulk: iterate the user's ISINs. |
| Setup and the key | Read FUNDFACTS_API_KEY from the environment (or the embedded key), ask the user if missing, never ship it client-side. |
| Endpoint and envelope | Every top-level key (cached, expiresAt, quota...) with its type and meaning. |
| Plan and rate limits | The user's actual plan and window, the X-RateLimit-* headers, what counts as a request. |
| Freshness and latency | Warm vs cold ISINs, the 300 s timeout, "never fire the same request twice", cache locally until expiresAt. |
| Errors | Each status and code with the one correct reaction (retry 502 twice, never retry 4xx, 404 means "not a fund"). |
| Field reference | All 74 fields of data as tables, with examples, grouped by identity, risk, portfolio, performance, metrics, freshness. |
| Rules for agents | Nine numbered rules the agent must respect, from "show dataAsOf next to figures" to "do not scrape any site as a workaround". |
| Reference client | A 40-line TypeScript client with timeout, in-memory cache and typed errors, plus a Python equivalent. |
| Recipes | Comparison table, portfolio look-through, screener, factsheet page, change monitor, export: each with the exact fields to use and the pitfalls. |
Two design points are worth copying whatever API you document. First, tell the agent what not to do: the rules section prevents most of the expensive mistakes (scraping, hard-coded keys, tight retry loops). Second, give it recipes, not just a schema: when a user asks for "a comparison page", the agent should recognise the recipe and follow it rather than design from scratch.
The kit adds three companions to AGENTS.md: a Cursor rule (.cursor/rules/fundfacts-api.mdc) and a Claude Code skill (.claude/skills/fundfacts-api/SKILL.md) that restate the hard rules in each tool's native format and point back to the long document, an OpenAPI 3.1 spec for client generators and MCP servers, and a fundfacts.d.ts with typed FundResponse and FundData.
Step 1: get the kit into the project
From the dashboard (Pro or Scale), choose a key mode and download fundfacts-agent-kit.zip:
- Environment variable (default): the files reference
FUNDFACTS_API_KEY. Safe to commit; the agent asks you for the key and writes it to.env.local. - Embedded key: a dedicated key named "AI companion kit" is created and written into the files. Zero setup, but keep those files out of shared repositories (a
.gitignore.snippetis included) and revoke the key from the keys panel when you are done.
Unzip at the root of a fresh Next.js project:
bashnpx create-next-app@latest fund-compare --ts --app --no-tailwind --eslint --src-dircd fund-compareunzip ~/Downloads/fundfacts-agent-kit.zipecho "FUNDFACTS_API_KEY=ffk_..." >> .env.local # env mode only
Open the folder in Cursor or start claude in it. Both tools see AGENTS.md immediately; Cursor also loads the rule, Claude Code the skill.
Step 2: the first prompt
Be explicit about the recipe and the ISINs, and say where the key is. This prompt reliably produces a working page:
What the agent does with the kit in place, and would not do without it:
- Creates
src/lib/fundfacts.tsfrom the reference client: 300 s timeout, bearer header, a typedFundFactsError, and a JSON-file cache keyed by ISIN withexpiresAt. - Fetches the three ISINs sequentially (the recipe says "3 in parallel at most", and it knows a cold ISIN is slow).
- Picks the fields the recipe lists:
data.headlineMetrics.ter,data.riskRating, the1 Yearand3 Years p.a.entries ofdata.annualisedReturns,data.headlineMetrics.volatility3y,data.metrics.maxDrawdown, the first three ofdata.sector. - Keeps formatted strings as published (
"0.20%"stays"0.20%") and footnotes each row withdata.dataAsOf, both from the rules section. - Handles
404 fund_not_foundas "not a covered fund" with a visible message, and does not retry it.
The result is about 150 lines across three files, in three to five minutes including the first cold load.
Step 3: iterate with the recipes
Once the client exists, follow-up prompts are short because the agent already knows the vocabulary:
- "Add a portfolio look-through: I hold 50/30/20 in these three. Aggregate sector and country exposure." The look-through recipe tells it to multiply each fund's weights by the portfolio weight and to caveat that top holdings are a lower bound.
- "Turn each row into a factsheet page at /fund/[isin] with the growth chart." The factsheet recipe fixes the section order and says to plot
indexedPerformance.pointsand only draw the index line whenhasIndexis true. - "Add a nightly job that refreshes the payloads and e-mails me when a TER or risk rating changes." The change monitor recipe lists exactly which fields to diff.
- "Export the comparison as CSV." The export recipe explains how to flatten dotted keys and serialise arrays.
Each of these is a one-line prompt because the design decisions are already written down.
Prompts that work, prompts that do not
Works: naming the recipe; listing ISINs explicitly; stating where the key is; asking for the loading state up front; asking the agent to "follow the rules in AGENTS.md section 8" when you review its code.
Does not work: "fetch all funds" (there is no list endpoint; give it ISINs); "make it real-time" (payloads refresh every 24 hours; the agent will say so if you ask, but it is better not to ask); "show everything" (74 fields is not a UI, pick a recipe).
If the agent ever proposes to scrape a fund website or a data vendor to fill a gap, that is the cue that it has not read the file: point it at rule 5 and it will stop.
Using the kit outside Cursor and Claude Code
- OpenAI Codex and Copilot coding agent read
AGENTS.mdfrom the repository root; nothing else to do. - Windsurf, Gemini CLI, Aider and most others either read
AGENTS.mdor accept it as a context file. - ChatGPT / Claude in a browser: paste
AGENTS.mdinto the conversation before asking for code. It is long, but it is the whole point. - Client generators and MCP servers: feed
openapi.yamlto openapi-generator, Kiota, Stainless or an OpenAPI-to-MCP bridge to exposegetFundas a tool a chat agent can call directly.
Regenerate when the API grows
The kit is built from the live field reference at download time, so when new fields appear in the documentation, download it again and replace the files. Because your project's code was written against named fields with the semantics spelled out, additions never break it; the agent simply has more to work with.
Ready to try it? Create a free account to explore the API, then upgrade to Pro to download the kit from your dashboard.