Skip to main content
Glama
sepehr071

codal-mcp

by sepehr071

codal-mcp: Codal (کدال) disclosure and financial statement MCP server for AI agents

codal-mcp lets an AI agent search and read Codal, the official disclosure system of Iranian listed companies. Codal (codal.ir, سامانه جامع اطلاع‌رسانی ناشران) is where companies and funds on the Tehran Stock Exchange, Iran Fara Bourse and the other Iranian exchanges publish financial statements, monthly activity reports, meeting decisions and material news. codal-mcp is an unofficial, read-only MCP server with 5 tools that turns those letters into text and tables for Claude, Cursor or Copilot.

PyPI Python CI MCP Registry License: MIT

Install in VS Code

For AI agents · Quick start · What it can do · Tools · FAQ · فارسی


For AI agents

  • What: unofficial MCP server (model context protocol) for codal.ir, the disclosure system of companies and funds listed on Iranian exchanges (Tehran Stock Exchange, Iran Fara Bourse, commodity and energy exchanges, and registered unlisted companies).

  • Install: uvx codal-mcp or claude mcp add codal -- uvx codal-mcp. Transport: stdio. Needs uv (Python 3.10+).

  • Auth: none, no API key or account. Optional CODAL_MCP_PROXY (HTTP proxy URL, or a comma-separated list); system proxy settings are ignored.

  • Access: read-only. It cannot log in or file anything, so no confirmation is needed before calling any tool.

  • Tools: 5, all prefixed cd_. Typical sequence: cd_company -> cd_search_letters -> cd_letter. cd_letter_types gives letter type ids for filtering; cd_financial_years gives a company's fiscal year ends.

  • Use when: the user asks what a listed company disclosed: its latest interim or annual financial statements, EPS, monthly sales and production, shareholder meeting decisions, dividend schedule, capital increase, or the text of one Codal letter.

  • Do not use when: the user wants share prices, order books or market indices (use tsetmc-mcp), or wants to trade.

  • Output: compact JSON with ASCII digits. Dates are Jalali (YYYY/MM/DD), Tehran time. Report amounts are as published, usually million Rial (see unit_note).

  • Rate limit: codal.ir blocks an IP for up to an hour after a burst of requests. Make few, targeted calls and reuse results. If a tool says codal.ir is rate limiting, stop and wait.

  • Network: codal.ir often answers only Iranian connections. If requests time out, set CODAL_MCP_PROXY to an Iranian HTTP proxy.

  • Machine-readable: server.json and the iran-mcp catalog.

Related MCP server: KAP MCP Server

Why

Everything an Iranian listed company publishes is on Codal, but behind a search form, Persian digits and report pages rendered by JavaScript, with one statement sheet per page. Answering "how did Foolad do in the first half of the year?" means finding the right letter among 1,475 and reading a table on screen. codal-mcp searches with the site's own filters and returns the statement as rows an agent can read:

You: What did Foolad (فولاد) report for its first six months of 1405?

Agent: calls cd_search_letters(symbol="فولاد", letter_type=6, period_months=6) -> cd_letter(tracing_no=1612323)

Mobarakeh Steel's unaudited six-month statements to 1405/06/31 (published 1405/07/30) show operating revenue of 2,509,422,184 million Rial, 56% more than the same period a year earlier, and a net profit of 591,629,286 million Rial, up 133%. Basic earnings per share were 308 Rial.

Real figures from tracing number 1612323, read with codal-mcp on 2026-10-31 and checked against the letter page on codal.ir.

What it can do

  • Search disclosures of any publisher on Codal, newest first: by symbol, letter group, letter type, words in the title, Jalali date range, report period (1-12 months) or tracing number

  • List the newest letters of the whole market when no filter is given

  • Read financial statements as tables, one sheet at a time: income statement, comprehensive income, balance sheet, changes in equity, cash flows and the interpretive report pages, with the unit note and listed capital

  • Read monthly activity reports: raw material purchases, production and sales by product, energy use and foreign currency sources and uses

  • Read text letters such as explanations, clarifications and notices, without the page's hidden form templates

  • Get the links to each letter's page, PDF, Excel file and attachments (with their descriptions and dates)

  • Look up companies and funds by symbol or name: ISIC code, market, kind, industry and reporting type

  • List letter groups and letter types with the ids the search takes, and a company's fiscal year ends

  • Read-only by design: no login, no captcha solving

Example prompts:

  • "What did Foolad report in its latest interim financial statements?"

  • "Show the balance sheet from that letter."

  • "List Iran Khodro's monthly activity reports for 1405."

  • "Which companies published monthly activity reports this week?"

  • "When does Foolad's fiscal year end, and when were its last annual statements published?"

  • آخرین صورت‌های مالی میان‌دوره‌ای فولاد در کدال چه بود؟

  • گزارش فعالیت ماهانه مهر ۱۴۰۵ ایران خودرو را بیاور.

  • تصمیمات آخرین مجمع عمومی سالیانه فولاد را از کدال بخوان.

Quick start

You need uv. No API key or account.

claude mcp add codal -- uvx codal-mcp

Settings → Developer → Edit Config, then add:

{
  "mcpServers": {
    "codal": { "command": "uvx", "args": ["codal-mcp"] }
  }
}

Add the Claude Desktop block above to ~/.cursor/mcp.json (or .cursor/mcp.json in a project).

Click Install in VS Code above, or add to .vscode/mcp.json:

{
  "servers": {
    "codal": { "type": "stdio", "command": "uvx", "args": ["codal-mcp"] }
  }
}
codex mcp add codal -- uvx codal-mcp

Or in ~/.codex/config.toml:

[mcp_servers.codal]
command = "uvx"
args = ["codal-mcp"]

Add to ~/.gemini/settings.json:

{
  "mcpServers": {
    "codal": { "command": "uvx", "args": ["codal-mcp"] }
  }
}

Add the Claude Desktop block to ~/.codeium/windsurf/mcp_config.json.

It is a standard stdio MCP server: run uvx codal-mcp, or pip install codal-mcp and run codal-mcp.

Tools

Pass the trading symbol in Persian (فولاد, خودرو). Dates are Jalali YYYY/MM/DD; Persian digits are accepted.

Tool

What it does

cd_search_letters

Search codal.ir disclosures (letters) of Iranian listed companies, newest first, 20 per page

cd_letter

Read one codal.ir letter: its text or tables, plus links to its page, PDF, Excel and attachments

cd_company

Find companies and funds on codal.ir by symbol or name, with their market, industry and type

cd_letter_types

List codal.ir letter groups, or the letter types of one group with the ids cd_search_letters takes

cd_financial_years

List the fiscal year-end dates codal.ir knows for one company, newest first (Jalali)

All 5 tools are annotated readOnlyHint: true.

How it works

  AI agent  (Claude, Cursor, Copilot, ...)
      │
      │  MCP over stdio
      ▼
  codal-mcp  (runs on your machine)
      │
      │  HTTPS, one request at a time, at least 2 s apart
      ├──────▶  search.codal.ir   search API, company list, letter types, fiscal years
      └──────▶  www.codal.ir      letter pages, sheets, attachment lists

codal-mcp runs locally and calls the same search API and letter pages the codal.ir website uses. It has no hosted server in between and no API key. Structured reports carry their tables as data inside the letter page; the server reads that data and returns each row as one line, in the site's column order. Other letters come back as their visible text. Requests go out through a Chrome-impersonating client, only to search.codal.ir and www.codal.ir. It only reads.

