
Disclosures
io.github.carrotly-aiPublished by GitHub account carrotly-aiv0.8.0Updated Oct 24, 2026
Corporate disclosures from 26 official sources across 21 jurisdiction routes via ten tools.
Overview
MCP server and TypeScript library that lets an assistant look up corporate filings, insiders, owners, financials and ownership chains from official registers…
- What you can do
- Resolve companies by name, ticker, LEI, ISIN or local register number across 21 jurisdiction routes
- Retrieve filed documents, insider and major-holder disclosures, and as-filed financial figures
- Trace GLEIF accounting-consolidation ownership chains globally
- Read filing text in pages or save a bounded PDF, and check secured charges and person appointments
- Return Markdown results with source links plus structured output for chaining calls
- When to use it
- Useful when an assistant needs sourced answers about public companies — boards, 5% holders, annual results, private Form D raises or group ownership — and every claim should link back to an official filing. Best for research and due-diligence style questions rather than live market data.
- Requirements
- Runs locally as a Node 18+ process, typically via npx. US and global lookups need a descriptive DISCLOSURES_USER_AGENT with contact details. Optional free keys: COMPANIES_HOUSE_API_KEY, OPENDART_API_KEY, EDINET_API_KEY, DBD_API_KEY. ASX and PSE data require setting DISCLOSURES_ACKNOWLEDGE_ASX_TERMS or DISCLOSURES_ACKNOWLEDGE_PSE_TERMS to 1. Network access to official registers is required.
Installation
In SourceWeft
- Open Disclosures in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
disclosures
Corporate-disclosure research for AI agents and TypeScript — filings, insiders, owners, financials, and ownership chains from 26 official sources across 21 jurisdiction routes (20 national routes plus the EU aggregate).
[npm version] [CI] [License: Apache-2.0] [Node >= 18] [Bundled runtime] [MCP Registry]
disclosures is a free, open-source Model Context Protocol server and a TypeScript library. It answers questions like "who are NVIDIA's directors?", "who owns 5% of Samsung Electronics?", or "show me Vale's last three annual results" — with every answer linked back to the official source document.
- 10 stable tools, 21 jurisdiction routes — six core tools dispatch via
jurisdiction;OwnershipChainis global; three specialized tools cover filed documents, secured charges, and person-level lookups. Tool names stay stable as coverage grows. - Official sources only — SEC EDGAR, GLEIF, Companies House, FCA NSM, filings.xbrl.org, OpenDART, EDINET, cninfo, SZSE, BSE, TWSE, CVM, BaFin, info-financiere, recherche-entreprises, HKEXnews, ACRA, DBD, AFM, IDX, Bursa Malaysia, KAP, DFM, PSE EDGE, ASX, and ASIC.
- Honest by design — real source links only, explicit "unsupported here" answers instead of empty or fabricated results, and clear caveats ("absence of a filing is not proof").
- Bundled runtime — one JavaScript file for Node 18+. MCP SDK and Zod are declared package dependencies so TypeScript consumers receive the types used by the public API.
Quick start
Requires Node 18+. SEC-backed US calls require a descriptive User-Agent under EDGAR's fair-access policy; keyless non-US routes can run without it.
Claude Code
Claude Desktop
Add to claude_desktop_config.json (Settings → Developer → Edit Config):
Cursor
Add the same mcpServers block as Claude Desktop to ~/.cursor/mcp.json (or per-project .cursor/mcp.json).
VS Code (Copilot / MCP)
Add to .vscode/mcp.json:
Other clients — Windsurf, Codex CLI, Gemini CLI, and any stdio MCP client
Windsurf (~/.codeium/windsurf/mcp_config.json) uses the same mcpServers JSON as Claude Desktop.
Codex CLI (~/.codex/config.toml):
Gemini CLI (~/.gemini/settings.json) uses the same mcpServers JSON as Claude Desktop.
Any other client: run npx -y disclosures as a stdio command with the DISCLOSURES_USER_AGENT environment variable set. The server speaks newline-delimited JSON-RPC on stdout. It is also listed on the official MCP registry as io.github.carrotly-ai/disclosures.
HTTP mode
The same server also speaks the MCP streamable-HTTP transport, for hosted or networked deployments. Pass --http (stdio remains the default with no flag):
- Binds
127.0.0.1by default. Port comes from--port, else thePORTenv var, else8080. Host and supplied Origin headers must match the server allowlists. Non-loopback binds require a bearer token and explicit allowed hosts. - MCP endpoint:
POST /mcp(the transport also answers the streamable-HTTPGET/DELETEhandshake). Runs stateless — no session id, a fresh server instance per request. - Health check:
GET /healthz→200 {"name","version","tools"}. - Diagnostics go to stderr only, as in stdio mode.
Connect any streamable-HTTP MCP client at http://127.0.0.1:8080/mcp.
For a hosted service, supply DISCLOSURES_HTTP_TOKEN through your deployment's secret configuration, then set:
Terminate TLS at your reverse proxy, preserve the configured Host header, and have clients send Authorization: Bearer <token>. Allowed hosts are exact authorities, including a port when clients send one; comma-separated values are supported. Origins default to http:// origins for the allowed hosts; set HTTPS origins explicitly behind TLS termination. Requests without Origin are supported for non-browser clients. The health endpoint checks Host/Origin but does not require the token.
Library deployments use runHttpServer({ bearerToken, allowedHosts, allowedOrigins, downloadDirectory }) for the same policy. HTTP downloads always stay in a server-controlled directory (a private temporary directory by default); output_path accepts a filename only. Stdio/library downloads may use an explicit local path. All modes refuse to overwrite existing files or symlinks; omitted paths produce unique private temporary files.
Restart the client after changing its configuration, then try:
"Use disclosures to list Apple's board of directors and their latest Form 4 activity." "Who holds 5% or more of NVIDIA? Link the filings." "Resolve Samsung Electronics in Korea and show its latest annual financials." "What's the GLEIF ownership chain above Apple Operations India?"
The ten tools
Six core tools dispatch across all jurisdiction routes via jurisdiction; OwnershipChain is global and jurisdiction-independent. CompanyDocument accepts US, GB (default), JP, KR, FR, HK, CN, IN, TR, AE, PH, and AU; PersonAppointments accepts US, GB (default), DE, FR, and AU; CompanyCharges is Companies House-specific and takes no jurisdiction.
Every company input accepts a name or a local identifier — ticker, CIK, LEI, or ISIN (US/global), Companies House number (GB — incl. SC/NI prefixes for Scotland and Northern Ireland), OpenDART corp/stock code (KR), EDINET/securities/corporate code (JP), A-share or HK code (CN), BSE scrip (IN), TWSE listing code (TW), CVM registration code (BR), BaFin-Id or ISIN (DE), SIREN/ISIN/LEI (FR), 4/5-digit HKEX stock code (HK), Singapore UEN (SG), 13-digit juristic-person registration number (TH), AFM-register issuer name or LEI (NL), 4-letter IDX ticker / kode emiten (ID), 4-digit Bursa stock code or issuer name (MY), BIST stock code (TR), DFM issuer symbol (AE), PSE ticker symbol or numeric PSE company id (PH). Pass jurisdiction: "US" | "GB" | "EU" | "KR" | "JP" | "CN" | "IN" | "TW" | "BR" | "DE" | "FR" | "HK" | "SG" | "TH" | "NL" | "ID" | "MY" | "TR" | "AE" | "PH" | "AU" (default US).
Coverage matrix
✅ supported · ⚠️ partial (FR CompanyOwners: threshold-crossing notifications with a best-effort structured extraction — holder, direction, threshold(s) and resulting % parsed from the notification PDF's text layer for the newest few; scanned/non-standard PDFs and older notifications stay a link-only list · HK CompanyOwners: the keyless CCASS shareholding search returns participant/custodian-level holdings (custodian banks, brokers, HKSCC Nominees, CSDC) — not beneficial owners; the SFO Part XV Disclosure of Interests register is captcha-walled and linked for manual lookup · HK CompanyFinancials: headline figures extracted from the issuer's latest results-announcement PDF, latest announcement only — standard issuers extract cleanly, complex segment-split/multi-column statements parse partially, and a page shortfall or missing statement degrades to the PDF link · CN CompanyFinancials: headline figures extracted from the 主要会计数据 key-data table of the issuer's latest periodic-report PDF, normalized to whole RMB from the report's stated unit (元/千元/万元/百万元), latest report only — a mojibake (object-stream) report, an over-cap PDF, or a missing key-data table degrades to the PDF link · CN CompanyOwners: the 前十名股东 top-10 shareholders table parsed from the issuer's freshest periodic report — real major-shareholder data, but ragged and issuer-variable in column order, so a value-heuristic parser emits only confidently-matched rows; an as-published point-in-time snapshot, not a live register and not UBO tracing · CN CompanyInsiders: asymmetric by exchange — SZSE codes (0/3xxxxx) use SZSE's keyless structured 董监高 share-change feed, while SSE codes (6xxxxx) fall back to the as-published 董监高 board roster in the latest annual report, names and positions only) · ID is served over an anti-bot-protected host (www.idx.co.id): the adapter sends browser-class headers and works wherever those pass, and where the edge refuses it returns an explicit "the host blocked this request — inject a browser-backed fetchFn" note stating it is not an empty result for the issuer, never a silent miss · TR CompanyFilings is a deliberate dash: KAP serves the BIST directory and every disclosure page/PDF keylessly, but its Next.js rebuild moved the data layer to kapsitebackend.mkk.com.tr, which does not resolve publicly — anything addressable by disclosure id works, while enumeration does not (the per-company notifications page returns 200 but server-renders an empty shell and fetches its rows from that unreachable host), so the tool explains why and points at the issuer's KAP page rather than faking a list · PH CompanyFinancials is partial: PSE EDGE serves the headline statement its own 17-A form carries (balance sheet + income statement, in PHP), not the full audited statements, which stay in the report's PDF attachments · — returns an honest unsupported-jurisdiction explanation, never an empty or fabricated result
NL CompanyOwners/CompanyInsiders are fully supported but read whole-file AFM register exports (no server-side filtering exists; the substantial-holdings export is ~108 MB): the first call in a session takes ~20–30 s, after which a cached 24 h per-issuer digest serves the rest in milliseconds. Supply an AdapterOptions.cache (e.g. FileCache) in per-request deployments.
⚠️ ASX and PSE EDGE are restricted sources and are disabled before network access by default. Their terms limit use and redistribution in ways that may conflict with an automated disclosure service. Review AU.md and PH.md, then set
DISCLOSURES_ACKNOWLEDGE_ASX_TERMS=1and/orDISCLOSURES_ACKNOWLEDGE_PSE_TERMS=1only if you have the rights to use that source in your context. ASIC's CC-BY Australian company and disqualification registers remain available without ASX acknowledgement. Enabled responses retain the source-specific terms notice. Not legal advice.
Each jurisdiction has a full reference page — data source, credentials, accepted identifiers, per-intent behavior, and caveats — under docs/jurisdictions/.
Data sources and credentials
US and global lookups work with just the User-Agent. Non-US sources are keyless where the upstream allows it; the few that need keys are free. Provide only the keys for jurisdictions you query — everything else keeps working without them, and a missing credential produces a readable error naming the exact variable to set.
SEC_EDGAR_USER_AGENT is accepted as a fallback for compatibility; DISCLOSURES_USER_AGENT wins.
Use as a TypeScript library
The same package imports cleanly without starting stdio — every adapter takes injectable { fetchFn?, env?, cache? }, so it embeds and tests deterministically.
Handlers never throw — every failure comes back as a readable MCP-shaped result. Individual adapters are also exported as namespaces (secEdgar, gleif, companiesHouse, openDart, edinet, cninfo, szse, bseIndia, fcaNsm, xbrlFilings, twseOpenApi, cvmOpenData) if you want the raw normalized records instead of Markdown.
Persistent caching — skip re-downloading the KR/JP reference archives on restart
The OpenDART corp-code list (KR) and EDINET code list (JP) are multi-megabyte archives that regenerate about daily. Without a supplied cache they use a TTL-aware process cache; supply one to persist across restarts:
cache is any DisclosuresCache (get/set). InMemoryCache and FileCache ship in the box; a corrupt, expired, or missing entry degrades to a normal refetch — a broken cache never breaks a lookup. FileCache publishes complete entries by atomic rename. Completed process values expire normally, and concurrent fetches share only in-flight work.
ISIN ↔ LEI cross-walk — map securities to issuers and back via GLEIF
CompanyResolve already accepts a bare ISIN and routes it through this cross-walk; the helpers are for building your own identifier maps.
MCP server factory — embed the server in your own process
Importing the package never opens stdio; only the CLI entry point connects the transport.
Built for AI clients
Responses are designed for the way an MCP client actually consumes them:
- Markdown-first rendering. Every result is one GitHub-flavored Markdown text block — headings, compact pipe tables (headers stated once, not repeated per row like JSON), real source links, and inline caveats. This is the token-efficient path for an LLM reader.
- Structured output for chaining. Data-bearing tools additionally return MCP
structuredContentmirroring the Markdown facts, so a client chains calls without parsing prose:CompanyResolveranked candidates with full identifier sets,CompanyFilingsand register records with a ready-to-usetransactionId,PersonAppointmentspeople with theirofficerId, plusCompanyInsiders,CompanyOwners,CompanyFinancials(per-concept facts labelled by fiscal period end),OwnershipChain,PrivateRaises, andCompanyCharges— each tagged with itssourceJurisdiction.OwnershipChainalso declares an MCPoutputSchema; the multi-jurisdiction tools keep their honest-miss text-only paths and so emit structure additively without a declared schema. - Next-step trailers. Chainable outputs end with a one-line
_Next: …_hint naming the tool and parameter to call next. - Tool annotations. All tools declare
openWorldHintandidempotentHint; all butCompanyDocument(whosepdfmode writes a local file) declarereadOnlyHint, so clients can parallelize and skip confirmation prompts. - Paged document text.
CompanyDocumentmodexhtmlreads in 50,000-character windows viatext_offset— long filings are fully readable, not head-truncated. - Fenced untrusted content. Extracted filer-authored text is wrapped between fixed
<<<BEGIN/END UNTRUSTED DOCUMENT TEXT>>>sentinels (with lookalikes inside the document defanged), so clients can quarantine it programmatically. - Jurisdiction resources. The server exposes
disclosures://jurisdictionsanddisclosures://jurisdictions/{code}MCP resources describing each jurisdiction's source, credential, accepted identifiers, and caveats — check requirements without a failed tool call.
Honesty and scope
These tools report public disclosures, faithfully — they are not KYC, UBO, or cap-table products:
- Absence is not proof. No Form D doesn't mean a company never raised privately; a missing PSC doesn't prove no controller exists; a blank ECCTA identity field doesn't prove an officer is unverified.
- GLEIF parents are accounting-consolidation relationships — not voting control, market-disclosure ownership, or ultimate beneficial ownership.
- Schedule 13D/13G identifies filers at the 5% threshold; it is not a complete or continuously current capitalization table.
- Section 16 insiders reflect recent Forms 3/4/5 and may not be a complete current roster.
- Filings can be amended, restated, late, or tagged under alternate XBRL concepts — verify against the linked source documents.
- Nothing here is legal, investment, accounting, or financial advice.
Resolution misses come back as plain "Could not find…" text; configuration, upstream, and rate-limit failures come back as flagged errors naming the fix. Every link is a real, resolvable source URL.
Documentation
Development
Requires Bun for development; the published artifact runs on Node 18+.
For automation that must not load local environment files, run package-manager
commands in a clean checkout: Bun's install/audit commands do not honor the
runtime --no-env-file flag. PRs run the complete offline gate on Node 22;
release validation additionally checks Node 18/20/22/24 and live providers.
See publishing for the version, security, and publication gates.
The default suite never touches the network: routed fetch stubs throw on any unmatched request. A separate live end-to-end suite builds the real Node artifact, drives it over MCP stdio, and uses whichever credentials are present in .env.local:
Live assertions are drift-tolerant (identity, identifier shape, source host, and response structure rather than volatile counts or dates), transient failures retry once, calls are time-bounded, and diagnostics redact configured keys. The live files use a .live.ts suffix so bare bun test cannot discover them. See the full testing discipline. The smaller bun run smoke:live SEC/GLEIF diagnostic remains available for quick checks.
stdio rule: the server reserves stdout for JSON-RPC — contributor diagnostics must go to stderr, since console.log corrupts the MCP transport.
Current gaps
Coverage grows additively behind the existing tool set. India's remaining deepening target is CompanyOwners from the latest-quarter BSE shareholding iXBRL/XML; annual-report PDF ownership tables are intentionally not parsed because the corpus was too irregular. The 20 October source check found current discovery blocked and a legacy endpoint serving stale data, so ownership remains unsupported until a current corpus is verified. Other gaps are documented per jurisdiction rather than represented as empty data. Suggestions and issues are welcome on GitHub.
License
Apache-2.0. Copyright Carrotly AI.
Source: README.md at commit ce99645
Tools
0Version history
1- v0.8.0LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts