Skip to main content
Glama

OpenFilings

Public-company filings for 25 non-US markets β€” normalized, keyless, local-first.

CI License: MIT Python 3.11+

EdgarTools gives you SEC/EDGAR in a few lines of Python. OpenFilings applies the same collection-first ergonomics to everything outside the US: resolve a listed company, list its filings, and get normalized IFRS financial statements β€” read from the regulator's own tagged or structured data wherever it exists, rather than scraped out of a PDF.

It runs as a Python library, a CLI, and a local MCP server, so an LLM agent can work through filing outlines, sections, and selected statements instead of pulling whole annual reports into context.

import asyncio

from openfilings import OpenFilings


async def main() -> None:
    async with OpenFilings.from_settings() as openfilings:
        company = await openfilings.company("Nokia", source="esef")
        filings = await company.get_filings(source="esef", limit=5)
        financials = await filings.latest().financials()
        print(financials.balance_sheet().to_markdown())


asyncio.run(main())
## Balance sheet (EUR)

| Line item                 | instant 2025-12-31 | instant 2024-12-31 |
| ------------------------- | -----------------: | -----------------: |
| Cash and cash equivalents |         5462000000 |         6623000000 |
| Inventories               |         2209000000 |         2163000000 |
| Total assets              |        37597000000 |        39149000000 |

What works today

The tiers above are not a marketing summary β€” they are the outcome of the last run of openfilings.smoke against the live regulator endpoints, and CI re-runs it weekly.

Status

Markets

What you get

βœ… Statements verified

Italy, Denmark, Finland, Norway, Poland, Belgium, Luxembourg, Portugal, Mexico, India, Peru, Colombia, Turkey

Search, filings, and normalized statements whose balance sheet reconciles on the issuer's own tagged totals

🟑 Statements extracted

United Kingdom, Netherlands, France, Spain, Sweden, Austria, Brazil, Singapore

The same pipeline, but the filing leaves one total to be derived, so assets = liabilities + equity cannot independently self-check. Singapore is PDF-heuristic; the rest are tagged

πŸ”‘ Key required

Japan (EDINET), South Korea (DART)

Company search is keyless for Japan. Filings need a free EDINET_API_KEY; DART needs DART_API_KEY for everything. South Korea has never been run against a live key

πŸ” Discovery only

Canada (SEDAR+), Australia (ASX)

Company search only. Canada additionally supports explicit user-supplied document imports. Neither regulator exposes keyless filing retrieval β€” see below

Colombia is a hybrid worth calling out: the balance sheet comes from SFC's CUIF supervisory dataset and reconciles exactly, while the income statement still comes from the PDF, because CUIF reports income and expense accounts unclosed.

Every normalized value carries its extraction provenance and a 0–100 confidence, so a tagged XBRL fact is never silently mixed with a derived or PDF-parsed one. See Research controls for what the live suite does and does not prove.

Related MCP server: @cyanheads/secedgar-mcp-server

Known issues

Tracked openly rather than discovered by you. Every item is a real, reproduced finding β€” most came from probing 42 issuers the test suite never touches. FIXES.md is the full working checklist, with the proposed fix beside each item and the research-model gaps that have no issue yet; the issue tracker carries the reproductions.

Correctness

  • #6 β€” Unilever's Form 20-F extracts a wrong currency (PEN for a UK issuer) and a ~1000Γ— scale. Loudly flagged: validation.ok is false with four failed rules, so it is never returned as trustworthy

  • #12 β€” one LEI can produce two company IDs when an issuer files ESEF in two jurisdictions

  • #14 β€” some ESEF issuers return a years-old "latest" filing; upstream gap vs discovery bug not yet separated

Verification gaps

  • #7 β€” the Sweden and Singapore regression guards cannot fire, because both filings derive a total and the identity check correctly refuses a circular comparison

  • #8 β€” pinned accuracy benchmarks cover 2 issuers across 25 markets. A value can reconcile perfectly and still be wrong

  • #9 β€” the multi-issuer probe that found this session's defects was a throwaway script, so the next per-issuer defect will be equally invisible

  • #11 β€” South Korea has never run against a live DART key; mocked tests only

Usability and operations

  • #10 β€” brand and ticker names don't resolve (PKO, Ford Otosan), since matching is a substring test against the registered legal name

  • #15 β€” cached facts and a running MCP server both survive a fix, so a corrected figure may not reach you until you restart and re-extract

  • #13 β€” every Dependabot PR fails CI because uv.lock is not regenerated

What is not coming

Two markets are permanently capped rather than merely unbuilt, and both were confirmed against live endpoints rather than assumed:

  • Canada β€” SEDAR+ blocks non-browser filing queries. Document import from a user-supplied public URL works and is the supported path.

  • Australia β€” ASX's announcements feed accepts no issuer filter, one uncached page costs 18–20 seconds and spans about six days, and the per-company endpoint is capped at five mostly-routine items. A single annual report is roughly twelve minutes of paging away, so filing retrieval was removed rather than shipped slow.

