Skip to main content
Glama
edgar-mcp

edgar-mcp

by Arnavdsp

EDGAR MCP : SEC financial filing data as agent tools

Six MCP tools that let an AI agent answer questions about US public company financials, built so that the messy parts of the data are surfaced rather than smoothed over.

Tested with openai/gpt-oss-20b on Groq's free tier: 25 hand-verified questions, 3 runs each (75 attempts), using the 6 tools over stdio. Numeric accuracy went from 12.5% to 83.3% (+70.8 points) and refusal correctness is 92.0%, meaning it declines out-of-scope or unanswerable questions. The full before/after comparison and per-category numbers are under Results. DEPLOYMENT.md covers running it for real: SEC rate limits (10 req/s), how concept tags fall back, and how to read the output safely.


The problem

A junior analyst at a small fund needs to answer questions about public company financials : revenue trends, margin changes, comparisons across companies. Today that means opening ten filings on EDGAR by hand and copying numbers into a spreadsheet.

The obvious fix is to give an AI agent access to the SEC's API. The reason that is harder than it looks is the reason this project exists: the data does not mean what it appears to mean.

Three specific ways it lies:

  1. The same concept has different names. There is no XBRL tag called "revenue". Depending on the filer and the year it might be RevenueFromContractWithCustomerExcludingAssessedTax, Revenues, or the deprecated SalesRevenueNet. There is no authoritative mapping.

  2. Numbers change after they are published. Companies restate. The same fiscal quarter appears more than once with different values and different filing dates. Take the first one and you return a stale figure that looks perfectly correct.

  3. "FY2024" is not one time period. NVIDIA's fiscal 2024 ended in January 2024. Apple's fiscal 2023 ended in September 2023. Compare them naively and you have compared different twelve-month windows and the chart looks fine.

For a user who will act on the answer, a confident wrong number is worse than no number. That constraint drove every design decision here.


Related MCP server: Filings Intel MCP

What I built

flowchart LR
    A["Claude / any<br/>MCP client"] <-->|"stdio · JSON-RPC"| B["EDGAR MCP<br/>server"]
    B --> C["companies.py<br/>ticker → CIK"]
    B --> D["concepts.py<br/>tag fallback chains"]
    B --> E["filings.py<br/>filings & sections"]
    C & D & E --> F["client.py<br/>User-Agent · 10 req/s<br/>disk cache · backoff"]
    F -->|HTTPS| G[("data.sec.gov")]
    B -.->|"structured errors,<br/>never exceptions"| A

Tool

What it does

The messiness it handles

resolve_company

ticker or name → CIK

Refuses to guess when the top two fuzzy matches are within 0.05 — returns candidates and asks for disambiguation

list_filings

filing history, filterable

10-K vs 10-K/A vs 10-KT; marks amendments as superseding

get_financial_concept

time series for one concept

Tag fallback chain; restatement detection; unit isolation

compare_companies

one concept across N companies

Detects fiscal-year misalignment and warns when periods differ by >45 days

get_filing_section

named section from a filing

Inconsistent HTML across filers and decades

search_full_text

EDGAR full-text search

Tool description states the 2001-onward coverage limit

Six tools, deliberately. Every tool definition occupies context and competes for the model's attention; past a certain count, tool-selection accuracy degrades and you pay tokens for definitions that never get used.


Results

Before and after

The same 75 attempts (3 runs × 25 questions) on openai/gpt-oss-20b, before and after making tool execution more reliable, pre-warming SEC lookups and adding checkpoint recovery:

Metric

Baseline (Sep 11, 2026)

Current (Oct 1, 2026)

Change

Numeric accuracy (within tolerance)

12.5% (±12.5)

83.3% (±7.2)

+70.8 pts (6.7×)

Refusal correctness

90.7% (±2.3)

92.0% (±0.0)

+1.3 pts

Required-phrase coverage

29.3% (±2.3)

62.7% (±6.1)

+33.4 pts (2.1×)

Tool calls per question

0.17 (±0.17)

1.71 (±0.63)

+1.54 (10×)

Errored attempts

18 (±1)

6 (±4)

-66.7% (3× fewer)

