Agents & API
FolioFact is agent-native: the same public research you see on the site — 13F holdings, fund portfolios, insider activity, and the tracking universe — is queryable by AI agents through the MCP server and the REST API v1. Everything is read-only, rate-limited, and gated by the same entitlements as the website. See what Pro unlocks.
What agents can do
- Search funds, stocks, and insider owners (
search) - Read fund portfolios and history (
get_fund,fund_holdings,fund_history) - Read stock pages (
get_stock), cited earnings reports (stock_earnings), investor pages (get_investor), and the cross-fund insider feed (insider_feed) - Fetch allowlisted public pages as Markdown (
fetch_page— published blog posts, static pages, and/llms.txt) - Pro: complete earnings analysis plus stock financials, the latest 50 stock-insider transactions, options, and side-by-side comparisons (
stock_earningswithinclude_full,stock_financials,stock_insiders,stock_options,compare_stocks)
MCP and REST use the same read models and cover the same research domains.
Their inventories are intentionally transport-specific: MCP includes
fetch_page, while REST includes catalog and roster endpoints. See the
API reference for REST endpoints and /openapi.yaml for the
machine-readable REST contract.
Connect an MCP client
The MCP server is a stateless Streamable HTTP endpoint at
https://foliofact.com/mcp. Clients use the standard MCP initialize
handshake; FolioFact does not issue a resumable Mcp-Session-Id, so each HTTP
request remains self-contained.
Use that URL exactly — the apex host, no www., no trailing slash. Browser
sign-in identifies this server as https://foliofact.com/mcp, and a client
that was pointed at www.foliofact.com will refuse the mismatch and abort
sign-in rather than fall back.
Claude Desktop
On a Claude plan that supports custom connectors, open Settings →
Connectors → Add custom connector and enter https://foliofact.com/mcp.
Public tools work straight away. When you ask for something that needs your account, Claude shows a Connect prompt, opens FolioFact in your browser, and you approve once — Pro authentication in Claude Desktop uses OAuth and no API key is involved.
ChatGPT
For development testing, follow OpenAI's MCP connection guide:
- Open Settings → Security and login and turn on Developer mode. Availability can depend on your account and workspace policy.
- Open ChatGPT Plugins, select the plus button,
and create a connection to
https://foliofact.com/mcp. - Review the discovered tools, add the connection from the conversation's tools menu, and test a public query.
Anonymous public tools work without a FolioFact key. For account and Pro access, ChatGPT uses OAuth: it registers itself, sends you to FolioFact to sign in, and you approve the connection once. An API key also works if you prefer to configure one directly.
Claude Code
From your terminal:
claude mcp add --transport http --scope user foliofact https://foliofact.com/mcp
For authenticated access, keep the key in an environment variable instead of putting it in shell history:
export FOLIOFACT_API_KEY=ff_YOUR_KEY
claude mcp add-json --scope user foliofact '{"type":"http","url":"https://foliofact.com/mcp","headers":{"Authorization":"Bearer ${FOLIOFACT_API_KEY}"}}'
claude mcp get foliofact
If foliofact already exists, remove or update that entry before adding it
again.
Codex
Anonymous:
codex mcp add foliofact --url https://foliofact.com/mcp
Authenticated:
export FOLIOFACT_API_KEY=ff_YOUR_KEY
codex mcp add foliofact --url https://foliofact.com/mcp --bearer-token-env-var FOLIOFACT_API_KEY
Cursor
Add .cursor/mcp.json at your project root:
{
"mcpServers": {
"foliofact": {
"url": "https://foliofact.com/mcp",
"headers": {
"Authorization": "Bearer ${env:FOLIOFACT_API_KEY}"
}
}
}
}
opencode
Add a remote server to your opencode.json. This is all you need — opencode
detects our OAuth challenge and opens your browser on the first Pro request:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"foliofact": {
"type": "remote",
"url": "https://foliofact.com/mcp",
"enabled": true
}
}
}
Do not add "oauth": false. That switch disables opencode's OAuth
auto-detection, so the sign-in challenge is swallowed and no browser ever
opens — you get an error instead. Omit the key entirely; auto-detection is the
default.
To use an API key instead of browser sign-in, add a headers block:
"headers": { "Authorization": "Bearer {env:FOLIOFACT_API_KEY}" }
Signing in
Anonymous access works with the public tools and the anonymous rate limits. To use your account's entitlements — and the Pro tools, if you're subscribed — there are two ways to sign in. Browser sign-in is the easier one, and most tools do it for you.
1. Browser sign-in (OAuth 2.1) — recommended
Just add the server. When you ask for something that needs your account, your tool opens a browser, you sign in to FolioFact the way you normally would (including Google sign-in), approve the connection once, and you're back in your tool. You never see or handle a key.
Behind the scenes this is standard OAuth 2.1 — Authorization Code with PKCE
(S256), protected-resource metadata at
/.well-known/oauth-protected-resource/mcp, authorization-server metadata at
/.well-known/oauth-authorization-server, and both Client ID Metadata
Documents and Dynamic Client Registration, so clients register themselves. No
setup on your side.
Approved apps are listed under Settings → Connected apps. Disconnecting one revokes its access immediately — there's no key to rotate.
Access tokens are short-lived and refresh automatically, so you stay signed in without re-approving.
2. API key
Useful for scripts, servers, and any client that can send a fixed header. Create one in Settings → API keys:
- Sign in and open Settings → API keys.
- Create a key with a name you'll recognize (e.g.
claude-desktop). - Copy the key once — only its fingerprint is stored, so it can't be shown again. Treat it like a password.
- Send it with every request as
Authorization: Bearer ff_…(theX-Api-Key: ff_…header also works).
Keys inherit your account's plan. Revoke any key from the same page; a revoked key stops working immediately.
Both methods give exactly the same access. Whichever you use, a request from a Free account asking for a Pro tool gets a clear pointer to /pricing rather than an authentication error — signing in again won't unlock it, a subscription will.
Tiers & limits
Tier What you get Rate limit Anonymous Public tools, public data 20 req/min, 1,000 req/day Free Public tools with your account's limits 60 req/min, 10,000 req/day Pro Everything, including full earnings reports and the four Pro-only tools 300 req/min, 100,000 req/dayLimits are enforced per key (per IP-hash when anonymous); the daily cap is
account-level, so creating extra keys can't bypass it. Exceed a limit and the
server answers 429 with a Retry-After header. Calls to a gated tool without
Pro return a clear error pointing at pricing.
Example queries
"Which funds hold Apple?"
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": { "name": "get_stock", "arguments": { "ticker": "AAPL" } } }
"What did Berkshire buy this quarter?"
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call",
"params": { "name": "fund_holdings", "arguments": { "slug": "berkshire-hathaway" } } }
"How did Mohnish Pabrai's fund change?"
{ "jsonrpc": "2.0", "id": 3, "method": "tools/call",
"params": { "name": "fund_history", "arguments": { "slug": "pabrai-funds" } } }
"What changed in Apple's latest earnings?"
{ "jsonrpc": "2.0", "id": 4, "method": "tools/call",
"params": { "name": "stock_earnings", "arguments": { "ticker": "AAPL", "include_full": true } } }
Try them with the MCP Inspector:
npx @modelcontextprotocol/inspector --cli https://foliofact.com/mcp --transport http --method tools/list
Or drop the same arguments into any of the clients above.