Good to know

  • Rate limit. codal.ir answers HTTP 429 and shows a captcha after a burst of requests, then blocks the IP for up to an hour. The server sends one request at a time, at least 2 seconds apart, keeps the company list and letter types for 12 hours, letters for an hour and searches for 2 minutes, and never retries a 429. After a 429 it stops calling codal.ir for 10 minutes and tells the agent to wait. It never solves captchas.

  • Iranian connection. codal.ir often does not answer connections from outside Iran (from a foreign VPN exit, requests timed out in our tests). Set CODAL_MCP_PROXY to an HTTP proxy with an Iranian exit. System proxy variables are ignored on purpose.

  • Units. Statement and report amounts are as published, usually million Rial; unit_note quotes the page. EPS is in Rial. Divide Rial by 10 for Toman.

  • Tables are text. Each table row is one line with cells separated by |. Numbers have no thousands separators, and negatives are -N where the site shows (N). Income statements have two «درصد تغيير» columns: change against the same period last year and against the last full year.

  • One sheet at a time. Financial statements are split into sheets; cd_letter returns the list of sheets and takes sheet to read another one (for example 0 for the balance sheet).

  • Attachments are listed, not read. Explanation letters often carry their content in an attached image or PDF. cd_letter returns the links.

  • Long letters are cut at 16,000 characters (truncated); the PDF link has the whole letter.

  • Search tips. period_months=12 finds annual reports, 6 half-year and 3 quarterly; title matches words in the letter title. cd_letter_types lists letter type ids (6 financial statements, 58 monthly activity report, 20 annual general meeting decisions).

  • Persian text. Letter text is returned as the company wrote it, including Arabic ي/ك. Digits are converted to ASCII.

  • What it does not do: no share prices (see tsetmc-mcp), no XBRL parsing, no reading of attached files, no login and no captcha solving.

FAQ

Codal (codal.ir, سامانه جامع اطلاع‌رسانی ناشران) is the official disclosure system run under Iran's Securities and Exchange Organization (SEO). Companies and funds listed on the Tehran Stock Exchange, Iran Fara Bourse and the other Iranian exchanges publish their financial statements, monthly activity reports, meeting notices and decisions, capital increases and material news there. About 5,400 publishers are on it.

Add codal-mcp to your agent, then ask in plain language. The agent finds the letter with cd_search_letters (for example symbol="فولاد", letter_type=6, period_months=6) and reads it with cd_letter(tracing_no=...), which returns the income statement as rows; sheet=0 gives the balance sheet.

There is no documented public API. codal-mcp uses the same search API and letter pages that the codal.ir website uses, without login, and returns compact JSON.

Often not directly: codal.ir did not answer requests from a foreign VPN exit in our tests. Run it on an Iranian connection, or set CODAL_MCP_PROXY to an HTTP proxy with an Iranian exit.

codal.ir blocks an IP for up to an hour after many requests in a short time. The server spaces and caches requests to avoid it; if it still happens, wait and ask again with fewer calls. Results you already have stay valid.

tsetmc-mcp gives market data from the Tehran Stock Exchange: prices, order book, trades and indices. codal-mcp gives what the companies themselves publish: statements, reports and notices. Use both for a full picture of a stock.

No. It returns the tables as the site shows them; the agent can compute ratios from the rows. For a spreadsheet, use the excel link that cd_letter returns.

No. It only reads what companies published. Nothing it returns is financial advice.

npx @modelcontextprotocol/inspector uvx codal-mcp

Configuration

Variable

Default

Meaning

CODAL_MCP_PROXY

unset

Optional HTTP proxy URL for codal.ir requests; system proxy settings are ignored. A comma-separated list is used one at a time: the next proxy takes over when one is blocked or cannot connect

فارسی: سرور MCP کدال برای دستیار هوش مصنوعی

پروژه codal-mcp یک سرور MCP غیررسمی و فقط‌خواندنی برای کدال (codal.ir) است، سامانه‌ای که شرکت‌ها و صندوق‌های بورس تهران، فرابورس و بقیه بورس‌های ایران اطلاعیه‌ها و صورت‌های مالی خود را در آن منتشر می‌کنند. با این سرور، دستیار هوش مصنوعی شما (Claude، Cursor، Copilot و ...) اطلاعیه‌های کدال را جستجو می‌کند و متن و جدول‌های آن‌ها را می‌خواند.

چه کارهایی می‌کند

  • جستجوی اطلاعیه‌ها با نماد، گروه و نوع اطلاعیه، کلمه‌های عنوان، بازه تاریخ شمسی، طول دوره گزارش یا شماره پیگیری؛ جدیدترین‌ها اول.

  • خواندن صورت‌های مالی به شکل جدول، هر بار یک برگه: سود و زیان، وضعیت مالی، جریان‌های نقدی و بقیه برگه‌ها.

  • خواندن گزارش فعالیت ماهانه: خرید مواد اولیه، تولید و فروش هر محصول، مصرف انرژی و منابع و مصارف ارزی.

  • متن اطلاعیه‌های توضیحی و شفاف‌سازی، همراه با لینک PDF، فایل اکسل و پیوست‌ها.

  • جستجوی شرکت‌ها و صندوق‌ها با نماد یا نام، با کد آیسیک، بازار، صنعت و سال‌های مالی.