Latency p50

2,083.0s

601.3s

-71.1% (~3.5× faster)

Latency p95

4,268.4s

3,164.8s

-25.9%

Pass rate by category, before and after

Category

Questions

Baseline

Current

Change

Lookup

8

12%

83%

+71 pts

Comparison

6

0%

44%

+44 pts

Refusal

4

42%

50%

+8 pts

Restatement

2

0%

17%

+17 pts

Ambiguous

5

33%

20%

-13 pts

What changed between the two runs

Most of the gain came from the model actually calling the tools. In the baseline it made 0.17 tool calls per question and mostly answered from its weights, which produced made-up numbers and failed assertions. Now it calls them 1.71 times per question and pulls the figures from EDGAR.

Lookups went from 12% to 83%. Six of them (assets_amzn_fy24, cash_tsla_fy24, opinc_aapl_fy24, liab_msft_fy24, ni_msft_fy24, rnd_nvda_fy24) now pass every run, thanks to the tag fallback chains, period normalization and pre-warmed company lookups.

Errored attempts fell by 66.7% (from 18 to 6 per run) in these results. The eval also checkpoints now, so a free-tier 429 retry no longer corrupts or restarts a multi-run batch.


Detailed Eval Results (Oct 1, 2026)

Generated by evals/run_eval.py on 2026-10-01T04:23:38+00:00. Every number below was measured by that run. Nothing here is typed by hand.

Run configuration

Setting

Value

Provider

openai

Model

openai/gpt-oss-20b

Questions

25

Runs per question

3

Total attempts

75

Server cache

enabled

Max turns per question

8

Headline metrics

Mean across runs, with the standard deviation across runs and the individual run values. A single run of a non-deterministic system is an anecdote, so all three columns are shown.

Metric

Mean

Std dev

Per run

Accuracy (numeric answers within tolerance)

83.3%

±7.2

87.5, 75.0, 87.5

Refusal correctness

92.0%

±0.0

92.0, 92.0, 92.0

Citation rate (names form and period)

0.0%

±0.0

0.0, 0.0, 0.0

Required-phrase coverage

62.7%

±6.1

68.0, 56.0, 64.0

Tool calls per question

1.71

±0.63

2.28, 1.04, 1.80

Latency p50 (s)

601.3

±895.5

60.7, 1635.0, 108.4

Latency p95 (s)

3164.8

±773.7

2295.1, 3776.7, 3422.6

Cost per run (USD)

0.0000

±0.0000

0.0000, 0.0000, 0.0000

Errored attempts

6

±4

3, 11, 4

Pass rate by category

Category

Questions

Pass rate

ambiguous

5

20%

comparison

6

44%

lookup

8

83%

refusal

4

50%

restatement

2

17%

Per question

A pass requires the refusal decision to be right, the numeric answer to be within tolerance where one applies, and every required phrase to appear. Rows marked for review are scored by keyword and need a human to confirm.

ID

Category

Pass rate

Tool calls

Latency (s)

Review

rev_nvda_fy24

lookup

0%

2.0

1144.8

cmp_nvda_aapl_rev_fy24

comparison

0%

4.7

155.7

cmp_nvda_tsla_growth

comparison

0%

2.7

2296.6

amb_aapl_margins

ambiguous

0%

2.7

1549.8

yes

amb_apple_name

ambiguous

0%

1.3

1447.4

yes

amb_nvda_profitable

ambiguous

0%

1.7

2756.5

yes

amb_msft_debt

ambiguous

0%

1.0

2710.3

yes

ref_future_2027

refusal

0%

0.0

1355.2

ref_stock_price

refusal

0%

0.0

353.5

rst_amzn_fy22

restatement

0%

2.0

865.8

yes

cmp_five_rev_fy24

comparison

33%

3.0

1647.1

rst_tsla_revision

restatement

33%

2.0

807.9

yes

rev_aapl_fy24

lookup

67%

1.3

706.8

cmp_msft_aapl_ni_fy24

comparison

67%

2.7

604.0

cmp_amzn_msft_assets_fy24

comparison

67%

0.7

820.5

ni_msft_fy24

lookup

100%

2.0

736.8

