Skip to main content
Glama

HKEx Filing Scraper

HKEx Filing Scraper — one scraper, many databases

CI GitHub Release PyPI License: MIT Python 3.10+ MCP Docs Ruff PRs Welcome

PostgreSQL MySQL SQLite MongoDB Neo4j ClickHouse DuckDB SurrealDB

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 hkex-scraper CLI

Setup

None — paste a URL

pip install + one environment variable

Data

Live from HKEx, nothing stored

Stored in your database(s)

Docs

Live MCP gateway · AI agent support

Getting started

Example: install, scrape filings into SQLite, then query the hosted MCP gateway from an AI agent

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/mcp

Three 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).

Two ways to reach HKEx filings from an AI agent: the hosted MCP gateway or the local stdio server

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 100

Optional 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.db

hkex-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

postgres

relational

PostgreSQL License

postgres

ON CONFLICT DO UPDATE

mysql / mariadb

relational

GPLv2

mysql

ON DUPLICATE KEY UPDATE

sqlite

relational

Public domain

ON CONFLICT DO UPDATE

mongodb

document

SSPL¹

mongodb

update_one(upsert=True)

neo4j

graph

GPLv3 (Community)

neo4j

MERGE

clickhouse

columnar

Apache-2.0

clickhouse

ReplacingMergeTree + read-merge

duckdb

relational

MIT

duckdb

ON CONFLICT DO UPDATE

surrealdb

graph + document

BSL 1.1¹

UPSERT / RELATE

¹ 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.db

How 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 --> C
  • Phase 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_filing and references_filing edges when COMPANY_TABLE is 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

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 tools
count_filingsA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_schemaA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_configA
Read-onlyIdempotent
Inspect

Use this to inspect the active configuration (DATABASE_TARGET, read sink, graph).

Never returns credentials. This tool is read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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

The description clearly states the tool's 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.

Usage Guidelines2/5

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_coverageA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum coverage rows to return (1..200).
date_toNoFilter by chunk month, YYYY-MM-DD.
date_fromNoFilter by chunk month, YYYY-MM-DD.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_filingA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
filing_idYes16-character filing id; obtain from search_filings.
text_offsetNoCharacter offset into document_text for paging.
include_textNoInclude the extracted document text window.
include_tablesNoInclude extracted document tables.
max_text_charsNoMaximum characters of text to return (0..200000).

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_filingsA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
filing_idsYesFiling ids to fetch (1..50); obtain from search_filings.
include_textNoInclude the extracted document text window (off by default).
include_tablesNoInclude extracted document tables.
max_text_charsNoMaximum characters of text to return (0..200000).

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_parityA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_infoA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_statisticsA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerNoCompany ticker filter, e.g. 0700.HK; comma-separate to match several.
date_toNoLatest filing date, YYYY-MM-DD inclusive.
exchangeNoExchange code, e.g. HK.
group_byNoDimension to count filings by.company_ticker
date_fromNoEarliest filing date, YYYY-MM-DD inclusive.
filing_typeNoFiling type(s), e.g. 'Annual Report'; comma-separate to match several.
title_queryNoCase-insensitive substring matched against the filing title.
document_statusNoDocument status(es): processed, skipped, failed, or unprocessed; comma-separate to match several.
filing_categoryNoFiling category(ies), e.g. LISTED_COMPANY; comma-separate to match several.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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_companiesA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum companies to return (1..100).
offsetNoZero-based offset for paging.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_filingsA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum filings to return (1..100).
document_statusNoDocument status(es): unprocessed (default), processed, skipped, failed; comma-separate for several.unprocessed

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_sinksA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_tickersA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum tickers to return (1..1000).
offsetNoZero-based offset for paging.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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_documentsA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNoZero-based offset for paging.
tickerNoCompany ticker filter, e.g. 0700.HK; comma-separate to match several.
date_toNoLatest filing date, YYYY-MM-DD inclusive.
order_byNoSort order of the result.filing_date_desc
date_fromNoEarliest filing date, YYYY-MM-DD inclusive.
page_sizeNoMaximum filings to return (1..100).
text_queryYesCase-insensitive term matched against extracted document text.
filing_typeNoFiling type(s), e.g. 'Annual Report'; comma-separate to match several.
document_statusNoDocument status(es): processed, skipped, failed, or unprocessed; comma-separate to match several.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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_filingsA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNoZero-based offset for paging.
tickerNoCompany ticker filter, e.g. 0700.HK; comma-separate to match several.
date_toNoLatest filing date, YYYY-MM-DD inclusive.
exchangeNoExchange code, e.g. HK.
order_byNoSort order of the result.filing_date_desc
date_fromNoEarliest filing date, YYYY-MM-DD inclusive.
page_sizeNoMaximum filings to return (1..100).
stock_codeNoNumeric stock code filter, e.g. 00700; comma-separate to match several.
filing_typeNoFiling type(s), e.g. 'Annual Report'; comma-separate to match several.
title_queryNoCase-insensitive substring matched against the filing title.
document_statusNoDocument status(es): processed, skipped, failed, or unprocessed; comma-separate to match several.
filing_categoryNoFiling category(ies), e.g. LISTED_COMPANY; comma-separate to match several.
referenced_tickerNoTicker referenced by the filing (graph edge).

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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

The description clearly states the tool's 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.

Usage Guidelines3/5

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_sinksA
Read-onlyIdempotent
Inspect

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

  1. 16 tool updates
    • First observedcount_filings
    • First observeddescribe_schema
    • First observedget_config
    • First observedget_coverage
    • First observedget_filing
    • First observedget_filings
    • First observedget_parity
    • First observedget_server_info
    • First observedget_statistics
    • First observedlist_companies
    • First observedlist_pending_filings
    • First observedlist_sinks
    • First observedlist_tickers
    • First observedsearch_documents
    • First observedsearch_filings
    • First observedverify_sinks

TDQS

A4.1/5.0

Scored across 16 tools

Disambiguation3/5

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.

Naming Consistency5/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    C
    maintenance
    A 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
    -
  • A
    license
    A
    quality
    C
    maintenance
    Read-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.
    5
    MIT