نکته‌ها

  • فقط اطلاعات منتشرشده را می‌خواند؛ وارد حسابی نمی‌شود و توصیه سرمایه‌گذاری نیست.

  • مبلغ‌ها همان‌طور است که در کدال آمده، معمولاً میلیون ریال. تاریخ‌ها شمسی است.

  • کدال بعد از تعداد زیادی درخواست، دسترسی را تا یک ساعت می‌بندد. این سرور درخواست‌ها را یکی‌یکی و با فاصله دست‌کم ۲ ثانیه می‌فرستد و نتیجه را نگه می‌دارد.

  • کدال معمولاً فقط به اینترنت ایران جواب می‌دهد. اگر درخواست‌ها بی‌جواب ماند، متغیر CODAL_MCP_PROXY را روی یک پراکسی HTTP با خروجی ایران بگذارید.

  • کلید API لازم نیست و سرور روی سیستم خود شما اجرا می‌شود.

نصب (اول uv را نصب کنید). در Claude Code:

claude mcp add codal -- uvx codal-mcp

در Claude Desktop، Cursor و بقیه برنامه‌ها همان تنظیم بخش Quick start را بگذارید.

نمونه پرسش‌ها

  • «آخرین صورت‌های مالی شش‌ماهه فولاد را بیاور و سود خالص را با پارسال مقایسه کن.»

  • «ترازنامه همان اطلاعیه را هم نشان بده.»

  • «گزارش‌های فعالیت ماهانه ایران خودرو در سال ۱۴۰۵ را فهرست کن.»

  • «این هفته کدام شرکت‌ها گزارش فعالیت ماهانه منتشر کرده‌اند؟»

  • «سال مالی فولاد کی تمام می‌شود؟»

Development

git clone https://github.com/sepehr071/codal-mcp && cd codal-mcp
uv sync
uv run ruff check . && uv run ruff format --check .
uv run python -m pytest -q          # offline unit tests on recorded codal.ir pages
uv run python -m pytest -m live -q  # one pass over every tool against codal.ir (about 8 requests)
uv build

All tools live in src/codal_mcp/codal.py; all HTTP, pacing and caching in src/codal_mcp/http.py. Keep the live suite small: codal.ir rate-limits hard. Issues and PRs are welcome.

Releases: bump the version in pyproject.toml and server.json, then push a v* tag. GitHub Actions publishes to PyPI.

  • tsetmc-mcp for Tehran Stock Exchange prices, order book, real vs legal trading and indices

  • iran-tax-mcp for Iranian tax data: goods IDs and VAT, activity codes, property values and tax laws

  • iran-mcp: catalog of all Iranian-service MCP servers

Disclaimer

Unofficial and not affiliated with or endorsed by Codal or the Securities and Exchange Organization of Iran (SEO). It is read-only and uses the search API and pages of the codal.ir website, which can change without notice. Data is informational. Nothing here is financial advice.

Author

Built and maintained by Sepehr Radmard (سپهر رادمرد). Connect on LinkedIn or follow @sepehr071 on GitHub for more MCP servers for Iranian websites, all listed in iran-mcp. If this saves you time, a star on the repo helps other people find it.

License

MIT

Available Tools

5 tools
cd_companyFind a company on CodalA
Read-onlyIdempotent

Find companies and funds on codal.ir by symbol or name, with their market, industry and type.

Use it to get the exact symbol for cd_search_letters and cd_financial_years, or to answer what a symbol is. Exact symbol or name matches come first, then symbols starting with the query, then names containing it; within each, exchange-listed companies before unlisted ones. Covers the ~5,400 publishers on codal.ir, including unlisted companies and funds. matched is the total number of hits.

