Developers & AI agents

Use TickerFacts fundamentals from your code or your AI agent. Free, sourced from SEC EDGAR, no API key required. A free key raises the agent rate limit. Use is subject to the terms of use: the figures are not investment advice and may contain errors, and an agent passing them on should say so.

MCP server for AI agents

TickerFacts speaks the Model Context Protocol, so an agent can call it as a tool. Point your MCP client at this endpoint:

https://tickerfacts.com/mcp

Transport: Streamable HTTP · No authentication (public data).

One-click install

Add to Cursor Add to VS Code

Claude (claude.ai and Claude Desktop): add a custom connector and paste the endpoint above. No sign-in is needed.

Claude Code

claude mcp add --transport http tickerfacts https://tickerfacts.com/mcp

Claude Desktop, Cursor, and other MCP clients

Add to your MCP config (e.g. claude_desktop_config.json or .cursor/mcp.json):

{
  "mcpServers": {
    "tickerfacts": { "url": "https://tickerfacts.com/mcp" }
  }
}

For a client that only supports local (stdio) servers, bridge with mcp-remote:

{
  "mcpServers": {
    "tickerfacts": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://tickerfacts.com/mcp"]
    }
  }
}

Available tools (9)

The same list, in the same words, that tools/list returns.

Example argument for get_fundamentals: { "ticker": "AAPL" }.

Free API key

Anonymous access is fine for trying things out. For real use, a free key moves /mcp and /a2a/v1 from 5 to 10 requests per second, on a budget you do not share with anonymous crawlers.

The key is emailed to you; receiving it is how the address is confirmed. We keep your email address with the key's ID in our server logs, to know who holds each key and to reach you about it (for example if it leaks, or the API changes). Delivery goes through our email provider, Resend.

Send the key as Authorization: Bearer tfk_… (or X-API-Key). Agents can request one too:

curl -X POST https://tickerfacts.com/api/v1/keys -H 'content-type: application/json' -d '{"email":"you@example.com"}'

Claude Code with a key:

claude mcp add --transport http tickerfacts https://tickerfacts.com/mcp --header "Authorization: Bearer tfk_…"

A2A (Agent2Agent)

Every tool is also an A2A skill with the same id. The Agent Card is at /.well-known/agent-card.json (0.3 clients: /.well-known/agent.json). Send JSON-RPC to https://tickerfacts.com/a2a/v1 with a data part naming the skill:

{"jsonrpc": "2.0", "id": 1, "method": "a2a.SendMessage",
 "params": {"message": {"messageId": "1", "role": "ROLE_USER",
   "parts": [{"data": {"skill": "get_fundamentals",
                         "arguments": {"ticker": "AAPL", "periods": 1}}}]}}}

Replies are immediate messages with the result as a JSON data part; no tasks are created. There is no language model behind this agent: free text works only for an upper-case ticker, and anything else is answered with the list of skills.

JSON API for code

The same data as JSON, no key required. Typed schemas for every response: OpenAPI 3.1.

GET https://tickerfacts.com/api/v1/companies/AAPL

get_fundamentals_batch reads up to 20 comma-separated tickers per call; default one latest annual period per issuer. Each unknown ticker has its own not_found result.

GET https://tickerfacts.com/api/v1/companies?tickers=MSFT,GOOGL,AMZN&periods=3&metrics=revenue,operating_income,capex

Use periods=1..20 and comma-separated metric keys to keep responses small. Single-company calls default to full history; through MCP and A2A, a history that would not fit in one 60,000-byte result comes back as its newest years, and selection.note says so. Unsupported query fields fail explicitly. Batch replies are capped at 120,000 bytes (60,000 through MCP and A2A); reduce tickers, periods or metrics if asked. coverage describes all available history; selection describes what this request returned.

Ratios and comparability

Each year carries ratios: gross, operating and net margin, return on equity (percent), liabilities_to_equity and long_term_debt_to_equity (plain ratios) and revenue_growth, computed on the screener's rules. Any metric's year-over-year change is available as <metric>_growth, e.g. eps_diluted_growth. Asking for a ratio in metrics returns its inputs too. A year's notes say when a figure is not comparable with the year before (a restatement or a stock split between them) or why a ratio is null; the metric pages mark the same years n/c.

GET https://tickerfacts.com/api/v1/companies/GE?periods=5&metrics=revenue_growth,operating_margin

Finding a ticker

search_companies(query) finds companies by name or ticker, forgiving typos, including companies that have left the ticker directory. An unknown ticker in any tool is answered with the likeliest matches.

GET https://tickerfacts.com/api/v1/search?query=berkshire

Citable source passages

get_company_evidence(ticker) returns short source passages with a stable event ID, section, source URL, review date and hashes. It currently covers selected events at MSFT, HON, SPGI, SPCX and XOM, including XOM's predecessor-registry link. No reviewed passages means unreviewed coverage, not an absence of events.

GET https://tickerfacts.com/api/v1/evidence/XOM

Cash-flow inputs and county context

get_cashflow_inputs(ticker) returns operating cash flow, capex, net income and share count per period, each with its source filing. Observations only: no discount rate, no fair value. Here values are decimal strings, unlike the fundamentals endpoint, where they are JSON numbers.

GET https://tickerfacts.com/api/v1/valuation/MSFT

get_county_context(county) takes a FIPS code or a name with its state and returns Census ACS characteristics with 90% margins of error and BLS QCEW private-industry jobs and pay, with a national comparison. An ambiguous name returns candidates instead of a guess.

GET https://tickerfacts.com/api/v1/counties/48453

Tell us what you needed

send_feedback(kind, summary, ...) is the one tool that writes: a report of a company, period, metric or filter you needed and did not get, a figure or label that looks wrong, a confusing response, a feature, or what worked. Give the task your user is trying to accomplish and exactly what would have solved it. Agents are asked to call it at every failed call and once at the end of a good session; every report is read, kept for 400 days and never published. Over REST it is a POST.

POST https://tickerfacts.com/api/v1/feedback  {"kind": "missing_data", "summary": "...", "use_case": "...", "would_solve_it": "..."}

Agent data contract

Company responses include requested_ticker and canonical ticker, dataset_sha256, coverage and metric_definitions. Follow research_url for former names and selected filings; sec_history_url opens the full SEC history.

coverage.status describes available annual observations, not valuation readiness. Missing metrics are absent from this mapping, never assumed zero. History follows the current CIK; reorganizations and predecessor filings require reconciliation. The snapshot contains current elected facts, not a historical point-in-time view.

Read metric_definitions before building a valuation: revenue may be a partial business concept; liabilities are not debt; dated common shares and weighted-average diluted shares have different meanings.

Notes