AStockEvent
A-share filings: reductions, penalties, regulatory letters and stock halts. Source-linked facts.
我该使用它吗
质量与安全性
基于对工具定义和协议合规性的自动分析。
上下文开销
这是每次将服务器的工具加载到模型上下文窗口时所消耗的大致 token 数。数值越高,可用于其他任务的注意力就越少。
安装
一键安装
将以下内容添加到你的 `claude_desktop_config.json` 文件中:
{
"mcpServers": {
"astockevent": {
"url": "https://astockevent.com/mcp/"
}
}
}远程端点
https://astockevent.com/mcp/streamable-http它能做什么
工具清单
工具(8)
🟢get_entity_state(code, market, aent_, locale)
Return what is true RIGHT NOW about one A-share listed company or one shareholder entity, folded from its regulatory filings: pending and executed share-reduction plans, administrative-penalty proceedings, and exchange inquiry letters. Call this when you need the current situation of a specific subject — for example 'is this shareholder still selling', 'is this company under investigation', 'has it replied to the inquiry letter'. Do NOT call this to find out what happened across the market recently — use scan_recent_events or whats_new for that. Do NOT pass both (code, market) and aent_; pick one addressing mode. Read the response in this order and stop at the first match: (1) found=false -> we do not cover this security/entity, do not retry; (2) visibility='hidden_unverified' -> the entity exists but its identity is not human-verified, so its name is withheld; query by code+market instead; (3) resolved_as='listed_company' -> your aent_ denoted the company itself and the request was redirected, use the returned code/market; (4) has_events=false -> the security EXISTS but had no covered filings in the covered period (this is the common case, ~85% of valid lookups) — report 'no filings in period', never 'company not found'; (5) companies=[...] -> a shareholder active across one or more companies, read each entry; (6) otherwise the state machines apply to that one company. Fields that separate 'did not happen' from 'we do not know' are load-bearing: current_holding_reason, window_status ('expired_no_closure' = the plan window lapsed with no closing filing), entity_link, entities_status, plan_pairing ('unresolved' = several open plans and we refuse to guess the pairing), and unclassified_count. Never collapse them into 'nothing there'. Values are objective extractions with a source PDF link; we never rate, score or attribute.
输入模式
{
"type": "object",
"properties": {
"code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Security code, e.g. '000029'. Must be given together with market.",
"title": "Code"
},
"market": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "One of ['SH', 'SZ', 'BJ']. Required when code is given.",
"title": "Market"
},
"aent_": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Opaque entity id taken from a previous response. Never construct or guess one. Mutually exclusive with code/market.",
"title": "Aent"
},
"locale": {
"default": "en",
"description": "Language of human-readable data labels only; errors and this description are always English.",
"enum": [
"en",
"zh"
],
"title": "Locale",
"type": "string"
}
},
"title": "get_entity_stateArguments"
}输出模式
{
"type": "object",
"properties": {
"found": {
"description": "False means we do not have this security/entity at all.",
"title": "Found",
"type": "boolean"
},
"reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Present only when found=false: 'unknown_security' or 'unknown_entity'.",
"title": "Reason"
},
"visibility": {
"anyOf": [
{
"const": "hidden_unverified",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Entity exists but its identity is not human-verified; its name and linked filings are withheld. Query by (code, market) instead.",
"title": "Visibility"
},
"resolved_as": {
"anyOf": [
{
"const": "listed_company",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The aent_ you passed denotes the listed company itself; the request was redirected. Use the returned code/market to attribute this state.",
"title": "Resolved As"
},
"has_events": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "False means the security EXISTS but has no filings of the covered types in the covered period. This is NOT the same as found=false.",
"title": "Has Events"
},
"companies": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Present for shareholder entities: one entry per company, each carrying the same state machines. An empty list means the entity exists but has no linked filings — not that the person did nothing.",
"title": "Companies"
},
"coverage_since": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Earliest filing date we cover. Data before this is absent.",
"title": "Coverage Since"
},
"disclaimer": {
"description": "Always present. Objective facts only, no ratings.",
"title": "Disclaimer",
"type": "string"
}
},
"required": [
"found",
"disclaimer"
],
"additionalProperties": true,
"description": "Current folded state of a listed company or a shareholder entity.",
"title": "EntityStateResult"
}🟢get_event_with_context(aevt, locale)
Return one specific filing event together with its full timeline (every stage the case went through, each with its own source PDF) and which subject's state it changed. Call this after another tool handed you an event id and you need the whole thread rather than a one-line summary — for example to see how a penalty case progressed from filing to decision. Do NOT call this without an event id from a previous response: ids are opaque and cannot be guessed or constructed. Internal database identifiers are rejected. affects_state lets you jump back to get_entity_state. Its subjects[].aent_ may be null when entity resolution has not run yet or does not apply — in that case use the code and market from the same affects_state, which never depends on entity resolution. If the id is unknown you get found=false, which is an answer, not an error: do not retry.
输入模式
{
"type": "object",
"properties": {
"aevt": {
"description": "Opaque event id from a previous response. Must start with 'aevt_'.",
"title": "Aevt",
"type": "string"
},
"locale": {
"default": "en",
"description": "Language of data labels only.",
"enum": [
"en",
"zh"
],
"title": "Locale",
"type": "string"
}
},
"required": [
"aevt"
],
"title": "get_event_with_contextArguments"
}输出模式
{
"type": "object",
"properties": {
"found": {
"title": "Found",
"type": "boolean"
},
"possible_related_filings": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Possible links to filings, each with aann_, title, ann_date, relation='possible_relation', reason, evidence_aanns and decided_at. These can change with new evidence and do not establish event identity.",
"title": "Possible Related Filings"
},
"reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Reason"
},
"event": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "The event itself, including source_pdf_url.",
"title": "Event"
},
"timeline": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Every frame of this case, newest first; each frame carries its own source_pdf_url.",
"title": "Timeline"
},
"affects_state": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Which subject's state this changed: {code, market, subjects[]}. Use it to jump back to get_entity_state. Note subjects[].aent_ can be null when entity resolution is pending or not applicable — in that case use code+market, which never depends on entity resolution.",
"title": "Affects State"
},
"coverage_since": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Coverage Since"
},
"disclaimer": {
"title": "Disclaimer",
"type": "string"
}
},
"required": [
"found",
"disclaimer"
],
"additionalProperties": true,
"description": "A single event plus its full timeline and what state it changed.",
"title": "EventContextResult"
}🟢whats_new(cursor, cursor_aevt, limit, locale)
Discover events with a linked filing dated within the last seven Beijing calendar days including today, and updated in the last seven days. A new filing may mention an old case; this does not imply new case progress. matched_filing gives the filing date and PDF that qualified the event; root source_pdf_url, phase and payload describe current event context. announce_ts remains the original first disclosure. Call this to follow recent disclosures. Do NOT use it for unrestricted history. Poll from the top and deduplicate event ids. To page backwards pass both cursor and cursor_aevt verbatim; these use processing time, not filing dates. Old cursors restart at the current window with clamped=true. Concurrent updates can move results between pages. end_of_window=true means no further results, including an empty first call; empty results are successful and do not prove the database is empty or ingestion is healthy. fallback_recent is always false: history never fills an empty window. Use a known company, entity or event for historical context.
输入模式
{
"type": "object",
"properties": {
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The `cursor` value from a previous response, passed back verbatim.",
"title": "Cursor"
},
"cursor_aevt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The `cursor_aevt` value from the same response. Required together with cursor for correct paging.",
"title": "Cursor Aevt"
},
"limit": {
"default": 50,
"description": "1..100. Default 50.",
"maximum": 100,
"minimum": 1,
"title": "Limit",
"type": "integer"
},
"locale": {
"default": "en",
"description": "Language of data labels only.",
"enum": [
"en",
"zh"
],
"title": "Locale",
"type": "string"
}
},
"title": "whats_newArguments"
}输出模式
{
"type": "object",
"properties": {
"events": {
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Events",
"type": "array"
},
"fallback_recent": {
"description": "Always false: an empty window never returns older events.",
"title": "Fallback Recent",
"type": "boolean"
},
"end_of_window": {
"description": "No more results in the allowed window for this request, including an empty first call. Events is empty and both cursor fields are null; this does not imply an empty database.",
"title": "End Of Window",
"type": "boolean"
},
"clamped": {
"description": "Your cursor was older than the lookback window, so paging restarted from the top of the window.",
"title": "Clamped",
"type": "boolean"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Pass back verbatim as `cursor` together with `cursor_aevt` to get the next page. Null means there is no next page. Do not construct it yourself.",
"title": "Cursor"
},
"cursor_aevt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Second half of the cursor. Both halves are required to page correctly; passing only `cursor` may repeat events sharing the same timestamp.",
"title": "Cursor Aevt"
},
"coverage_since": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Coverage Since"
},
"disclaimer": {
"title": "Disclaimer",
"type": "string"
}
},
"required": [
"events",
"fallback_recent",
"end_of_window",
"clamped",
"cursor",
"cursor_aevt",
"disclaimer"
],
"additionalProperties": true,
"description": "Recently created or updated events, newest first.",
"title": "WhatsNewResult"
}🟢scan_recent_events(event_type, since, until, phase, limit, ...)
Discover one filing event type across companies using linked filing dates within the last seven Beijing calendar days including today. Dates omitted use this whole window; one omitted end uses the corresponding allowed boundary. Partial overlap is clamped; reversed or wholly outside dates are errors. effective_since/effective_until report the actual dates. A new filing mentioning an old case qualifies without claiming new case progress. Call this for market-wide recent filings. Do NOT use it for a full company state. Each event appears once, newest matching filing date first. matched_filing contains the qualifying filing id, date and its own PDF link; root source_pdf_url and phase describe current event context, not historical state at the selected date. phase filters current stage. At most 100 events per page. Pass cursor to continue; only non-null cursor means another page. Omit dates/phase on continuation or repeat their effective values; changing filters requires a fresh call. event_type must remain the same; limit/locale may change. matched_count counts the whole frozen window, so truncated can remain true on the last page. Windows that move outside the allowed dates fail with cursor_expired; restart without cursor. Results are a dynamic view, not a snapshot: new filings, stage changes or merges can move events between pages. Poll from the first page and deduplicate by aevt_. Empty results mean no matches after this position, not an empty database. coverage_since is data coverage, not permission to scan history. For a known company/entity use get_entity_state; for a known event use get_event_with_context.
输入模式
{
"type": "object",
"properties": {
"event_type": {
"description": "Which filing type to scan. Call list_coverage for the current scope.",
"enum": [
"share_reduction",
"violation_penalty",
"regulatory_letter",
"trading_halt_resume"
],
"title": "Event Type",
"type": "string"
},
"since": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Inclusive start date, YYYY-MM-DD.",
"title": "Since"
},
"until": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Inclusive end date, YYYY-MM-DD (the whole day counts).",
"title": "Until"
},
"phase": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Restrict to one stage of the case. Must belong to the chosen event_type; the error message lists the valid values.",
"title": "Phase"
},
"limit": {
"default": 50,
"description": "1..100. Default 50.",
"maximum": 100,
"minimum": 1,
"title": "Limit",
"type": "integer"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Return the previous cursor unchanged to continue within its frozen dates.",
"title": "Cursor"
},
"locale": {
"default": "en",
"description": "Language of data labels only.",
"enum": [
"en",
"zh"
],
"title": "Locale",
"type": "string"
}
},
"required": [
"event_type"
],
"title": "scan_recent_eventsArguments"
}输出模式
{
"type": "object",
"properties": {
"events": {
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Events",
"type": "array"
},
"matched_count": {
"description": "How many events matched in the whole window, before the limit was applied.",
"title": "Matched Count",
"type": "integer"
},
"truncated": {
"description": "True when the whole-window count exceeds this page's size, even on the last page. Only a non-null cursor means another page exists.",
"title": "Truncated",
"type": "boolean"
},
"window_clamped": {
"description": "Requested dates were intersected with the allowed recent window.",
"title": "Window Clamped",
"type": "boolean"
},
"effective_since": {
"description": "Inclusive matching filing start date actually queried, YYYY-MM-DD.",
"title": "Effective Since",
"type": "string"
},
"effective_until": {
"description": "Inclusive matching filing end date actually queried, YYYY-MM-DD.",
"title": "Effective Until",
"type": "string"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Continuation within the frozen effective dates; null means no next page. An expired window is an error: restart without cursor.",
"title": "Cursor"
},
"coverage_since": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Coverage Since"
},
"disclaimer": {
"title": "Disclaimer",
"type": "string"
}
},
"required": [
"events",
"matched_count",
"truncated",
"window_clamped",
"effective_since",
"effective_until",
"cursor",
"disclaimer"
],
"additionalProperties": true,
"description": "Cross-company scan of one filing type within a bounded time window.",
"title": "ScanResult"
}🟡list_company_filings(code, market, limit)
List the most recent filings of ONE listed company: title, date, a direct link to the source PDF, and — where we have it — the structured extraction that filing produced. Call this to answer 'what has this company filed lately' and 'give me the original document', which is what most callers actually want before any analysis. This is the widest view we offer: it covers EVERY filing we hold for the company, not just the ones we extract. Do NOT use it to ask what a case or a plan currently amounts to — it returns documents in date order, not folded state; get_entity_state does that. Do NOT use it to sweep the market for one filing type across companies (scan_recent_events), and do NOT page through it for bulk export: it has no cursor and stops at 50 rows per call. Read with_extraction: most filings have none, because we extract a focused set of filing types — call list_coverage for the ones we support today. `extraction: null` means we have not extracted that filing — it never means the filing is unimportant. When extraction is present, pass its aevt_ to get_event_with_context for the full case timeline. Titles are returned in the original Chinese, unchanged — translating a filing title would be rewriting the fact. There is no cursor: this is a recent-filings view, not a bulk export. `published_at` is null for most filings: it is present only when the source itself supplied a timestamp, and we do not substitute our own collection time for it. Use ann_date, which is always present, for the filing date.
输入模式
{
"type": "object",
"properties": {
"code": {
"description": "Six-digit A-share ticker, e.g. 000029.",
"title": "Code",
"type": "string"
},
"market": {
"description": "Which exchange the ticker belongs to.",
"enum": [
"SH",
"SZ",
"BJ"
],
"title": "Market",
"type": "string"
},
"limit": {
"default": 20,
"description": "1..50. Default 20.",
"maximum": 50,
"minimum": 1,
"title": "Limit",
"type": "integer"
}
},
"required": [
"code",
"market"
],
"title": "list_company_filingsArguments"
}输出模式
{
"type": "object",
"properties": {
"found": {
"description": "False means we have no such security on file at all — not that it filed nothing. Check this before reading filings.",
"title": "Found",
"type": "boolean"
},
"reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Reason"
},
"filings": {
"anyOf": [
{
"items": {
"$ref": "#/$defs/FilingEntry"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Newest first. One entry per filing, already merged across the five sources it may appear in; `sources` lists every link we hold for it.",
"title": "Filings"
},
"returned": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Returned"
},
"with_extraction": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "How many of the returned filings carry structured extraction. This is normally a small fraction — call list_coverage for the filing types we support today. A zero here means 'not extracted yet', never 'nothing happened'.",
"title": "With Extraction"
},
"more_available": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "True when older filings exist beyond what came back. There is no cursor; this tool is a recent-filings view, not a bulk export.",
"title": "More Available"
},
"disclaimer": {
"title": "Disclaimer",
"type": "string"
}
},
"required": [
"found",
"disclaimer"
],
"$defs": {
"FilingEntry": {
"additionalProperties": true,
"description": "一份公告。🔴 **把内层字段声明出来,别让 `filings` 退化成裸 `object`**\n(2026-08-21 评审逮到:原来生成的 schema 是 `{\"type\":\"object\",\"additionalProperties\":true}`,\n六个字段一个都不可机器读 —— 而本仓自己的原则是「判别式要机器可校验,不能只活在描述里」,\n见 2.21 §5.5)。\n⚠️ 仍然 `extra=\"allow\"` 且字段有默认值:schema 的作用是让调用方**能读懂**,\n不是当\"新增一个字段就把响应打回\"的闸门(同 `_Base` 上方的注释)。",
"properties": {
"ann_date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Filing date, YYYY-MM-DD.",
"title": "Ann Date"
},
"title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Original Chinese title, with the stock-name prefix that some sources prepend removed. Never translated.",
"title": "Title"
},
"published_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Null for most filings: present only when the source itself supplied a timestamp. We never substitute our own collection time. Use ann_date.",
"title": "Published At"
},
"aann_": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Opaque filing id, present only once the filing has been parsed.",
"title": "Aann"
},
"sources": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Every source we hold this filing from, best first: {source, pdf_url, page_url}. More than one means more than one way to open the original.",
"title": "Sources"
},
"extraction": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Single compatibility representative {aevt_, event_type, phase}, or null when no event was extracted. Use extractions for the complete list. Null never means the filing is unimportant.",
"title": "Extraction"
},
"extractions": {
"description": "Complete list of extracted events: [{aevt_, event_type, phase}, ...]. Empty means no extracted events are available for this filing; it does not mean the filing is unimportant.",
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Extractions",
"type": "array"
}
},
"title": "FilingEntry",
"type": "object"
}
},
"additionalProperties": true,
"description": "Recent filings of one listed company, with source links and any extraction.",
"title": "FilingsResult"
}🟢get_filing_parsed(aann_, text_offset)
Return ONE filing already parsed for you: its available normalised text and its tables as structured cells. Call it after list_company_filings, with the `aann_` id that tool returned, when you need what a filing actually says rather than just its title and PDF link. This is the step your own pipeline would otherwise have to do: a filing PDF is a layout format, not a data format, so pulling clean text and real table cells out of it is where ad-hoc extraction usually goes wrong. Tables come back as rows of cells you can read directly, not as an image or a flattened blob. It serves ONE filing per call, whose date is at most seven days before the database current date (eight calendar dates including today). Older filings are not gone — the filing itself and its source PDF link stay available from list_company_filings for the company's whole history; only the parsed text is recent-only. When that is why you got nothing, `reason` says outside_parsed_window, which is a different answer from unknown_filing. Source coverage is limited: PDFs over 150 pages are parsed only through the first 30 pages; table coverage is limited above 50 pages. Use source links for the complete original. text_chars measures stored text, not source completeness. text_truncated=false or next_text_offset=null does not mean every PDF page was parsed. Stored text arrives in slices: read `text_chars` for the stored total and call again with `next_text_offset` until it is null. Do NOT use this to sweep a company or the market — it takes a single filing id and has no cursor. Read `text_unavailable` before trusting the text. Two of its values are properties of the source file — a scan with no text layer, or a font we cannot map to Unicode — and retrying those will not help. A third, parse_failed, means the failure is ours rather than the document's, and asking again later may well work. Either way the source links are still worth opening.
输入模式
{
"type": "object",
"properties": {
"aann_": {
"description": "Opaque filing id from list_company_filings, e.g. aann_Kyw46MM1gCnIaBxA.",
"title": "Aann",
"type": "string"
},
"text_offset": {
"default": 0,
"description": "0-based offset into the filing's full text. Start at 0; then pass next_text_offset from the previous call.",
"title": "Text Offset",
"type": "integer"
}
},
"required": [
"aann_"
],
"title": "get_filing_parsedArguments"
}输出模式
{
"type": "object",
"properties": {
"found": {
"description": "False means either we hold no filing under this id, or the filing is outside the parsed-text window. Read `reason` to tell those apart.",
"title": "Found",
"type": "boolean"
},
"reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "unknown_filing = no such filing id. outside_parsed_window = the filing exists and its source PDF is still available from list_company_filings, but parsed text is only served for recent filings.",
"title": "Reason"
},
"ann_date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Filing date, YYYY-MM-DD.",
"title": "Ann Date"
},
"window_days": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Maximum filing-date age in database calendar days, inclusive of age zero.",
"title": "Window Days"
},
"note": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Note"
},
"aann_": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Aann"
},
"code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Code"
},
"market": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Market"
},
"title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Original Chinese title. Never translated.",
"title": "Title"
},
"sources": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Every source link we hold for this filing, best first. Use them to check our text against the original.",
"title": "Sources"
},
"text": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Normalised plain text of this filing, from `text_offset`, at most `limits.parsed_text_chunk_chars` characters per call.",
"title": "Text"
},
"text_chars": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Length of stored parsed text, which may cover only part of the PDF. Compare with text_offset + len(text) to see how much is left.",
"title": "Text Chars"
},
"text_offset": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Text Offset"
},
"text_truncated": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "True when more stored text follows. False does not guarantee full PDF coverage.",
"title": "Text Truncated"
},
"next_text_offset": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Where to continue, or null at the end of stored text, not necessarily the source PDF.",
"title": "Next Text Offset"
},
"text_unavailable": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Why the text cannot be used, or null when it can. no_text_layer = the source PDF carries no text layer at all (a scan), so there is nothing to extract. unreadable_font_encoding = it has text, but the PDF embeds a subset font without a Unicode map, so the characters come out as (cid:NNNN) placeholders; the text is still returned, and the numbers and structure may still be readable, but the words are not. Those two are properties of the source file — re-requesting will not help. parse_failed means the failure is OURS, not the document's: we did not parse it successfully, and it is worth asking again later. Check this field rather than testing whether `text` is empty.",
"title": "Text Unavailable"
},
"tables": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Tables as cells, in document order: {index, page, n_rows, n_cols, cells, continuation_of}. continuation_of points at the table this one continues from when a table spans pages. Empty list means this filing has no tables.",
"title": "Tables"
},
"table_count": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Table Count"
},
"parsed_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "When we parsed it.",
"title": "Parsed At"
},
"disclaimer": {
"title": "Disclaimer",
"type": "string"
}
},
"required": [
"found",
"disclaimer"
],
"additionalProperties": true,
"description": "One filing's parsed text and tables (tier 2).",
"title": "ParsedFilingResult"
}🟢get_related_filings(aann_, limit)
Return the other filings this filing cites. Call it after list_company_filings or get_filing_parsed, with the `aann_` id they returned, when you need the paper trail around a filing rather than the filing alone. Chinese listed companies print a filing number on most of their filings (e.g. 2026-047) and later filings cite it in their text. This tool follows those citations. Matching is exact and scoped to the same company — those numbers are per-company yearly counters and collide across the market, so a cross-company match would be wrong, not merely noisy. Unlike get_filing_parsed this has NO recency window: you can ask about a filing of any age. What comes back is title, date and id, so you can feed any `aann_` straight back into get_filing_parsed — that step is the one limited to recent filings. Read the empty case carefully, because two different facts look similar. found=false means we hold no such filing id. found=true with an empty `related` means we do hold it and it cites nothing we have. `own_number` tells you the other half of the story: when it is null, this filing prints no number of its own, so nothing can cite it either. About a third of filings carry no printed number, so an empty result is ordinary rather than a sign of missing data. WHERE COVERAGE ENDS: every filing whose text we hold has been scanned for citations, so an empty `related` on those is a real answer, not a gap. What is still incomplete is the corpus itself — a sizeable part of the archive is crawled but not yet parsed, and a filing we have not parsed cannot appear on either side of a citation. So a cited filing may be missing simply because we have not processed it yet, which is also why `matched_no` is worth reading: it names the number that was cited, even when we can only resolve some of them. `aevt_` on an entry is null when the cited filing produced no event. That is normal: we extract only a few event types so far (list_coverage names them), and the citation link itself does not depend on extraction. Do NOT use this to sweep a company or the market: it takes a single filing id, has no cursor, and follows citations one hop at a time. Do NOT expect the cited filing's text here either — this returns identity only; pass the `aann_` to get_filing_parsed for text, and note that step does have a recency window.
输入模式
{
"type": "object",
"properties": {
"aann_": {
"description": "Opaque filing id from list_company_filings, e.g. aann_Kyw46MM1gCnIaBxA.",
"title": "Aann",
"type": "string"
},
"limit": {
"default": 20,
"description": "Max related filings to return. See limits.related_limit_max.",
"title": "Limit",
"type": "integer"
}
},
"required": [
"aann_"
],
"title": "get_related_filingsArguments"
}输出模式
{
"type": "object",
"properties": {
"found": {
"description": "False means we hold no filing under this id at all. An empty `related` list with found=true is a different answer: we have the filing, it just does not cite any filing we hold.",
"title": "Found",
"type": "boolean"
},
"reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "unknown_filing = no such filing id.",
"title": "Reason"
},
"aann_": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Aann"
},
"code": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Code"
},
"market": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Market"
},
"ann_date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Filing date, YYYY-MM-DD.",
"title": "Ann Date"
},
"title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Original Chinese title. Never translated.",
"title": "Title"
},
"own_number": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "This filing's OWN printed number, or null when its text does not carry one (about a third do not). This is also why other filings may fail to link here: without a printed number there is nothing for them to cite.",
"title": "Own Number"
},
"related": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Newest first. Each entry includes {aann_, title, ann_date, matched_no, extractions, aevt_, event_type}. matched_no is the printed number that tied the two together. extractions is the complete event list; aevt_ and event_type are a single compatibility representative. They are null when the cited filing produced no event. See list_coverage for supported types.",
"title": "Related"
},
"returned": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"title": "Returned"
},
"more_available": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "True when there may be more beyond `limit`. There is no cursor; raise limit (max in list_coverage) if you need more.",
"title": "More Available"
},
"disclaimer": {
"title": "Disclaimer",
"type": "string"
}
},
"required": [
"found",
"disclaimer"
],
"additionalProperties": true,
"description": "Which other filings this filing cites, by printed filing number within the same company.",
"title": "RelatedFilingsResult"
}🟢list_coverage
Return exactly what this server covers and the limits it enforces. Call this first, or whenever a query comes back empty and you want to know whether the filing type is even in scope, before concluding the data is incomplete. It takes no arguments and does not touch the database, so it works even when everything else is degraded. Coverage is deliberately narrow and expanding over time; the `event_types` list in the response is the authoritative answer, and stating it plainly is preferable to letting you discover the boundary by trial and error. Read `limits` instead of probing for the caps.
输入模式
{
"type": "object",
"properties": {},
"title": "list_coverageArguments"
}输出模式
{
"type": "object",
"properties": {
"event_types": {
"items": {
"type": "string"
},
"title": "Event Types",
"type": "array"
},
"markets": {
"items": {
"type": "string"
},
"title": "Markets",
"type": "array"
},
"expanding": {
"description": "True: more filing types are being added over time.",
"title": "Expanding",
"type": "boolean"
},
"limits": {
"additionalProperties": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "integer"
},
{
"type": "string"
}
]
},
"description": "Server-side caps. Read them instead of discovering them by hitting walls.",
"title": "Limits",
"type": "object"
},
"disclaimer": {
"title": "Disclaimer",
"type": "string"
}
},
"required": [
"event_types",
"markets",
"expanding",
"limits",
"disclaimer"
],
"additionalProperties": true,
"description": "What this server covers and the limits it enforces.",
"title": "CoverageResult"
}社区
证据