NameRequiredDescriptionDefault
limitNoMost companies to return.
queryYesTrading symbol or part of the company name, in Persian, e.g. فولاد or فولاد مبارکه.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing ranking behavior: exact symbol or name matches first, then prefix matches, then containing-name matches, with exchange-listed companies before unlisted ones. It also states the coverage (~5,400 publishers) and that `matched` is the total hit count.

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 purpose is front-loaded in the first sentence, followed by usage guidance, ranking details, coverage, and return-count semantics. Each sentence adds useful information with no 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 two-parameter read-only lookup tool with full schema coverage and safety annotations, the description provides enough context: purpose, routing, ranking, scope, and what `matched` means. No output schema exists, and the description adequately covers the return fields and count.

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 schema already documents `query` and `limit` thoroughly. The description adds ranking and coverage context but does not add parameter-specific meaning beyond what the schema provides, so the baseline 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?

States a specific verb and resource: finding companies and funds on codal.ir by symbol or name, returning market, industry, and type. It also positions the tool against siblings by explaining that it supplies the exact symbol needed for cd_search_letters and cd_financial_years.

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?

Explicitly says when to use it: to get the exact `symbol` for cd_search_letters and cd_financial_years, or to answer what a symbol is. It names the relevant alternatives, so the agent does not need to infer routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cd_financial_yearsFiscal years of a companyA
Read-onlyIdempotent

List the fiscal year-end dates codal.ir knows for one company, newest first (Jalali).

Use it to learn when a company's fiscal year ends (e.g. 12/29 or 03/31) before searching for its annual statements with cd_search_letters (from_date after the year end, period_months 12). An empty list usually means the symbol is wrong: check it with cd_company.

NameRequiredDescriptionDefault
symbolYesExact trading symbol in Persian, e.g. فولاد.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive, open-world, so the safety profile is covered. The description adds value beyond that: result ordering (newest first), calendar convention (Jalali), and the meaning of an empty result. It stops short of describing the exact return shape (array of strings vs objects), which matters somewhat since there is no output schema.

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 tight sentences: the first states what is returned and how it is ordered; the second gives the downstream use and the failure diagnostic. No filler, and the core capability is front-loaded.

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 one-parameter read tool with no output schema, the description covers purpose, ordering, calendar, downstream use, and the empty-result case — enough to call it correctly. The only omission is the concrete return shape (what each element looks like), which the absence of an output schema leaves slightly underspecified.

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% for the single `symbol` parameter, so baseline 3 applies. The description reinforces the required input indirectly ("for one company", wrong symbol ⇒ empty list) and points at cd_company for validating the symbol, but adds no format rules beyond what the schema already states.

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?

"List the fiscal year-end dates codal.ir knows for one company, newest first (Jalali)" names a specific verb (list), a specific resource (fiscal year-end dates for one company), plus ordering and calendar. It is instantly distinguishable from siblings like cd_search_letters and cd_company, which are named as different steps.

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?

Explicit workflow guidance: call this before cd_search_letters and pass from_date after the year end with period_months 12. It also gives an exclusion/failure rule — an empty list usually means a wrong symbol, check with cd_company — covering both when to use it and what to do when it fails.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cd_letterRead one Codal letterA
Read-onlyIdempotent

Read one codal.ir letter: its text or tables, plus links to its page, PDF, Excel and attachments.

Use it after cd_search_letters to see what a letter says. Structured reports (financial statements, monthly activity reports) come back as tables, one line per row with cells separated by ' | ' (amounts as on the site, usually million Rial; see unit_note). Financial statements show one sheet at a time: sheets lists them (income statement, balance sheet, cash flows ...); call again with sheet to read another. Other letters come back as text. attachments are files the company attached (often the real content of an explanation letter). Long letters are cut at 16,000 characters (truncated); the PDF link has the full letter.

NameRequiredDescriptionDefault
sheetNoFor financial statements with several sheets: the `sheet` id from the `sheets` list of a previous call, e.g. 0 for the balance sheet. Omit for the first sheet.
tracing_noYesTracing number (شماره پیگیری) from cd_search_letters, e.g. 1612323.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive and open-world, and the description layers on real behavioral detail: the tables-vs-text branch, ' | '-separated rows, the unit caveat for amounts, one-sheet-at-a-time paging, attachments often carrying the real content, and truncation at 16,000 characters with a `truncated` flag and a full-PDF fallback.

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 core capability is front-loaded in the first sentence, and every following sentence carries operational information an agent would otherwise have to discover by trial: format branching, sheet paging, attachment caveat, truncation limit. No filler or restatement of the name.

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 no output schema, the description carries the full burden of explaining returns, and it does: response variants, row encoding, unit note, paging, attachments, truncation. An agent can call this correctly and interpret the result without further documentation.

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?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning: it explains that `sheet` ids come from a prior call's `sheets` list and that omitting it returns the first sheet, and it ties `tracing_no` to the value obtained from cd_search_letters.

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?

