codal-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@codal-mcpWhat did Foolad report for its first six months of 1405?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
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-mcporclaude 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_typesgives letter type ids for filtering;cd_financial_yearsgives 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 (seeunit_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_PROXYto an Iranian HTTP proxy.Machine-readable:
server.jsonand 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-mcpSettings → 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-mcpOr 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 |
| Search codal.ir disclosures (letters) of Iranian listed companies, newest first, 20 per page |
| Read one codal.ir letter: its text or tables, plus links to its page, PDF, Excel and attachments |
| Find companies and funds on codal.ir by symbol or name, with their market, industry and type |
| List codal.ir letter groups, or the letter types of one group with the ids |
| 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 listscodal-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_PROXYto 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_notequotes 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-Nwhere 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_letterreturns the list ofsheetsand takessheetto read another one (for example0for the balance sheet).Attachments are listed, not read. Explanation letters often carry their content in an attached image or PDF.
cd_letterreturns the links.Long letters are cut at 16,000 characters (
truncated); the PDF link has the whole letter.Search tips.
period_months=12finds annual reports,6half-year and3quarterly;titlematches words in the letter title.cd_letter_typeslists 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-mcpConfiguration
Variable | Default | Meaning |
| 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 buildAll 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.
Related servers
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
Available Tools
5 toolscd_companyFind a company on CodalARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Most companies to return. | |
| query | Yes | Trading symbol or part of the company name, in Persian, e.g. فولاد or فولاد مبارکه. |
TDQS
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.
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.
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.
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.
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.
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 companyARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| symbol | Yes | Exact trading symbol in Persian, e.g. فولاد. |
TDQS
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.
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.
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.
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.
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.
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 letterARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| sheet | No | For 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_no | Yes | Tracing number (شماره پیگیری) from cd_search_letters, e.g. 1612323. |
TDQS
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.
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.
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.
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.
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.
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 typesARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Letter group code (1-11) to list its letter types; omit to list the groups. |
TDQS
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.
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.
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.
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.
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.
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 disclosuresARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Result page, 20 letters each, newest first. | |
| title | No | Words that must appear in the letter title, in Persian, e.g. سود or افزایش سرمایه. | |
| symbol | No | Exact trading symbol in Persian, e.g. فولاد or خودرو. Use cd_company to find it. | |
| to_date | No | Sent on or before this Jalali date, YYYY/MM/DD. | |
| category | No | Letter 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_date | No | Sent on or after this Jalali date, YYYY/MM/DD, e.g. 1405/07/01. | |
| tracing_no | No | Codal tracing number (شماره پیگیری) of one letter, e.g. 1612323. | |
| letter_type | No | One 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_months | No | Only reports covering this many months, e.g. 12 annual, 6 half-year, 3 quarterly, 1 monthly. |
TDQS
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.
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.
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.
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.
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.
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.
5 tool updates
v0.1.0- First observed
cd_company - First observed
cd_financial_years - First observed
cd_letter - First observed
cd_letter_types - First observed
cd_search_letters
TDQS
Scored across 5 tools
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.
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.
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.
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
Related MCP Connectors
SEC-filed company financials with filing citations, plus market data, for AI agents
SEC EDGAR financials, insider trading, and economic data for AI agents. US GAAP + IFRS.
Primary-source SEC filing intelligence and financial/disclosure reconciliation for AI agents.
SEC filings and financial data for AI agents: 59 tools for statements, valuation and supply chains.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables 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.635 npmMIT
- AlicenseBqualityBmaintenanceEnables 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.101MIT
- AlicenseNot gradedqualityBmaintenanceEnables 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
- AlicenseNot gradedqualityAmaintenanceEnables 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 npmMIT