mcp-hkex-filing
HKEx Filing Scraper

An open-source Python tool that scrapes 25+ years of Hong Kong Stock Exchange (HKEx) regulatory filings and ingests them into any combination of nine databases — with full-text and table extraction, chunk-level coverage, optional graph linking, and a read-only MCP server so AI agents can query the corpus or the live site.
It speaks the undocumented HKEx JSON API directly, which is faster and more resilient than driving a browser.
Two ways to use it
Hosted MCP gateway | Local pipeline | |
What | A public endpoint you point an AI agent at | The |
Setup | None — paste a URL |
|
Data | Live from HKEx, nothing stored | Stored in your database(s) |
Docs |
Related MCP server: local-tools-mcp-server
Use the hosted MCP gateway
POST, Streamable HTTP, no API key:
https://hkex-listco-updates.ascent-partners.com/api/mcpThree read-only tools: get_server_info, search_filings (a window of at most 31 days), and
get_filing (downloads one document and extracts its text and tables).

Point a client at it — for example opencode:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"hkex-live": {
"type": "remote",
"url": "https://hkex-listco-updates.ascent-partners.com/api/mcp"
}
}
}Then ask:
Use hkex-live to list the filings published between 2026-09-01 and 2026-09-18,
then summarise the interim report.Ready-made configuration for Claude, ChatGPT, Cursor, VS Code/Copilot, Gemini CLI, opencode,
Manus, and Perplexity is in AI agent support — and for a stored corpus,
the stdio MCP server exposes a wider tool catalog. The gateway is listed in the
official MCP Registry as
io.github.simonplmak-cloud/hkex-filings.
Quick start (local)
pip install hkex-filing-scraper # core; SQLite needs no server
pip install "hkex-filing-scraper[all]" # Excel + dotenv + every driver + the MCP server
cp .env.example .env # then set DATABASE_TARGET (below)
hkex-scraper --metadata-only --limit 100Optional extras: excel, postgres, mysql, duckdb, mongodb, clickhouse, neo4j,
mcp, pdf, all, dev.
DATABASE_TARGET is an ordered, comma-separated list of sink ids; the order decides which
sink serves reads. To start with no server:
DATABASE_TARGET=sqlite
SQLITE_PATH=hkex.dbhkex-scraper runs the full pipeline (metadata + documents + graph); hkex-scraper --full-history covers everything since April 1999. The schema is created automatically.
Full install options and per-sink settings are in Getting started.
Database support
Every sink is a first-class destination; rows are in documented popularity order. The full matrix — licenses, capability differences, per-engine notes — is in Database sinks.
Sink | Model | License | Extra | Idempotent upsert |
| relational | PostgreSQL License |
|
|
| relational | GPLv2 |
|
|
| relational | Public domain | — |
|
| document | SSPL¹ |
|
|
| graph | GPLv3 (Community) |
|
|
| columnar | Apache-2.0 |
|
|
| relational | MIT |
|
|
| graph + document | BSL 1.1¹ | — |
|
¹ Source-available, not OSI-approved — labelled exceptions per ADR 0003.
Valid sink ids, in documented order: postgres, mysql, sqlite, mongodb, mariadb, neo4j, clickhouse, duckdb, surrealdb. Set one variable and the same run feeds every sink:
# Order sets read precedence.
DATABASE_TARGET=postgres,sqlite
POSTGRES_DSN=postgresql://user:password@localhost:5432/hkex
SQLITE_PATH=hkex.dbHow it works
flowchart LR
A[HKEx JSON API] --> B[Phase 1: metadata]
B --> C[Canonical record]
C --> D{DATABASE_TARGET}
D --> E[(PostgreSQL)]
D --> F[(MySQL / MariaDB)]
D --> G[(SQLite)]
D --> H[(MongoDB)]
D --> I[(Neo4j)]
D --> J[(ClickHouse)]
D --> K[(DuckDB)]
D --> L[(SurrealDB)]
B --> M[Graph linking]
M --> D
B --> N[Phase 2: download and extract]
N --> CPhase 1 scrapes filing metadata through a JSF session, splitting the range into monthly chunks and deduplicating on a 16-character MD5
filingId.Phase 2 downloads each filing's PDF/HTML/Excel document, extracts text and tables to Markdown, and writes the payload.
Graph linking (optional) writes
has_filingandreferences_filingedges whenCOMPANY_TABLEis set.Failure isolation — a failure on one sink is logged and counted but never blocks another; the run exits non-zero if any configured sink failed.
Deeper detail: Architecture · ADR 0002.
Features
Fast API scraping — direct HKEx JSON API; no browser or Selenium.
Full history — every filing from April 1999 to today, with chunk-level coverage checks.
Document processing — PDF/HTML/Excel text and structured tables, extracted to Markdown.
Multi-sink — any ordered combination of nine databases, each with native idempotent upserts.
AI-ready — a hosted live MCP gateway plus a local stdio MCP server.
Resumable and observable — batching, parallel downloads, stalled-job detection, per-sink counters, and
--coverage-report/--parity-report/--verify.Optional dependencies — the core is
requests+beautifulsoup4; drivers and document extraction are extras with graceful fallbacks.
Documentation
Database sinks (matrix) — PostgreSQL, MySQL/MariaDB, SQLite, MongoDB, Neo4j, ClickHouse, DuckDB, SurrealDB
Docs site: https://hkex-listco-updates.ascent-partners.com/ · Try it locally (
examples/)
Development
pip install -e ".[dev,all]"
ruff check # lint (py310, line-length 100)
ruff format --check # formatting
pytest # unit tests (no DB or network required)Tests are pure unit tests; SQLite and DuckDB contract tests run in-process, and integration tests that need a server are skipped unless that sink is configured. See Testing.
Contributing
See CONTRIBUTING.md; report security issues per SECURITY.md. Ideas and questions are welcome in Discussions.
If this saves you time, a star helps others find it.
License
MIT — see LICENSE. That covers this project's code only; optional dependencies
carry their own licenses, notably the pdf extra (PyMuPDF / pymupdf4llm), which is
AGPL-3.0 and deliberately excluded from .[all]. See
docs/legal.md.
Data & Terms of Use: this is a research tool for the undocumented HKEx JSON API, and it is not affiliated with or endorsed by HKEx. Commercial redistribution of HKEx data may require a licensed HKEx feed; see docs/legal.md.
Available Tools
16 toolscount_filingsARead-onlyIdempotentInspect
Use this to report how many filings each configured sink holds.
Returns a per-sink count (or a per-sink error). Counts only; it does not return rows.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context beyond the annotations: it returns a per-sink count or a per-sink error, and it never returns rows. This clarifies the tool's output shape and limitations without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, no filler. The main purpose is front-loaded, and the key behavioral caveat ('does not return rows') is stated immediately after the main claim. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only counting tool with an output schema present, the description is complete. It tells the agent what to expect (per-sink count or error) and what not to expect (rows), which is sufficient context for correct invocation and interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and full schema description coverage, so there is nothing for the description to add about parameter semantics. It implicitly confirms that the operation runs across all configured sinks with no arguments, which is all that is needed here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('report'), a clear resource ('how many filings each configured sink holds'), and explicitly differentiates the tool from row-returning siblings by adding 'Counts only; it does not return rows.' The name count_filings is expanded into a precise, actionable statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly says when to use the tool: to report per-sink filing counts. It also provides an exclusion ('does not return rows') that helps an agent avoid selecting it when row-level data is needed. However, it does not explicitly name alternative tools like search_filings or get_filings for those row-level needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_schemaARead-onlyIdempotentInspect
Use this before filtering or interpreting results to learn the canonical fields.
Returns the filing and document field names with types, plus the known filing types, categories, document statuses, and graph edge kinds. Reads no filings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already mark this as read-only and idempotent. The description adds meaningful context beyond that: it explicitly says the tool 'reads no filings,' which reassures the agent that this is a metadata-only operation with no side effects. This is useful 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the usage guidance is the first sentence, and the return contents are listed in the second. Every sentence earns its place with no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter introspection tool with a rich output schema, the description is fully complete. It tells the agent when to use it, what it returns, and that it has no data-reading side effects. Nothing necessary for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema covers everything structurally. The baseline of 4 applies. The description adds no parameter details because none are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('describe schema') with a clear resource, and enumerates exactly what is returned: filing/document field names with types, known filing types, categories, document statuses, and graph edge kinds. It also distinguishes itself from sibling data-retrieval tools by noting it 'reads no filings.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage timing: use it 'before filtering or interpreting results to learn the canonical fields.' It does not explicitly name alternatives or when not to use it, but the guidance is clear enough for an agent to know this is the precondition step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_configARead-onlyIdempotentInspect
Use this to inspect the active configuration (DATABASE_TARGET, read sink, graph).
Never returns credentials. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond the annotations: it explicitly states 'Never returns credentials', which is a valuable safety guarantee not present in the annotations. The read-only statement is redundant with readOnlyHint=true, but the credential non-disclosure is meaningful and helps an agent decide whether to call the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no wasted words. The primary purpose is front-loaded, and the safety note is concise. It earns a high score for efficiency and clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no parameters and an output schema exists, so return format is already covered. The description mentions the scope of configuration (DATABASE_TARGET, read sink, graph) and the credential safety. For a simple read-only inspection tool, this is sufficiently complete; the only minor gap is that it doesn't state what exactly the response looks like, but the output schema handles that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline is 4. There are no parameter details to clarify, and the description correctly focuses on the tool's behavior rather than input semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: to inspect the active configuration, naming specific elements (DATABASE_TARGET, read sink, graph). This is a specific verb+resource combination that distinguishes it from siblings like list_sinks (which lists sinks) or get_server_info (server info). However, it does not explicitly name a sibling alternative, so it doesn't fully differentiate itself in the sibling set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a direct instruction to use this tool for inspecting configuration but gives no guidance on when not to use it or which alternative to choose instead. With many sibling tools (e.g., get_server_info, list_sinks), the lack of exclusionary or comparative context leaves the agent to infer the appropriate selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_coverageARead-onlyIdempotentInspect
Use this to report scrape coverage per monthly chunk, with totals.
Optional date_from/date_to (YYYY-MM-DD) filter by chunk month. Returns rows
newest-first plus totals (api/ingested/unique counts and coverage percent). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum coverage rows to return (1..200). | |
| date_to | No | Filter by chunk month, YYYY-MM-DD. | |
| date_from | No | Filter by chunk month, YYYY-MM-DD. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds behavioral context beyond the annotations by stating that rows are returned newest-first and that a totals object is included with specific counts and coverage percent. It also repeats the read-only nature, which is consistent with the annotations and reinforces safety.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the main purpose, and every sentence contributes useful information about scope, filters, result ordering, totals, and safety. There is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only reporting tool with fully documented parameters and an output schema present, the description covers what the tool does, how results are ordered, what totals are returned, and its read-only behavior. An agent has enough to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100%, so the schema already documents all parameters. The description mostly restates the date_from/date_to filtering semantics and does not add substantial detail about the limit parameter. This meets the baseline but adds little beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'report scrape coverage per monthly chunk, with totals.' This clearly distinguishes it from the sibling tools like get_statistics or count_filings, which relate to different report types. The scope is precise and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Use this to report scrape coverage per monthly chunk' gives an explicit intended use case. However, it does not mention when not to use it or name any alternative tools, leaving some differentiation to inference from the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_filingARead-onlyIdempotentInspect
Use this to read one filing's metadata and extracted document content.
Returns the canonical filing and document fields. document_text is a window of
max_text_chars from text_offset; when text_truncated is true, call again
with next_text_offset for more. Tables (document_tables) are included only when
include_tables is true. Obtain ids from search_filings. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| filing_id | Yes | 16-character filing id; obtain from search_filings. | |
| text_offset | No | Character offset into document_text for paging. | |
| include_text | No | Include the extracted document text window. | |
| include_tables | No | Include extracted document tables. | |
| max_text_chars | No | Maximum characters of text to return (0..200000). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds a precise paging contract: document_text is a window of max_text_chars from text_offset, text_truncated signals another page, and next_text_offset is the continuation point. It also discloses that tables are only included when include_tables is true, which is valuable behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: core purpose first, then return fields, paging behavior, table inclusion, and the source of IDs. Every sentence contributes operational guidance with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full input schema, rich annotations, and an output schema present, the description covers the remaining operational essentials: paging, table inclusion, and how to get the filing ID. An agent has everything needed to invoke the tool correctly and process paginated results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers all five parameters with descriptions, so the baseline is solid. The description adds extra relational meaning by explaining how text_offset, max_text_chars, and next_text_offset work together for pagingapper. It does not add much on filing_id, but the schema already covers that sufficiently.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'read one filing's metadata and extracted document content.' It clearly identifies this as a single-filing accessor and distinguishes it from search-oriented siblings by directing agents to obtain IDs from search_filings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the intended use case ('Use this to read one filing's...') and the prerequisite workflow of obtaining IDs from search_filings. However, it does not explicitly name alternatives like get_filings or describe when not to use them, so the guidance is clear but not fully exclusionary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_filingsARead-onlyIdempotentInspect
Use this to read several filings in one call (up to 50 ids).
Returns each filing's metadata plus, when include_text is true, a bounded text
window. Ids not found are listed in not_found. Text is off by default. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| filing_ids | Yes | Filing ids to fetch (1..50); obtain from search_filings. | |
| include_text | No | Include the extracted document text window (off by default). | |
| include_tables | No | Include extracted document tables. | |
| max_text_chars | No | Maximum characters of text to return (0..200000). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, and the description adds useful behavior beyond those: returned metadata, a bounded text window, and that missing ids are listed in 'not_found'. This gives the agent expectations about output shape and edge cases without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the primary purpose in the first sentence. Some redundancy exists ('Text is off by default' repeats the schema default), but it is short, readable, and not bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that the schema covers all parameter semantics and an output schema exists, the description covers the essential contextual details: batching limit, returned metadata plus optional text window, not-found behavior, and read-only safety. It omits mention of include_tables in prose, but the schema handles that parameter fully.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already fully documented. The description adds only marginal extra meaning, such as 'bounded text window' and 'text is off by default', which mostly mirrors the schema's max_text_chars and default false values rather than adding substantive new semantic detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and resource: 'read several filings in one call (up to 50 ids)'. This clearly states what the tool does and differentiates it from siblings like get_filing by emphasizing the batched/batch nature.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction 'Use this to read several filings in one call' gives a clear batching use case and the read-only nature is reinforced by 'Read-only'. It does not explicitly name alternatives or exclusion conditions, but the batching framing gives enough context for an agent to select it over singular or search tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_parityARead-onlyIdempotentInspect
Use this to compare filing counts across two or more configured sinks.
Returns per-sink counts and the spread; parity is OK when the spread is zero.
Requires two or more configured sinks. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the description's 'read-only' note is redundant. It adds value beyond annotations by specifying return semantics (per-sink counts and spread) and the interpretation of parity (OK when spread is zero), plus the multi-sink precondition. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, with the core purpose in the first sentence. The only redundancy is the final 'This tool is read-only' sentence, which duplicates annotation information; otherwise every sentence contributes to purpose, output, or prerequisites.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters, output schema exists), the description covers purpose, return values, and prerequisites sufficiently. It does not address edge cases like behavior when fewer than two sinks are configured, but for a read-only comparison tool this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline is 4. The description does not need to explain parameters, and it adds relevant context by stating the configuration requirement of two or more sinks, which is not a parameter but a usage condition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('compare') and resource ('filing counts across configured sinks'), clearly stating the tool's function. It also names the key output ('per-sink counts and the spread') and the concept of parity, which distinguishes it from siblings like count_filings (aggregate counts) and verify_sinks (verification).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use it to compare filing counts across two or more configured sinks, and it states a prerequisite (requires two or more configured sinks). However, it does not explicitly name alternative tools or conditions for when not to use it, so it stops short of full guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_server_infoARead-onlyIdempotentInspect
Use this first to learn the server version, configured sinks, and read sink.
Returns server metadata only; it reads no filings. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds value by clarifying it 'reads no filings' and returns 'server metadata only.' This reinforces and extends the annotation context without contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler. The core directive is front-loaded, and the supporting scope statement is immediately relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with no parameters, an output schema, and rich annotations, the description fully covers what an agent needs to invoke it correctly. Nothing is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema already covers everything (100% coverage with an empty properties object). Baseline 4 for 0-parameter tools is appropriate; the description adds no parameter detail, but none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('learn') and resource ('server version, configured sinks, and read sink'), making the tool's purpose immediately clear. It also explicitly distinguishes the tool from siblings by stating it 'reads no filings,' so it won't be confused with filing-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The directive 'Use this first' provides clear context for when to invoke the tool, positioning it as an initial discovery step. It does not name alternatives or explicit when-not-to-use conditions, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statisticsARead-onlyIdempotentInspect
Use this to count filings grouped by one dimension.
group_by is one of: company_ticker (default), filing_type, filing_category,
document_status, exchange. Optional filters narrow the population. Returns buckets
sorted by count descending plus the total. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| ticker | No | Company ticker filter, e.g. 0700.HK; comma-separate to match several. | |
| date_to | No | Latest filing date, YYYY-MM-DD inclusive. | |
| exchange | No | Exchange code, e.g. HK. | |
| group_by | No | Dimension to count filings by. | company_ticker |
| date_from | No | Earliest filing date, YYYY-MM-DD inclusive. | |
| filing_type | No | Filing type(s), e.g. 'Annual Report'; comma-separate to match several. | |
| title_query | No | Case-insensitive substring matched against the filing title. | |
| document_status | No | Document status(es): processed, skipped, failed, or unprocessed; comma-separate to match several. | |
| filing_category | No | Filing category(ies), e.g. LISTED_COMPANY; comma-separate to match several. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true. The description reinforces read-only status and adds behavioral detail not in annotations: 'Returns buckets sorted by count descending plus the total.' This gives an agent a clear expectation of the response shape and ordering, exceeding the minimum disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tight sentences, front-loads the core purpose, and uses a code block for the enum list. Every sentence contributes distinct information: the action, the grouping options, the filtering behavior, and the output format. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only aggregator with 9 optional parameters, an output schema, and rich annotations, the description covers the main functional behavior, grouping, filtering, and return tallies. It does not explicitly mention pagination or empty-result behavior, but the output schema and read-only annotations cover most agent needs. A small gap is the lack of differentiation from the sibling count_filings, but overall it is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description lists group_by values (redundant with the schema enum) and states that filters narrow the population, but it adds no per-parameter meaning beyond the schema. It does not need to compensate for a coverage gap, so a 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'count filings grouped by one dimension.' It enumerates allowable group_by values and clarifies the output (buckets plus total), making the tool's purpose distinct from siblings like count_filings, which presumably returns a simple total. The tool's role is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The lead-in 'Use this to' provides a use case, and 'Optional filters narrow the population' gives general context. However, it does not explicitly differentiate get_statistics from sibling count_filings or state when to prefer one over the other, leaving the choice to inference rather than explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_companiesARead-onlyIdempotentInspect
Use this to list companies (ticker and name) with their filing counts.
Returns a paged list ordered by filing count. Use search_filings for a company's filings. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum companies to return (1..100). | |
| offset | No | Zero-based offset for paging. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is already covered. The description adds useful behavioral context not in annotations: results are paged and ordered by filing count. This goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the core purpose and return behavior. The final 'This tool is read-only' sentence is redundant with the annotations, slightly keeping it from a perfect score, but overall it has no unnecessary bulk.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple paged list tool with an output schema, rich annotations, and fully documented parameters, the description covers purpose, ordering, paging, and the key alternative. Nothing essential is missing for an agent to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both limit and offset have clear descriptions with defaults. The description adds little parameter-specific detail, but the schema already carries that burden, so the baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: listing companies with ticker, name, and filing counts. It also differentiates from search_filings by explicitly noting that search_filings is for a company's filings, so the agent can distinguish this tool from a close sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use search_filings for a company's filings,' giving a clear alternative for a different task. It does not enumerate every sibling distinction, but it provides targeted routing guidance for the most likely point of confusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pending_filingsARead-onlyIdempotentInspect
Use this to list filings by document-processing status.
Defaults to unprocessed (no document yet); accepts processed, skipped, failed, or a
comma-separated mix. Returns the total (when known) and up to limit filing rows.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum filings to return (1..100). | |
| document_status | No | Document status(es): unprocessed (default), processed, skipped, failed; comma-separate for several. | unprocessed |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: it returns total when known, enforces a limit, and defaults to unprocessed status. It doesn't describe pagination or ordering, but the output schema likely covers return structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core purpose, then defaults, then return behavior. No wasted words. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with full schema coverage and an output schema, the description is nearly complete. It covers defaults, accepted values, and return shape. It doesn't mention ordering or pagination, but those are minor for a simple list tool with a limit parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters fully. The description adds the default behavior and the comma-separated mix capability, which is slightly redundant with the schema. Baseline 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('list'), a resource ('filings'), and a clear dimension ('by document-processing status'). It distinguishes itself from siblings like search_filings and get_filings by focusing on status-based listing. The default and accepted statuses are explicitly enumerated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly explains when to use the tool: to list filings by document-processing status, with defaults and accepted values. It doesn't explicitly name alternatives or exclusions, but the status-focused scope and sibling context make the use case clear. A brief mention of when not to use it (e.g., for full-text search) would push this to 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sinksARead-onlyIdempotentInspect
Use this when the user asks which databases are configured or their capabilities.
Returns every known sink id with its license, optional extra, configured/available status, per-sink capabilities, and which sink serves reads. Reads no filings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, non-destructive, and idempotent behavior. The description adds behavioral context by specifying exactly what information is returned (license, optional extra, status, capabilities, read-serving sink) and explicitly notes that it 'Reads no filings,' which clarifies it doesn't access underlying data. This goes beyond the annotation basics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences, front-loaded with the usage trigger. Every word provides necessary information—no filler. The list of returned fields is compact yet complete for the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters and an output schema is present, the description sufficiently explains the purpose and return content. The note that it doesn't read filings is a valuable clarifier, ensuring the agent doesn't confuse it with data access tools. No critical gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the parameter semantics are trivially satisfied. The description adds value by detailing what the response will contain, which helps the agent set expectations even though no input is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists configured databases and their capabilities, with a specific verb ('Returns') and resource ('sink id'). It distinguishes itself from siblings like verify_sinks, as it focuses on listing configuration and capabilities rather than verifying functionality.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the trigger condition: 'when the user asks which databases are configured or their capabilities.' While it doesn't name alternatives, this is unambiguous for this tool's use case, and sibling differentiation is implied by the distinct purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tickersARead-onlyIdempotentInspect
Use this to list the distinct company tickers that have filings.
Returns a sorted, paged list. Use search_filings to fetch filings for a ticker.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum tickers to return (1..1000). | |
| offset | No | Zero-based offset for paging. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering safety. The description adds useful behavioral context by specifying that the result is sorted and paged, and that it lists distinct tickers that have filings, which goes beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary purpose and a direct pointer to the sibling tool. Every sentence earns its place with zero redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering the safety profile, the description provides all necessary information: what the tool does, how it behaves (sorted, paged), and where to go next. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for limit and offset, so the schema fully documents the parameters. The description mentions 'paged list' but adds no new semantics beyond what the schema already provides, keeping the baseline at 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('list the distinct company tickers that have filings') and resource, distinguishing it from tools that fetch filings. It also mentions sorted and paged output, reinforcing its unique purpose among siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent to use search_filings to fetch filings for a ticker, providing an alternative and clarifying when not to use this tool. It implies the use case of enumerating tickers before querying filings, giving clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_documentsARead-onlyIdempotentInspect
Use this for full-text search over extracted document text.
Matches text_query case-insensitively inside document_text and returns filing
rows with a snippet when the sink supports it (see snippets_supported). Returns
nothing until documents are processed. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | Zero-based offset for paging. | |
| ticker | No | Company ticker filter, e.g. 0700.HK; comma-separate to match several. | |
| date_to | No | Latest filing date, YYYY-MM-DD inclusive. | |
| order_by | No | Sort order of the result. | filing_date_desc |
| date_from | No | Earliest filing date, YYYY-MM-DD inclusive. | |
| page_size | No | Maximum filings to return (1..100). | |
| text_query | Yes | Case-insensitive term matched against extracted document text. | |
| filing_type | No | Filing type(s), e.g. 'Annual Report'; comma-separate to match several. | |
| document_status | No | Document status(es): processed, skipped, failed, or unprocessed; comma-separate to match several. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive, but the description adds useful context: case-insensitive matching, snippet support conditionally, and the fact that it returns nothing until documents are processed. This goes beyond the annotations by explaining the data dependency and snippet behavior, which is valuable for the agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with three sentences that are front-loaded: it states the primary use case first, then details behavior and constraints. Each sentence adds value, though it could be slightly more structured with bullet points, but it's clear and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of 9 parameters but with full schema descriptions and an output schema, the description covers the key behavioral aspects: search functionality, case-insensitivity, snippet availability, and dependency on document processing. It doesn't explain return format, but that's covered by the output schema. It's complete enough for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 100% of parameters, so the schema already documents each parameter clearly. The description adds minimal extra meaning beyond the schema, such as mentioning case-insensitivity for text_query and snippet support. Since schema coverage is high, baseline 3 is appropriate; it doesn't need to compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it performs full-text search over extracted document text, with a specific verb 'search' and resource 'documents'. It distinguishes itself from siblings like search_filings by focusing on text content rather than metadata, and even mentions the snippet behavior, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for full-text search scenarios and notes that it returns nothing until documents are processed, which guides expectations. However, it does not explicitly contrast with search_filings or other alternatives, though the phrase 'Use this for full-text search' implies a specific use case. Lacking explicit exclusions, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_filingsARead-onlyIdempotentInspect
Use this to find filings by ticker, type, status, date range, or title text.
Filters are optional and combinable; comma-separate a value to match several (e.g.
filing_type="Annual Report,Dividend"). document_status accepts the real statuses
plus unprocessed (no document yet). date_from/date_to are YYYY-MM-DD
inclusive. order_by is one of filing_date_desc (default), filing_date_asc,
title_asc, filing_id_asc. Returns complete filing rows (no document text); call
get_filing for the document. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | Zero-based offset for paging. | |
| ticker | No | Company ticker filter, e.g. 0700.HK; comma-separate to match several. | |
| date_to | No | Latest filing date, YYYY-MM-DD inclusive. | |
| exchange | No | Exchange code, e.g. HK. | |
| order_by | No | Sort order of the result. | filing_date_desc |
| date_from | No | Earliest filing date, YYYY-MM-DD inclusive. | |
| page_size | No | Maximum filings to return (1..100). | |
| stock_code | No | Numeric stock code filter, e.g. 00700; comma-separate to match several. | |
| filing_type | No | Filing type(s), e.g. 'Annual Report'; comma-separate to match several. | |
| title_query | No | Case-insensitive substring matched against the filing title. | |
| document_status | No | Document status(es): processed, skipped, failed, or unprocessed; comma-separate to match several. | |
| filing_category | No | Filing category(ies), e.g. LISTED_COMPANY; comma-separate to match several. | |
| referenced_ticker | No | Ticker referenced by the filing (graph edge). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, and the description reinforces this at the end with 'This tool is read-only.' It adds value by explaining optional filters, comma-separation behavior, and the inclusive date semantics, which goes beyond the schema. Also clarifies that returns complete filing rows without document text, which is useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: starts with the purpose, then explains filter combinability, date format, ordering, and return behavior. It's a bit long (about 100 words) but each sentence adds important operational detail. The front-loading is effective, and there's no redundancy with the schema. Slightly verbose but purposeful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 13 parameters and an output schema, the description covers the key aspects: filter usage, date format, ordering, and that it doesn't return document text. It doesn't explain pagination details like page_size/offset, but the schema covers that. The output schema presumably details the return structure, so not explaining it here is fine. It's complete enough for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds context on comma-separation and the special 'unprocessed' status for document_status, which is not in the schema. However, it doesn't explain all parameters (like offset, page_size, exchange), but the schema already does that. Overall, it adds some but not substantial meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'find filings by ticker, type, status, date range, or title text' – a specific verb, resource, and searchable attributes. This helps distinguish it from siblings like search_documents (which likely searches document content) and get_filing/filings (which likely retrieve specific filings).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains the search criteria and combinability, but doesn't explicitly mention when to prefer this over siblings like get_filing or list_pending_filings. The line 'call get_filing for the document' gives a hint for follow-up but doesn't cover exclusion cases. Some guidance is implied (search vs. retrieval) but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_sinksARead-onlyIdempotentInspect
Use this to check that configured sinks hold the same filings and document hashes.
Compares (filing_id, document_sha256) sets across comparable sinks and returns a bounded sample of any missing/extra/mismatched ids. Requires two or more comparable sinks. This tool is read-only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses the comparison mechanism ('compares (filing_id, document_sha256) sets'), the bounded nature of output ('returns a bounded sample'), and the kinds of discrepancies found ('missing/extra/mismatched ids'). This gives the agent a clear, accurate model of the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, followed by precise mechanics and a requirement. Every sentence contributes useful information; the only mild redundancy is restating read-only behavior already present in annotations, but it is brief and does not hurt clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless, read-only verification tool with an output schema, the description covers everything needed to select and invoke it: what it checks, what it returns, its precondition, and its safety profile. No critical context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is nothing for the description to clarify beyond the schema, which is already complete. The description appropriately focuses on behavior and requirements rather than parameter syntax.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a specific verb ('verify'/'check') and resource ('configured sinks' holding 'filings and document hashes'), and clearly conveys a consistency-checking purpose. However, it does not explicitly distinguish itself from sibling tools like get_parity, which may perform related verification, so it falls short of a full 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the condition for use ('requires two or more comparable sinks') and the scenario ('check that configured sinks hold the same filings and document hashes'). It does not mention when not to use the tool or name alternative sibling tools, leaving some usage routing implicit.
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.
16 tool updates
- First observed
count_filings - First observed
describe_schema - First observed
get_config - First observed
get_coverage - First observed
get_filing - First observed
get_filings - First observed
get_parity - First observed
get_server_info - First observed
get_statistics - First observed
list_companies - First observed
list_pending_filings - First observed
list_sinks - First observed
list_tickers - First observed
search_documents - First observed
search_filings - First observed
verify_sinks
TDQS
Scored across 16 tools
Most tools have distinct purposes, but several boundaries blur: get_config, get_server_info, and list_sinks all describe configured sinks, while count_filings and get_statistics both provide counts. list_tickers/list_companies and search_filings/list_pending_filings also overlap, though the descriptions provide enough context to disambiguate with care.
All names follow a consistent lowercase snake_case verb_noun pattern (describe_, count_, list_, get_, search_, verify_). The semantic mapping of verbs is coherent: list for enumerations, get for retrieval, search for filtered lookup, count for totals. The singular/plural pair get_filing/get_filings is handled predictably.
At 16 tools, the surface is just at the upper boundary, but the extra tools are mostly administration/verification functions (coverage, parity, sinks, config) that serve a distinct operational purpose. It is slightly heavy for a read-only filing server but remains reasonable.
The core filing workflow is well covered: schema discovery, metadata search, full-text search, single and batch retrieval, and pending/status listing. Minor gaps exist, such as no obvious way to combine full-text search with metadata filters and graph edge kinds are mentioned but no graph query tool is exposed, but agents can work around these.
Maintenance
Related MCP Connectors
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Read-only MCP server exposing a user ORANO library to their own AI agent.
Read-only MCP server: let AI agents read your ORANO saved-video library, tasks, and memory.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server that gives AI agents the web as compact, ranked, verified evidence — no API keys, no cloud retrieval, all models local.17 npm1MIT
- FlicenseAqualityCmaintenanceA read-only MCP server that enables AI assistants to search files, list directories, retrieve system info, and get file metadata on the local file system.4-
- AlicenseAqualityCmaintenanceRead-only MCP server providing AI access to verifiable web, GitHub, and local sources, plus a managed fantasy entity catalog, with strong security and provenance tracking.101MIT
- AlicenseAqualityCmaintenanceRead-only MCP server exposing a W3C PROV knowledge graph of verified facts with provenance, enabling AI agents to list, search, and check facts while enforcing that writes remain CLI-only.5MIT