States a specific verb and resource ('Read one codal.ir letter') and immediately enumerates what comes back: text or tables plus page, PDF, Excel and attachment links. That is enough to distinguish it from cd_search_letters, which only finds letters rather than reading one.

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?

'Use it after cd_search_letters to see what a letter says' gives an explicit trigger and names the prerequisite sibling. It also explains the re-invocation path for multi-sheet statements ('call again with `sheet`'), though it never states when not to use the tool or what a search-only workflow looks like.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cd_letter_typesList Codal letter typesA
Read-onlyIdempotent

List codal.ir letter groups, or the letter types of one group with the ids cd_search_letters takes.

Call it without arguments for the 11 groups, then with category for that group's letter types. Use the id of a type as letter_type in cd_search_letters (with or without the same category).

NameRequiredDescriptionDefault
categoryNoLetter group code (1-11) to list its letter types; omit to list the groups.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so safety is covered. The description adds real behavioral context beyond them: the no-argument default behavior (returns 11 groups), the two-phase expansion via `category`, and the cross-tool contract that the returned `id` is the `letter_type` value for cd_search_letters. It stops short of describing the returned fields or ordering, which keeps it below a 5.

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 tight sentences, front-loaded with the core purpose and followed by the operational recipe. Every clause carries actionable information; nothing is repeated from the schema or annotations.

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 single-optional-parameter read tool with no output schema, the description covers purpose, sequencing and downstream consumption. The remaining gap is the shape of the returned group/type objects (names, ids, counts), which the agent must discover by calling it.

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?

Schema coverage is 100% with a 1-11 range already documented, so the baseline is 3. The description adds semantics the schema cannot: omitting the parameter changes the result set entirely (groups vs. types), and the returned ids are meant to be fed into another tool's `letter_type` parameter.

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?

States a specific verb and resource ('List codal.ir letter groups, or the letter types of one group') and explicitly ties the output to what the sibling cd_search_letters consumes. An agent can distinguish this lookup tool from cd_search_letters/cd_letter without opening any schema.

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?

Gives an explicit two-step procedure: call with no arguments for the 11 groups, then with `category` for that group's types, and names the downstream use of the returned `id` as `letter_type` in cd_search_letters. Both the when and the how are spelled out, with no alternatives left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cd_search_lettersSearch Codal disclosuresA
Read-onlyIdempotent

Search codal.ir disclosures (letters) of Iranian listed companies, newest first, 20 per page.

Use it for "latest letters of a company", financial statements, monthly reports, meeting decisions, dividend schedules or capital increases. With no filters it lists the newest letters of all companies. Combine filters to narrow down; total is the number of matching letters and pages the number of pages (pass page for more). Each letter has its tracing_no: pass it to cd_letter to read the letter's text and tables and get its PDF, Excel and attachment links. files lists what the letter has. Dates and times are Jalali (Tehran time). No results: check the symbol with cd_company, widen the dates or drop a filter.

NameRequiredDescriptionDefault
pageNoResult page, 20 letters each, newest first.
titleNoWords that must appear in the letter title, in Persian, e.g. سود or افزایش سرمایه.
symbolNoExact trading symbol in Persian, e.g. فولاد or خودرو. Use cd_company to find it.
to_dateNoSent on or before this Jalali date, YYYY/MM/DD.
categoryNoLetter group: 1 financial statements, board reports and dividend schedules; 2 material information, clarifications and EPS forecasts; 3 monthly activity and portfolio reports; 4 articles of association and prospectuses; 5 board and audit committee; 6 shareholder meetings (invitations, decisions); 7 capital increase; 8 exchange notices; 9 SEO (regulator) notices; 10 other; 11 debt securities.
from_dateNoSent on or after this Jalali date, YYYY/MM/DD, e.g. 1405/07/01.
tracing_noNoCodal tracing number (شماره پیگیری) of one letter, e.g. 1612323.
letter_typeNoOne letter type id from cd_letter_types, e.g. 6 interim/annual financial statements, 58 monthly activity report, 20 annual general meeting decisions, 11 material information, 30 dividend payment schedule.
period_monthsNoOnly reports covering this many months, e.g. 12 annual, 6 half-year, 3 quarterly, 1 monthly.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/openWorld, and the description adds genuinely new behavior: newest-first ordering, fixed 20-per-page pagination, the meaning of total and pages, Jalali/Tehran time convention, and what each letter carries (tracing_no, files). It also describes the chaining path to cd_letter for full text, tables and PDF/Excel/attachment links.

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?

