
Disclosures
io.github.carrotly-ai由 GitHub 帳號 carrotly-ai 發布v0.8.0更新於 Oct 24, 2026
Corporate disclosures from 26 official sources across 21 jurisdiction routes via ten tools.
概覽
一個 MCP 伺服器兼 TypeScript 函式庫,讓助理從各國官方登記機關查詢公司揭露、董監事、股東、財務資料與股權鏈。
- 可以做什麼
- 依名稱、股票代號、LEI、ISIN 或當地登記號在 21 條司法管轄路由中解析公司
- 取得申報文件、內部人與大股東揭露,以及依原始申報擷取的財務數字
- 透過 GLEIF 追蹤全球會計合併基礎的股權鏈
- 分頁讀取申報內文或儲存限定大小的 PDF,並查詢擔保登記與個人任職
- 回傳附官方來源連結的 Markdown 結果,並提供可串接呼叫的結構化輸出
- 適用情境
- 適合需要可溯源答案的公開公司問題,例如董事會成員、5% 以上股東、年度業績、美國 Form D 私募募資或集團股權結構,並要求每項結論都能連回官方文件。較適合研究與盡職調查類查詢,而非即時行情。
- 執行需求
- 以 Node 18+ 本機程序執行,通常透過 npx 啟動。美國及全球查詢需提供含聯絡方式的 DISCLOSURES_USER_AGENT。可選免費金鑰:COMPANIES_HOUSE_API_KEY、OPENDART_API_KEY、EDINET_API_KEY、DBD_API_KEY。使用 ASX 與 PSE 資料需將 DISCLOSURES_ACKNOWLEDGE_ASX_TERMS 或 DISCLOSURES_ACKNOWLEDGE_PSE_TERMS 設為 1。需要連線至各官方登記機關。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Disclosures,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
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.
來源:README.md,提交 ce99645
工具
0版本歷史
1- v0.8.0最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分