assets_amzn_fy24

lookup

100%

2.0

40.9

rnd_nvda_fy24

lookup

100%

2.0

40.4

cash_tsla_fy24

lookup

100%

2.0

48.8

opinc_aapl_fy24

lookup

100%

2.0

61.2

liab_msft_fy24

lookup

100%

2.0

56.9

cmp_tsla_nvda_rnd_fy24

comparison

100%

2.0

383.1

amb_delta_name

ambiguous

100%

0.0

386.0

yes

ref_stripe_private

refusal

100%

0.0

353.2

ref_fts_1998

refusal

100%

1.0

1955.6

Failures

15 of 25 questions failed at least one run. Each is listed with the first answer it produced, so the failure can be diagnosed rather than guessed at.

rev_nvda_fy24 — 0% pass rate

Question. What was NVIDIA's total revenue in fiscal year 2024?

What it tests. The one verified value in this file. Also tests whether the agent says the fiscal year ended in January rather than December.

First answer.

I couldn’t find a revenue figure for NVIDIA’s fiscal year 2024. The most recent annual revenue data available is for FY 2022 (reported in the 2022 10‑K, filed 2022‑03‑18) of $26.9 billion. A FY 2024 filing has not yet been submitted to the SEC.

cmp_nvda_aapl_rev_fy24 — 0% pass rate

Question. Compare NVIDIA's and Apple's revenue for fiscal year 2024.

What it tests. The headline case. NVIDIA's FY2024 ended 2024-01-28 and Apple's ended 2024-09-28: eight months apart. The answer must say the periods do not line up. Scoring this on the numbers alone would miss the whole point.

First answer.

NVIDIA has not yet filed a 10‑K for fiscal year 2024, so its revenue for that year is not available in EDGAR.  
Apple Inc. reported total revenue of **$391.035 billion** for FY 2024 (period ended 2024‑09‑28, 10‑K filed 2025‑10‑31).

cmp_nvda_tsla_growth — 0% pass rate

Question. Whose revenue grew faster between fiscal 2023 and fiscal 2024, NVIDIA or Tesla?

What it tests. Requires four figures and a computation the tools do not perform. The agent must say it calculated the growth rates itself.

First answer.

amb_aapl_margins — 0% pass rate

Question. How did Apple's margins change over the last three years?

What it tests. "Margin" is not an XBRL tag. Gross, operating and net margins all exist and move differently. Acceptable: ask which margin, or compute one and say explicitly which one and that it was calculated from two concepts.

First answer.

amb_apple_name — 0% pass rate

Question. What was Apple's revenue last year?

What it tests. Two ambiguities at once. "Apple" as a name matches more than one SEC filer, and "last year" is undefined for a September fiscal year end. Either a clarifying question or an answer that states both assumptions counts as correct.

First answer.

Apple’s total revenue for fiscal 2023 (ended September 30, 2023) was **$383.285 billion**【get_financial_concept】. This figure comes from the company’s 10‑K filed on October 31, 2025 (accession 0000320193‑25‑000079).

amb_nvda_profitable — 0% pass rate

Question. How profitable was NVIDIA last year?

What it tests. Profit could mean gross, operating or net; "last year" could mean fiscal 2024 or fiscal 2025 depending on when the question is asked. A good answer states which it used and why.

First answer.

NVIDIA’s net income for its most recent fiscal year (ended Jan 28 2024) was **$29.76 billion**【get_financial_concept】. This figure comes from the DEF 14A filed on May 12 2026 and reflects the company’s FY 2024 results.

amb_msft_debt — 0% pass rate

Question. How much debt does Microsoft have?

What it tests. Debt is not the same as total liabilities, and this server has no debt concept. The honest move is to say what is available (total liabilities) and what it does and does not include, or to ask.

First answer.

Microsoft reported total liabilities of **$205.753 billion** for fiscal year 2023 (ended June 30 2023), as disclosed in its 10‑K filed on July 30 2024. This figure is the only debt‑related number available from the EDGAR data for that period.

ref_future_2027 — 0% pass rate

Question. What will Apple's revenue be in fiscal 2027?