Front-loaded with purpose, scope and ordering in the first sentence, then use cases, then return/pagination semantics, then follow-up and troubleshooting. Every clause conveys actionable information; nothing is redundant with the schema text.

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 9 optional parameters and no output schema, the description still covers return metadata (total, pages, per-letter files), pagination limits, date conventions, and the next-step tool. An agent has everything needed to call it and interpret 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?

Schema coverage is 100%, so field meanings are already documented; the description still adds value by explaining pagination usage (pass page for more), the total/pages relationship, the Jalali date format expectation, and the tracing_no handoff to cd_letter. It does not add further semantics for title/symbol/category beyond the schema, which keeps it below a 5.

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?

States a specific verb (search), a specific resource (codal.ir disclosures/letters of Iranian listed companies), plus ordering and page size. It implicitly distinguishes itself from cd_letter (which reads a single letter's text/tables) and cd_company (symbol lookup), so an agent can route without opening a schema.

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?

Gives concrete use cases (latest letters of a company, financial statements, monthly reports, meeting decisions, dividend schedules, capital increases), explains the no-filter behavior, advises combining filters to narrow down, and provides explicit no-results recovery steps (check symbol with cd_company, widen dates, drop a filter). Alternatives are named.

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. 5 tool updatesv0.1.0
    • First observedcd_company
    • First observedcd_financial_years
    • First observedcd_letter
    • First observedcd_letter_types
    • First observedcd_search_letters

TDQS

A4.6/5.0

Scored across 5 tools

Disambiguation5/5

Each tool occupies a distinct niche: search (cd_search_letters), read one record (cd_letter), entity lookup (cd_company), taxonomy browsing (cd_letter_types), and fiscal calendar (cd_financial_years). The only near-overlap — cd_letter_types vs. the letter_type filter of cd_search_letters — is explicitly explained in the descriptions, so an agent can choose correctly.

Naming Consistency4/5

All names share a clear 'cd_' namespace prefix and read naturally. The minor deviation is verb style: cd_search_letters uses a verb_noun form while cd_letter, cd_company, cd_letter_types and cd_financial_years are pure noun phrases, but the pattern is still predictable enough to guess names.

Tool Count5/5

Five tools is well-scoped for a read-only gateway to one disclosure site: one search, one reader, and three small resolution/lookup helpers. Every tool has a clear purpose and no filler operations appear to exist.

Completeness4/5

The surface covers the full read workflow — find company, find letter type, find fiscal year, search letters, read letter content and get file links (PDF/Excel/attachments). As a read-only source CRUD is not applicable, though there is no bulk/aggregate retrieval (e.g. multi-year statement series) and no tool for non-letter codal content, which are minor gaps an agent can work around through repeated calls.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to look up verified investor relations page URLs and earnings release (kessan tanshin) URLs for 3,821 Japanese listed companies by securities code, company name, former or brand name, and to fetch selected company attributes. Also supports retrieving monthly change data, checking credit balance and expiry, and inspecting available field definitions.
    6
    35 npm
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables AI agents to search Turkish companies, funds, and members and to retrieve their public disclosures, attachment files, and financial statements. It also parses fund portfolio PDFs into structured positions and totals, reports corporate actions, and provides upcoming disclosure calendars.
    10
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI tools to read-only query Korean listed companies’ disclosures, financial statements, shareholder information, and filing documents via OpenDART, with optional Toss Securities market data when configured.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to search and analyze Korean corporate disclosures, financial statements, ownership data, XBRL, insider trading signals, accounting-risk scores, and Buffett-style quality metrics, while converting HWP/PDF attachments into Markdown.
    1,087 npm
    MIT