filing-agent
This server exposes read-only tools for researching US public-company filings and SEC XBRL financial data, plus exact arithmetic.
Resolve companies by name, ticker, or CIK to get canonical identifiers, filing availability, and fiscal year end.
List filings for a company, optionally filtered by filing type or fiscal year.
Search filing pages with BM25 keyword search, filtered by company, filing, type, or fiscal year.
Read full filing pages, including aligned tables, detected units/statement type, and optional neighboring pages.
Find XBRL concepts/tags by description for a company.
Retrieve XBRL facts with exact periods, fiscal-year labels, source filing, and restatement handling.
Calculate exactly using named variables and arithmetic expressions.
All tools are marked read-only and non-destructive.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@filing-agent What was 3M's capital expenditure in fiscal year 2018?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Filing Research Agent
An agent that answers analyst questions about US public companies, such as "What is 3M's FY2018 capital expenditure?" or "Does 3M have a healthy quick ratio in Q2 FY2023?". It uses the SEC's XBRL financial-data API, search over filing text, and a calculator. It is graded on the open-source sample of FinanceBench.
The evaluation is the core of the project:
component metrics (retrieval recall, XBRL coverage)
attribution of each failure to retrieval, table reading or arithmetic
before/after scores with confidence intervals for every fix
The tools are also exposed as an MCP server.
Status: complete. Headline results are below; docs/RESULTS.md has every run and docs/ERROR_ANALYSIS.md every failure.
Results
The frozen system is Claude Opus 5.5 at medium effort, with filing search, page reading, SEC XBRL facts and a calculator. Each row is one run; 95% Wilson intervals are in parentheses.
Evaluation | Full agent |
FinanceBench dev (50 questions) | 96% (86–99%) |
FinanceBench test (100) | 85% (76.7–90.7%); 88% after correcting 2 wrong golds and a judge error |
Fresh benchmark: filings published after the model's training cutoff (114) | 100% (96.7–100%) |
Fresh hard tier: segment figures, two-year changes, ratios without formulas (75) | 94.7% (87.1–97.9%); 98.7% counting the readings 3 ambiguous questions allowed |
A memorization check ran the same model closed book, with no tools and no documents, once on each kind of question:
Memorization check | Closed book |
FinanceBench dev (50 questions) | 80% |
Fresh benchmark (114) | 0% (all refusals) |
FinanceBench is largely memorized. With no documents, the model answers 80% of dev questions, but none about filings published after its training cutoff. The fresh benchmark (docs/FRESH.md) is built from 38 post-cutoff 10-Ks and 10-Qs, with golds taken from the filings' own XBRL tags and checked against the SEC API.
The agent's accuracy is research, not recall. It scores 100% on the post-cutoff questions. It uses the XBRL API only when the figure exists nowhere else (23 of 25 two-year-change questions, against 2 of 114 in the first tier).
The SEC API alone answers most metric questions. The agent answered 34 of FinanceBench's 50 metric questions correctly without opening a filing, a lower bound on what the XBRL data covers.
Almost every failure is on the question side. Of 21 failures in 339 questions, 2 are agent errors (both used a source for the wrong period). The rest are unstated definitions, judgment calls, ambiguous questions, wrong golds and one judge error. There are no retrieval, table-reading or arithmetic failures.
The grading holds up. A blind human check of 40 judge verdicts found no lenient ones (32 of 32 "correct" verdicts agreed). Where the two differed, the judge had been the stricter.
The one measured fix was rejected. A prompt change targeting the period error fixed it, but dev dropped 96% → 90% on three judgment questions (p = 0.25). The pre-registered rule rejected it, and the negative result is reported.
The baseline ladder on dev shows where the accuracy comes from. Tools add 12 to 16 points over memory, a single search without follow-up does worse than memory, and the full agent is within one question of being handed the evidence pages (docs/RESULTS.md has the paired tests).
Related MCP server: sec-edgar-mcp
See it work
One question from the hard tier, as the agent answered it in the evaluation run. Adobe filed this 10-Q on September 22, 2026, after the model's training cutoff. The filing compares the quarter only with the year before, and no fiscal 2024 filing is in the search corpus, so the earlier figure has to come from the SEC XBRL API. Tool calls are written as function calls, and their results are abridged.
By what percentage did Adobe's total revenue change from the third quarter of fiscal 2024 to the third quarter of fiscal 2026? Answer in percent, rounded to one decimal place. Use a negative number for a decrease.
thinking I'm working out when Adobe's fiscal year ends, which seems to be late November or early
December. That would put Q3 FY2026 around August or September 2026, which might not be
available yet, so I'll check.
tool list_filings(company="Adobe", fiscal_year=2026)
result ADOBE_2026Q3_10Q, a 10-Q of 52 pages
tool search_filings(query="total revenue three months ended", doc_name="ADOBE_2026Q3_10Q")
result 8 hits. Page 29, three months ended August 28, 2026 and August 29, 2025:
"Total revenue | $6,760 | $5,988 | 13% | ..."
thinking I'm pulling the Q3 FY2024 revenue next, checking the XBRL data or the FY2024 10-Q for
the figure.
tool xbrl_get_facts(company="Adobe", concept="us-gaap:Revenues", fiscal_year=2024,
period="quarter")
result 3 quarters. Q3, 2024-06-01 to 2024-08-30: 5,408 million USD, from the 10-Q filed
2024-09-25 (accession 0000796343-24-000208)
tool calculate(expression="round((q3_2026 - q3_2024) / q3_2024 * 100, 1)",
variables={"q3_2026": 6760, "q3_2024": 5408})
result round((6760 - 5408) / 5408 * 100, 1) = 25.0Answer: Adobe's total revenue rose 25.0%, from $5,408 million in Q3 fiscal 2024 (quarter ended August 30, 2024) to $6,760 million in Q3 fiscal 2026 (quarter ended August 28, 2026).
Sources:
ADOBE_2026Q3_10Qpage 29, and XBRLus-gaap:Revenuesfrom accession 0000796343-24-000208. Confidence: high.
The first note shows that the model did not know whether this quarter had even been reported. The answer was graded correct by the numeric rules (gold 25.0%) and took 5 model calls, 14 seconds and $0.06. The full trace, with every model call, tool output and token count, is in docs/demo/. To ask your own question, see Ask the agent.
Setup
Requires uv and Python 3.12.
uv sync
cp .env.example .env # then fill in SEC_USER_AGENT and your Claude API credentials
uv run fa --helpData
uv run fa data download # questions, document metadata, and the 84 PDFs the 150 questions use
uv run fa data stats # dataset summary
uv run fa data parse # PDFs -> per-page text (plain and column-aligned), units and statement tags
uv run fa data verify # checks each gold evidence passage is on its labeled page
uv run fa data split # company-grouped dev/test split -> configs/splits/See docs/DATASET_NOTES.md for composition, quirks found in the source data, and the split.
Search and retrieval eval
uv run fa data download --pdfs all && uv run fa data parse --docs all # full 358-filing corpus
uv run fa index build --name contextual # BM25 over page-bounded chunks
uv run fa index search "purchases of property, plant and equipment" --company 3M --year 2018
uv run fa eval retrieval --modes bm25 # gold-page recall, 4 settingsResults and what they imply for the agent are in docs/RESULTS.md.
SEC XBRL data
Needs SEC_USER_AGENT (a name and contact email) in .env. Responses are cached under data/cache/sec/; set FA_SEC_OFFLINE=1 to answer only from the cache.
uv run fa sec warm # submissions + XBRL facts for all 40 companies
uv run fa sec verify-companies # every CIK matches the SEC entity name
uv run fa sec concepts 3M "payments to acquire property plant and equipment"
uv run fa sec facts 3M PaymentsToAcquirePropertyPlantAndEquipment --year 2018 --period annual
uv run fa sec filings 3M --form 10-KHow periods, fiscal-year labels and restatements are handled is in docs/METHODOLOGY.md.
Fresh benchmark (post-cutoff filings)
FinanceBench is public, and the model answers much of it from memory: closed book scores 80% on dev. The fresh benchmark uses each company's latest 10-K or 10-Q filed after the agent model's training cutoff.
uv run fa fresh select --filed-after 2026-08-01 --as-of 2026-11-12 # pick 38 filings, pin their SHA-256
uv run fa fresh fetch # download or read from cache, verify, parse
uv run fa index build --name contextual_fresh --fresh # FinanceBench + fresh filings
uv run fa fresh draft-text # Claude drafts the text questions (~$0.85, saved)
uv run fa fresh questions # 114 questions, split, review sheet
uv run fa fresh hard-questions # hard tier: 75 questions, no formulas, fiscal periodsSelection, HTML parsing, fiscal-period quirks and how the questions are built are in docs/FRESH.md.
Running experiments
uv run fa eval run configs/experiments/b3_shared_text.yaml --split dev --dry-run # plan and rough cost
uv run fa eval run configs/experiments/b3_shared_text.yaml --split dev --reps 2 --max-cost 25
uv run fa eval run configs/experiments/b3_shared_text.yaml --resume <run_id> # retry failures
uv run fa eval run configs/experiments/b0_closed_book.yaml --split test --batch # half price; configs without toolsThe eight baseline configs, from closed-book to long-context, are described in docs/METHODOLOGY.md.
Grading and reports
uv run fa eval grade <run_id> # numeric rules, then the LLM judge -> grades.jsonl
uv run fa eval report <run_id> # accuracy with 95% CI, breakdowns, cost, latency -> metrics.json
uv run fa eval compare <run_a> <run_b> # paired change with 95% CI, McNemar p, fixed/broken questions
uv run fa eval chart # redraw the baseline ladder chart from the saved runs
uv run fa eval grader-check # known-good and known-bad answers through the numeric grader
uv run fa eval gold-review # how each bare-number gold is read -> results/labels/gold_review.csv
uv run fa eval xbrl-use --run <run_id> # metric questions answered from the XBRL API aloneThe rules (tolerance, scales, percents, refusals) are in docs/METHODOLOGY.md.
Ask the agent
Needs Claude API credentials: ant auth login, or ANTHROPIC_API_KEY in .env. One question costs about $0.04–0.07 on Claude Opus 5.5, as measured in the evaluation runs.
uv run fa ask "What is the FY2018 capital expenditure amount (in USD millions) for 3M?"
uv run fa ask "..." --no-xbrl # text tools only
uv run fa ask "..." --doc 3M_2018_10K # restrict the agent to one filing
uv run fa ask "..." --effort high --model claude-sonnet-5-5
uv run fa ask "..." --live # may download any 10-K or 10-Q from SEC EDGAREach tool call prints as it happens. The full trace (model calls, tool calls, tokens, cost, transcript) is saved under results/ask/. How the loop works is in docs/METHODOLOGY.md.
Agent tools
Seven tools, defined once and shared by the agent and the MCP server: company lookup, filing list, page search, page reading, XBRL concept search, XBRL facts, and an exact calculator with named inputs.
uv run fa tools list
uv run fa tools run search_filings '{"query": "purchases of property, plant and equipment", "company": "3M", "fiscal_year": 2018}'
uv run fa tools run read_filing_page '{"doc_name": "3M_2018_10K", "page": 59}'
uv run fa tools run calculate '{"expression": "capex / revenue * 100", "variables": [{"name": "capex", "value": 1577}, {"name": "revenue", "value": 32765}]}'fa data download --pdfs all fetches all 368 PDFs (705 MB) for the shared-corpus setting. Every file is checked against its git blob SHA at a pinned FinanceBench commit.
Filings on demand
The search index covers a fixed set of filings. With --live, an eighth tool, fetch_filing, downloads any 10-K or 10-Q of a registered company from SEC EDGAR, parses it and makes it available to the list, search and read tools within a few seconds:
uv run fa tools run fetch_filing '{"company": "Nike", "form": "10-K", "period_ending": "2024"}' --liveFetched filings are kept in
data/live/with their accession number and SHA-256, and stay available in later sessions.The built index is never changed, and evaluation configs never include this tool, so results are unaffected.
It needs filings with inline XBRL cover facts (roughly fiscal 2019 onward) and the 40 companies in
configs/companies.yaml.
MCP server
The seven tools are served over MCP, so Claude Code, Claude Desktop or any MCP client can research filings with them. The server lists the agent's exact tool definitions and runs calls through the same code; tests/test_mcp_server.py checks this parity.
uv run fa mcp serve # stdio, which desktop clients launch
uv run fa mcp serve --transport http --port 8000 # streamable HTTP at http://127.0.0.1:8000/mcp
uv run fa mcp serve --sec-offline --index contextual # cached SEC data only; FinanceBench filings only
uv run fa mcp serve --live # adds fetch_filing: any 10-K or 10-Q from SEC EDGARThe server needs the parsed filings and an index (fa data parse, fa fresh fetch, fa index build). It uses SEC_USER_AGENT from .env for live SEC data.
Claude Code:
claude mcp add filing-agent -- uv run --directory "/path/to/filing agent" fa mcp serveClaude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"filing-agent": {
"command": "uv",
"args": ["run", "--directory", "/path/to/filing agent", "fa", "mcp", "serve"]
}
}
}Limitations
One run per configuration.
Run-to-run variation on judgment questions is about three of 50, as large as small fixes.
Repetitions were not affordable, so differences under about 10 points are not significant.
The judge is a model, checked against a person. Claude Sonnet 5.5 grades prose answers, with its figures cross-checked numerically.
In a blind check of 40 of its verdicts, a person agreed with all 32 it called correct and 3 of 7 it called incorrect: 93.7% weighted agreement, kappa 0.55.
It is not lenient. It is stricter than a person where the answer key uses an unusual formula, so the strict scores are conservative.
The fresh text questions were drafted by Claude. They were checked automatically, read in a first pass, and sampled by a person. The same model family answers them, which may favor its wording; the numeric two-thirds are template-based.
Left out, and why:
The whole-filing long-context baseline. At roughly 200K tokens per question, it would have cost about as much as every other run combined.
Dense and hybrid retrieval at corpus scale. Both are implemented, but keyword search produced no retrieval failures in 339 questions, so there was nothing for them to fix.
Diagnostic baselines on the test split. Closed book and the other baselines ran on dev only; test was kept for the frozen system.
Development
uv run pytest # offline tests
uv run pytest -m live # tests that need network access or API credentials
uv run ruff check . && uv run ruff format --check . && uv run pyrightData license and attribution
FinanceBench (Islam et al., 2023, arXiv:2311.11944) is released under CC-BY-NC-4.0. This repository does not redistribute it; fa data download fetches it from the original source. The code in this repository is MIT-licensed.
Available Tools
7 toolscalculateARead-only
Evaluate arithmetic exactly. Use it for every computed figure. Give each input number a name in variables and use the names in the expression, e.g. expression '(capex_2018 / revenue_2018) * 100' with variables capex_2018=1577 and revenue_2018=32765. Supports + - * / **, parentheses, abs, round(x, digits) (half-up), min, max, sum, avg and sqrt.
Inputs: variables (required), expression (required).
list_filingsARead-only
List the filings available to search and read for a company: doc_name, type (10-K, 10-Q, 8-K, earnings release), fiscal year and page count. Use it to pick the filing that matches the question's period before searching.
Inputs: company (required), doc_type, fiscal_year.
read_filing_pageARead-only
Read one page of a filing in full, with table columns aligned, plus the page's statement type and units line (e.g. 'In millions, except per share data') when detected. Read the full page before taking a number from a table: check the units and which column is which period. include_neighbors adds the pages before and after.
Inputs: page (required), doc_name (required), include_neighbors.
resolve_companyARead-only
Look up a company by name, ticker or CIK. Returns the canonical name the other tools use, its SEC CIK and tickers, how many filings are available, and (when known) the fiscal year end as MMDD, e.g. '0131' for a year ending January 31.
Inputs: query (required).
search_filingsARead-only
Keyword search (BM25) over filing pages; returns the best-matching pages with a snippet each. Always filter by company, and by fiscal_year or doc_name once you know them: unfiltered search across all companies rarely finds the right page. Use the filing's own wording ('purchases of property, plant and equipment', not 'capex'). Results are pages; read them with read_filing_page.
Inputs: query (required), top_k, company, doc_name, +2 more.
xbrl_find_conceptsARead-only
Find the XBRL concepts (tags) a company reports that match a description, e.g. 'payments to acquire property plant and equipment' or 'revenue'. Returns concept names, labels, units and the years covered. Use it before xbrl_get_facts: tag names differ between companies and years.
Inputs: query (required), company (required), top_k.
xbrl_get_factsARead-only
Reported values of one XBRL concept from the company's 10-K and 10-Q filings (SEC API). Each value has its exact period (start, end), period type (annual, quarter, ytd, instant), the company's own fiscal-year label, the filing it came from, and a restated flag. Values are in whole units ('display' shows the scale: 1577000000 USD is 1,577 million USD). Filter by fiscal_year and period. Returns values as first reported unless policy is 'latest'.
Inputs: company (required), concept (required), period, policy, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Each tool targets a distinct step in a clear pipeline: company resolution, filing enumeration, page-level keyword search, page reading, XBRL concept discovery, fact retrieval, and arithmetic. The one potential overlap (search_filings vs xbrl_find_concepts) is explicitly separated in the descriptions as 'text search over pages' versus 'tag lookup', and the descriptions even cross-reference the next tool to use.
All names are snake_case verb_noun (resolve_company, list_filings, search_filings, read_filing_page, xbrl_find_concepts, xbrl_get_facts), with a sensible xbrl_ namespace prefix grouping the tag-based tools. The lone bare verb 'calculate' lacks a noun object, a minor deviation from an otherwise tight convention.
Seven tools is well-scoped for SEC filing research: two entry points (text and XBRL), one read tool, one lookup, one arithmetic utility. No tool looks redundant or padded, and nothing essential appears to be missing for the stated workflow.
The surface covers the full research loop: identify company, pick filing, search, read pages, find tags, pull reported facts, and compute ratios. Minor gaps remain — there is no way to enumerate all XBRL concepts for a company without a description query, and no statement/section-level listing or cross-company comparison — but agents can work around these via search and repeated calls.
Maintenance
Related MCP Connectors
Query SEC EDGAR filings, XBRL financials, and company data via MCP. STDIO or Streamable HTTP.
Financial data MCP server for Claude, ChatGPT, Cursor and Codex. Real-time stock quotes, financial statements, options flow, SEC filings, insider trades, 13F holdings, macro data and market news from gloom.sh, the open-source Bloomberg Terminal alternative.
Your agent needs company financials it can compute on — statements, ratios, earnings, estimates, filings and insider activity as structured data, not a PDF. **What you can ask for** • "Give me 8 quarters of income statement, balance sheet and cash flow for this ticker." • "What do analysts estimate for next quarter, and how did the last four surprise?" • "Find this exact line item across every filing." • "Who bought or sold as an insider in the last 90 days?" • "Screen for profitable companies under this valuation with growing revenue." **How to use it** Point any MCP client at https://mcp.aisa.one/marketpulse/mcp and sign in with OAuth — there is no key to create or paste. 21 tools: prices and snapshots, income statements, balance sheets, cash-flow statements, financial metrics and snapshots, earnings, analyst estimates, company facts, filings and filing items, line-item search, a screener, insider trades, macro interest rates, news, plus EDINET documents and filing digests for Japanese issuers. **Why this rather than the source** Statements as fields you can compute on, and a screener in the same place. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Read the fundamentals here, then ask the same agent what social is saying about the ticker — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/finance/mcp for equities, crypto and prediction markets in one place.
Read, search, and compare SEC EDGAR filings, pull tables, and run AI analysis from any MCP client.
Related MCP Servers
- AlicenseCqualityBmaintenanceMCP server for accessing SEC EDGAR filings. Connects AI assistants to company filings, financial statements, and insider trading data with exact numeric precision.21849 PyPI386AGPL 3.0
- AlicenseNot gradedqualityDmaintenanceHosted MCP server that gives AI agents real-time access to SEC EDGAR filings search, 10-K/8-K reading, XBRL financial facts, and insider-trade (Form 4) alerts.12 npm1MIT
- AlicenseNot gradedqualityDmaintenanceHosted MCP server granting AI agents access to 20M+ SEC EDGAR filings, 100M+ exhibits, and comprehensive entity data through 49 tools, with support for raw documents, extracted sections, and structured JSON.12 npm3MIT
- FlicenseNot gradedqualityDmaintenanceAn MCP server that provides natural-language access to SEC EDGAR filings, including company lookups, financial figures, insider transactions, and filing comparisons, over streamable HTTP for any MCP client.-