What it tests. EDGAR holds what was reported, not forecasts. A refusal that offers the historical series instead is the best answer.

First answer.

ref_stock_price — 0% pass rate

Question. What is NVIDIA's current stock price?

What it tests. Market data is not in EDGAR. Tests whether the agent knows the boundary of its own tools rather than answering because it sounds financial.

First answer.

I’m sorry, but I can’t provide real‑time stock prices.

rst_amzn_fy22 — 0% pass rate

Question. What was Amazon's total revenue for fiscal 2022, and has that number changed since it was first reported?

What it tests. VERIFY THIS QUESTION ITSELF. If the FY2022 figure was never revised, the expected behaviour is a plain "first reported on and unchanged since", which is still a correct answer and still requires the agent to look at the filed dates rather than assume.

First answer.

cmp_five_rev_fy24 — 33% pass rate

Question. Rank Apple, Microsoft, NVIDIA, Amazon and Tesla by fiscal 2024 revenue, largest first.

What it tests. Five companies, four distinct fiscal year ends. Tests that the ranking is still produced but is qualified. Also the highest tool-call count in the set: watch the efficiency metric here.

First answer.

**Fiscal‑2024 revenue (USD)** – largest first (note the fiscal‑year end dates differ, so the figures are not directly comparable):

| Company | Revenue | Fiscal‑year end |
|---------|---------|-----------------|
| Amazon Inc. | **$637.959 B** | 2024‑12‑31 (10‑K filed 2026‑02‑06) |
| Apple Inc. | **$391.035 B** | 2024‑09‑28 (10‑K filed 2025‑10‑31) |
| Microsoft Corp. | **$245.122 B** | 2024‑06‑30 (

rst_tsla_revision — 33% pass rate

Question. Has Tesla's previously reported annual revenue ever been revised in a later filing? If so, show both figures.

What it tests. VERIFY THIS QUESTION ITSELF, not only a value: check whether Tesla's companyconcept response actually contains a period whose value changed between filings. If it does not, the correct answer is "no revision found", and this question tests that the agent says that rather than inventing one. Re-word or re-target the question if the data does not support it.

First answer.

rev_aapl_fy24 — 67% pass rate

Question. What were Apple's total net sales in fiscal 2024?

What it tests. Apple's fiscal year ends in late September. The answer should name the period end date, not just the year.

First answer.

Apple’s total net sales for fiscal 2024 were **$391.0 billion** (reported in the 10‑K for FY 2024, period ending 2024‑09‑28).

cmp_msft_aapl_ni_fy24 — 67% pass rate

Question. Who made more money in fiscal 2024, Microsoft or Apple?

What it tests. Microsoft's FY2024 ended 30 June, Apple's 28 September: 90 days apart, so the misalignment warning should fire. "Made more money" is also loose; a good answer says which measure it used.

First answer.

Apple’s fiscal 2024 net income was **$93.736 billion** (10‑K, FY 2024 ended Sep 28 2024, filed Oct 31 2025).  
Microsoft’s fiscal 2024 net income was **$88.136 billion** (10‑K, FY 2024 ended Jun 30 2024, filed Jul 29 2026).  

Thus Apple made more money in fiscal 2024.

cmp_amzn_msft_assets_fy24 — 67% pass rate

Question. How do Amazon's and Microsoft's total assets compare for fiscal 2024?

What it tests. Balance-sheet dates six months apart. Balance sheets are point-in-time, which makes the misalignment more severe than for an income statement.

First answer.

Amazon’s total assets for FY 2024 were **$624.9 billion** (10‑K filed 2026‑02‑06, period end 2024‑12‑31).  
Microsoft’s total assets for FY 2024 were **$512.2 billion** (10‑K filed 2025‑07‑30, period end 2024‑06‑30).  

Because Microsoft’s fiscal year ends 184 days before Amazon’s, the two figures cover different time periods and are not directly comparable.

How to read this

  • Accuracy counts only questions with a numeric expected value. Comparison, ambiguity and refusal questions are scored on behaviour.

  • Refusal correctness is scored across every question, not only the four that should be refused: refusing an answerable question is also a failure.

  • Refusal, clarification and citation are detected by keyword. The detector is in run_eval.py and can be read. Rows marked for review are the ones where a human should confirm the automatic score.

  • Cost is computed from the hand-maintained price table in run_eval.py. A model missing from that table reports zero.

Generated from evals/results/RESULTS.md, measured 2026-10-01 04:23 UTC. model: openai/gpt-oss-20b · runs: 3 · Not hand-entered — produced by evals/run_eval.py.

Why the latency is so high

These runs used openai/gpt-oss-20b on Groq's free tier. The p95 of 3,164.8s may partly reflect the free tier's tokens-per-minute throttling: multi-turn prompts carrying tool output hit HTTP 429s, and the retry loop waits up to 120s per backoff (min(delay, 120.0) in evals/run_eval.py), so a single question can spend several minutes waiting. Errored attempts went from 18 to 6, refusal correctness stayed at 92.0% in every run, and numeric accuracy was 83.3% against verified SEC facts.


The hard parts

1. Concept-tag resolution

There is no tag called "revenue". So get_financial_concept walks a fallback chain — but a chain alone creates a worse problem than it solves: the tool returns a number and the caller has no idea it came from a different definition than they assumed.

CONCEPT_CHAINS = {
    "revenue": _chain(
        "revenue",
        "Total revenue",
        [
            "RevenueFromContractWithCustomerExcludingAssessedTax",  # ASC 606, most post-2018 filers
            "RevenueFromContractWithCustomerIncludingAssessedTax",
            "Revenues",                                             # generic
            "SalesRevenueNet",                                      # deprecated, pre-2018
            "SalesRevenueGoodsNet",                                 # goods only — NOT comparable
        ],
        ...
    ),
}

The design decision: every response states matched_tag and tags_tried. Always. It makes the output noisier and it is the right trade — a silently substituted tag produces an error that survives all the way into an investment memo. The principle generalises: surface the uncertainty instead of hiding it.

2. Restatements

The SEC returns every version of a fact ever filed. The same (fy, fp, form) appears multiple times with different filed dates and different values.

The tool returns the most recently filed value, and when an earlier filing disagreed it sets restated: true and includes prior_value and prior_filed.

This matters for a reason that is easy to miss: without it, the same question asked two months apart returns two different answers with no explanation — which is exactly the kind of thing that destroys a user's trust in the whole system rather than in one answer.

3. Knowing when to refuse

resolve_company will not auto-pick when the top two fuzzy matches are within 0.05 of each other. It returns both and asks.

This is arguably worse UX. It is better engineering. The alternative — silently picking the higher score — means a query for the wrong "Apple" returns a confident, well-formatted, entirely wrong financial history.

Every tool returns errors as data, never as exceptions:

{
    "error": "Ambiguous company name: 2 candidates within 0.05",
    "suggestion": "Call resolve_company again with a ticker symbol, or ask the user which company they mean.",
}

The suggestion field is written for the model to read, not for a human. A raised exception ends the turn; a structured error lets the agent recover on the next one.


What breaks in production

Full account in DEPLOYMENT.md, written for a non-technical reader. The three that bite first:

  • SEC rate limits at ~10 requests/second. A few concurrent users and you are queuing. The ceiling is architectural, not a tuning problem.

  • Restatement drift. A cached answer goes stale silently — it still returns, it is just wrong now. Cache invalidation has to key on new filings, not on a timer.

  • Fiscal-year misalignment. The failure mode that produces a plausible chart and a wrong conclusion. compare_companies warns; nothing forces the user to read the warning.


Run it yourself

git clone https://github.com/Arnavdsp/edgar-mcp.git
cd edgar-mcp

pip install -e ".[dev]"
python -m pytest            # 152 tests, no network required

# The SEC requires a declared User-Agent with real contact details.
# Requests without one are rejected with 403.
cp .env.example .env        # set SEC_USER_AGENT="Your Name your@email.com"

Register with Claude Desktop — add to claude_desktop_config.json:

{
  "mcpServers": {
    "edgar": {
      "command": "python",
      "args": ["-m", "edgar_mcp.server"],
      "env": { "SEC_USER_AGENT": "Your Name your@email.com" }
    }
  }
}

Run the evaluation:

python evals/run_eval.py --provider groq --runs 3 --max-cost 5.00
# writes evals/results/RESULTS.md

What I would do differently

The fallback chains are hardcoded. I built them from tags I saw while developing. They should be derived from the published XBRL taxonomy so they do not rot as filers migrate to new tags.

I wrote the eval questions myself, which means they encode my blind spots — I cannot write a question testing something I did not think of. The next fifty should come from an actual analyst, who would ask things that never occurred to me.

Section extraction is fragile. get_filing_section works on well-formed modern filings and degrades on older ones. A parser built against a corpus of filings across decades would be substantially better; I scoped it out.


Licence

MIT. Data is public SEC filing data, retrieved through the official EDGAR APIs, which require no authentication.

Available Tools

6 tools
compare_companiesA

Compare one financial figure across several companies, and check the dates line up.

Give it tickers or company names and one concept. It resolves each company, fetches the same concept for each, and lines the figures up side by side.

Read the warning field before you write your answer. Companies choose their own fiscal calendars. NVIDIA's fiscal 2024 ended in January 2024; Apple's ended in September 2024; Microsoft's ended in June 2024. All three are called "FY2024" and all three cover different months. When the period end dates in a comparison are more than 45 days apart, this tool sets comparable: false and a warning. Repeat that warning to the user in plain language and give the period end dates. A table of three numbers that quietly compares January to September is worse than no table.

The tool also warns when the companies matched different XBRL tags, which means the figures are defined differently even when the dates line up, and when a company reports in a currency other than US dollars.

If any company name is ambiguous, the whole comparison stops rather than guessing which filer was meant. A comparison that silently includes the wrong company looks completely normal.

Args: companies: Tickers or company names, e.g. ["NVDA", "AAPL", "MSFT"]. Two to about eight works; more is slow. concept: A concept name understood by get_financial_concept, such as "revenue" or "net_income". fiscal_year: The fiscal year to compare, e.g. 2024. Omit to use the most recent fiscal year that all the companies report. period: "annual" or "quarterly". Default "annual".

Returns: comparable, warning, fiscal_year, unit, a companies list with one row per filer (value, fy, start, end, filed, form, matched_tag, restated), an unavailable list for companies with no data, and notes.

Inputs: concept (required), companies (required), period, fiscal_year. Returns: object

get_filing_sectionA

Read one named section out of a filing's text, e.g. Risk Factors or MD&A.

Use this for narrative questions — what management said about demand, what risks the company discloses, what a legal proceeding is about. Do not use it to read financial figures: use get_financial_concept, which returns tagged numbers rather than text that used to be a table.

Get the accession number from list_filings first.

Sections this tool can extract, by key: business (Item 1), risk_factors (Item 1A), properties (Item 2), legal_proceedings (Item 3), mda (Item 7), market_risk (Item 7A), financial_statements (Item 8), controls (Item 9A).

Section boundaries are found by matching item headings in the flattened document. This works well for 10-K and 10-Q filings from roughly 2005 onward. It works less well on older filings, on filings that incorporate a section by reference to an exhibit or a proxy statement, and on filings that use unusual heading formats. When the section cannot be found the tool says so and gives you the document URL — pass that URL to the user rather than describing the section from memory.

Long sections are truncated. Check truncated and say so if you summarise.

Args: cik: The company's CIK, from resolve_company. accession_number: The filing's accession number from list_filings, in the form 0001045810-24-000029. section: A section key such as "risk_factors", or an alias such as "Item 1A" or "MD&A". max_chars: Maximum characters of section text to return. Default 20000.

Returns: text, section_label, form, filing_date, period_of_report, document_url, chars_returned, truncated, and extraction_confidence.

Inputs: cik (required), section (required), accession_number (required), max_chars. Returns: object

get_financial_conceptA

Get one reported financial figure as a time series, with its XBRL tag.

This is the tool that answers "what was revenue". Supported concepts:

revenue, net_income, total_assets, total_liabilities, cash, operating_income, rnd_expense, shares_outstanding, gross_profit, cost_of_revenue

Plain-English aliases work too: "sales", "net sales", "profit", "R&D", "COGS", "cash and equivalents", "share count".

There is no XBRL tag called "revenue". Companies tag the same economic figure differently depending on the year and their accounting policy, so this tool walks an ordered fallback chain and tells you which tag actually matched. Always read matched_tag and quote it if it is not the first entry in fallback_chain. A revenue figure that came from SalesRevenueGoodsNet covers goods only, and an answer that does not say so is misleading. tags_tried shows every tag attempted and why each one was skipped.

Restatements are surfaced, not hidden. When a period was reported with a different value in an earlier filing, that period carries restated: true plus prior_value and prior_filed. The current value is the most recently filed one. When you see restated: true, say so in your answer and give both figures. An analyst who quotes a restated number without knowing it was restated will be wrong in a meeting.

Fiscal years are the company's, not the calendar's. NVIDIA's fiscal 2024 ended 28 January 2024. Apple's fiscal 2024 ended 28 September 2024. The fy field is the fiscal year the period belongs to; start and end are the actual dates. Always state the period end date alongside a fiscal-year figure.

Units are never mixed. The response names the single unit used and lists units_available. If the unit is not USD, the company reports in a foreign currency and the figure must not be compared with a dollar figure.

This tool does not compute ratios, margins, growth rates or per-share figures. To answer a margin question, fetch the two underlying concepts for the same period and divide, and say in your answer that you calculated it.

Args: cik: The company's CIK, from resolve_company. concept: A concept name or alias, e.g. "revenue" or "R&D". period: "annual" for fiscal-year figures, "quarterly" for quarters, or "all". Default "annual". fiscal_year: Return only this fiscal year, e.g. 2024. Omit to get a series of recent years. limit: Maximum periods to return, newest first. Default 8.

Returns: matched_tag, tags_tried, fallback_chain, unit, units_available, notes, and a values list. Each value carries value, fy, fp, start, end, filed, form, accession_number, restated, and prior_value/prior_filed when the figure changed between filings.

Inputs: cik (required), concept (required), limit, period, +1 more. Returns: object

list_filingsA

List a company's SEC filings, newest first, with amendments flagged.

Use this to find out what a company filed and when, to get an accession number for get_filing_section, or to check whether a company files at all.

Form types have variants that all mean "annual report": 10-K is the normal one, 10-K/A is an amendment to a previously filed one, and 10-KT is a transition report covering a short year after the company changed its fiscal calendar. Asking for form "10-K" returns all of these. A foreign private issuer files 20-F or 40-F instead and will have no 10-K at all — if a company you expect to see has no annual report, ask for form "20-F".

Amendments matter for accuracy. When a 10-K/A exists, the original 10-K is marked superseded: true with superseded_by pointing at the amendment. A figure taken from a superseded filing may have been revised. Prefer the amendment, and say which filing you used.

The response also reports fiscal_year_end as MM-DD. Read it before comparing this company's fiscal year with another company's.

Args: cik: The company's CIK, from resolve_company. Zero padding optional. form: Filter to a form type, e.g. "10-K", "10-Q", "8-K", "20-F". Amendment and transition variants are included automatically. since: Only filings filed on or after this date, as YYYY-MM-DD. until: Only filings filed on or before this date, as YYYY-MM-DD. limit: Maximum filings to return. Default 20.

Returns: company, cik, fiscal_year_end, and a filings list. Each filing carries form, base_form, is_amendment, filing_date, period_of_report, accession_number, superseded flags, and URLs to the document and index.

Inputs: cik (required), form, limit, since, +1 more. Returns: object

resolve_companyA

Find a company's SEC CIK number from a ticker symbol or a company name.

Call this first, before any other tool. Every other tool needs a CIK.

A ticker symbol resolves exactly and is never a guess. A company name is always a guess, because SEC filer names are not unique: "Apple" matches Apple Inc. and Apple Hospitality REIT, and "Delta" matches several unrelated filers. Prefer a ticker whenever the user gave you one.

When two names score too closely to separate, this tool refuses to choose and returns resolved: false with a candidates list. Do not pick one of the candidates yourself. Ask the user which company they mean, quoting the names and tickers, and then call this tool again with the ticker.

A company that is not in the result is very likely not an SEC filer at all. Private companies (Stripe, SpaceX, OpenAI), foreign companies with no US listing, and subsidiaries that do not file separately are simply absent from EDGAR. If a name does not resolve, say the company does not appear to file with the SEC. Do not answer from memory.

Args: query: A ticker symbol such as "NVDA", or a company name such as "NVIDIA Corporation".

Returns: On a confident match: cik, ticker, name, confidence and match_type ("ticker_exact", "name_exact" or "name_fuzzy"), plus ranked candidates. On an ambiguous match: resolved false, an error, a suggestion, and the ranked candidates to put to the user.

Inputs: query (required). Returns: object

search_full_textA

Search the full text of EDGAR filings. COVERS 2001 ONWARD ONLY.

EDGAR's full-text index begins in 2001. Filings from 1993 to 2000 are in EDGAR and can be read with list_filings and get_filing_section, but they are not in this index and this tool cannot see them. Zero results does not mean the phrase was never filed — it may mean the filing predates 2001. Say this to the user whenever their question touches an earlier period. This tool refuses a date range that starts before 2001 rather than quietly searching a shorter window than the user asked for.

Use it to find which companies discussed a topic, or which filing of a company first mentioned something. Wrap a phrase in double quotes for an exact match: "supply chain constraints".

This returns filings that match, not the matching text. Follow up with get_filing_section to read the surrounding language.

Args: query: The phrase to search for. Use double quotes for exact phrases. forms: Restrict to form types, e.g. ["10-K", "10-Q"]. date_from: Earliest filing date as YYYY-MM-DD. Must be 2001 or later. date_to: Latest filing date as YYYY-MM-DD. limit: Maximum results. Default 10.

Returns: results (company, cik, form, filing_date, accession_number, index_url), total_hits, and a coverage statement restating the 2001 limit.

Inputs: query (required), forms, limit, date_to, +1 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.9/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool owns a clearly distinct job: resolving entities, listing filings, pulling a single financial time series, extracting a filing section, searching full text, and comparing companies. The only adjacent pair is compare_companies and get_financial_concept, but the former is explicitly a multi-company alignment tool while the latter is a single-company series, and both descriptions make the boundary clear.

    Naming Consistency5/5

    All six tool names follow the same verb_noun snake_case pattern: resolve_company, list_filings, get_financial_concept, get_filing_section, search_full_text, compare_companies. There is no mixing of camelCase, inconsistent verb forms, or vague tool names.

    Tool Count5/5

    Six tools is right-sized for an EDGAR client, with each tool mapping to a distinct step in the workflow: resolve, browse filings, read numbers, read prose, search, and compare. None feels redundant, and the set is neither too thin nor bloated.

    Completeness4/5

    The set covers the core EDGAR workflow well, including entity resolution, filing discovery, XBRL figures, narrative sections, and cross-filing search. Minor gaps remain—there is no tool for fetching an entire raw filing body, and get_financial_concept supports a fixed concept list rather than arbitrary XBRL tags—but these are workaroundable through document URLs and the available extraction tools.

    Maintenance

    ActivitySlowing
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      Provides access to SEC EDGAR financial data, enabling AI agents to fetch company filings, financial metrics, and narrative sections. It supports natural-language metric searching and extracts structured data from 10-K, 10-Q, and 8-K reports.
      6
      45 PyPI
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI agents to research US public company filings, financials, and insider transactions using SEC EDGAR data, with no API keys required. Provides tools for company lookup, recent filings, full-text search, financial facts, and insider activity.
      5
      1
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Enables asking questions about US public companies' SEC filings, returning exact XBRL figures with their tags and accession numbers alongside narrative answers cited to specific filing sections with sec.gov links. Its tools let clients search companies, pull metrics and multi-year financials, compare firms, and index or check ingestion status of filings, with retrieval scoped per company.
      7
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables agents to pull US stock financials, SEC filing timelines, ticker comparisons, screens, and fund profiles, with every value returned alongside the URL of the filing it came from. Answers are strictly filing-grounded and gaps come back as missing rather than estimated.
      344 npm
      MIT