Also ruled out: Switzerland (SIX's data APIs are commercial), Egypt (disclosure pages sit behind a CAPTCHA, which this project will not bypass), Hong Kong (out of scope by decision), and Argentina, Malaysia, Qatar (no keyless structured path found at reasonable effort).

What is being looked at next

No dates are promised. In rough order of how close each one is:

Candidate

State

category="current_report" / "proxy" for UK, India, Brazil

Cheapest remaining EdgarTools-parity step β€” needs only a type-code allowlist per source, no new HTTP calls. These disclosures are already returned unfiltered today

Live verification of South Korea (DART)

Needs a free API key. The connector is written and unit-tested; nothing about it has touched a real response

Pinned reference facts for Sweden and Singapore

Their regression guards currently cannot fire, because both filings derive a total. Closing this needs source-transcribed figures in benchmarks.py

Germany

Blocked upstream β€” filings.xbrl.org currently lists German filings as unavailable for reliable discovery

Chile, Indonesia, Thailand

On hold. Chile's CMF exposes a legacy PHP form rather than an API and needs fresh live reconnaissance before any build starts

Insider and major-holding coverage for the 13 ESEF national OAMs

Largest remaining lift, lowest priority

Institutional holdings in the 13F sense are deliberately out of scope: no general non-US equivalent exists, and the two narrow leads found were not worth the surface area. See FUTURE_INTEGRATIONS.md for the full research trail behind every row above.

Test runs

Three layers, and they prove different things. Real output, not illustrative.

Unit tests β€” uv run pytest

219 passed, 7 warnings in 1.65s

Fast and offline: every source is a recorded fixture, so this catches parsing and mapping regressions but says nothing about whether a regulator's endpoint still exists or still returns the same shape.

Live smoke β€” uv run python -m openfilings.smoke

One issuer per keyless source, against the real endpoints, ending in a tally of what was actually proved:

PASS  ESEF Italy       it_lei_WOCMU6HCI0OJWNPRZS33  it_esef_18316   held
PASS  ESEF Finland     fi_lei_549300A0JPRWG1KI7U06  fi_esef_23894   held
PASS  ESEF Portugal    pt_lei_529900CLC3WDMGI9VH80  pt_esef_19216   held
PASS  Mexico BMV       mx_bmv_6024                  mx_bmv_filing_1575696  held
PASS  India NSE        in_nse_RELIANCE              in_nse_filing_29285    held
PASS  Colombia SFC     co_sfc_001_039               co_sfc_filing_125473   held
PASS  Turkey KAP       tr_kap_4028e4a1486ec80a...   tr_kap_1605247  held
PASS  ESEF Sweden      se_lei_549300HGV012CNC8JD22  se_esef_18913
      not_applicable (no common source-extracted balance-sheet period)
PASS  Singapore SGX    sg_sgx_1U68                  sg_sgx_CMLEN559K1LSH1QR
      not_applicable (no common source-extracted balance-sheet period)
PASS  Australia ASX    au_asx_BHP                   None            search_only

24 cases: 13 balance-sheet identity verified, 8 extracted but unverifiable
(a total was derived), 3 company-search only.

not_applicable is deliberately not dressed up as a pass. Where a filing leaves one of the three totals to be derived, checking assets = liabilities + equity against a total computed as assets - equity is circular, so the case proves only that extraction ran. The thirteen that do verify are asserted strictly β€” degrading to a derived total fails the run.

Multi-issuer probe

One issuer per market is the suite's real limit: it proves an endpoint responds, not that a market works. Probing 42 issuers the smoke suite never touches found four defects it could never have caught, including Indian PDF figures understated by a factor of ten million and equity totals silently dropping non-controlling interests. Both are fixed; see the changelog. Broadening this into a repeatable check is open work, not something the suite does today.

Documentation

What works

  • Search UK-listed issuers through the FCA National Storage Mechanism (NSM)

  • Search Japanese filers by name, ticker, or EDINET code

  • Search Netherlands, French, Spanish, Italian, Danish, Swedish, and Finnish ESEF issuers without a key

  • Search active Brazilian exchange-listed issuers from the official CVM register

  • List and download CVM annual and interim financial statements without a key

  • Search current SGX Mainboard and Catalist companies while excluding non-stock products

  • List and download SGX annual reports without a key

  • Search BMV, NSE, Peruvian, and Colombian issuers

  • List and download their public annual or interim financial reports without a key

  • Search ASX-listed Australian issuers from the official listed-company directory (company discovery only - ASX has no keyless filing history)

  • Search TSX and TSXV operating companies through the official TSX directory

  • Import a user-selected SEDAR+ generated URL or browser-downloaded Canadian PDF

  • List and download keyless Inline XBRL financial reports from filings.xbrl.org

  • List EDINET annual, semiannual, quarterly, and current reports

  • Search South Korean KOSPI/KOSDAQ issuers through the official DART corp-code registry

  • List DART annual, semiannual, and quarterly reports and prefer their IFRS-XBRL-tagged financial-statement data over the filed document

  • Search BIST-listed Turkish issuers through KAP, the official Public Disclosure Platform

  • List KAP quarterly, semiannual, and annual "Finansal Rapor" filings and read their IFRS-tagged financial statements directly from KAP's own rendered viewer tables, skipping PDF parsing entirely

  • List director/PDMR dealing notifications (category="insider") and major- shareholding notifications (category="major_holdings") for UK FCA NSM, India NSE, and Brazil CVM, alongside financial-statement filings

  • Full-text search across every issuer's disclosures, not scoped to one company, for UK FCA NSM and Brazil CVM

  • Merge a company's recent filings into one multi-period fact series per line item, across any market with structured or PDF-derived financials

  • Parse UK TR-1 major-shareholding notifications into structured fields (holder name, position, dates) and run a bounded reverse lookup - what has a given holder disclosed a stake in, across UK issuers

  • Resolve listed-company names to legal entity identifiers (LEIs)

  • List regulated disclosures in one timeline

  • Download public PDF, HTML/XHTML, and tagged-report ZIP documents

  • Prefer tagged XHTML annual reports over PDF when available

  • Convert documents locally to Markdown; retain originals only for explicit SEDAR+ imports so they remain usable without browser automation

  • Navigate extracted documents by heading and search within sections

  • Extract standardized income, balance-sheet, cash-flow, and comprehensive income statements from UK-GAAP, ESEF/IFRS, and EDINET Inline XBRL

  • Read Brazil's normalized statements directly from CVM's Open Data DFP/ITR datasets - a standardized chart of accounts, not PDF parsing

  • Derive high-confidence normalized statements from aligned SGX PDF tables (and CVM as a fallback when a filing isn't in the open dataset) while preserving labels, periods, currencies, and scale

  • Score extraction quality with explainable warnings

  • Optionally route scanned PDFs through page-at-a-time Tesseract OCR

  • Reuse compressed Markdown and duplicate content through a SQLite cache

  • Enforce a logical cache limit and reclaim space with a cleanup command

  • Use the same operations from the CLI or an MCP server

All filing-feed families are free. FCA, European ESEF, CVM, SGX, BMV, NSE, SMV, SFC, ASX, KAP, and TSX company discovery need no key. EDINET filing retrieval requires free API-key registration. DART requires a free API key (immediate for individual sign-ups) for company search, filing history, and financial statements alike - unlike EDINET, DART has no keyless surface at all. SEDAR+ discovery remains browser-based, but a generated public document URL or locally downloaded PDF can be imported without an account, API key, or browser runtime.

Research controls

Every normalized financial value includes its extraction provenance and a 0--100 extraction confidence: tagged XBRL, regulator structured data, PDF table extraction, or a transparent derived calculation. Confidence describes the extraction path, not the issuer's accounting quality; retain the filing URL and reconcile investment-critical figures against the source report.

The scheduled live suite checks one issuer per keyless source. A separate, reviewed accuracy benchmark pins selected facts from public annual reports and can be run locally with uv run python -m openfilings.benchmarks.

The smoke suite's balance-sheet identity check only proves something when the filing tags all three totals. Where an issuer leaves one to be derived, checking assets = liabilities + equity would be circular, so the case is reported as extracted-but-unverifiable rather than verified, and the run's closing tally states how many of each. At present 13 of 21 financial cases verify the identity outright.

Setup

uv sync

Expose the keys for the sources you want to use:

export EDINET_API_KEY="your-key"
export DART_API_KEY="your-key"

Never commit the key. .env is ignored, but OpenFilings intentionally does not load dotenv files implicitly.

Register a DART key at opendart.fss.or.kr (인증킀 μ‹ μ²­/관리 -> 인증킀 μ‹ μ²­) with an email sign-up; individual applicants receive the 40-character key immediately, with a 10,000-request daily allowance.

Register through the EDINET API registration page.

The pdf-detect extra (uv sync --extra pdf-detect) enables a fast, optional pre-extraction PDF classification via pdf-inspector. It does not replace the PDF-to-Markdown engine β€” three filings tested head-to-head (Unilever, DBS, Keppel) produced identical figures from both engines, and the existing table-parsing heuristics do not recognize pdf-inspector's markdown dialect. What it adds: skipping a doomed-to-fail native-extraction attempt when a PDF is confidently classified as scanned or image-based (pure work avoidance β€” assess_markdown already routes those to OCR), and flagging broken font encodings as a diagnostic warning the document-level text-quality heuristic cannot see on its own. Falls back to today's behavior with no code changes when the extra is not installed.

CLI

UK-listed company usage works immediately:

uv run openfilings search "Tesco" --source fca-nsm
uv run openfilings filings uk_lei_2138002P5RNKC5W2JZ46 --source fca-nsm
uv run openfilings fetch uk_nsm_1cc57f6a-e707-4fe8-a137-04731cb7c217
uv run openfilings financials uk_nsm_NI-000144970 -o tesco-financials.json
uv run openfilings sections uk_nsm_NI-000144970 --query revenue

Each fetched document includes its extraction method and quality score. OCR defaults to auto: it runs only when native PDF extraction is unusable and a system Tesseract executable is available. Override it per request with --ocr never or --ocr always.

The default all source searches every configured listed-company market:

uv run openfilings search "Tesco"
uv run openfilings filings uk_lei_2138002P5RNKC5W2JZ46 --limit 50

Japanese company search works without a key. Filing history and download use EDINET API v2 and require EDINET_API_KEY:

uv run openfilings search "Sony" --source edinet
uv run openfilings filings jp_E01777 --source edinet --history-days 120
uv run openfilings fetch jp_edinet_S1000001 -o sony-report.md
uv run openfilings financials jp_edinet_S1000001 -o sony-financials.json

Netherlands company search, filing history, Markdown, and structured IFRS financials work without registration:

uv run openfilings search "ASML" --source esef
uv run openfilings filings nl_lei_724500Y6DUVHQD6OXN27 --source esef
uv run openfilings fetch nl_esef_23718 -o asml-report.md
uv run openfilings financials nl_esef_23718 -o asml-financials.json

France uses the same keyless ESEF path:

uv run openfilings search "TotalEnergies" --source esef
uv run openfilings filings fr_lei_529900S21EQ1BO4ESM68 --source esef
uv run openfilings fetch fr_esef_24364 -o totalenergies-report.md
uv run openfilings financials fr_esef_24364 -o totalenergies-financials.json

Spain is available through the same commands and es_lei_... IDs:

uv run openfilings search "Iberdrola" --source esef
uv run openfilings filings es_lei_5QK37QC7NWOJ8D7WVQ45 --source esef
uv run openfilings fetch es_esef_18556 -o iberdrola-report.md
uv run openfilings financials es_esef_18556 -o iberdrola-financials.json

Italy uses it_lei_... IDs and the same keyless pipeline:

uv run openfilings search "Enel" --source esef
uv run openfilings filings it_lei_WOCMU6HCI0OJWNPRZS33 --source esef
uv run openfilings fetch it_esef_18316 -o enel-report.md
uv run openfilings financials it_esef_18316 -o enel-financials.json

Denmark uses dk_lei_... IDs. The public index includes annual and interim reports, so select the year-end filing when annual financials are required:

uv run openfilings search "Novo Nordisk" --source esef
uv run openfilings filings dk_lei_549300DAQ1CVT6CXN342 --source esef
uv run openfilings fetch dk_esef_24266 -o novo-nordisk-report.md
uv run openfilings financials dk_esef_24266 -o novo-nordisk-financials.json

Sweden uses se_lei_... IDs and the same keyless pipeline:

uv run openfilings search "Ericsson" --source esef
uv run openfilings filings se_lei_549300W9JLPW15XIFM52 --source esef
uv run openfilings fetch se_esef_19170 -o ericsson-report.md
uv run openfilings financials se_esef_19170 -o ericsson-financials.json

Finland uses fi_lei_... IDs and the same keyless pipeline:

uv run openfilings search "Nokia" --source esef
uv run openfilings filings fi_lei_549300A0JPRWG1KI7U06 --source esef
uv run openfilings fetch fi_esef_23894 -o nokia-report.md
uv run openfilings financials fi_esef_23894 -o nokia-financials.json

Brazil uses the official keyless CVM company register and IPE document archive. Only active BOLSA issuers are returned. CVM reports are PDFs for Markdown and document reading, but financials reads structured statement rows directly from CVM's Open Data DFP/ITR datasets when the company and year are covered, falling back to PDF-derived tables otherwise - both need no key:

uv run openfilings search "Banco do Brasil" --source cvm
uv run openfilings filings br_cvm_001023 --source cvm
uv run openfilings fetch br_cvm_1046308 -o banco-do-brasil-report.md
uv run openfilings financials br_cvm_1046308 -o banco-do-brasil-financials.json

Singapore uses SGX's keyless stocks, market-metadata, and financial-reports feeds. Only Mainboard and Catalist stock counters are joined to issuer records; GlobalQuote counters and non-stock exchange products are excluded:

uv run openfilings search "S68" --source sgx
uv run openfilings filings sg_sgx_1J26 --source sgx
uv run openfilings fetch sg_sgx_2J4PCEOQYA3WTBWP -o sgx-report.md
uv run openfilings financials sg_sgx_2J4PCEOQYA3WTBWP -o sgx-financials.json

Mexico, India, Peru, and Colombia use keyless official exchange or regulator data. Each example begins with a live company search; pass the returned ID to filings:

uv run openfilings search "AMX" --source bmv
uv run openfilings search "RELIANCE" --source nse
uv run openfilings search "Alicorp" --source smv
uv run openfilings search "Ecopetrol" --source sfc

BMV annual PDFs and quarterly IFRS JSON archives both convert to Markdown and normalized financial statements. Peru reads SMV statement tables through bounded official statement operations with limited request concurrency.

Australia is company-discovery-only. ASX publishes its listed-company directory as a free CSV, so search works keylessly across every listed issuer, but no keyless path to a company's filing history exists, and this was measured rather than assumed:

  • ASIC's lodged financial reports are a paid-download product (connectonline.asic.gov.au).

  • ASX's public announcements feed accepts no issuer filter - issuer_code, asx_code and every variant tested are silently ignored - so one company's history can only be recovered by paging the global feed and discarding almost every row. Against the live endpoint an uncached page costs 18-20 seconds and covers about six days, putting a company's last annual report around twelve minutes away and four years of history over an hour.

  • The per-company endpoint on asx.api.markitdigital.com returns a hard cap of five items regardless of any count or date parameter, and those are dominated by routine notices, so periodic financial reports are usually absent from it.

filings and fetch therefore raise a SourceError for ASX that points at the public announcements page. Use the issuer's own investor-relations site or a commercial ASIC/ASX data product for Australian financial reports.

uv run openfilings search "BHP" --source asx

Canada supports official TSX/TSXV listed-company discovery plus explicit user-selected filing imports. Search and cache the issuer first. Then use the SEDAR+ document search's Generate URL action:

uv run openfilings search "SHOP" --source sedar
uv run openfilings import-sedar ca_sedar_tsx_SHOP \
  "https://www.sedarplus.ca/csa-party/..." \
  --title "2025 Annual Report" \
  --filing-date 2026-03-12 \
  --period-end 2025-12-31
uv run openfilings filings ca_sedar_tsx_SHOP --source sedar
uv run openfilings fetch ca_sedar_filing_RETURNED_ID -o shopify-2025.md

If SEDAR+ returns a browser-verification page for the generated URL, download the PDF normally and import the local file instead:

uv run openfilings import-sedar ca_sedar_tsx_SHOP shopify-2025.pdf \
  --source-url "https://www.sedarplus.ca/csa-party/..." \
  --title "2025 Annual Report" \
  --filing-date 2026-03-12 \
  --period-end 2025-12-31

URLs are restricted to official HTTPS SEDAR+ paths and redirects cannot escape the allowlist. Imports accept PDFs up to 100 MB. The compressed original shares the configured cache budget with Markdown and structured financials.

Use the real filing ID returned by filings in the last two commands. Available source values are all, fca-nsm, edinet, esef, cvm, sgx, bmv, nse, sedar, smv, and sfc. Use --output report.md with fetch to save Markdown. Set OPENFILINGS_DATA_DIR to move the SQLite cache; it defaults to .openfilings in the current directory.

Inspect and benchmark a local document without adding it to the cache:

uv run openfilings inspect-document annual-report.pdf
uv run openfilings inspect-document scan.pdf --ocr always -o scan.md

Inspect or prune the cache:

uv run openfilings cache status
uv run openfilings cache prune --max-mb 512

Python API

The public API follows EdgarTools' collection-first ergonomics without importing its SEC-specific runtime:

from openfilings import OpenFilings

async with OpenFilings.from_settings() as openfilings:
    company = await openfilings.company("Nokia", source="esef")
    filings = await company.get_filings(source="esef", limit=100)
    filing = filings.latest()
    assert filing is not None

    markdown = await filing.markdown()
    document = await filing.obj()
    matches = await filing.search("revenue operating profit")

    financials = await filing.financials()
    income = financials.income_statement()
    if income is not None:
        print(income.to_markdown())

    # Cache processed documents and financials for offline reuse.
    result = await filings.head(5).prefetch(documents=True, financials=True)
    print(result)

    # Later, browse previously cached metadata without regulator requests.
    cached_company = await openfilings.company("Nokia", offline=True)
    cached_filings = await cached_company.get_filings(offline=True)

Company search results and filing collections support slicing, head, find, filter, and latest. Bound filings expose markdown, obj, sections, ranked search, financials, and xbrl methods. Prefetching retains compressed processed results while continuing to discard source documents. Explicit SEDAR+ imports are the exception: their compressed source PDF is retained so future extraction does not depend on the browser session.

Canadian imports are also available through the service API:

from datetime import date

async with OpenFilings.from_settings() as openfilings:
    filing = await openfilings.import_sedar_filing(
        "ca_sedar_tsx_SHOP",
        document_url="https://www.sedarplus.ca/csa-party/...",
        title="2025 Annual Report",
        filing_date=date(2026, 3, 12),
        period_end=date(2025, 12, 31),
    )
    print(await filing.markdown())

Financial statements support to_records(), to_markdown(), and optional pandas conversion. Install the extra only when DataFrames are needed:

uv sync --extra dataframe

Structured values preserve their source concept, period, unit, decimals, and dimensions. The lower-level OpenFilingsService, normalized models, and raw list_filings methods remain available for integrations that need them.

MCP tools

Discovery and content:

  • companies_search(query, limit=5, source="all")

  • filings_list(company_id, category="accounts", limit=10, source="all", history_days=120)

  • disclosures_search(keyword, limit=10, source="all") β€” full-text, FCA NSM and CVM only

  • filing_outline(filing_id, limit=100, refresh=False)

  • filing_read(filing_id, section, offset=0, max_chars=6000, refresh=False)

  • filing_search(filing_id, query, limit=5, snippet_chars=1200)

  • filing_sections(filing_id, query=None, limit=20) β€” compatibility alias returning headings only

  • filing_markdown(filing_id, offset=0, max_chars=12000, refresh=False, ocr_mode=None)

  • sedar_filing_import(company_id, document_url, title, filing_date, period_end=None, filing_type="annual", category="accounts")

Financials:

  • filing_financials(filing_id, statements=None, periods=4, detail="standard", max_line_items=40)

  • financials_query(company_id, codes, periods=4, source="all") β€” selected facts only, across a company's filing history

  • company_facts(company_id, periods=8, source="all", statements=None, detail="standard", max_line_items=40)

  • data_quality_report(filing_id) β€” extraction provenance, confidence, and validation for one filing; check this before trusting a figure

  • filings_diff(first_filing_id, second_filing_id) β€” changed values between two filings

  • historical_backfill(company_id, source, limit=100) β€” download UK/ESEF structured history into local storage

  • historical_facts_query(company_id, codes=None, view="latest_restated", as_of=None, limit=1000) β€” restatement-aware: as_reported, latest_restated, or as_of a date

  • companies_compare(company_ids, code, source="all") β€” one normalized fact across 2–20 UK/ESEF issuers

  • watchlist_check(company_ids, since, source="all") β€” stateless check for filings published since a date

Ownership and research:

  • insider_dealings_list(company_id, limit=25) β€” UK MAR director/PDMR/PCA dealings

  • major_holders_list(company_id, limit=25)

  • major_holders_search(holder_name, scan_limit=200, limit=25)

  • company_research_brief(company_id, source="all") β€” recent filings plus a compact three-period financial profile

The MCP interface uses progressive disclosure. Start with company and filing metadata, inspect a filing's outline, then read one section or retrieve short ranked excerpts. Full Markdown is paginated and capped at 24,000 characters per call. Financial responses can be restricted by statement, period, detail level, and line-item count. Every response includes a compact success envelope and suggested next steps where another focused call is useful. filing_sections remains as a compatibility alias that returns headings without section bodies.

Start the stdio server with uv run openfilings serve.

Working with an AI agent

Every transcript below is a real call against the live MCP server, trimmed only for width. The point of the design is that an agent never has to pull a 300-page annual report into its context to answer a question about it.

Resolve, list, extract

"Give me Ferrari's latest balance sheet." Three calls, no document download:

// companies_search {"query": "Ferrari", "source": "esef", "limit": 3}
{"companies": [
  {"id": "nl_lei_549300RIVY5EX8RCON76", "name": "FERRARI N.V.", "market": "NL"},
  {"id": "nl_lei_984500Y7F9EB3DRC4406", "name": "FERRARI GROUP PLC", "market": "NL"}],
 "next_steps": ["Use filings_list with a company id to discover recent filings."]}

// filings_list {"company_id": "nl_lei_549300RIVY5EX8RCON76", "source": "esef"}
{"filings": [{"id": "nl_esef_23727", "period_end": "2025-12-31",
              "filing_date": "2026-03-04", "xbrl_available": true}]}

// filing_financials {"filing_id": "nl_esef_23727", "statements": ["balance_sheet"]}
{"extraction_method": "inline-xbrl-stream", "fact_count": 479,
 "statements": [{"currency": "EUR", "line_items": [
   {"code": "total_assets",      "values": {"2025-12-31": "9628352000"}},
   {"code": "total_equity",      "values": {"2025-12-31": "3914742000"}},
   {"code": "total_liabilities", "values": {"2025-12-31": "5713610000"}}]}],
 "validation": {"ok": true, "checks_passed": 4, "checks_failed": 0}}

3,914,742,000 + 5,713,610,000 = 9,628,352,000. The identity holds, and the agent is told so rather than having to check.

The agent is told when the data is doubtful

This is the part that matters for an autonomous agent. Unilever's Form 20-F is a PDF whose tables this extractor reads badly. It does not quietly return the numbers:

// data_quality_report {"filing_id": "uk_nsm_NI-000140673"}
{"extraction_method": "pdf-aligned-text", "fact_count": 34,
 "provenance_counts": {"pdf_table": 34},
 "confidence": {"minimum": 75, "maximum": 75},
 "validation": {"ok": false, "checks_passed": 0, "checks_failed": 4, "findings": [
   {"rule_id": "EQ.accounting_equation", "description": "assets = liabilities + equity",
    "period": "2025-12-31", "expected": 102305000000000, "actual": 79750000000000,
    "difference": -22555000000000},
   {"rule_id": "FOOT.bs.total_liabilities",
    "description": "total liabilities = current + non-current liabilities",
    "period": "2025-12-31", "expected": 57195000000000, "actual": 79750000000000}]}}

ok: false with the failing rule, the period, and the size of the gap. An agent can refuse to answer, fall back to filing_search over the document text, or escalate β€” instead of reporting a confident wrong number. Compare the confidence: 75 / pdf_table provenance above with Ferrari's tagged-XBRL confidence: 100.

Unsupported operations fail with the reason and the alternative

// filings_list {"company_id": "au_asx_BHP", "source": "asx"}
{"success": false, "error_code": "SOURCEERROR",
 "error": "ASX filing retrieval has no keyless source: ASIC's lodged financial
  reports are a paid product, and ASX's public announcements feed accepts no
  issuer filter... Browse this issuer's announcements at
  https://www.asx.com.au/markets/trade-our-cash-market/announcements (ASX code
  BHP), or use a commercial ASIC/ASX data product."}

Cross-issuer and ownership questions

Not scoped to one company:

// disclosures_search {"keyword": "climate transition plan", "source": "fca_nsm"}
{"filings": [{"id": "uk_nsm_202503120300PR_NEWS_UKDISCLO_0006",
              "title": "FirstGroup Plc - Publication of Climate Transition Plan",
              "filing_date": "2025-03-12"}]}

// insider_dealings_list {"company_id": "uk_lei_549300MKFYEKVRWML317", "limit": 1}
{"dealings": [{"person_name": "Srinivas Phatak",
               "position": "Chief Financial Officer (Director)",
               "isin": "GB00BVZK7T90",
               "price_volume": [{"price": "45.39243", "currency": "GBP", "volume": 474}]}]}

Connecting it

// claude_desktop_config.json / .mcp.json
{"mcpServers": {"openfilings": {"command": "uv",
  "args": ["run", "--directory", "/path/to/openfilings", "openfilings", "serve"]}}}

The server is long-running, so restart it after upgrading β€” a running process keeps serving the code it started with. Cached facts also survive an upgrade; pass refresh: true to re-extract a filing whose figures a fix should change.

Production checks

Pull requests and main-branch changes run locked dependency installation, Ruff, the complete offline suite, Python 3.11–3.14 compatibility, wheel and source distribution builds, and installed-package smoke tests. CodeQL and a strict locked-dependency audit run separately. A scheduled keyless smoke job checks one listed issuer per ESEF jurisdiction plus FCA, CVM, SGX, BMV, NSE, SMV, and SFC - fetching each one's latest filing's financials and verifying the fundamental balance-sheet identity (assets = liabilities + equity) holds, not just that a filing was found. Japan, Canada and Australia check company search only: EDINET's filing API requires a key, SEDAR+ permits browser search but not stable automated filing retrieval, and ASX's announcements feed accepts no issuer filter.

Run the same local gates before a release:

uv sync --locked --all-extras --dev
uv run ruff check src tests
uv run ruff format --check src tests
uv run pytest
uv build
uv run openfilings-smoke

See CONTRIBUTING.md for the release and rollback checklist and SECURITY.md for vulnerability reporting and supported-version policy.

Resource footprint

The complete development environment is approximately 129 MB. Normal search and listing operations use only HTTP plus SQLite. PDF extraction loads native PDF libraries only when required; HTML extraction is lightweight and local. Source documents are discarded after conversion, while Markdown and normalized financials are compressed. Inline XBRL is processed with a bounded streaming parser, avoiding a full DOM for large annual reports. Tesseract is an optional system executable and adds nothing to the Python environment when it is not installed.

EDINET issuer search downloads a roughly 0.6 MB compressed code list. Filing ZIPs are capped at 150 MB and discarded after conversion; the default Japanese history window makes 120 small metadata requests and is reused for six hours. European ESEF retrieval downloads the main XHTML report directly instead of the complete report package, reducing bandwidth and temporary memory use. Brazilian search downloads the roughly 1.4 MB CVM register once per process. Filing history reads up to five annual IPE ZIP indexes (currently about 1–2 MB each), retaining only normalized matching records; report PDFs remain bounded by the same 150 MB document limit and are discarded after conversion. Singapore search downloads SGX's roughly 0.13 MB stock list and 8.3 MB metadata feed once per process, then retains only normalized Mainboard and Catalist companies. Annual-report history uses one small paged query; validated PDFs use the shared 150 MB limit and are discarded after conversion. The new adapters request bounded official issuer and filing feeds on demand. Mexico, India, China, and Colombia download only selected filing PDFs or ZIPs; Peru renders normalized HTML statement tables directly from SMV's open datasets. Canada queries the small TSX/TSXV directory endpoints and does not automate SEDAR+ discovery. Only a user-selected SEDAR+ URL or local PDF is downloaded, validated, compressed, and retained within the configured cache budget.

On Tesco's 2026 FCA ESEF filing (29.5 MB Inline XBRL), the structured parser ran in about 0.63 seconds with approximately 150 MB peak resident memory on the development machine. Results vary by filing and platform.

Relevant environment settings:

export OPENFILINGS_OCR_MODE=auto       # auto, never, or always
export OPENFILINGS_OCR_LANGUAGE=eng    # eng+fra for multiple installed packs
export OPENFILINGS_OCR_DPI=200
export OPENFILINGS_OCR_MAX_PAGES=250
export OPENFILINGS_CACHE_MAX_MB=512

Source and licensing notes

The FCA connector uses the same public read-only search endpoint as the NSM web application. The endpoint is not published as a separately versioned consumer API, so its alias and response schema are isolated in the FCA adapter. Requests are user-triggered, bounded, and do not crawl in the background.

The Japan connector uses the official EDINET API v2 specification and issuer-code archive. It sends a subscription key only as an API parameter and never persists it.

The South Korea connector uses the Financial Supervisory Service's official OPENDART API - the corpCode.xml issuer registry, list.json disclosure search, and fnlttSinglAcntAll.json IFRS-tagged financial-statement endpoint. Unlike EDINET, DART has no keyless surface: company search, filing history, and financial statements all require DART_API_KEY. Financial-statement rows are matched to standardized line items through their account_id (DART's XBRL standard account ID, which for IFRS-XBRL filers is the literal ifrs-full taxonomy concept), so no DART-specific aliasing is needed. This integration was built against DART's documented request/response shapes and verified with mocked-response tests; it has not been exercised against a live API key.

The Turkey connector uses KAP (Kamuyu Aydinlatma Platformu)'s own public website endpoints - not the paid, contract-gated Rest API data-distribution product - for keyless company search and disclosure listing. KAP's "Finansal Rapor" filings don't expose a downloadable raw XBRL instance; instead, each statement is pre-rendered as an HTML viewer table whose rows carry the filer's literal IFRS-tagged concept (ifrs-full_Assets, kap-fr_...) next to its reported value, so the same concept mapping used elsewhere applies directly - no Turkey-specific aliasing needed. The statement-of-changes-in-equity table uses a different rowspan-based period layout this connector doesn't parse. Live-verified end-to-end (search, filings, financials, balance-sheet identity) against Deniz Gayrimenkul GYO, Turkcell, and BIM.

The Netherlands, France, Spain, Italy, Denmark, Sweden, Finland, Norway, Poland, Belgium, Austria, Luxembourg, and Portugal connectors use the free, keyless filings.xbrl.org API. XBRL International sources ESEF reports from the relevant national collection authority; its index can lag or omit filings, so this feed should not be treated as a real-time legal record. Germany is not enabled because the upstream repository currently lists German filings as unavailable for reliable discovery and download.

The Brazil connector uses the official keyless CVM listed-company register and IPE filing archive. It filters the register to active operational issuers whose market type is BOLSA; document links remain on CVM's public RAD system.

UK FCA NSM, India NSE, and Brazil CVM support category="insider" (director/PDMR dealing notifications) and category="major_holdings" (substantial-shareholding notifications) alongside category="accounts". NSM maps these to existing NSM type codes (DSH/HOL) on the same feed already used for accounts. NSE calls SEBI's PIT and shareholding-pattern endpoints directly, each returning a real downloadable XBRL document. CVM reads its own yearly VLMO Open Data archive (CVM InstruΓ§Γ£o 358 art. 11) - the same row shape as the IPE archive, just a different yearly ZIP - which combines insider trading and holdings into one filing, so both are covered by category="insider" alone.

For the UK only, category="current_report" returns material operational updates, acquisitions, disposals, trading statements, and board changes; category="proxy" returns AGM/EGM notices and resolutions. These categories are intentionally not exposed for other markets until their official source taxonomy has been live-verified.

search_disclosures() runs a full-text keyword search across every issuer's disclosures for one source, not scoped to a single company. NSM's own top-level keyword field on its search API is a no-op (confirmed live: it doesn't change result counts at all); this uses a headline criterion instead, which does filter. CVM's yearly IPE archive already covers every issuer in one file, so this filters it by subject/type instead of a new endpoint.

get_company_facts() merges a company's most recent structured filings into one multi-period time series per line item - closer to EdgarTools' get_facts() than a single filing's statements. It's pure composition over list_filings()/get_filing_financials(), so it works for any market with structured or PDF-derived financials already, with no adapter changes.

UK TR-1 major-shareholding filings (category="major_holdings" on FCA NSM) are pre-rendered HTML, not a structured feed, but FCA prescribes a fixed section order for the form. list_major_holders() parses that sequence into structured fields (holder name, ISIN, position, dates) - returning None rather than a wrong answer when the expected labels aren't found. search_major_holders() is a bounded, 13F-style reverse lookup: since NSM's search index doesn't carry the holder's identity (only each filing's document body does), it scans the scan_limit most recent TR-1 filings across every issuer and parses each one - not the full historical record, and the cost scales with scan_limit.

The Singapore connector uses SGX's official keyless corporate-information page, listed-stock API, and financial-reports API. It joins stock counters to SGX issuer metadata, keeps Mainboard and Catalist companies, and validates both announcement-detail and PDF-attachment paths.

Mexico uses BMV's official issuer and financial-information services. India uses NSE's listed-equity CSV and annual-report service for filing discovery; financial statements are read directly from NSE's Integrated Filing XBRL (the exclusive format for SEBI Regulation 33 financial results since April 2025 - PDF submission was discontinued), falling back to the annual-report PDF only if no audited XBRL filing covers that exact fiscal year-end. Peru uses SMV's open financial-statement datasets, and Colombia uses SFC/SIMEV's current BVC-equity and financial-report services. For Colombia, the balance sheet is read directly from SFC's CUIF supervisory dataset on datos.gov.co (assets, liabilities, and equity accounts reconcile exactly) instead of parsed from the PDF filing; the income statement still comes from the PDF, since CUIF reports income/expense accounts unclosed for supervisory purposes. Each adapter filters out funds and other non-operating exchange products and validates document hosts before download.

Canada uses the official TSX/TSXV company directory for issuer discovery. SEDAR+ document search is public in a normal browser, but its stateful callbacks and Radware anti-automation controls do not provide a stable public API contract. OpenFilings therefore does not automate discovery or bypass those controls. It accepts the platform's user-generated public document URLs and browser-downloaded PDFs, then routes them through the normal filing pipeline without a browser runtime.

NSM materials remain subject to the FCA's terms and the rights attached to each filed document. PyMuPDF4LLM and PyMuPDF are AGPL-3.0 licensed; review their licensing requirements before proprietary distribution.

The public API and parsing architecture were informed by the MIT-licensed EdgarTools. OpenFilings does not bundle EdgarTools or its SEC, Pandas, and PyArrow runtime. See THIRD_PARTY_NOTICES.md.

The lightweight Inline XBRL path extracts the normalized values used by the application. Use Arelle separately when standards-complete taxonomy loading or regulatory conformance validation is required.

Available Tools

22 tools
companies_compareB

Compare one normalized fact across two to twenty UK/ESEF issuers.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYes
sourceNoall
company_idsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden for behavioral disclosure. It only states the action 'compare' without explicitly confirming that it is a read-only operation, nor does it explain the 'normalized fact' processing or any limitations. The agent cannot infer safety or side effects from this minimal description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire description is one sentence with no filler or redundant phrasing. It is front-loaded with the action word 'Compare' and immediately gives the scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given three parameters, no annotations, and a critical need for parameter clarification, this one-sentence description is incomplete. It doesn't explain what 'normalized fact' means, how to specify sources, or what the output represents, leaving significant gaps for the agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It gives context for `code` as the 'normalized fact' and for `company_ids` as the range of two to twenty issuers, but it fails to explain the `source` parameter or the format of the identifiers. This is insufficient for a tool with three parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'compare' and specifies the resource: 'one normalized fact across two to twenty UK/ESEF issuers.' This clearly distinguishes the tool from sibling tools like company_facts or financials_query, which likely focus on single-company data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for cross-company comparison but does not explicitly state when to use it instead of alternatives like financials_query or disclosures_search. No exclusions or alternative references are provided, so the guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

company_factsA

Merge a company's most recent structured filings into one multi- period fact series per line item, instead of one filing at a time.

ParametersJSON Schema
NameRequiredDescriptionDefault
detailNostandard
sourceNoall
periodsNo
company_idYes
statementsNo
max_line_itemsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the transparency burden. It does disclose the core behavior of merging filings into a multi-period fact series, but it does not explain how 'most recent' filings are selected, how line items are normalized, or any potential limitations. This is moderate transparency given the absence of annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence with no fluff. It front-loads the core action and includes a useful contrast clause. Every word contributes to understanding the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 6 parameters, an output schema, and is one of many related tools, the description provides only the essential purpose. It lacks guidance on parameter selection, data coverage, and edge cases. While the output schema may handle return values, the description alone is insufficient for an agent to fully understand how to use the tool effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not elaborate on any parameters. It only hints at 'multi-period' and 'line item' which might relate to 'periods' and 'max_line_items', but it does not explain the meaning of 'detail', 'source', 'statements', or the exact behavior of the parameters. The description adds minimal value beyond the schema fields themselves.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly uses a specific verb ('Merge') and identifies the resource ('a company's most recent structured filings') and the output ('one multi-period fact series per line item'). It distinguishes from sibling tools like filings_list and financials_query by emphasizing consolidated multi-period data rather than individual filings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'instead of one filing at a time' provides implicit usage guidance, suggesting this tool is for aggregating across filings when a per-filing view is insufficient. However, it does not explicitly name alternative tools or state when not to use it, so it falls slightly short of full clarity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

company_research_briefA

Return recent filings and a compact three-period financial profile.

Ownership and director-dealing data stay in their dedicated tools because coverage differs by source; missing data must not imply no activity.

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceNoall
company_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It does this well by explaining that ownership and director-dealing data are omitted due to source coverage differences and cautioning that missing data should not imply no activity. This is valuable behavioral context beyond the basic purpose, though it doesn't cover aspects like error handling or output structure, which are partially addressed by the output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, with two short sentences/paragraphs. The first sentence states the core purpose, and the second provides a crucial caveat. There is no filler or repetition; every word earns its place, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the tool's primary function and a key caveat, but it lacks essential parameter semantics (especially 'source') and doesn't explicitly relate the tool to siblings like filings_list or financials_query. Given the presence of an output schema, return structure is covered, but the absence of parameter guidance is a significant gap for a tool with only two parameters and no schema descriptions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not explain either parameter. The purpose mentions 'recent filings' and 'financial profile' but doesn't clarify what 'source' means (e.g., valid sources, format) or the exact role of 'company_id' beyond its name. This leaves the agent with insufficient information to correctly set the 'source' parameter, which has a default but no enumerated options.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool's function: 'Return recent filings and a compact three-period financial profile.' This clearly identifies the verb (return), the resource (filings and financial profile), and distinguishes it from siblings like filings_list and financials_query. The mention of ownership and director-dealing data being in dedicated tools further differentiates its scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context that ownership and director-dealing data are intentionally excluded and handled by dedicated tools, which implicitly advises when not to use this tool. It also warns that missing data must not be interpreted as no activity, offering guidance on interpreting results. However, it doesn't explicitly name the alternative tools or state 'use this tool when you need a quick brief.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

data_quality_reportB

Report extraction provenance, confidence, and validation for one filing.

ParametersJSON Schema
NameRequiredDescriptionDefault
filing_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It implies a read-only 'report' operation but does not explicitly state safety, potential side effects, or the nature of validation performed. Additional context such as whether it requires special permissions or returns sensitive data is missing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that directly states the tool's function without any filler or redundancy. It earns full marks for conciseness and structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While the description covers the core purpose and an output schema exists (freeing the description from explaining return values), it lacks usage guidance and behavioral transparency. For a tool with one parameter and no annotations, more context is needed to fully support agent decision-making, making this incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one required parameter (filing_id) with 0% description coverage. The description's phrase 'for one filing' implicitly connects to this parameter but provides no additional meaning about the format or expected values. Since the parameter is self-explanatory, this minimal compensation is acceptable, though it does not fully offset the lack of schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Report extraction provenance, confidence, and validation for one filing' clearly identifies the tool's purpose with a specific verb and resource. It distinguishes itself from sibling tools like filings_list or filing_read by focusing on data quality metadata rather than listing or reading filing content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It does not mention use cases, prerequisites, or scenarios where this tool is preferred over other filing-related tools, so agents lack context for tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

filing_financialsC

Return selected statements with bounded periods and line items.

ParametersJSON Schema
NameRequiredDescriptionDefault
detailNostandard
periodsNo
refreshNo
filing_idYes
statementsNo
max_line_itemsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full burden of behavioral disclosure. The description only says 'Return', which implies a read operation, but it doesn't explain behavior around parameters like refresh (which might trigger side effects), detail levels, or edge cases. It lacks any commentary on safety, caching, or mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no filler. It front-loads the core action. However, it may be too terse for the tool's complexity, but it is appropriately concise for a summary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the six parameters, lack of annotations, and specific sibling tools, the description is under-specified. It doesn't mention the required filing_id, provide context on return values (though output schema exists), or explain how it differs from similar tools like financials_query. The tool is moderately complex, and the description leaves major gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has zero description coverage for its 6 parameters. The description provides partial mapping: 'selected statements' likely refers to the statements parameter, 'bounded periods' to periods, and 'line items' to max_line_items. However, it does not explain filing_id, detail, or refresh. Since schema coverage is 0%, the description inadequately compensates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns selected statements with bounded periods and line items, indicating the resource (financial statements) and action (return). It is not a tautology. However, it doesn't explicitly mention it's from a filing, though the tool name and required filing_id imply this, and it doesn't differentiate from siblings like financials_query.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention any prerequisites, exclusions, or alternative tools. Given the array of sibling tools, this is a clear gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

filing_markdownA

Read a bounded Markdown page; prefer outline, search, or section tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
refreshNo
ocr_modeNo
filing_idYes
max_charsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses the read-only nature ('Read') and bounded output ('bounded'), but does not explain offset/refresh/ocr_mode behavior, pagination, or error cases. It adds some useful context but leaves significant behavioral traits unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very short and front-loaded with no filler, which is positive. However, it is under-specified for a five-parameter toolβ€”essential parameter semantics are missing, so conciseness comes at the cost of completeness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given five parameters, no annotations, and zero schema description coverage, the description is too sparse. It does not explain offset, refresh, ocr_mode, or max_chars semantics, and only provides sibling guidance. The output schema may cover return values, but input behavior remains largely unexplained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not name any of the five parameters. 'Bounded' hints at max_chars and 'Read' implies filing_id, but the semantics of offset, refresh, and ocr_mode are entirely unaddressed, so the description fails to compensate for the schema's lack of parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('Read') and resource ('bounded Markdown page'), and further distinguishes itself from siblings by saying to prefer outline, search, or section tools. This makes the tool's purpose unmistakable and differentiates it from filing_read, filing_outline, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'prefer outline, search, or section tools' gives explicit guidance to use alternatives when possible, implying this tool is a fallback for whole-page Markdown reads. It does not specify exact conditions (e.g., 'use when you need full text'), but it provides clear contextual direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

filing_outlineB

Return headings and sizes only, allowing targeted section selection.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
refreshNo
filing_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the burden. It does add scope ('only' headings and sizes) and the selection use case, but it does not disclose behavior around the `refresh` flag, caching, failure modes, or the meaning of 'sizes'. This is a minimal but non-contradictory addition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One concise sentence, front-loaded with the core action, and no wasted words. It is appropriately short for the simplicity of the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description lacks context about when this is preferable to sibling tools, what `limit` and `refresh` do, and any caveats. Though an output schema exists, the absence of usage guidance and parameter explanation makes it incomplete for effective tool selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does not explain `filing_id` (though obvious), `limit`, or `refresh`. The phrase 'headings and sizes' relates to output, not input parameters. No parameter semantics are provided beyond the schema's names and defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Return') and identifies the resource ('headings and sizes') with a clear scope constraint ('only'). It distinguishes the tool from siblings like filing_read or filing_markdown by signaling that this is a structural outline, not full content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'allowing targeted section selection' implies the use case, but it does not explicitly name alternatives or state when not to use this tool. No exclusionary guidance is given relative to sibling tools like filing_sections or filing_read.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

filing_readB

Read one named filing section through a bounded, paginated response.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
refreshNo
sectionYes
filing_idYes
max_charsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden for behavioral disclosure. It does reveal that responses are 'bounded, paginated', which is a positive trait, but it fails to explain what 'bounded' means (e.g., via max_chars), how pagination works (offset), whether refresh has side effects, or whether any permissions are needed. The safety profile (read-only) is only implied by the word 'Read', which is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler or redundant information. It conveys the core purpose and a key behavioral trait (bounded, paginated) in just ten words, earning high marks for conciseness and structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having an output schema (which covers return values), the description is incomplete for a tool with five parameters. It lacks any guidance on required fields (filing_id, section), optional parameters (offset, refresh, max_chars), or prerequisites like obtaining the section name. The brevity leaves the agent to guess parameter usage, making the description insufficient for effective tool invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, but it does not explain any of the five parameters. The phrase 'bounded, paginated' loosely relates to max_chars and offset, but no parameter names or meanings are given. For a tool with multiple parameters, this is extremely inadequate; the agent cannot correctly map arguments from the description alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads one named filing section, using the verb 'Read' with a specific resource ('one named filing section') and notes the bounded, paginated response. This distinguishes it from siblings like filing_sections (lists sections) and filing_markdown (full text), making it distinct among the filing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool (when a specific named filing section is needed), and the phrase 'one named filing section' hints that the section name must already be known, possibly from filing_sections. However, it provides no explicit guidance on when not to use it or alternatives, leaving usage context mostly inferential.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

filings_diffB

Compare normalized facts in two filings and return changed values.

ParametersJSON Schema
NameRequiredDescriptionDefault
first_filing_idYes
second_filing_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It implies a read-only comparison but does not explicitly state that no changes are made to filings, nor does it disclose any permissions, side effects, or edge cases (e.g., what happens when there are no changed values). The phrase 'return changed values' hints at output but lacks detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that efficiently conveys the core purpose. It is appropriately sized, has no redundant content, and is easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is conceptually simple with a clear output schema available, so a brief description may suffice. However, it lacks context on how the IDs are used, what 'normalized facts' means, and whether the tool requires any preconditions (e.g., filings must exist and be comparable). The description is minimal but not entirely inadequate for a tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameter descriptions (0% coverage), and the description only says 'two filings' without explaining the purpose or format of first_filing_id and second_filing_id. It does not clarify the type of IDs expected (e.g., filing IDs vs. accession numbers) or the relationship between the two parameters. The description adds minimal value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Compare normalized facts in two filings and return changed values.' It uses a specific verb (compare) and resource (filings), and the context (normalized facts, changed values) distinguishes it from siblings like companies_compare or filing_read.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. It does not mention exclusions, prerequisites, or scenarios where other tools (e.g., filing_read or companies_compare) would be more appropriate. The description simply states what it does, leaving usage decisions to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

filing_sectionsB

Compatibility outline tool; returns headings without section bodies.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryNo
filing_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It usefully discloses that the tool returns only headings (not section bodies), which is a key behavioral trait. However, it omits other potentially relevant details such as authorization requirements, rate limits, or handling of invalid filing IDs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that conveys the essential function without redundant language. It is front-loaded with the tool's role and core outcome.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The presence of an output schema reduces the need to describe return values. However, the description lacks usage guidance and parameter semantics, which are critical for an agent to confidently select this tool over similar filing tools. It is minimally complete but has clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With schema description coverage at 0%, the description should compensate by explaining parameter meanings and relationships. It does not mention any of the three parameters (filing_id, limit, query). The schema provides names and types but no descriptions, leaving the agent to infer semantics from names alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns headings without section bodies, specifying the verb 'returns' and the resource (headings). However, it does not explicitly differentiate from the sibling tool 'filing_outline', which likely serves a similar purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternatives like filing_outline, filing_read, or filing_markdown. There is no mention of use cases, prerequisites, or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

filings_listB

List compact filing metadata without downloading document content.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
sourceNoall
categoryNoaccounts
company_idYes
history_daysNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It only states that it lists compact metadata, but does not disclose filtering options, default limits, history_days behavior, or output characteristics. Given the tool has five parameters, this is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no redundant words, effectively communicating the core function in seven words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has five parameters and many related siblings, but the description provides minimal context. It lacks guidance on parameter usage, relationships to other filing tools, and any nuances beyond the basic metadata-only scope.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description does not mention any parameter, leaving limit, source, category, company_id, and history_days unexplained. The description adds no value for understanding these parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description specifies the action 'List' and the resource 'compact filing metadata', and explicitly excludes downloading document content, which distinguishes it from content-focused tools like filing_read and filing_markdown.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use when metadata is needed, but does not explicitly state when to use it over alternative tools or when not to use it. The 'without downloading document content' provides some context but lacks direct comparison to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

financials_queryB

Return only selected multi-period financial facts with provenance.

ParametersJSON Schema
NameRequiredDescriptionDefault
codesYes
sourceNoall
periodsNo
company_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that results are filtered ('only selected'), span multiple periods ('multi-period'), and include provenance, which adds useful context. However, it does not explain the nature of provenance, any limitations, or whether the query is read-only, leaving gaps in behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly worded sentence that front-loads the key information with no redundancy. Every phrase ('only selected', 'multi-period', 'with provenance') contributes meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-value details are not required. However, given the tool's moderate complexity (4 parameters, 2 required) and several closely related sibling tools, the description lacks usage guidance and parameter semantics needed to fully disambiguate. It is adequate but not comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It loosely maps 'selected' to the 'codes' parameter and 'multi-period' to 'periods', but it does not explain the meaning of 'source', 'company_id', or how the parameters interact. The description adds minimal value over the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Return') and resource ('financial facts') with qualifiers ('selected multi-period', 'with provenance'), making the core function clear. It distinguishes itself from siblings like historical_facts_query or company_facts by emphasizing selectivity and provenance, though it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus siblings such as company_facts or filing_financials. The description only implies a narrowed scope ('only selected') but does not state exclusions, prerequisites, or alternative tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

historical_backfillB

Download available UK/ESEF structured filing history into local storage.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
sourceYes
company_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It states the download action but does not disclose side effects such as whether data is overwritten, whether authentication or rate limits apply, or what 'local storage' entails. This is insufficient for a tool that writes data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with a clear verb and object, front-loaded and free of jargon or unnecessary words. It earns its place despite being terse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has moderate complexity with three parameters and no annotations, and the description is too minimal to support correct invocation. It lacks usage criteria, parameter details, and behavioral implications, making it incomplete for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has zero descriptions for its three parameters, and the description does not compensate. It only hints that 'UK/ESEF' relates to the source enum, but does not explain company_id or limit. The meaning must be inferred from parameter names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool downloads UK/ESEF structured filing history into local storage, naming a specific verb (download), resource (filing history), and scope (UK/ESEF). This differentiates it from sibling tools like filings_list or filing_read that focus on viewing or querying, not bulk downloading.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. The description does not mention any exclusions, prerequisites, or comparisons to sibling tools such as filings_list or historical_facts_query, leaving the agent without usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

historical_facts_queryC

Query locally stored filing facts with restatement-aware semantics.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNolatest_restated
as_ofNo
codesNo
limitNo
company_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description bears full responsibility for behavioral disclosure. It mentions 'locally stored' and 'restatement-aware semantics' which hints at data locality and restatement handling, but it does not explain what restatement-aware means, whether results reflect as-reported or restated values, or any side effects. The description is vague and fails to disclose important details about output behavior or constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that concisely states the core action. It avoids unnecessary words and is easy to parse. It is appropriately brief for a simple query tool, though the brevity comes at the cost of essential details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has five parameters, an enum, and restatement-aware semantics, the description is far too sparse to be complete. It does not explain the view modes, the as_of date behavior, or the meaning of codes and limit. Although an output schema exists, the description still needs to explain how to use the tool, which it does not. The agent would struggle to use this correctly without external documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description adds no explanation of the five parameters (view, as_of, codes, limit, company_id). The enum for 'view' and the date logic for 'as_of' are left completely unexplained. The description's phrase 'restatement-aware semantics' does not translate to parameter meaning, leaving the agent to guess how to set parameters correctly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool queries locally stored filing facts, with the specific qualifier 'restatement-aware semantics' indicating a key differentiator from sibling tools like company_facts or financials_query. The verb 'query' plus the resource 'filing facts' makes the core purpose unambiguous, though it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. It does not mention prerequisites, exclusions, or conditions for selecting this over sibling tools. The description merely states what it does, leaving the agent to infer usage context from the name and parameters.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

insider_dealings_listB

List UK MAR director/PDMR/PCA dealings parsed into structured fields.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
company_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It adds 'parsed into structured fields,' which hints at output formatting, but does not disclose behaviors such as sorting, pagination, or any limitations. It does not contradict annotations (none exist), but it provides minimal additional context beyond the tool's name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence that conveys the core function without fluff. It is well-structured and efficient, earning a high score for conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (two parameters, output schema exists), but the description is too sparse to be complete. It does not explain what structured fields are returned, nor any edge cases or usage context. The existence of an output schema helps, but the description itself leaves gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not elaborate on parameters. However, the parameter names are self-explanatory (company_id and limit), and limit has a default. The description adds no semantic value beyond the schema, so a score of 2 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List UK MAR director/PDMR/PCA dealings parsed into structured fields.' It specifies the verb (List), the resource (dealings), and the scope (UK MAR director/PDMR/PCA), which distinguishes it from sibling tools like major_holders_list or disclosures_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. It does not mention when not to use it, nor does it reference sibling tools. The usage context is implied by the tool name and description, but there is no explicit direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

major_holders_listC

List structured major-holder records for a UK or Brazilian issuer.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
company_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It only says 'List structured...' which implies a read operation, but does not disclose behaviors such as pagination, authorization requirements, or error handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence with no redundant words. It is highly efficient and front-loaded, earning every word.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite the presence of an output schema, the description lacks essential context such as what constitutes a 'UK or Brazilian issuer', how the list is sorted or paginated, and when to use this tool. Given no annotations and poor parameter coverage, it is insufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not explain the meaning or purpose of the 'company_id' or 'limit' parameters. It only vaguely implies that an issuer is needed, but adds no value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: listing structured major-holder records for a UK or Brazilian issuer. It uses a specific verb and resource, but does not explicitly distinguish from the sibling tool 'major_holders_search'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided about when to use this tool versus alternatives like 'major_holders_search' or other siblings. The description only states what it does without indicating appropriate usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sedar_filing_importC

Import one official SEDAR+ generated PDF URL into the local cache.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
categoryNoaccounts
company_idYes
period_endNo
filing_dateYes
filing_typeNoannual
document_urlYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the basic action (import to cache) but does not mention side effects, permissions, whether it overwrites existing entries, rate limits, or any error conditions. This is a significant gap for a tool that modifies local state.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence with no redundant words. It front-loads the core action and resource, making it easy to grasp. However, the brevity sacrifices necessary detail for a tool with 7 parameters, so it is concise but not optimally structured for completeness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter import tool with no annotations and minimal description, this is severely incomplete. It does not explain return values, behavior on repeated imports, or how parameters interrelate. Although an output schema exists, the description alone leaves critical gaps that prevent an agent from using it effectively.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not explain any of the 7 parameters. It only hints at document_url via 'PDF URL', leaving required fields like company_id, title, filing_date, and optional fields like category, period_end, filing_type completely unaddressed. This fails to guide the agent in constructing valid calls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the action (import) and resource (one official SEDAR+ generated PDF URL into local cache). This distinguishes it from siblings like filing_read or filings_list. However, it doesn't elaborate on what 'import' entails (download, parse, store), which keeps it from a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives. It does not mention prerequisites, exclusions, or scenarios where this tool is preferred over filing_read or filings_list. The implied usage (import a PDF URL into cache) is present but there is no explicit context or direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

watchlist_checkC

Statelessly return filings published on or after since.

ParametersJSON Schema
NameRequiredDescriptionDefault
sinceYes
sourceNoall
company_idsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The term 'statelessly' discloses that the call does not depend on prior state, which is useful behavioral context. However, with no annotations provided, the description does not go further to explain effects (e.g., whether a watchlist must exist), potential side effects, or data scope, leaving the burden largely unaddressed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence and is not padded with unnecessary details. It is front-loaded with the core action ('return filings') and quickly specifies the key filter. However, the brevity comes at the cost of missing context, so it is concise but not fully effective.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has three parameters and an output schema, the description is too terse to be fully useful. It omits the relationship between company_ids and the returned filings, what 'watchlist' implies, and the meaning of `source`, leaving an agent with incomplete information for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It clarifies the `since` parameter's role as a date cutoff, but it does not explain `company_ids` beyond the schema's property name, nor does it elaborate on the `source` parameter and its default 'all' value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the tool 'return[s] filings published on or after since', identifying a clear verb and resource with a date filter. However, it does not clarify the role of company_ids or what 'watchlist' refers to, and it does not differentiate this tool from siblings like filings_list or filing_search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives such as filings_list or filing_search. The description neither provides context for typical use cases nor mentions exclusions, so an agent receives no help in selecting among the many filing-related sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 22 tool updatesv0.22.0
    • First observedcompanies_compare
    • First observedcompanies_search
    • First observedcompany_facts
    • First observedcompany_research_brief
    • First observeddata_quality_report
    • First observeddisclosures_search
    • First observedfiling_financials
    • First observedfiling_markdown
    • First observedfiling_outline
    • First observedfiling_read
    • First observedfiling_search
    • First observedfiling_sections
    • First observedfilings_diff
    • First observedfilings_list
    • First observedfinancials_query
    • First observedhistorical_backfill
    • First observedhistorical_facts_query
    • First observedinsider_dealings_list
    • First observedmajor_holders_list
    • First observedmajor_holders_search
    • First observedsedar_filing_import
    • First observedwatchlist_check

TDQS

B3/5.0

Scored across 22 tools

Disambiguation3/5

Most tools target distinct resources or actions, but filing_outline and filing_sections are nearly identical, both returning headings without section bodies. Additionally, filing_read, filing_markdown, and filing_search could be confused if descriptions are not carefully read, though their purposes are subtly different.

Naming Consistency3/5

Tool names mostly follow an object-first pattern (e.g., filings_list, companies_search), but the action placement is inconsistentβ€”sometimes at the end (filings_diff, financials_query) and sometimes absent or noun-based (filing_outline, company_research_brief, company_facts). This mix makes the naming less predictable than a uniform verb_noun scheme.

Tool Count4/5

22 tools is on the higher end but appropriate for a comprehensive filings domain that spans company research, filing retrieval, structured financial queries, ownership data, and historical backfill. The count is not excessive given the breadth, though one redundant tool pair slightly inflates it.

Completeness4/5

The tool set covers the core workflows: locating companies, listing and reading filings, extracting structured financial facts, comparing filings, and monitoring new submissions. It also includes an import tool for external filings. Minor gaps exist (e.g., no full-text search for insider dealings), but the surface is largely complete for the intended use.

Maintenance

ActivitySlowing
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    MCP server for Chinese A-share (Shanghai/Shenzhen/Beijing) financial statements: pull annual reports, run 4 industry-aware accounting cross-checks, and peer-compare companies with derived avg-equity ROE.
    3
    5
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    MCP server to fetch Vietnamese corporate financial reports (balance sheet, income statement, cash flow) from cafef.vn using public API, no PDF or OCR needed.
    3
    7 npm
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that wraps SEC EDGAR APIs to provide company financial data, screening metrics, and disclosure signals for investment diligence, with every figure traced to its source filing.
    8
    MIT