FinBridge
Server Details
Korean company disclosures in English: DART filings, financial statements, segments, 13F.
- Status
- Healthy
- Uptime
- 98.8% over 36 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- Jakechj/finbridge-mcp
- GitHub Stars
- 0
- Server Listing
- FinBridge
TDQS
Scored across 26 tools
Tools are largely distinct, with market-specific adapters (dart_* vs edgar_*), dedicated functions for filings, financials, insiders, portfolio, and watchlist. Some overlap exists among the filing/feed tools (get_dart_filings, get_dart_major_events, get_disclosure_feed, get_edgar_filings), but their descriptions explicitly delineate boundaries and use cases.
All tool names use consistent snake_case verb_noun patterns with clear qualifiers (e.g., get_dart_financials, search_edgar_company, import_portfolio). Prefixes (get_/search_/import_/manage_/query_/restore_/screen_) are used consistently across the set.
26 tools is heavy for a single MCP server, and several could arguably be consolidated (e.g., filing list tools, watchlist get/manage, portfolio history/restore). However, the server covers a broad multi-market domain and each tool has a distinct role, so the count is borderline rather than excessive.
Core workflows for KR/US filings, financials, insider trades, pricing, valuation, peers, portfolio, and watchlist are covered. Notable gaps remain: no dedicated search or financials for Japan/Taiwan/Europe (only query_db), no US filing-body parser analogous to get_dart_document, and no insider tools for JP/EU; these are workaroundable via query_db but represent real omissions.
Available Tools
26 toolscompare_financials_kr_usCompare KR vs US Company FinancialsARead-onlyInspect
Compare annual financial statements of a Korean listed company (source: OpenDART, K-IFRS) and a US listed company (source: SEC EDGAR, US-GAAP) side by side, with KRW values converted to USD using Federal Reserve H.10 annual-average exchange rates.
Args:
kr_company: Korean company name / 6-digit stock code / DART corp_code (e.g. '삼성전자', '005930')
us_company: US ticker / name / CIK (e.g. 'AAPL', 'Apple')
years: number of recent fiscal years, 1-5 (default 3; free plan up to 4)
metrics: subset of [revenue, gross_profit, operating_income, net_income, eps_diluted, assets, liabilities, equity, cash_and_equivalents, operating_cash_flow]
response_format: 'markdown' (default) or 'json'
Returns per-metric, per-year rows: {fiscal_year, kr_krw, kr_usd, us_usd, ratio_kr_over_us} plus the FX rates used and accounting-basis caveats.
Examples:
"삼성전자 vs Apple 최근 3년 매출·영업이익 비교" -> {kr_company:'삼성전자', us_company:'AAPL', metrics:['revenue','operating_income']}
Don't use for quarterly data (annual only) or non-KR/US companies.
Errors: unknown company names suggest using search_dart_company / search_edgar_company first.
| Name | Required | Description | Default |
|---|---|---|---|
| years | No | How many recent fiscal years to compare (default 3; the free plan covers up to 4) | |
| metrics | No | Metrics to compare (default: revenue, operating_income, net_income, assets, equity). Available: revenue, gross_profit, operating_income, net_income, eps_diluted, assets, liabilities, equity, cash_and_equivalents, operating_cash_flow | |
| kr_company | Yes | Korean company: name (e.g. '삼성전자'), 6-digit stock code (e.g. '005930'), or 8-digit DART corp_code | |
| us_company | Yes | US company: ticker (e.g. 'AAPL'), company name, or CIK | |
| response_format | No | 'markdown' for tables, 'json' for compact machine-readable output | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| fx | No | |
| kr | Yes | |
| us | Yes | |
| notes | No | |
| metrics | No | |
| comparison | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, openWorldHint=true, so the safety profile is carried by structured data. The description nonetheless adds real context beyond it: upstream sources (OpenDART K-IFRS, SEC EDGAR US-GAAP), the Fed H.10 annual-average FX basis, accounting-basis caveats, and a plan quota ('free plan up to 4' years). Only minor operational details (rate limits, latency) are absent.
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 one-sentence summary followed by clearly delimited Args/Returns/Examples/Errors sections, each earning its place. Minor redundancy: the Args and metrics enumeration duplicate the schema's own descriptions, so a small amount of text could be trimmed without losing information.
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?
Covers everything an agent needs: valid inputs, FX conversion basis, accounting-standard mismatch caveats, output shape, hard exclusions, and error recovery paths. An output schema exists so the return-value explanation is optional, yet the description still orients the agent correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 — every parameter (kr_company, us_company, years, metrics, response_format) is already documented in the schema, and the description's Args block largely restates it. The worked natural-language example does add value by showing how kr_company's three accepted identifier forms map to a real query.
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 (compare) and resource (annual financial statements of a Korean vs US listed company), plus the exact data sources and FX methodology. An agent can distinguish this immediately from get_dart_financials and get_edgar_financials, which cover only one market each.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when not to use it ('annual only', 'non-KR/US companies') and routes the agent to search_dart_company / search_edgar_company on unknown-name errors. This is a full when/when-not/alternative specification, not an implied one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dart_documentExplore Korean Disclosure Document (DART)ARead-onlyInspect
Explore one DART filing by receipt number while preserving section and table structure — the main body by default, or one of its attachments (audit reports carry the consolidated statements; the main body carries the business description).
Use get_dart_filings first to obtain rcept_no. Start with action='overview', then select a section or table instead of requesting a long flattened filing. The overview lists the archive's entries (main body + attachments with their first heading); pass entry='' to explore an attachment.
Args:
rcept_no: 14-digit DART receipt number
entry: archive entry name from the overview's entries list (default: the main body)
action: overview (default) | section | table | compare_tables | compare_sections
compare_rcept_no and compare_index: second filing and its selected table/section index for comparison; table_index/section_index selects the first. Use both overviews first. Only selected content is compared, not entire filings.
section_index or section_query: one section selector for action='section'
table_index: 1-based table selector for action='table'
max_chars: section text cap, 1,000-100,000 (default 30,000)
max_rows/max_columns: selected table caps (defaults 50/30)
overview_offset/overview_limit: paginate both section and table summaries with the same 0-based slice (defaults 0/20, max 100)
response_format: markdown or json
Returns source evidence for the OpenDART document entry and character range. Tables retain row/column order, cell text, rowspan/colspan and nearby reported unit labels. Zero and negative strings are not discarded. Separate HWP/PDF files are not fetched or rehosted.
This tool does not claim an XBRL presentation/calculation hierarchy. Use get_dart_financials for normalized figures, reported account groups and known statement sum checks.
| Name | Required | Description | Default |
|---|---|---|---|
| entry | No | Archive entry to explore, exactly as the overview's entries list names it (e.g. 20260313001021_00761.xml for a consolidated audit report). Omit for the main body. Attachments are read from DART, not from the preserved copy. | |
| fresh | No | false (default): read FinBridge's preserved copy of this filing when we hold one, and DART otherwise. true: fetch the current version from DART now — use only when the user asks for the latest text or suspects a correction. | |
| action | No | Start with the outline, then select a section or a leaf table. | overview |
| max_rows | No | Maximum selected table rows; original row count is retained. | |
| rcept_no | Yes | 14-digit DART receipt number from get_dart_filings | |
| max_chars | No | Maximum characters of selected section text; truncation is explicit. | |
| max_columns | No | Maximum selected table columns; original column count is retained. | |
| table_index | No | 1-based leaf-table number; required for table action. | |
| compare_index | No | Table or section index inside the second filing. Read that filing's overview first; table_index/section_index selects the first filing's side. | |
| section_index | No | 1-based section number from the outline; use only with section action. | |
| section_query | No | Section title search; use instead of section_index. Ambiguous matches are rejected. | |
| overview_limit | No | Maximum section and table summaries per outline page; follow next_offset. | |
| overview_offset | No | 0-based outline slice offset for both sections and tables. | |
| response_format | No | Readable markdown or JSON; both retain structured content. | markdown |
| compare_rcept_no | No | Second filing's 14-digit receipt number, for compare_tables / compare_sections. The first filing is rcept_no. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | No | |
| table | No | |
| action | Yes | |
| tables | No | |
| section | No | |
| overview | No | |
| sections | No | |
| comparison | No | |
| preservation | No | |
| source_evidence | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/destructive=false, but the description adds real behavioral context beyond them: preserved-copy vs live-DART reads (fresh), table structure retention (row/col order, span, unit labels), that zero/negative strings survive, and the explicit disclaimer that no XBRL hierarchy is claimed.
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 and routing before the arg list, and every section carries information. The args block largely restates schema fields, which is mild redundancy rather than waste; overall it is long but well organized.
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 15-parameter, multi-action tool with an output schema and annotations, the description covers workflow ordering, comparison semantics, truncation/pagination behavior, and explicit non-goals. An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so per-parameter meaning is already documented; the description still adds interaction-level semantics the schema lacks — that compare_rcept_no compares only the selected table/section, that both overviews must be read first, and that section_query rejects ambiguous matches.
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 ('Explore one DART filing by receipt number') and immediately scopes it: main body by default or a named attachment. It also names the sibling it is not (get_dart_financials for normalized figures), so an agent can route correctly without opening schemas.
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 sequencing: 'Use get_dart_filings first to obtain rcept_no', 'Start with action=overview', then select a section/table rather than requesting a flattened filing. It also names the alternative tool for normalized figures and the condition selecting it, plus the HWP/PDF exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dart_filingsKorean Disclosure Filings (DART)ARead-onlyInspect
List corporate disclosure filings from DART, optionally filtered by company, date range, and disclosure type. Report names are in Korean.
Not this tool for: US filings (get_edgar_filings), a cross-market feed already stored here (get_disclosure_feed), or major-event reports specifically (get_dart_major_events, a narrower slice of this one).
Args:
corp: optional — Company: Korean name (e.g. '삼성전자'), 6-digit stock code (e.g. '005930'), or 8-digit DART corp_code (e.g. '00126380'). Omit for a market-wide list.
from / to: YYYY-MM-DD (default: last 90 days)
type: DART pblntf_ty — A=periodic reports(정기공시), B=major events(주요사항보고), C=securities issuance(발행공시), D=ownership/stake(지분공시), E=other(기타공시), F=external audit(외부감사관련), G=funds(펀드공시), H=asset securitization(자산유동화), I=KRX disclosures(거래소공시), J=fair trade(공정위공시)
limit: results per page, 1-100 (default 20); page: page number (default 1)
Returns: {total, page, filings: [{rcept_no, corp_name, report_nm, flr_nm, rcept_dt, url}]} — url opens the filing in the DART viewer. Pass rcept_no to get_dart_document to explore its primary body by outline, section, or table.
Examples:
{corp: '삼성전자'} -> Samsung filings in the last 90 days
{type: 'A', from: '2026-03-01', to: '2026-03-31'} -> March periodic reports market-wide
Use to track what a company disclosed. For major events with keyword filtering use get_dart_major_events. Errors: no filings in range (DART status 013) -> widen dates or drop filters; unknown company -> search_dart_company.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | End date YYYY-MM-DD (default: today) | |
| corp | No | Optional filter — Company: Korean name (e.g. '삼성전자'), 6-digit stock code (e.g. '005930'), or 8-digit DART corp_code (e.g. '00126380') | |
| from | No | Start date YYYY-MM-DD (default: 90 days ago) | |
| page | No | Page number (default 1) | |
| type | No | Disclosure type: A=periodic, B=major events, C=issuance, D=ownership, E=other, F=audit, G=funds, H=asset-backed, I=KRX, J=fair-trade | |
| fresh | No | false (default): answer from FinBridge's DART filings index (refreshed every 5 minutes) for the part of the window it covers, and ask DART live only for the uncovered remainder (saves DART's daily quota). true: ask DART directly for the whole window; on daily-quota exhaustion (020), falls back to the index for whatever it covers and says what could not be refreshed. | |
| limit | No | Results per page, 1-100 (default 20) |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| page | No | |
| total | No | |
| filings | Yes | |
| sources | No | |
| uncovered | No | |
| index_as_of | No | |
| served_from | No | |
| quota_fallback | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, destructiveHint=false), but the description adds non-obvious context: report names are in Korean, error codes (DART 013 for empty range, 020 for quota exhaustion) with recovery advice, and the follow-up path of passing rcept_no to get_dart_document. It does not restate what the read-only annotation already conveys, which is the right call.
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?
Well front-loaded: purpose, then exclusions, args, returns, examples, errors. It is on the long side and partly restates schema parameter lines, but each block is scannable and earns its place for a 7-parameter tool with quota subtlety.
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 an open-world, quota-sensitive, 7-parameter list tool, the description covers filtering, defaults, pagination, return fields, next-step chaining, and error recovery. An output schema exists, yet the brief return summary is only a glanceable convenience rather than a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description expands the `type` enum with full Korean label meanings for every code and gives worked examples showing acceptable corp formats and date combinations. This adds genuine interpretation value over the terse schema enum descriptions.
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?
Opens with a specific verb+resource ('List corporate disclosure filings from DART') and enumerates the filter dimensions. The 'Not this tool for' block explicitly separates it from get_edgar_filings, get_disclosure_feed, and get_dart_major_events, so an agent can distinguish it from siblings 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?
Provides explicit when-to-use ('track what a company disclosed'), when-not-to-use (four named alternative tools with the condition that selects each), and reinforces the routing with a closing line about keyword-filtered major events. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dart_financialsKorean Company Financials (DART)ARead-onlyInspect
Fetch financial statements of a Korean company from OpenDART (fnlttSinglAcntAll: full single-company statements) and normalize them to standard metrics. Amounts are raw KRW (no scaling); EPS is KRW per share.
Not this tool for: US statements (get_edgar_financials), a KR-vs-US pair on one screen (compare_financials_kr_us), or ranking many companies at once (query_db, which reads the stored table and covers KR/US/TW/JP/EU). This tool requests one Korean company's statements through the DART adapter; results may be reused from a process-local cache for up to 24 hours. When FinBridge's own database already has this exact company/year/report/basis with account-level detail and no newer filing receipt, it answers from the database instead of calling DART (served_from: finbridge_db) — saved to conserve the shared daily DART quota; a 'statement'/'account_query' filter always goes live since the DB keeps only the top reported rows. data_as_of.generated_at is response creation time, not source retrieval time. Peer comparisons use separately dated database snapshots.
Args:
corp: Company: Korean name (e.g. '삼성전자'), 6-digit stock code (e.g. '005930'), or 8-digit DART corp_code (e.g. '00126380')
year: business year 2015-2026 (default: last year). Annual reports are filed ~March of the following year (FY2025 filed 2026-03).
report: 'annual' | 'q1' | 'half' | 'q3' (default 'annual')
fs: 'consolidated' | 'separate' (default 'consolidated'). If consolidated statements do not exist, automatically retries separate and says so in notes.
statement: optional BS/IS/CIS/CF/SCE account-group filter
account_query: optional case-insensitive account name or account_id substring
account_limit: returned account rows, 1-200 (default 40)
as_of: optional YYYY-MM-DD. Adds point_in_time: the version of this period/basis that was public on that day.
response_format: 'markdown' (default, tables) or 'json' (compact)
Returns structured {normalized, accounts}:
normalized: {company:{name,id,ticker}, basis, periods:[{period, fiscal_year, currency:'KRW', metrics:{revenue, gross_profit, operating_income, net_income, eps_diluted, assets, liabilities, equity, cash_and_equivalents, operating_cash_flow}}], notes}. Annual reports include the prior-year comparative as a second period.
accounts: selected reported statement rows with statement, account id/detail, reported order, currency, current and previous amounts.
statement_groups: counts and reported order ranges by BS/IS/CIS/CF/SCE. These are flat DART groups, not an inferred XBRL hierarchy.
sum_checks: known balance-sheet equations with pass/fail/not_tested, operands, currency, tolerance and receipt-number evidence.
preserved_revisions: bounded numeric filing versions for the exact database company, requested period and actual statement basis. Includes provider, metric units, publication-day evidence, latest observation, unknown first-seen state, and explicit comparison uncertainty.
revision_links: original filing <-> amendment filings for this period/basis, linked only by DART report names ([기재정정]/[첨부정정] prefix, same title, one original, later receipt numbers). restated_items lists each metric whose value changed with original_value, amended_value, both receipt numbers, both publication dates and both DART URLs. Exact 1,000^k ratios are flagged as suspected unit errors, not restatements. Unlinkable cases return a reason instead of a guess.
point_in_time (only with as_of): the last preserved version with publication_date <= as_of (no look-ahead; latest-value fallback is never used). status found | uncertain (an amendment public by as_of has no preserved values) | not_yet_filed | original_not_preserved | no_versions | unavailable.
earnings_disclosures (only when stored filings exist for this period): figures the company itself disclosed, next to its periodic-report figures. preliminary_vs_reported = the last 영업(잠정)실적 filing published on or before the periodic report vs that report's original values (difference, difference_pct, within_rounding = within half the preliminary table's unit; window_ambiguous/scale_suspect assert nothing), with every preliminary version, its amendment link (only when exactly one earlier original exists) and unreadable filings. outlook_vs_reported = single-number items from 영업실적등에대한전망/장래사업ㆍ경영계획 for this exact period with achievement_pct = reported ÷ disclosed × 100, or a status explaining why nothing is computed (basis_not_stated, definition_may_differ, period_not_reported_directly …). history = counts of those filings and their amendments since recorded_from. Facts only — no forecast, estimate or recommendation.
Examples:
{corp: '삼성전자', year: 2024} -> FY2024+FY2023, revenue ~3.0e14 KRW
{corp: '005930', year: 2025, report: 'q1'} -> Q1 2025 (3-month income-statement figures)
{corp: '010130', year: 2024, as_of: '2025-06-30'} -> FY2024 as known on 2025-06-30 (before the 2026-08-13 amendment)
Use for KR-listed company fundamentals. Don't use for US companies (get_edgar_financials) or for filings text (get_dart_filings). Errors: 'no data' (DART status 013) -> try another year/report or fs='separate'; unknown company -> run search_dart_company first.
| Name | Required | Description | Default |
|---|---|---|---|
| fs | No | Statement scope: consolidated(연결, CFS) or separate(별도, OFS). Default consolidated. | consolidated |
| corp | Yes | Company: Korean name (e.g. '삼성전자'), 6-digit stock code (e.g. '005930'), or 8-digit DART corp_code (e.g. '00126380') | |
| year | No | Business year (bsns_year), 2015-2026. Default: last year (2025). | |
| as_of | No | Optional YYYY-MM-DD. Return point_in_time: the preserved version of this period that was public on that day. | |
| report | No | Report type: annual(사업보고서) | q1(1분기) | half(반기) | q3(3분기). Default annual. | annual |
| statement | No | Optional statement-group filter. | |
| account_limit | No | Maximum returned account rows (default 40). | |
| account_query | No | Optional account name/account_id substring. | |
| response_format | No | 'markdown' for tables, 'json' for compact machine-readable output | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| accounts | No | |
| data_as_of | No | |
| normalized | Yes | |
| plan_limit | No | |
| receipt_id | No | |
| sum_checks | No | |
| receipt_url | No | |
| served_from | No | |
| stored_as_of | No | |
| point_in_time | No | |
| disclosed_date | No | |
| revision_links | No | |
| peer_comparison | No | |
| live_dart_status | No | |
| statement_groups | No | |
| account_selection | No | |
| preserved_revisions | No | |
| earnings_disclosures | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly/openWorld/non-destructive, but the description goes far beyond: 24-hour process-local cache reuse, a database-first fallback with served_from=finbridge_db to conserve the shared daily DART quota, the rule that statement/account_query filters always go live, the fact that data_as_of.generated_at is response-creation time not retrieval time, no-look-ahead point-in-time semantics, and explicit 'facts only, no forecast' caveats. This is unusually rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded well with purpose first, but the definition is sprawling. The lengthy Returns block restates structures that an output schema already provides (normalized, accounts, sum_checks, preserved_revisions, revision_links, earnings_disclosures), which the scoring brief says the description needn't explain. Much of this is genuinely useful context, but the volume exceeds what is needed to call the tool.
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 9-parameter, open-world, quota-constrained tool with an output schema, the description covers the gaps the structured fields leave: fallback/auth/quota behavior, point-in-time correctness, restatement vs unit-error distinction, and error handling. Nothing material is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: the ~March filing lag for annual reports, the automatic consolidated->separate retry with a note, what as_of actually returns (point_in_time version), and that account_query is a case-insensitive substring. These are semantics the schema's terse field descriptions do not carry.
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?
Opens with a specific verb+resource ('Fetch financial statements of a Korean company from OpenDART') and names the exact DART endpoint. It immediately distinguishes itself from siblings by explicitly listing what it is NOT for (US statements, KR-vs-US pairs, multi-company ranking), so an agent can route correctly 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?
Provides an explicit 'Not this tool for' block naming get_edgar_financials, compare_financials_kr_us, and query_db, plus a closing 'Use for KR-listed company fundamentals. Don't use for US companies... or for filings text (get_dart_filings)'. Error recovery ('no data' -> try another year/report or fs='separate'; unknown company -> search_dart_company) is also spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dart_insider_tradesGet KR Insider Trades (DART 임원·주요주주 소유보고)ARead-onlyInspect
Korean insider transactions for a listed KR company, from DART's 임원ㆍ주요주주 특정증권등 소유상황보고서 (elestock) — the Korean equivalent of SEC Form 4. Includes a buy-vs-sell summary and an optional buy/sell filter.
Not this tool for: US insiders (get_edgar_insider_trades) or institutional managers, which are a different kind of holder entirely (get_edgar_13f).
Buy vs sell is the SIGN of the reported share change (증감수): positive = 취득 (acquire / buy), negative = 처분 (dispose / sell). Insider BUYING is a stronger sentiment signal.
Args:
company (required): KR 6-digit stock code (e.g. '005930'), company name, or 8-digit DART corp_code
limit: number of most-recent reports to return, 1-100 (default 20)
tx_type: 'all' (default) | 'buy' (share change > 0) | 'sell' (share change < 0)
response_format: 'markdown' (default) or 'json'
Returns: {company:{corp_code, corp_name}, tx_type, summary:{buys:{count,shares}, sells:{count,shares}}, count, trades:[{filedAt, reporter, position, registered_exec, major_shareholder, change, shares_after, change_rate}], notes}. summary totals cover the whole fetched set regardless of the filter.
Important: this elestock summary API does not provide transaction dates or prices. filedAt is the filing date, not the transaction date. The underlying filing may contain these details; use get_dart_document with the returned rcept_no to inspect its tables.
Examples:
"삼성전자 임원 매수" -> {company:'005930', tx_type:'buy'}
"SK하이닉스 내부자 매도 최근" -> {company:'000660', tx_type:'sell'}
Use when: monitoring KR officer / major-shareholder buy/sell activity. For US insiders use get_edgar_insider_trades. For institutional holdings use get_edgar_13f. Errors: unknown company -> use search_dart_company; a filter with no matches returns count 0 (not an error).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of most-recent reports (default 20) | |
| company | Yes | KR 6-digit stock code (e.g. '005930'), company name, or DART corp_code | |
| tx_type | No | 'all' (default), 'buy' = acquisitions (change > 0), 'sell' = disposals (change < 0) | all |
| response_format | No | 'markdown' for a table, 'json' for compact machine-readable output | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| notes | No | |
| trades | Yes | |
| company | Yes | |
| summary | No | |
| tx_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/non-destructive, but the description adds rich behavioral context beyond them: the buy/sell sign semantics, that the API provides no transaction dates or prices, that filedAt is the filing date not the transaction date, that summary totals cover the whole fetched set regardless of filter, and that an empty filter match returns count 0 rather than an error.
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?
Well front-loaded with purpose first, then exclusions, args, returns, caveats, examples, and usage. It is on the longer side, but nearly every block carries actionable information; the Returns block partially duplicates the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a filter-heavy tool with an output schema, this definition is fully sufficient: it states scope, alternatives, argument formats, the derived semantics of the buy/sell field, error handling, and the data-availability caveat, so an agent can call it correctly without further inference.
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 domain meaning beyond the schema: it spells out the accepted company identifiers (6-digit code / name / 8-digit corp_code), explains buy/sell as the sign of 증감수 at the conceptual level, and clarifies the summary-vs-filter interaction.
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+resource scoped to Korean listed companies, names the DART filing type (elestock) and explicitly equates it to SEC Form 4. It also names what it is NOT (get_edgar_insider_trades, get_edgar_13f), so an agent can distinguish it from siblings without opening schemas.
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?
Has explicit 'Not this tool for:' and 'Use when:' sections that route to the correct sibling for US insiders and institutional holdings, plus an Errors section telling the agent what to do when a company is unknown.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dart_major_eventsKorean Major-Event Disclosures (DART)ARead-onlyInspect
List major-event disclosures (주요사항보고서, DART type B): capital increases, mergers, convertible bonds, treasury stock, bankruptcy, lawsuits, etc. Optionally filter report names with a regex.
Not this tool for: the full disclosure list or other report categories (get_dart_filings — periodic reports, securities issuance, ownership, KRX notices), US 8-K events (get_edgar_filings), or the cross-market stored feed (get_disclosure_feed). What this adds over get_dart_filings type='B': a 'kinds' regex over Korean report names (e.g. '증자|합병|전환사채'), a 180-day default window tuned for event scans, and matched-count totals — so use it when the question is 'which companies announced X', not 'what did company Y file'.
Args:
corp: optional — Company: Korean name (e.g. '삼성전자'), 6-digit stock code (e.g. '005930'), or 8-digit DART corp_code (e.g. '00126380'). Omit for market-wide events.
from / to: YYYY-MM-DD (default: last 180 days)
kinds: optional JavaScript regex matched against the Korean report name, e.g. '증자|합병|전환사채' (capital increase | merger | CB) or '자기주식' (treasury stock). Filtering runs over every event in range when FinBridge's index covers the window, otherwise over the most recent 100 events DART returns.
limit: max results, 1-100 (default 20)
Returns: {total, page, filings: [{rcept_no, corp_name, report_nm, flr_nm, rcept_dt, url}]} — same shape as get_dart_filings. When kinds is given, total = matched count within the scanned window.
Examples:
{corp: '삼성전자', kinds: '자기주식'} -> Samsung treasury-stock decisions in the last 180 days
{kinds: '유상증자', from: '2026-01-01', to: '2026-06-30'} -> market-wide rights offerings in H1 2026
Use when: event-driven screening (rights offerings, mergers, CBs, treasury stock, lawsuits) market-wide or for one company. For every filing category, or when you already know the report you want, use get_dart_filings. Errors: no events in range (DART status 013) -> widen dates; invalid kinds regex; unknown company -> search_dart_company.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | End date YYYY-MM-DD (default: today) | |
| corp | No | Optional filter — Company: Korean name (e.g. '삼성전자'), 6-digit stock code (e.g. '005930'), or 8-digit DART corp_code (e.g. '00126380') | |
| from | No | Start date YYYY-MM-DD (default: 180 days ago) | |
| fresh | No | false (default): answer from FinBridge's DART filings index (refreshed every 5 minutes) for the part of the window it covers, and ask DART live only for the uncovered remainder (saves DART's daily quota). true: ask DART directly for the whole window; on daily-quota exhaustion (020), falls back to the index for whatever it covers and says what could not be refreshed. | |
| kinds | No | Regex filter on Korean report names, e.g. '증자|합병|전환사채' or '자기주식' | |
| limit | No | Max results, 1-100 (default 20) |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| page | No | |
| total | No | |
| filings | Yes | |
| sources | No | |
| uncovered | No | |
| index_as_of | No | |
| served_from | No | |
| quota_fallback | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/destructive, but the description adds substantial behavior beyond them: the 180-day default scan window, matched-count totals when kinds is set, the index-vs-live-DART scan boundary (FinBridge index vs recent 100 events), quota fallback semantics, and the DART status 013 empty-range error. This is well above the bar set by the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and organized into clear labeled sections (Args, Returns, Examples, Use when, Errors), so it scans well. It is on the long side and some of the retroactive-correction phrasing ('What this adds over...') is dense, but essentially every sentence carries decision-relevant information.
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 6-param optional-filter list tool with an output schema, the description covers return shape, defaults, examples, sibling routing, and failure modes. An agent has everything needed to call it correctly and interpret the result without further inference.
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 baseline is 3, but the description adds real meaning: regex examples in Korean for kinds, the corp identifier format variants, and the scanning-window caveat tied to how kinds filtering behaves. It stops short of documenting the 'fresh' parameter, which is left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) plus the exact resource (major-event disclosures, DART type B) and enumerates the event types covered. It explicitly distinguishes itself from get_dart_filings, get_edgar_filings, and get_disclosure_feed, so an agent can select it 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?
Provides an explicit 'Not this tool for' list naming the alternative for each excluded case, a 'What this adds over get_dart_filings type=B' comparison, and a 'Use when' clause with a concrete decision rule ('which companies announced X' vs 'what did company Y file'). When-to-use and when-not-to-use are both fully covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_db_schemaFinBridge DB SchemaARead-onlyInspect
Inspect the schema of the local finbridge database (SQLite with ingested KR/US company fundamentals, filings, and daily prices): tables, views, columns, per-table row counts (counted in the background and refreshed every 30 minutes; null with rows_note "counting…" right after a server start), and ready-to-run example queries for query_db.
Read this before writing a query_db statement. It returns no company data itself — get_db_schema describes the tables, query_db runs the SELECT.
Args: (none)
Returns: {tables: [{name, columns: [{name, type}], rows}], views: [{name, columns: [{name, type}]}], examples: [sql_string]}
Key objects:
companies: KR companies have source='dart' + stock_code (6-digit), US companies source='edgar' + ticker
financials: one row per company x fiscal_year x quarter (quarter=0 = annual); raw unscaled KRW/USD amounts
prices_daily: daily OHLCV per company_id
views v_financials (financials joined with company name/ticker/stock_code) and v_latest_annual (latest annual row per company) — prefer these in query_db
Examples:
Call before writing SQL for query_db, to learn table/column names.
Check row counts to see how much data the nightly ingest has loaded.
Use when: preparing a query_db, or checking ingest coverage. Don't use for market data itself (get_stock_prices / get_valuation read the same tables with the right joins already done). FinBridge has no real-time equity quote tool — equity prices here are end-of-day closes from the nightly ingest; the only live data is regulator filings (get_dart_filings / get_edgar_filings). Errors: 'database has not been built yet' — the ingest pipeline has not run on the server.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| views | Yes | |
| tables | Yes | |
| examples | No | |
| rows_note | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint=true and destructiveHint=false annotations, the description discloses meaningful runtime behavior: row counts are counted in the background and refreshed every 30 minutes, rows can be null with rows_note 'counting…' after server start, and the likely error state 'database has not been built yet' is explained. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but organized with clear sections and a front-loaded purpose. Some redundancy exists between 'Read this before writing a query_db statement' and 'Use when: preparing a query_db,' but the density is largely justified given the tool's role as a schema-discovery prerequisite.
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 zero parameters and a provided output schema, the description goes well beyond the minimum by listing key tables, views, row-count behavior, example SQL queries, usage boundaries, and failure modes. An agent can confidently decide when to call this tool and what to do with its results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the input schema already fully defines the call shape. The description adds an explicit 'Args: (none)' confirmation, which is useful but not a heavy burden; the baseline 4 for zero-parameter tools applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Inspect') and resource ('schema of the local finbridge database'), then clarifies exactly what it does not do: 'It returns no company data itself — get_db_schema describes the tables, query_db runs the SELECT.' This clearly distinguishes it from the close sibling query_db and from data-returning tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use directions: 'Read this before writing a query_db statement' and 'Use when: preparing a query_db, or checking ingest coverage.' It also names exclusions and alternatives, such as get_stock_prices and get_valuation, and warns that FinBridge has no real-time quote tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_disclosure_feedDisclosure Feed (FinBridge DB)ARead-onlyInspect
Recent regulatory disclosures from the local finbridge database (filings table, refreshed nightly + intraday for KR), newest first — positioned as a faster-than-news primary source. By default returns only MATERIAL filings: US Form 8-K (current reports) and KR 주요사항보고서 (major events: capital raises, M&A, convertible bonds, buybacks, etc.).
Args:
market: 'kr' (DART), 'us' (EDGAR), or 'all' (default)
company: optional — restrict to one company (US ticker, KR 6-digit code, or name). Takes priority over watchlist.
material_only: default true (8-K / KR type-B only); false = all filing types
forms: optional explicit form_type filter (e.g. ['10-K','8-K'] or ['A','B']); overrides material_only
days: look-back window in days, 1-120 (default 14); or use from/to
from/to: optional explicit YYYY-MM-DD range (overrides days)
limit: 1-100 (default 30); response_format: 'markdown'|'json'
brief: default true — attach the plain-language fact summary (headline_en/headline_ko/facts_en/facts_ko/company_en/event_type) where one exists. Rows without a summary are unaffected. The markdown rendering shows the English side; both sides stay in the JSON.
watchlist: default false — restrict to the authenticated account's watchlist companies instead of all companies. Needs a personal API key (not the admin token). Ignored when 'company' is also given.
Returns: {count, market, since, rows:[{source, company_name, form_type, title, filed_date, url, items?, headline_en?, headline_ko?, facts_en?, facts_ko?, company_en?, event_type?}]}. 'items' (8-K item codes) is included when available. Summary fields are present only for filings that have one. Note: with brief:true, a filing that only exists as a summary (not yet in our filings index) can still appear — such rows omit form_type/items and, for non-DART sources, url.
Examples:
Latest US material events this week: {market:'us', days:7}
Samsung's recent major-event filings: {company:'005930', material_only:true, days:90}
All of a company's filings: {company:'AAPL', material_only:false}
My watchlist's recent disclosures with summaries: {watchlist:true}
Use when: scanning for catalysts / breaking corporate events, or one company's recent filings. Don't use for filing BODIES (open the url) or for financial statement values (get_dart_financials / get_edgar_financials / query_db). Notes: Filing metadata only; bodies are at the linked source URLs. Not investment advice. Errors: empty result is not an error (count 0).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Explicit end date YYYY-MM-DD | |
| days | No | Look-back window in days (default 14) | |
| from | No | Explicit start date YYYY-MM-DD (overrides days) | |
| brief | No | Attach the fact-summary fields where one exists (default true). Rows without a summary are unaffected. | |
| forms | No | Explicit form_type filter; overrides material_only | |
| limit | No | Max rows (default 30) | |
| market | No | Market: 'kr', 'us', or 'all' (default) | all |
| company | No | Optional company filter: US ticker, KR 6-digit code, or name | |
| watchlist | No | Restrict to the authenticated account's watchlist companies (default false). Needs a personal API key. Ignored when 'company' is set. | |
| material_only | No | Only material filings (US 8-K / KR type-B). Default true | |
| response_format | No | 'markdown' or 'json' | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | |
| count | Yes | |
| since | No | |
| market | No | |
| company | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true and destructiveHint=false, but the description layers on rich operational detail: refresh cadence (nightly + intraday for KR), default material_only behavior, summary-only rows that may omit form_type/items/url, 'empty result is not an error', and precedence rules between args. This fully discloses edge cases and side effects without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well organized with distinct sections (Args, Returns, Note, Examples, Use when, Errors). It is front-loaded with the purpose statement. Some non-essential marketing language ('positioned as a faster-than-news primary source') and the 'Not investment advice' disclaimer could be trimmed, but overall each section earns its place given the tool's complexity.
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 11 optional parameters and an output schema present, the description nevertheless documents every relevant operational aspect: default ranges, limits, precedence, authentication requirements, output shape including optional summary fields, edge cases, and error semantics. It includes multiple examples covering different markets, companies, watchlists, and materiality settings, so an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds essential semantic detail: override precedence (from/to overrides days, forms overrides material_only, watchlist ignored when company set), the watchlist's personal-API-key requirement, and the effect of brief on returned fields. It also supplies concrete examples for each major parameter combination.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise definition: 'Recent regulatory disclosures from the local finbridge database (filings table, refreshed nightly + intraday for KR), newest first' and specifies the material filing types by market. It differentiates from siblings by explicitly naming what it is not for ('filing BODIES', 'financial statement values' with get_dart_financials/get_edgar_financials/query_db).
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?
Contains an explicit 'Use when' section ('scanning for catalysts / breaking corporate events, or one company's recent filings') and a 'Don't use for' section that points to alternative tools for bodies and financial values. This gives clear routing guidance and leaves nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_edgar_13fGet Institutional Holdings (SEC Form 13F)ARead-onlyInspect
Quarter-end institutional manager holdings reconstructed from SEC 13F-HR and 13F-HR/A (RESTATEMENT or NEW HOLDINGS), for the latest reportDate in recent submissions. Pass a manager name or CIK, not an issuer ticker. top=1–50 (default 20) limits displayed rows. response_format=markdown or json.
Returns reported security rows with separate class, PUT/CALL, SH/PRN, discretion and other-manager fields; no ticker mapping or reverse ownership lookup. Values normalize each filing to USD using the 2023-01-03 filing-date boundary. Missing numbers stay null. Duplicate/shared reporting, incomplete amendment chains and confidential omissions withhold totals/weights. sources carries accession, primary/table URLs, report/filed/acceptance/fetch times and amendment evidence.
prior_period is a distinct reportDate; no prior omits changes. Unverified corporate actions, missing rows, options/principal and incomplete reports withhold change signals with explicit comparison_exclusions. Empty changes does not establish no activity. 13F covers disclosed Section 13(f) positions, not a complete/current portfolio; 45 days is a filing deadline, not a freshness guarantee. Not investment advice.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | Number of largest holdings by value to return (default 20) | |
| filer | Yes | Institutional manager name ('Berkshire Hathaway Inc', 'Bridgewater Associates') or CIK number ('1067983') | |
| response_format | No | 'markdown' for tables, 'json' for compact machine-readable output | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| filed | No | |
| filer | Yes | |
| notes | No | |
| period | No | |
| changes | No | |
| sources | Yes | |
| holdings | Yes | |
| value_unit | No | |
| total_value | No | |
| generated_at | No | |
| num_holdings | No | |
| prior_period | No | |
| prior_sources | No | |
| index_warnings | Yes | |
| comparison_status | No | |
| calculation_version | No | |
| comparison_exclusions | Yes | |
| reconstruction_status | No | |
| prior_reconstruction_status | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnlyHint/openWorldHint annotations by disclosing normalization details (2023-01-03 filing-date boundary), null handling, withheld totals/weights for incomplete data, amendment evidence, and the 45-day filing deadline caveat. It also warns that empty changes does not establish no activity, which is critical behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized, front-loading the core purpose and then covering caveats. It is longer than ideal, but every sentence carries meaningful behavioral or usage information. The structure is logical: purpose, parameters, return details, limitations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (13F data, amendments, normalization, exclusions), the description is remarkably complete. It covers input requirements, output contents, edge cases, and limitations. The output schema exists, so return values don't need to be spelled out, but the description still explains the sources and changes fields.
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 all three parameters. The description adds value by explaining the filer parameter accepts either a name or CIK, and by clarifying the top parameter limits displayed rows. It doesn't add much beyond the schema, but the filer clarification is genuinely useful.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reconstructs quarter-end institutional manager holdings from SEC 13F filings, and explicitly distinguishes it from issuer-ticker lookups. It names the resource (SEC 13F-HR filings) and the specific verb (get/reconstruct), making it easy to differentiate from siblings like get_edgar_filings or get_edgar_financials.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to pass a manager name or CIK, not an issuer ticker, and explains the top parameter range and response_format options. It also clarifies what the tool does not do (no ticker mapping, no reverse ownership lookup), which helps an agent decide when to use it versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_edgar_filingsList SEC FilingsARead-onlyInspect
List a US company's recent SEC filings (10-K, 10-Q, 8-K, S-1, proxy statements, Form 4, ...) from the EDGAR submissions index. Returns metadata and document URLs only — it does NOT download filing contents; fetch the returned url yourself for the document text.
Not this tool for: Korean filings (get_dart_filings) or a cross-market feed already stored here (get_disclosure_feed).
Args:
company (required): ticker / company name / CIK
forms: optional form-type filter, e.g. ['10-K'] or ['10-K','10-Q','8-K'] (exact match, case-insensitive)
from / to: optional YYYY-MM-DD filing-date range
limit: max rows, 1-50 (default 20)
Returns: {company:{cik, name, ticker}, count, filings:[{form, filingDate, accessionNumber, primaryDocument, items?, url}], notes?}. 8-K rows include 'items' (e.g. '2.02,9.01' = results of operations + exhibits). Coverage = the latest ~1000 filings per company.
Examples:
"Apple's latest annual report" -> {company:'AAPL', forms:['10-K'], limit:1} then fetch the url
"Tesla 8-Ks this year" -> {company:'TSLA', forms:['8-K'], from:'2026-01-01'}
Use when: you need filing dates, document links, or 8-K event items for a US company. Don't use for: Korean disclosures (get_dart_filings) or filing full-text search across all companies.
Errors: unknown company -> use search_edgar_company; an empty result usually means the form/date filter is too narrow for the ~1000-filing window.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Latest filing date, YYYY-MM-DD | |
| from | No | Earliest filing date, YYYY-MM-DD | |
| forms | No | Form types to include, e.g. ['10-K','8-K']. Omit for all forms | |
| limit | No | Max filings to return (default 20) | |
| company | Yes | US company: ticker (e.g. 'AAPL', 'BRK-B' or 'BRK.B'), company name, or CIK number |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| notes | No | |
| company | Yes | |
| filings | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is transparent about read-only behavior, coverage limits (~1000 filings per company), error handling, and the fact that it only returns metadata/URLs and does not fetch full documents. This aligns perfectly with the readOnlyHint and destructiveHint annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well structured with clear sections for purpose, examples, usage boundaries, and errors. It is detailed but every sentence adds value, and the included examples improve clarity without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description, schema, and output schema together provide complete context: parameters, return shape, coverage limits, error handling, and disambiguation from sibling tools. No critical information is missing for an agent to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of parameters with meaningful descriptions, and the tool description further clarifies company formats, form-type filtering, date range syntax, and limit defaults. Examples make parameter usage concrete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool lists a US company's recent SEC filings from EDGAR, returns metadata and document URLs, and does not download contents. It also distinguishes itself from sibling tools like get_dart_filings and get_disclosure_feed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases, examples, and a 'Use when' / 'Don't use for' section that clearly scopes the tool. It also explains likely errors and empty results, giving strong practical guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_edgar_financialsGet US Company Financials (SEC XBRL)ARead-onlyInspect
Normalized annual (10-K) or quarterly (10-Q) financial statements for a US company, from SEC EDGAR XBRL company facts (US-GAAP). Values are raw USD (not scaled); eps_diluted is USD per share.
Not this tool for: Korean statements (get_dart_financials), a KR-vs-US pair on one screen (compare_financials_kr_us), or ranking many companies at once (query_db, which reads the stored table and covers KR/US/TW/JP/EU). This tool requests one US company's SEC XBRL company facts through the source adapter; results may be reused from a process-local cache for up to 24 hours. data_as_of.generated_at is response creation time, not source retrieval time. Peer comparisons use separately dated database snapshots.
Args:
company (required): ticker / company name / CIK (e.g. 'AAPL', 'Microsoft', '789019')
freq: 'annual' (default, from 10-K) or 'quarterly' (discrete Q1-Q3 from 10-Qs; Q4 is not reported separately)
periods: how many most-recent periods, 1-12 (default 3)
metrics: optional subset of [revenue, gross_profit, operating_income, net_income, eps_diluted, assets, liabilities, equity, cash_and_equivalents, operating_cash_flow] (default all)
response_format: 'markdown' (default) or 'json'
Returns NormalizedFinancials: {company:{name, id(CIK), ticker}, basis:'US-GAAP (10-K)', periods:[{period:'FY2024', fiscal_year, end, currency:'USD', metrics:{revenue, net_income, ...}}], notes}. periods are most-recent first; fiscal_year = calendar year of the period end date.
Examples:
"Apple's revenue and net income for the last 3 years" -> {company:'AAPL', metrics:['revenue','net_income']}
"MSFT last 4 quarters" -> {company:'MSFT', freq:'quarterly', periods:4}
Use when: you need US-GAAP fundamentals for a US-listed company. Don't use for: Korean companies (get_dart_financials), stock prices, or IFRS 20-F foreign private issuers (not supported).
Errors: unknown company -> use search_edgar_company first; companies without us-gaap XBRL facts (funds, 20-F filers) return an error explaining why.
| Name | Required | Description | Default |
|---|---|---|---|
| freq | No | 'annual' = fiscal years from 10-K filings; 'quarterly' = discrete Q1-Q3 from 10-Q filings | annual |
| company | Yes | US company: ticker (e.g. 'AAPL', 'BRK-B' or 'BRK.B'), company name, or CIK number | |
| metrics | No | Optional metric subset. Available: revenue, gross_profit, operating_income, net_income, eps_diluted, assets, liabilities, equity, cash_and_equivalents, operating_cash_flow. Default: all | |
| periods | No | Number of most-recent periods (default 3) | |
| response_format | No | 'markdown' for a table, 'json' for compact machine-readable output | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| basis | No | |
| notes | No | |
| company | Yes | |
| periods | Yes | |
| data_as_of | No | |
| plan_limit | No | |
| peer_comparison | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, but the description adds substantial behavioral context: results may be cached up to 24 hours, data_as_of.generated_at is response creation time not retrieval time, peer comparisons use separately dated snapshots, Q4 is not reported separately for quarterly, and unsupported companies (funds, 20-F filers) return explanatory errors. These details go well beyond the annotations and significantly aid correct invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured and front-loaded: it opens with the core purpose, then exclusions, then detailed parameter explanations, return format, examples, and usage guidance. Every section adds value; there is no filler. The structure mirrors the tool's complexity and makes the information easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 parameters, output schema, error cases, sibling tools), the description is fully complete. It covers all parameters with nuanced explanations, describes the return structure (NormalizedFinancials with periods), provides usage examples, names sibling alternatives, and explains error behavior for unknown or unsupported companies. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds meaning beyond the schema: it explains the meaning of 'annual' vs 'quarterly' (Q4 not separately reported), that periods are most-recent first, that values are raw USD, and that eps_diluted is per share. It also provides concrete examples mapping natural-language queries to parameter values ('Apple's revenue...' -> {company:'AAPL', metrics:['revenue','net_income']}). This fully compensates any gaps and enhances parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb ('get') and resource ('US company financials from SEC EDGAR XBRL company facts (US-GAAP)'), and specifies scope (annual 10-K, quarterly 10-Q, raw USD). It explicitly differentiates from siblings like get_dart_financials and compare_financials_kr_us, so an agent can instantly tell what it does and what it is not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit 'Not this tool for' guidance naming specific alternatives (get_dart_financials, compare_financials_kr_us, query_db) and conditions ('Korean statements', 'KR-vs-US pair', 'ranking many companies'). It also provides 'Use when' and 'Don't use for' statements, leaving no ambiguity about selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_edgar_insider_tradesGet Insider Trades (SEC Form 4)ARead-onlyInspect
Latest insider transactions for a US company, parsed from SEC Form 4 filings, with a buy-vs-sell summary and an optional buy/sell filter. Each trade lists the reporting insider, their relationship, and non-derivative (common stock) transactions.
Not this tool for: Korean insiders (get_dart_insider_trades) or institutional managers, which are a different kind of holder entirely (get_edgar_13f).
Insider BUYS (open-market purchases, code P) are a stronger sentiment signal than sells (code S), which happen for many reasons (diversification, taxes). Use tx_type to monitor one side.
Args:
company (required): ticker / company name / CIK
limit: number of most-recent Form 4 filings to parse, 1-25 (default 10)
tx_type: 'all' (default) | 'buy' (code P purchases only) | 'sell' (code S sales only)
Returns: {company:{cik, name, ticker}, tx_type, summary:{buys:{count,shares,value}, sells:{count,shares,value}}, count, trades:[{filedAt, owner, relationship, url, transactions:[{date, code, shares, price_per_share, acquired_or_disposed, shares_owned_after}]}], notes}. summary totals cover the whole fetched window regardless of the filter; value = shares x price where a price is reported. Transaction codes: P=open-market purchase, S=open-market sale, M=option exercise, F=shares withheld for tax, A=award/grant, G=gift. acquired_or_disposed: A=acquired, D=disposed.
Examples:
"insider BUYING at Apple" -> {company:'AAPL', tx_type:'buy'}
"recent insider SELLING at Nvidia" -> {company:'NVDA', tx_type:'sell'}
"all TSLA insider activity, more history" -> {company:'TSLA', limit:25}
Use when: monitoring insider buy/sell activity (officers, directors, 10% owners) for a US-listed company. Larger 'limit' widens the time window. Don't use for: institutional holdings (use get_edgar_13f), Korean companies, or derivative-only detail (option grids are skipped).
Errors: unknown company -> use search_edgar_company; a filter with no matching transactions returns count 0 (not an error); unparseable Form 4 XMLs are skipped and counted in notes.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of most-recent Form 4 filings to parse (default 10) | |
| company | Yes | US company: ticker (e.g. 'AAPL', 'BRK-B' or 'BRK.B'), company name, or CIK number | |
| tx_type | No | 'all' (default), 'buy' = open-market purchases (code P) only, 'sell' = sales (code S) only | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| notes | No | |
| trades | Yes | |
| company | Yes | |
| summary | No | |
| tx_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses important behaviors: summary totals cover the whole fetched window regardless of filter, unparseable XMLs are skipped and counted in notes, and a filter with no matches returns count 0 (not an error). This is valuable for expectation-setting.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (main purpose, exclusions, filter explanation, args, returns, examples, usage, errors). It is thorough but not verbose, using bullet-like sections and staying concise while covering all necessary information. The main purpose 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?
The description includes a detailed 'Returns' section that acts as an output schema, explaining the structure of the result including summary, trades array, and notes. It also covers error handling and edge cases, making the tool's behavior fully predictable for an agent.
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?
All three parameters are described in the schema, and the description adds further meaning: it explains transaction codes (P, S, M, F, A, G), acquired_or_disposed values, and clarifies that 'limit' is the number of filings parsed. The examples also map user intents to parameter values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches latest insider transactions for a US company from SEC Form 4 filings, with a buy/sell summary and optional filter. It distinguishes from get_dart_insider_trades and get_edgar_13f by explicitly noting the US scope and the focus on Form 4 filings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use when' and 'Don't use for' sections, naming alternatives like get_edgar_13f for institutional holdings and get_dart_insider_trades for Korean companies. Includes concrete examples and clarifies the effect of the limit parameter, making selection straightforward.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_peersPeer CompaniesARead-onlyInspect
Comparison references for one company across KR / US / TW / JP / EU. The default uses a sourced business theme or broad source classification and does not assert direct competition or add unrelated companies to fill the limit. Explicit rank='size' returns same-currency size references and does not assert an industry relationship. Also returns the company's business-segment revenue split where available (Japan from 有価証券報告書 XBRL, the US from SEC DERA financial-statement datasets; US segment names are usually end markets, not industries) — informational unless rank='segments'.
Args:
company: US ticker ('AAPL'), KR 6-digit code ('005930'), TW/JP 4-digit code ('2330', '7203'), or a company name (local or English).
market: 'kr'|'us'|'tw'|'jp'|'eu' (optional) — disambiguates codes/names shared across markets (TW and JP both use 4-digit codes; 'eu' companies are addressed by ISIN).
limit: 1-10 peers (default 5).
same_market_only: true = restrict peers to the company's own market (default false — a KR chipmaker can sit next to a US one).
rank omitted = business-related references; 'size' = explicit size references with verified equal market-cap currency; 'segments' = rank by business-mix similarity — each company's segment revenue shares are mapped to standard industries (companies without segment data count as 100% their own industry) and compared by cosine similarity, ties broken by normalized size. Conglomerates (Sony: games/music/pictures/electronics/finance) then get conglomerate peers instead of whichever single bucket they were filed under.
response_format: 'markdown' (default) or 'json'.
Returns: existing fields plus policy_version, purpose, insufficiency_reason; each peer also has selection_reason, comparison_role and evidence_status. Broad/theme rows are business-related references, not verified direct competitors. Explicit size rows are size-reference only.
Examples:
{company:'7203'} -> Toyota + transportation-equipment peers, with its Automotive / Financial Services segment split
{company:'005930', same_market_only:true} -> Samsung Electronics + KR tech-hardware peers only
{company:'6758', rank:'segments'} -> Sony ranked against other multi-segment conglomerates by business mix
Use when: building a comparison table or choosing competitors for a financial comparison. Don't use for strategy screens (screen_*) or for full financial statements (get_dart_financials / get_edgar_financials). Notes: curated business themes remain separate from official company-level classifications. Segment names may be geographic (Japan/Asia/USA) when a company defines its reportable segments by region. Unverified cross-currency absolute market-cap ordering is never used. Errors: unknown/ambiguous company -> candidate list; no classification -> basis_kind='size' with a note.
| Name | Required | Description | Default |
|---|---|---|---|
| rank | No | Omit for business-related references; 'size' explicitly requests same-currency size references; 'segments' uses business-mix similarity | |
| limit | No | Peers to return (default 5) | |
| market | No | Restrict resolution to one market ('eu' = ESEF filers, identified by ISIN) | |
| company | Yes | Ticker, KR 6-digit code, TW/JP 4-digit code, or name | |
| response_format | No | Output format (default markdown) | |
| same_market_only | No | Only peers from the company's own market |
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | No | |
| basis | No | |
| notes | No | |
| peers | Yes | |
| sector | No | |
| company | Yes | |
| purpose | No | |
| segments | No | |
| basis_kind | No | |
| data_as_of | No | |
| basis_label | No | |
| industry_mix | No | |
| policy_version | No | |
| insufficiency_reason | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover safety (readOnly=true, destructive=false, openWorld=false), and the description adds substantial behavioral context beyond that: the non-assertion policy for default rows, same-currency constraint for size ranking, segment-data provenance (有価証券報告書 XBRL / SEC DERA), the conglomerate-matching rule, and explicit error/fallback behavior. This is rich disclosure on top of structured fields.
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?
Well front-loaded and sectioned (Args / Returns / Examples / Use when / Notes / Errors), with examples that anchor each mode. It is long and repeats the 'business-related references, not verified competitors' point several times, which is mildly redundant but defensible given the tool's misuse risk.
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?
An output schema exists, yet the description still correctly frames what comes back (policy_version, purpose, insufficiency_reason, selection_reason, evidence_status) without over-specifying formats. Combined with the routing guidance and per-market identifier rules, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description goes well beyond it: it defines what rank='segments' actually computes (cosine similarity over mapped segment industries, tie-break by normalized size), clarifies same_market_only's default and cross-market implication, and documents company-identifier formats per market. That materially changes how an agent would set these params.
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+resource (find comparison reference peers for one company) and instantly distinguishes itself: it produces references, not asserted competitors, across five named markets. The three rank modes are named up front, so an agent can tell it apart from screen_*/financial-statement tools without opening the 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?
Explicit 'Use when' (comparison tables / choosing competitors) paired with 'Don't use for strategy screens (screen_*) or full financial statements (get_dart_financials / get_edgar_financials)'. This names the alternatives and the condition that routes away from this tool, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_portfolioMy PortfolioARead-onlyInspect
Return the holdings this user has already registered in FinBridge with import_portfolio — listed stocks plus cash, crypto, ETF and physical assets — valued at the latest prices, with return and asset allocation. A user who has registered nothing gets an empty list.
Not this tool for: analysing or valuing a company (get_valuation), prices (get_stock_prices), or finding companies (search_dart_company / search_edgar_company). It reads only what this user stored, so it knows nothing about a company they do not hold.
Crypto and ETFs use live ccxt quotes, stocks the latest close in the database, cash and physical assets the registered amount. allocation is aggregated per currency; combined converts everything to KRW using an ECB-derived USD/KRW rate.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| error | No | |
| notes | No | |
| combined | No | |
| holdings | No | |
| allocation | No | |
| total_value | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the readOnly/openWorld/destructive annotations by disclosing valuation sources (live ccxt for crypto/ETFs, latest database close for stocks, registered amounts for cash/physical), currency aggregation behavior, and KRW conversion method. It also documents empty-list behavior and the tool's ignorance of unheld companies.
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?
Every sentence carries useful information: purpose, exclusions, empty behavior, data freshness, and currency handling. Despite the length, it is tightly organized and front-loaded with the core definition.
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?
Covers all non-obvious aspects an agent needs: input-less scope, return composition, valuation rules, currency conversion, empty result behavior, and explicit sibling routing. With an output schema present and zero parameters, nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so there is nothing to document. The description still adds meaningful context about the implicit scope (the current user's registered holdings), which is the closest analog to parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Return') and resource (holdings registered in FinBridge via import_portfolio), and enumerates the asset classes covered. It names sibling exclusions (get_valuation, get_stock_prices, search_dart_company / search_edgar_company) so the agent can disambiguate.
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 not to use the tool and names the relevant alternatives: valuation, prices, and company search. Also clarifies that it only reflects the current user's stored holdings, which prevents misuse for general market/screening queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_portfolio_historyPortfolio Import HistoryARead-onlyIdempotentInspect
List the append-only portfolio snapshots recorded for this user. Each import_portfolio call that actually changes the stored holdings/assets (and each restore_portfolio_snapshot) appends one snapshot of the whole portfolio at that moment — quantities, average prices, symbols and asset classes, never market prices or computed valuations (those are recomputed fresh whenever needed). Identical resubmissions do not create a duplicate entry. Use this to see when the portfolio changed, then restore_portfolio_snapshot to undo a bad import.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max snapshots to return, most recent first. Default 20. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | |
| error | No | |
| snapshots | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing append-only semantics, the exact trigger conditions for a new entry (import_portfolio only when holdings/assets actually change, plus each restore), the dedup rule for identical resubmissions, and precisely what is and is not captured. These are behavioral facts the readOnly/idempotent hints cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core definition before the trigger rules and the recovery hint. Information density is high, though the parenthetical about valuations being recomputed is slightly tangential and the sentences are long.
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?
An output schema exists, so return values need not be described; the description instead covers everything else an agent needs — snapshot contents, creation triggers, dedup behavior, and the undo path. Nothing material is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'limit' parameter (min 1, max 100, default 20, most recent first) is fully documented in the schema. The description adds no parameter-level detail, which is acceptable here but earns only the baseline.
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 (list) and resource (append-only portfolio snapshots) and immediately defines what a snapshot is: whole-portfolio quantities, average prices, symbols and asset classes at a moment in time. It also distinguishes itself from computed data by noting market prices/valuations are never stored, which separates it from get_portfolio/analyze-style siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use it ('to see when the portfolio changed') and names the follow-on action restore_portfolio_snapshot for undoing a bad import. It does not, however, state when NOT to use it — e.g. that get_portfolio should be used for current holdings — so the routing against the closest sibling is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_stock_pricesDaily Stock Prices (FinBridge DB)ARead-onlyInspect
Get daily OHLCV price history from the local finbridge database (populated by the nightly ingest jobs). Rows are returned newest first.
Listed equities and ETFs. Japan and Europe carry no prices at all, and crypto is not served.
Price coverage by market — we only store what we have redistribution rights to:
Korea (DART + Financial Services Commission): full daily history, corporate-action adjusted. SERVED.
Taiwan (TWSE OpenAPI, Open Government Data License): daily history. SERVED.
US (Databento EQUS.SUMMARY): daily history from 2023-03-28. SERVED. Split-adjusted; dividend-adjusted closes exist where SEC-reported dividends do (adj_close).
Japan: NOT served. EDINET publishes disclosure documents, not prices, so we hold Japanese filings and the company master but no quotes.
Args:
company: a ticker (US 'AAPL', TW/JP 4-digit '2330'), a KR 6-digit stock code ('005930'), or a company name in the local language or English ('TSMC', 'Toyota', '삼성전자'). Resolution priority: exact ticker > 6-digit KR code > exact name (name or English name) > partial name (multiple partial matches return a candidate list error).
from / to: optional YYYY-MM-DD range bounds (inclusive)
limit: max rows, 1-500 (default 60)
response_format: 'markdown' (default) or 'json'
Account limits: a free account includes the most recent 130 trading sessions of each name. Results follow the current account's history entitlement. When the window is trimmed the response carries a plan_limit field saying so.
Returns: {company: {name, source, ticker|stock_code}, count, truncated, prices: [{date, open, high, low, close, volume}]} — newest date first; truncated=true means older rows exist beyond 'limit'.
Examples:
{company: '005930', limit: 30} -> last 30 KR trading days for Samsung Electronics
{company: '005930', from: '2026-01-01', to: '2026-06-30'} -> Samsung Electronics H1 2026
Use when: historical closes/volumes for charting or return calculations from ingested data. Don't use for crypto, which is not served. FinBridge has no real-time equity quote tool — equity prices here are end-of-day closes from the nightly ingest; the only live data is regulator filings (get_dart_filings / get_edgar_filings). Errors: unknown company -> no-match or candidate-list error; JP/EU company -> no-prices error (those markets carry statements only); no price rows -> a market-specific hint (new listing, delisted, nightly lag).
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | End date YYYY-MM-DD (inclusive) | |
| from | No | Start date YYYY-MM-DD (inclusive) | |
| limit | No | Max rows, 1-500 (default 60), newest first | |
| company | Yes | KR 6-digit stock code (e.g. '005930') or company name | |
| response_format | No | 'markdown' for a table, 'json' for compact machine-readable output | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| prices | Yes | |
| company | Yes | |
| truncated | No | |
| data_as_of | No | |
| data_notes | No | |
| plan_limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite readOnlyHint=true and destructiveHint=false covering the safety profile, the description adds substantial behavioral context: newest-first ordering, account entitlement trimming with plan_limit, split/dividend adjustments, truncation semantics, market-specific no-price errors, and coverage boundaries. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place given the many market caveats, account limits, and resolution rules. It is well-structured: core capability first, then coverage, args, return shape, examples, use-when, and errors. The information is front-loaded and scannable.
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 tool with five parameters, account limits, market coverage variations, and error modes, the description is exceptionally complete. It even provides the return object shape, truncation meaning, and market-specific error hints, so an agent has everything needed to call and interpret the result correctly. The output schema presence does not reduce the value of this added context.
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%, but the description goes far beyond the schema by explaining company resolution priority (ticker > KR code > exact name > partial name), candidate-list errors on ambiguous names, inclusive date semantics, and giving concrete examples for limit and from/to usage. This materially improves correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Get daily OHLCV price history from the local finbridge database') and immediately scopes what it covers: listed equities and ETFs, with explicit exclusions for Japan, Europe, and crypto. This clearly distinguishes it from the many filing- and financial-data siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use it ('historical closes/volumes for charting or return calculations from ingested data') and when not to ('Don't use for crypto...'). It also names the live-data alternatives (get_dart_filings / get_edgar_filings) and clarifies that no real-time quote tool exists, fully routing the agent to the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tw_insider_transfersTaiwan Insider Share-Transfer Pre-AnnouncementsARead-onlyInspect
Taiwan insider share-transfer filings from TWSE (上市) and TPEx (上櫃), served from the local finbridge database.
⚠These are PRE-ANNOUNCEMENTS, not executed trades. Taiwan requires directors, supervisors, managers and 10% shareholders to declare a transfer BEFORE selling (內部人持股轉讓事前申報). There is no "sold" table at all — a declaration says what someone intends to transfer and by when. What does exist is the opposite: an 未轉讓 (not-transferred) table listing declarations whose window expired without a sale, with the filer's stated reason. This tool returns both.
This is why it is a separate tool from get_dart_insider_trades (Korea) and get_edgar_insider_trades (US Form 4), which report trades that already happened. Do not compare the numbers across those tools as if they were the same event.
⚠Coverage is short and has permanent holes. The upstream endpoints publish only the CURRENT day's table — there is no historical query — so our history starts when we began collecting and any day the collector missed is unrecoverable. The response's coverage.first_report_date and coverage.days say exactly how much history exists; "no rows" for an earlier date means we never had it, not that nobody filed.
⚠No rankings or aggregates in this version (no "most-sold-by-insiders this month"). A few days of snapshots is not a sample.
Units are SHARES (股) — not the thousands of shares used by Taiwan margin data. No monetary conversion is done: planned shares times a closing price is not a transaction value. Role, method and reason strings are returned in the original Chinese so they can be checked against the source.
Args:
company: optional filter — TW 4-digit code, '2330.TW', 'tw:2330', or the company name
from / to: report_date range (YYYY-MM-DD)
role: substring of the declarant's role in Chinese (董事 / 監察人 / 經理人 / 大股東 / 法人董事代表人)
min_shares: minimum planned_shares (applies to the transfer table only)
include_untransferred: also return expired declarations that were not acted on (default true)
limit: 1-200 (default 50); response_format: 'markdown' | 'json'
Returns: {market, company?, range, transfers: [{report_date, company, declarant_role, declarant_name, method, period_from, period_to, planned_shares, daily_max_shares, transferee, held, planned, after}], untransferred: [{report_date, company, declarant_role, declarant_name, untransferred, held, declared, reason}], coverage: {first_report_date, last_report_date, days}, notes, data_as_of, page_url}
Use when: someone asks what Taiwanese insiders have declared they intend to sell, or whether a declared sale actually went through (an 未轉讓 row means it did not). Don't use it to claim an insider "sold" — this data cannot show that.
| Name | Required | Description | Default |
|---|---|---|---|
| to | No | Latest report date (YYYY-MM-DD) | |
| from | No | Earliest report date (YYYY-MM-DD) | |
| role | No | Substring of the declarant role in Chinese (董事 / 監察人 / 經理人 / 大股東) | |
| limit | No | Max rows per table, 1-200 (default 50) | |
| company | No | TW company filter: 4-digit code, '2330.TW', 'tw:2330', or name | |
| min_shares | No | Minimum planned shares (股); transfer table only | |
| response_format | No | 'markdown' for tables, 'json' for compact output | markdown |
| include_untransferred | No | Also return expired declarations that were not acted on (default true) |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | No | |
| range | No | |
| market | Yes | |
| company | No | |
| coverage | No | |
| page_url | No | |
| transfers | Yes | |
| data_as_of | No | |
| untransferred | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations mark readOnlyHint=true and destructiveHint=false, the description goes far beyond by explaining the data is pre-announcements, not executed trades, has short unrecoverable coverage, no historical query, no aggregates, and units are shares. It also notes the 未轉讓 table. This adds critical behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries unique value—scope, warnings, units, usage. It is well-structured with headers and front-loads the core purpose. Slightly verbose but not redundant, earning a 4.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is exceptionally complete: it covers return fields, coverage details, units, usage scenarios, and even explains the 未轉讓 table. Given the tool's complexity (8 params, output schema), nothing an agent needs is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 100% schema coverage, the description adds meaning: min_shares applies to transfer table only, include_untransferred default true, role is a Chinese substring, units are shares not thousands, and no monetary conversion. It clarifies the exact meaning and constraints of parameters, exceeding the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states it returns Taiwan insider share-transfer pre-announcements from TWSE and TPEx, clearly distinguishing them from executed trades. It names the sibling tools (get_dart_insider_trades, get_edgar_insider_trades) it is not, making its scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit when-to-use guidance ('Use when: someone asks what Taiwanese insiders have declared they intend to sell...') and when-not-to ('Don't use it to claim an insider sold'). It also warns against comparing numbers across tools, giving clear exclusions and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_valuationCompany Valuation (FinBridge DB)ARead-onlyInspect
Get the latest valuation snapshot for one KR, US, or Taiwan company from the local finbridge database: market cap (latest close x shares) with PER, PBR, PSR, ROE, debt ratio, and 3-year revenue/net-income CAGR, joined to the company's latest annual fundamentals. Includes metric-level calculation basis, dates, sources, missing reasons, and 1-2 same-market percentile hints. Computed by the nightly valuation ingest job.
Share counts: KR uses data.go.kr listed shares, US prefers SEC-reported shares, and Taiwan uses exchange-reported shares; the nightly job can fall back to net_income / eps_diluted when a positive result is available. PER prefers price / eps_diluted, falling back to market_cap / net_income. Taiwan exchange-published PER/PBR replace derived values when present. Any derived ratio whose required denominator is null or <= 0 is returned as null.
Args:
company: US ticker (e.g. 'AAPL'), KR 6-digit stock code (e.g. '005930'), or company name. Resolution priority: exact ticker > 6-digit code > exact name > partial name (multiple partial matches return a candidate-list error).
per_multiples: optional 1-5 positive user-supplied PER assumptions (maximum 1000)
pbr_multiples: optional 1-5 positive user-supplied PBR assumptions (maximum 100)
response_format: 'markdown' (default) or 'json'
Returns the existing valuation fields plus metric_evidence and multiple_scenarios. Ratios are plain numbers; roe/debt_ratio/CAGR and scenario upside/downside are in percent. A scenario is arithmetic from the user's multiple, not a target-price recommendation. If no multiple is supplied, no multiple or target price is invented.
Examples:
{company: '005930'} -> Samsung Electronics PER/PBR/ROE plus "PER in the cheapest N% of the KR market"
{company: 'AAPL'} -> Apple valuation snapshot with US-market percentiles
Caveats: if statements are in another currency than the listing (Korean listings reporting in USD/CNY/JPY), statement values are converted at one Federal Reserve H.10 rate on or before the price date before PER/PBR/PSR (fx_conversion shows the rate and date; no rate → null). ROE/debt ratio need no conversion; growth across a statement-currency change is null. market_cap keeps the listing currency. KR fundamentals are K-IFRS and US are US-GAAP, so cross-market comparisons are approximate. This is snapshot data (not real-time) and not investment advice.
Use when: assessing one company's valuation/quality at a glance, or comparing it to its own market. Don't use for many-company ranking (use query_db) or raw statements (get_dart_financials / get_edgar_financials). Errors: unknown company -> no-match or candidate-list error; 'no valuation snapshot' -> the valuation ingest job has not produced a row for this company (needs a price and latest-annual fundamentals).
| Name | Required | Description | Default |
|---|---|---|---|
| company | Yes | US ticker (e.g. 'AAPL'), KR 6-digit stock code (e.g. '005930'), or company name | |
| pbr_multiples | No | Optional 1-5 positive PBR assumptions supplied by the user; no default is invented | |
| per_multiples | No | Optional 1-5 positive PER assumptions supplied by the user; no default is invented | |
| response_format | No | 'markdown' for a table + interpretation, 'json' for compact machine-readable output | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| pbr | No | |
| per | No | |
| psr | No | |
| roe | No | |
| ttm | No | |
| as_of | No | |
| notes | No | |
| price | No | |
| shares | No | |
| company | Yes | |
| currency | No | |
| data_as_of | No | |
| debt_ratio | No | |
| market_cap | No | |
| ni_cagr_3y | No | |
| updated_at | No | |
| fiscal_year | No | |
| rev_cagr_3y | No | |
| peer_context | No | |
| fx_conversion | No | |
| interpretation | No | |
| metric_evidence | No | |
| peer_comparison | No | |
| multiple_scenarios | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds substantial behavioral context: the nightly ingest job, snapshot-not-real-time caveat, share-count and PER fallback logic, Taiwan exchange-published value precedence, null denominator behavior, currency conversion details, and the explicit 'not investment advice' disclaimer. No contradiction with the read-only annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but tightly organized with labeled sections: intro, share/PER methodology, Args, examples, Caveats, Use when, and Errors. It front-loads the core purpose and then layers edge cases and disclaimers. Every section contributes actionable guidance; nothing is redundant filler.
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 complex, multi-market valuation tool, the description is complete: it covers return semantics (plain numbers vs percents, metric_evidence, multiple_scenarios), units, fallback behavior, currency conversion, basis of accounting, error conditions, and what should not be inferred from scenarios. Even with an output schema present, the description provides the interpretive context needed to use results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description enriches parameter understanding beyond the schema: it explains company resolution priority (ticker > code > exact name > partial name), the candidate-list error for multiple partial matches, the meaning and bounds of per_multiples/pbr_multiples ('no default is invented'), and response_format behavior for markdown vs json. These are semantics not present in the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'Get the latest valuation snapshot for one KR, US, or Taiwan company from the local finbridge database.' It enumerates the metrics returned (market cap, PER, PBR, ROE, etc.) and explicitly differentiates from siblings by saying what it is not for (many-company ranking, raw statements). An agent can immediately tell this is a single-company valuation tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes an explicit 'Use when' section and a 'Don't use' section naming alternatives: 'use query_db' for ranking and 'get_dart_financials / get_edgar_financials' for raw statements. This gives clear selection criteria and exclusions beyond any schema or annotations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_watchlistMy WatchlistARead-onlyIdempotentInspect
Read the companies followed by the authenticated user. Returns names, symbols and markets without changing the watchlist or holdings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| total | No | |
| watchlist | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds that it returns specific fields (names, symbols, markets) and explicitly states it does not change the watchlist or holdings, which reinforces the non-mutating nature. This adds some value beyond annotations but isn't rich with additional behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences that front-load the purpose and immediately state the return content and non-mutating behavior. There is no filler or redundant information.
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 tool with no parameters and a full output schema (which describes the return structure), the description covers the purpose, the exact return fields, and the read-only nature. Nothing an agent needs to decide to call it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is nothing for the description to explain. Per the calibration rule, a baseline of 4 applies when there are no parameters. The description doesn't need to add parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Read' and the resource 'companies followed by the authenticated user', and specifies what is returned (names, symbols, markets). It distinguishes itself from write tools like manage_watchlist and from other read tools like get_portfolio or get_peers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it is for viewing the authenticated user's watchlist. It doesn't explicitly name alternatives or say when not to use it, but the read-only framing and sibling tool manage_watchlist make the intended use obvious. It's clear enough without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_portfolioImport Portfolio HoldingsADestructiveInspect
Store the structured holdings explicitly entered by the user in their FinBridge portfolio. Uploaded files, screenshots, chat history and extracted file content are not supported sources for this connector. Accepts listed stocks (KR/US/TW/JP) as well as cash, crypto (BTC etc.) and physical assets (gold): stocks are matched against the database, crypto and gold (PAXG) get live ccxt quotes, cash and physical assets are stored at the given value. For ETFs or foreign products not in the database, pass value directly. If the user specifies an asset class, pass asset_class as well (cash|bond|physical|growth|dividend|crypto|other; Korean labels 현금|채권|현물|성장주|배당주|가상자산|기타 are accepted). Registered listed stocks are also added to the watchlist automatically. Use when: the user explicitly enters what they hold and wants it stored for get_portfolio. There is no per-holding edit or delete tool: to change or remove holdings, re-import the complete corrected list with replace=true (replace=false only adds/updates the rows given). Not this tool for: the watchlist (manage_watchlist — companies followed, no quantities), valuing a company (get_valuation), or reading what is already stored (get_portfolio).
IMPORTANT — read the response before telling the user you are done:
Confirmation gate: if the user already has a stored portfolio, this call returns
preview:truewith achangesdiff (added/removed/changed) and does NOT save anything, unless you pass confirm=true. Show the diff to the user — call outchanges.removedespecially: if the submission was only part of their holdings, those positions will look fully sold. Only pass confirm=true after the user has seen and accepted the diff (skip this ifget_portfoliowas empty to begin with — there is nothing to compare against).Missing fields: each saved row reports
missing_fields(commonlyacquired_on, since brokerage statements rarely include it) and unresolved symbols appear inneeds_input— ambiguous names/codes listcandidates(do not guess one), unmatched symbols need a ticker/code or avalue. Rows with missing fields ARE saved (never block on incompleteness) — ask the user for the missing pieces and call this tool again for just those rows to fill them in.Cash: check the
cashfield. Ifstatusisnot_asked, the stored portfolio has no cash balance on file (this is different from a confirmed zero) — ask the user for their cash balance (amount or % of the portfolio) and its currency, then import it as one more holding:{symbol:'현금', value, currency, asset_class:'현금'}. Without it, equity weights in get_portfolio are overstated.Always show the user the per-row summary (name/qty/avg_price recognized) before treating the import as authoritative — a misread quantity produces a wrong return. If something was saved wrong, undo it with restore_portfolio_snapshot (defaults to the snapshot right before this one).
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Set true to apply after the user has reviewed the `changes` preview from a prior call with the same holdings/replace. Required whenever a portfolio already exists and this submission would change it; not needed for a first import into an empty portfolio. | |
| replace | No | true = wipe the existing portfolio (stocks + assets) and replace it; default false = merge | |
| holdings | Yes | Structured holdings entered by the user. Each item accepts exactly: symbol (required), qty, avg_price, return_pct, asset_class, currency, value, acquired_on, price_symbol, unit, price_scale. Other keys (e.g. quantity, cost, price, shares) are rejected with an error naming the key — map them to qty / avg_price / value before calling. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cash | No | |
| error | No | |
| notes | No | |
| changes | No | |
| preview | No | |
| holdings | No | |
| imported | No | |
| snapshot | No | |
| unmatched | No | |
| needs_input | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true, openWorldHint=true, and readOnlyHint=false, but the description adds rich behavioral context beyond them: a confirmation gate that returns preview:true with a changes diff and does not save unless confirm=true, the fact that rows with missing fields are saved with missing_fields and needs_input, cash status not_asked meaning no balance is on file, and undo via restore_portfolio_snapshot. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and usage, then organized into a numbered list under an 'IMPORTANT' heading for response handling. Despite its length, each sentence earns its place by conveying essential operational detail for a complex, destructive import tool with a confirmation gate. No redundant or filler content is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, schema richness, and the presence of an output schema, the description is complete. It explains the preview/confirm workflow, how to handle missing fields and unresolved symbols, cash balance detection, and the undo path, covering everything an agent needs to invoke the tool correctly and interpret its responses.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful usage context beyond the schema, such as how different asset types are priced, when to pass value directly for ETFs or foreign products, and additional asset_class labels. However, much of the parameter-level detail (e.g., unit, price_scale, price_symbol) is already well documented in the schema, so the added value is helpful but not exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Store the structured holdings... in their FinBridge portfolio'), and explicitly distinguishes itself from siblings by naming what it is not for: 'Not this tool for: the watchlist (manage_watchlist), valuing a company (get_valuation), or reading what is already stored (get_portfolio).' It also clarifies supported sources and asset types. An agent can tell this apart from related tools without opening schemas.
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 guidance is provided: 'Use when: the user explicitly enters what they hold and wants it stored for get_portfolio.' It also gives when-not conditions, lists alternatives, and covers prerequisites through the confirmation gate, missing fields, cash handling, and undo instructions. The routing logic is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_watchlistAdd or Remove Watchlist CompaniesADestructiveIdempotentInspect
Add or remove a company from the user's watchlist. This changes saved preferences, not financial assets. Only remove deletes an entry.
action='add' and action='remove' each take one symbol and are idempotent: adding a company already on the list leaves it there, removing one that is not on the list is a no-op. Both report the resulting list size.
Not this tool for: holdings and cash (that is a portfolio — use get_portfolio / import_portfolio), or for any market data. The watchlist stores which companies the user follows, nothing about quantities, prices or returns.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | 'add' and 'remove' each need a symbol. | |
| symbol | No | Stock code, ticker or company name. Required for 'add' and 'remove'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| error | No | |
| total | No | |
| action | No | |
| market | No | |
| symbol | No | |
| watched | No | |
| watchlist | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description clarifies that removing deletes an entry while adding is non-destructive, and that it changes saved preferences, not financial assets. This complements the destructiveHint and idempotentHint annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat repetitive in the second paragraph, restating idempotency and the exclusion of financial assets, but it remains well-organized and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains what the tool does, when to use it, what it does not handle, and the result behavior (reports list size). With an output schema present, this is complete enough for an agent.
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?
Although the schema already covers the parameters, the description adds the critical conditional requirement that symbol is needed for both 'add' and 'remove', which is not fully captured by the required array. It also clarifies action semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool adds or removes a company from the user's watchlist, with specific verbs and resource. It distinguishes itself from portfolio and market data tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Not this tool for holdings and cash' and names the alternatives get_portfolio/import_portfolio, plus excludes market data. It also explains idempotent behavior for add/remove.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_dbFinBridge DB Read-Only SQLARead-onlyInspect
Run a single read-only SELECT query against the local finbridge database (ingested KR/US fundamentals, filings, daily prices). The statement must start with SELECT or WITH; multiple statements, PRAGMA, and any write/DDL keywords (INSERT/UPDATE/DELETE/DROP/ALTER/CREATE/ATTACH/...) are rejected. The query runs in a separate read-only process with SQLite authorization, a 2-second deadline, two concurrent queries per server process, and a 1 MB result budget. Free accounts cannot query raw history or history views; the latest-annual snapshot remains available.
The escape hatch for questions no dedicated tool answers — Japan, Taiwan and Europe are largely reachable only this way. Prefer get_valuation or get_peers for ordinary single-company work (they handles per-market period and currency rules that a hand-written query will get wrong), and call get_db_schema first for the table shapes.
Args:
sql: one SELECT (or WITH ... SELECT) statement. A single trailing ';' is tolerated.
limit: max rows returned, 1-500 (default 50)
response_format: 'markdown' (default, table) or 'json' (compact)
Returns: {columns: [name], rows: [[cell, ...]], row_count, truncated} — truncated=true means more rows matched than 'limit'.
Examples (v_financials / v_latest_annual views are the easiest entry points):
Largest companies by latest annual revenue: "SELECT name, ticker, stock_code, fiscal_year, revenue FROM v_latest_annual ORDER BY revenue DESC LIMIT 10"
Samsung Electronics annual trend: "SELECT fiscal_year, revenue, operating_income, net_income FROM v_financials WHERE stock_code = '005930' AND quarter = 0 ORDER BY fiscal_year DESC"
KR vs US company counts: "SELECT source, COUNT(*) AS n FROM companies GROUP BY source"
Recent Samsung Electronics closes: "SELECT date, close FROM prices_daily p JOIN companies c ON c.id = p.company_id WHERE c.stock_code = '005930' ORDER BY date DESC LIMIT 20" (prices_daily holds KR, US, TW; US history starts 2023-03-28)
Use when: custom aggregation/joins over ingested data that no dedicated tool expresses. Don't use for anything that writes — it will be rejected. FinBridge has no real-time equity quote tool — equity prices here are end-of-day closes from the nightly ingest; the only live data is regulator filings (get_dart_filings / get_edgar_filings). Errors: non-SELECT input, ';' inside, or forbidden keywords -> rejected with the reason; unknown table/column -> SQL error with a hint to call get_db_schema first.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | A single read-only SELECT (or WITH ... SELECT) statement | |
| limit | No | Max rows returned, 1-500 (default 50) | |
| response_format | No | 'markdown' for a table, 'json' for compact machine-readable output | markdown |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | |
| columns | Yes | |
| row_count | Yes | |
| truncated | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, but the description adds extensive behavioral context: rejection of non-SELECT input, separate read-only process with SQLite authorization, 2-second deadline, concurrency limits, 1 MB result budget, free-account restrictions, and specific error behavior (e.g., 'rejected with the reason'). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with clear sections (overview, constraints, alternatives, args, returns, examples, when to use, errors). It is front-loaded with core purpose and constraints. While it could be trimmed slightly, every section adds value and the examples are highly instructive.
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 complex SQL tool, the description covers all necessary aspects: query constraints, return format, error behavior, usage context, and even points to specific views (v_financials, v_latest_annual). It explicitly mentions the output structure and includes a hint to call get_db_schema for table shapes, making it complete for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema documents each parameter, but the description adds meaningful nuances: SQL must start with SELECT or WITH, a single trailing ';' is tolerated, limit range (1-500, default 50), and response_format choices. It also provides concrete examples that illustrate parameter usage. This goes beyond the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb-resource-scope statement: 'Run a single read-only SELECT query against the local finbridge database (ingested KR/US fundamentals, filings, daily prices).' It clearly distinguishes itself from siblings by explicitly saying 'Prefer get_valuation or get_peers for ordinary single-company work' and positioning itself as the 'escape hatch' for questions no dedicated tool answers.
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?
Provides explicit when-to-use and when-not-to-use instructions: 'Use when: custom aggregation/joins over ingested data that no dedicated tool expresses. Don't use for anything that writes — it will be rejected.' It also names alternatives (get_valuation, get_peers) and prerequisites (call get_db_schema first).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
restore_portfolio_snapshotRestore a Past PortfolioADestructiveInspect
Roll the stored portfolio back to a past snapshot from get_portfolio_history, replacing ALL current holdings and assets with that snapshot's content. Use this to undo a bad import_portfolio call. Omit snapshot_id to restore the snapshot immediately before the current state (undo the last change). This action is itself recorded as a new snapshot — history is append-only, so restoring is itself reversible the same way. Tell the user what was restored (get_portfolio afterwards shows it valued at current prices).
| Name | Required | Description | Default |
|---|---|---|---|
| snapshot_id | No | Snapshot id from get_portfolio_history. Omit to restore the one immediately before the latest. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| notes | No | |
| assets | No | |
| holdings | No | |
| snapshot | No | |
| restored_from | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and idempotentHint=false; the description goes further by disclosing that ALL holdings are replaced, that the restore is itself recorded as a new snapshot, and that history is append-only so the action is reversible the same way. It also flags a user-facing consequence (tell the user what was restored).
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-loads the destructive scope in the first sentence, then usage, then reversibility. Four sentences with little waste, though the closing parenthetical about get_portfolio valuation is marginally decorative.
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 destructive, non-idempotent mutation with an output schema present, the description covers scope of destruction, the optional-parameter fallback, and the reversibility model. It tells the agent everything needed to call it responsibly without explaining return values.
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% and the schema already documents the omit behavior, but the description adds interpretive meaning by framing omission as 'undo the last change' and restating the fallback semantics in plain language. This is a modest value-add over the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (roll back/restore) and resource (stored portfolio snapshot), names the source (get_portfolio_history), and specifies scope ('replacing ALL current holdings and assets'). It is clearly distinguishable from siblings like import_portfolio and get_portfolio_history.
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 explicit when-to-use ('to undo a bad import_portfolio call') and a precise operating rule for the optional parameter (omit snapshot_id to undo the last change). The alternative tools are named and tied to the condition that selects them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screen_etfsScreen ETFs (FinBridge DB)ARead-onlyInspect
Screen exchange-traded funds in the local finbridge database on the things that actually distinguish an ETF: premium/discount to NAV, fund size (AUM), the index it tracks, price momentum, and — for US funds — the audited calendar-year TOTAL return from the fund's own prospectus.
Funds only. For an operating company use get_valuation (one company) or query_db (many at once).
⚠Funds file no annual financial statements, so the statement-based tools (get_dart_financials, get_valuation) have nothing to say about them — that is why they are screened here instead.
Coverage differs by market and the response says so per row:
KR (1,170 listed ETFs): NAV, AUM (net assets, KRW), listed units and the tracked index come from the same daily feed as prices, 2020-01-02 onward. premium_pct is close/NAV-1 computed on the SAME day (mixing dates would be meaningless).
US (5,868 ETFs): no NAV or AUM source exists that we may redistribute, so those fields are null. Instead total_return_pct carries the fund's audited calendar-year total return (distributions reinvested) from SEC prospectus data — the only distribution-inclusive number available.
⚠ret_20d / ret_120d are PRICE returns in every market: ETF distributions are not in the daily bars, so income funds look worse than they were. For US funds compare against total_return_pct to see the gap. ⚠aum is in the listing currency (KRW today). Do not rank across markets on it. ⚠total_return_pct is pinned to ONE calendar year across all rows (reported as total_return_year), because prospectus refresh dates differ per fund — ranking a 2024 figure against a 2025 one would be a silently wrong table.
Args:
market: 'kr', 'us', or 'all' (default)
min_aum: minimum net assets in listing currency (KR only; e.g. 100000000000 = 1,000억)
max_abs_premium_pct: keep funds trading within this |premium| of NAV, e.g. 0.5
min_premium_pct: keep funds at or above this premium (negative values find discounts)
min_price, min_volume: liquidity floors (vol_avg20 is the 20-session average)
index_contains: substring of the tracked index name — 'TR' finds total-return index trackers, '코스피' finds KOSPI trackers
name_contains: substring of the fund name or ticker
total_return_year: calendar year for total_return_pct; omit for the best-covered year
sort_by: aum | premium | abs_premium | ret_20d | ret_120d | ret_250d | volume | total_return (default aum); order: 'asc'|'desc' (default desc)
limit: 1-100 (default 20); response_format: 'markdown'|'json'
Returns: {count, market, total_return_year, sort_by, order, rows: [{market, symbol, name, as_of, close, nav, premium_pct, aum, index_name, ret_20d, ret_120d, vol_avg20, total_return_pct, total_return_period}]}
Examples:
Large KR ETFs trading close to fair value: {market:'kr', min_aum: 100000000000, max_abs_premium_pct: 0.3, sort_by:'aum'}
KR ETFs at the deepest discount to NAV: {market:'kr', sort_by:'premium', order:'asc'}
KR trackers of a total-return index: {market:'kr', index_contains:'TR', sort_by:'aum'}
US ETFs by audited total return: {market:'us', sort_by:'total_return'}
Use when: choosing or comparing funds. Don't use for stocks (get_valuation / query_db) or for a single fund's price history (get_stock_prices). Errors: 'database has not been built yet' — ingest has not run; an empty result is not an error (count 0).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max rows, 1-100 (default 20) | |
| order | No | Sort direction (default desc) | desc |
| market | No | Market: 'kr', 'us', or 'all' (default) | all |
| min_aum | No | Minimum net assets in listing currency (KR only; US is null) | |
| sort_by | No | Sort key (default aum) | aum |
| min_price | No | Minimum last close in listing currency | |
| min_volume | No | Minimum 20-session average volume | |
| name_contains | No | Substring of the fund name or ticker | |
| index_contains | No | Substring of the tracked index name ('TR' for total-return indices) | |
| min_premium_pct | No | Keep funds at or above this premium in percent (negative finds discounts) | |
| response_format | No | 'markdown' for a table, 'json' for compact output | markdown |
| total_return_year | No | Calendar year for total_return_pct; omit for the best-covered year (the response says which) | |
| max_abs_premium_pct | No | Keep funds within this |premium to NAV| in percent |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | |
| count | Yes | |
| order | No | |
| market | Yes | |
| sort_by | No | |
| data_as_of | No | |
| total_return_year | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds substantial behavioral context: market-specific coverage (KR vs US), price vs total return caveat, currency caveat for AUM, single-year pinning for total_return_pct, and the 'database has not been built yet' error case. These go well beyond the annotations and are critical for correct interpretation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but exceptionally well-structured: it front-loads the purpose, then provides parameter semantics, coverage caveats, return format, examples, and usage guidance in logical sections. Every sentence contributes information; there is no redundancy or filler, making the length justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (13 optional parameters, market-specific behavior, data quality caveats), the description is complete: it explains coverage differences, return semantics, parameter usage with examples, the exact return structure, and error handling. With annotations covering the read-only/destructive profile and an output schema described in the Returns section, nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema has 100% parameter description coverage, the description enriches it further: it explains the meaning of min_aum with an example (100000000000 = 1,000억) and notes it's KR-only because US AUM is null; clarifies index_contains 'TR' for total-return indices; explains premium_pct is same-day; and provides real usage examples for each filter. This adds value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool screens ETFs in the local FinBridge database on specific distinguishing metrics (premium/discount to NAV, AUM, tracked index, momentum, and US audited total return). It explicitly distinguishes from operating-company tools by directing to get_valuation or query_db, and from statement-based tools like get_dart_financials.
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 'Use when: choosing or comparing funds' and 'Don't use for stocks (get_valuation / query_db) or for a single fund's price history (get_stock_prices).' It also explains why statement-based tools are not applicable to funds, giving clear when/when-not guidance with named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_dart_companySearch Korean Companies (DART)ARead-onlyInspect
Search companies registered with DART, South Korea's corporate disclosure system, by name, 6-digit stock code, or 8-digit DART corp_code. Returns the corp_code required by the other dart_* tools.
Not this tool for: US registrants (use search_edgar_company). Japan, Taiwan and Europe have no search tool — reach them through query_db on the companies table.
Args:
query: company name in Korean ('삼성전자') or English ('Samsung Electronics'), 6-digit KRX stock code ('005930'), or 8-digit corp_code
listed_only: restrict to KRX-listed companies (default true). Set false to include ~90k unlisted entities.
limit: max results, 1-50 (default 10)
Returns: {count, companies: [{corp_code, corp_name, corp_name_en, stock_code}]} — corp_name is the Korean name DART registers, corp_name_en the registered English name where the company files one (about three quarters of Korean issuers). stock_code is null for unlisted companies. Match priority: exact stock code > exact Korean name > listed Korean partial > unlisted Korean partial > English name. English matching reads our own company table, so it covers issuers whose English name we hold, not every DART entity.
Examples:
{query: '삼성전자'} -> corp_code 00126380, stock_code 005930
{query: '카카오', listed_only: false} -> listed 카카오 plus unlisted same-name entities
{query: 'Samsung Electronics'} -> 삼성전자 (matched on the registered English name)
Use when you need a corp_code or must disambiguate similar names. Don't use for US companies (use search_edgar_company). Errors: DART_API_KEY not configured; no match returns count 0 (not an error).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results, 1-50 (default 10) | |
| query | Yes | Company name, 6-digit stock code, or 8-digit DART corp_code | |
| listed_only | No | Only KRX-listed companies (default true) |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| companies | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds valuable behavioral details: no-match returns count 0 (not an error), DART_API_KEY error condition, match priority ordering, and English name matching limitations. These go well beyond annotations and inform the agent of edge cases.
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?
Though long, the description is front-loaded with purpose and usage, then parameters, return format, matching, examples, and errors. Each sentence adds value; no fluff. The structure uses headers ('Args:', 'Returns:', 'Match priority:', 'Examples:') which aids scanning. Appropriate length for the tool's complexity.
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?
Covers all necessary information: purpose, usage, parameters, return structure, matching behavior, examples, error conditions, and limitations. Even though an output schema exists, the description explains the return format clearly. The tool's complexity (multiple query types, matching priority, edge cases) is fully addressed.
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 baseline is 3. The description goes beyond schema by explaining query accepts name/stock code/corp_code, clarifying listed_only default and meaning, and detailing match priority (exact stock code > Korean name > partial > English). This adds substantial semantic value beyond the schema's terse descriptions.
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?
Description states a specific verb ('search'), resource ('companies registered with DART'), and output (corp_code required by other dart_* tools). It distinguishes itself from search_edgar_company by name and usage, and clarifies its role as the entry point for DART tools. Purpose is unambiguous and differentiated.
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 tells when to use ('Use when you need a corp_code or must disambiguate similar names') and when not to use ('Don't use for US companies' with alternative 'use search_edgar_company'). Also covers Japan/Taiwan/Europe via query_db. No ambiguity left for the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_edgar_companySearch SEC EDGAR CompaniesARead-onlyInspect
Search SEC EDGAR registrants (US-listed companies) by ticker, company name, or CIK. Returns the 10-digit zero-padded CIK needed by the other edgar_* tools.
Not this tool for: Korean companies (use search_dart_company). Japan, Taiwan and Europe have no search tool — reach them through query_db on the companies table.
Args:
query (required): ticker ('AAPL', 'BRK-B' or 'BRK.B'), company-name fragment ('Berkshire'), or CIK number ('320193')
limit: max results, 1-50 (default 10)
Returns: {count, companies: [{cik, ticker, title}]} ranked exact-ticker > exact-name > prefix > substring.
Examples:
"find Apple's CIK" -> {query: 'AAPL'}
"companies named Berkshire" -> {query: 'Berkshire', limit: 5}
Use when: you need a CIK or to disambiguate a company name before calling get_edgar_financials/filings/insider_trades (those also accept tickers directly, so for an exact ticker you can skip this step). Don't use for: Korean companies (use search_dart_company) or private companies not registered with the SEC.
Errors: no match -> error suggesting a shorter name fragment; only SEC registrants with a listed ticker are searchable.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max matches to return (default 10) | |
| query | Yes | Ticker (e.g. 'AAPL', 'BRK-B'), company-name fragment (e.g. 'Berkshire'), or CIK number |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| companies | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context: ranking order (exact-ticker > exact-name > prefix > substring), the error behavior (no match -> error suggesting a shorter fragment), and the constraint that only SEC registrants with a listed ticker are searchable. This goes beyond what annotations provide, though it doesn't describe pagination or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: the core purpose is in the first sentence, followed by routing guidance, args, return format, examples, and error behavior. Every section earns its place, and the examples are compact and illustrative. No fluff or repetition of schema details.
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 search tool with a rich output schema and full schema coverage, the description is complete. It covers what the tool does, when to use it, what it returns, how results are ranked, and what happens on error. The only minor gap is lack of pagination details, but the limit parameter and return shape make this sufficient for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both parameters. The description adds value by giving concrete examples of valid query formats ('AAPL', 'BRK-B' or 'BRK.B', 'Berkshire', '320193') and clarifying the limit range (1-50, default 10). It also explains the return shape ({count, companies: [...]}) which helps the agent understand what the query parameter produces.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Search'), a specific resource ('SEC EDGAR registrants'), and the exact purpose: returning the 10-digit zero-padded CIK needed by other edgar_* tools. It also distinguishes itself from search_dart_company by explicitly excluding Korean companies. This is a clear, differentiated purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use this tool ('when you need a CIK or to disambiguate a company name before calling get_edgar_financials/filings/insider_trades'), when not to use it ('Don't use for: Korean companies'), and names the alternative (search_dart_company). It also notes that exact tickers can skip this step, which is valuable routing guidance.
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 tool update
- Changed
get_dart_document3 fields changed- added
Input schema / properties / entry / maxLengthAdded value: +120 - added
Input schema / properties / entry / minLengthAdded value: +1 - removed
Input schema / properties / entry / patternRemoved value: -"^[\\p{L}\\p{N}._/-]{1,120}$"
4 tool updates
- Changed
get_dart_filings7 fields changed- changed
Input schema / properties / fresh / descriptionPrevious value: -"false (default): answer from FinBridge's DART filings index (refreshed every 5 minutes) when it covers the window, DART otherwise. true: ask DART directly."New value: +"false (default): answer from FinBridge's DART filings index (refreshed every 5 minutes) for the part of the window it covers, and ask DART live only for the uncovered remainder (saves DART's daily quota). true: ask DART directly for the whole window; on daily-quota exhaustion (020), falls back to the index for whatever it covers and says what could not be refreshed." - added
Output schema / properties / index_as_ofAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / noteAdded value: +{ + "type": "string" +} - added
Output schema / properties / quota_fallbackAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / served_fromAdded value: +{ + "type": "string" +} - added
Output schema / properties / sourcesAdded value: +{ + "additionalProperties": true, + "properties": {}, + "type": "object" +} - added
Output schema / properties / uncoveredAdded value: +{ + "items": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "type": "array" +}
- Changed
get_dart_financials6 fields changed- added
Output schema / properties / disclosed_dateAdded value: +{ + "$ref": "#/properties/served_from" +} - added
Output schema / properties / live_dart_statusAdded value: +{ + "$ref": "#/properties/served_from" +} - added
Output schema / properties / receipt_idAdded value: +{ + "$ref": "#/properties/served_from" +} - added
Output schema / properties / receipt_urlAdded value: +{ + "$ref": "#/properties/served_from" +} - added
Output schema / properties / served_fromAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / stored_as_ofAdded value: +{ + "$ref": "#/properties/served_from" +}
- Changed
get_dart_major_events7 fields changed- changed
Input schema / properties / fresh / descriptionPrevious value: -"false (default): answer from FinBridge's DART filings index (refreshed every 5 minutes) when it covers the window, DART otherwise. true: ask DART directly."New value: +"false (default): answer from FinBridge's DART filings index (refreshed every 5 minutes) for the part of the window it covers, and ask DART live only for the uncovered remainder (saves DART's daily quota). true: ask DART directly for the whole window; on daily-quota exhaustion (020), falls back to the index for whatever it covers and says what could not be refreshed." - added
Output schema / properties / index_as_ofAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / noteAdded value: +{ + "type": "string" +} - added
Output schema / properties / quota_fallbackAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / served_fromAdded value: +{ + "type": "string" +} - added
Output schema / properties / sourcesAdded value: +{ + "additionalProperties": true, + "properties": {}, + "type": "object" +} - added
Output schema / properties / uncoveredAdded value: +{ + "items": { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + "type": "array" +}
- Changed
get_peers5 fields changed- added
Output schema / properties / basis_kindAdded value: +{ + "type": "string" +} - added
Output schema / properties / basis_labelAdded value: +{ + "type": "string" +} - added
Output schema / properties / insufficiency_reasonAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / policy_versionAdded value: +{ + "type": "string" +} - added
Output schema / properties / purposeAdded value: +{ + "type": "string" +}
1 tool update
- Changed
compare_financials_kr_us1 field changed- changed
Input schema / properties / years / descriptionPrevious value: -"How many recent fiscal years to compare (default 3)"New value: +"How many recent fiscal years to compare (default 3; the free plan covers up to 4)"
1 tool update
- Changed
get_dart_document1 field changed- added
Input schema / properties / entryAdded value: +{ + "description": "Archive entry to explore, exactly as the overview's entries list names it (e.g. 20260313001021_00761.xml for a consolidated audit report). Omit for the main body. Attachments are read from DART, not from the preserved copy.", + "pattern": "^[\\p{L}\\p{N}._/-]{1,120}$", + "type": "string" +}
3 tool updates
- Changed
get_dart_document1 field changed- added
Input schema / properties / freshAdded value: +{ + "default": false, + "description": "false (default): read FinBridge's preserved copy of this filing when we hold one, and DART otherwise. true: fetch the current version from DART now — use only when the user asks for the latest text or suspects a correction.", + "type": "boolean" +}
- Changed
get_dart_filings1 field changed- added
Input schema / properties / freshAdded value: +{ + "default": false, + "description": "false (default): answer from FinBridge's DART filings index (refreshed every 5 minutes) when it covers the window, DART otherwise. true: ask DART directly.", + "type": "boolean" +}
- Changed
get_dart_major_events1 field changed- added
Input schema / properties / freshAdded value: +{ + "default": false, + "description": "false (default): answer from FinBridge's DART filings index (refreshed every 5 minutes) when it covers the window, DART otherwise. true: ask DART directly.", + "type": "boolean" +}
1 tool update
- Changed
get_dart_document2 fields changed- added
Input schema / properties / compare_index / descriptionAdded value: +"Table or section index inside the second filing. Read that filing's overview first; table_index/section_index selects the first filing's side." - added
Input schema / properties / compare_rcept_no / descriptionAdded value: +"Second filing's 14-digit receipt number, for compare_tables / compare_sections. The first filing is rcept_no."
1 tool update
- Added
screen_etfs
1 tool update
- Changed
get_disclosure_feed2 fields changed- added
Input schema / properties / briefAdded value: +{ + "default": true, + "description": "Attach the fact-summary fields where one exists (default true). Rows without a summary are unaffected.", + "type": "boolean" +} - added
Input schema / properties / watchlistAdded value: +{ + "default": false, + "description": "Restrict to the authenticated account's watchlist companies (default false). Needs a personal API key. Ignored when 'company' is set.", + "type": "boolean" +}
20 tool updates
- Removed
analyze_factors - Removed
backtest_portfolio - Removed
compare_crypto_exchanges - Removed
delete_backtest_run - Removed
get_backtest_runs - Removed
get_crypto_ohlcv - Removed
get_crypto_ticker - Removed
get_technicals - Removed
real_estate_get_coverage - Removed
real_estate_list_regions - Removed
real_estate_search_trades - Removed
real_estate_summarize_trades - Removed
screen_canslim - Removed
screen_companies - Removed
screen_etfs - Removed
screen_kell - Removed
screen_minervini - Removed
screen_schwartz - Removed
screen_technical - Changed
search_dart_company1 field changed- added
Output schema / properties / companies / items / properties / corp_name_enAdded value: +{ + "$ref": "#/properties/companies/items/properties/corp_code" +}
1 tool update
- Changed
get_valuation1 field changed- added
Output schema / properties / fx_conversionAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "properties": {}, + "type": "object" + }, + { + "type": "null" + } + ] +}
Related MCP Connectors
Korean equities in English: DART filings, activist & foreign-holder classification, KRX news.
Search company disclosures and financial statements from the Korean market. Retrieve stock profile…
Korean (DART/KIND) and US SEC filings with AI summaries, direction labels and market reaction.
1Cross-market (US/JP/KR) structured financials, segments, ownership & metrics, traceable to filings.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables LLM agents to access Korean stock market data including DART disclosures, financial statements, and KOSPI/KOSDAQ prices, with an English-first interface designed for non-Korean speaking analysts.6MIT
- FlicenseAqualityBmaintenanceEnables searching corporate disclosures from Korea's DART system, including company info, financial statements, and disclosure search.16-
- AlicenseNot gradedqualityDmaintenanceProvides access to South Korea's DART (Data Analysis, Retrieval and Transfer System) financial disclosure system, enabling users to retrieve corporate information, financial statements, debt summaries, subsidiary investments, employee data, and stock information for Korean companies.6MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI-powered analysis of Korean stock market data and corporate disclosures using official DART and KRX APIs.132 npmISC
Glama MCP Gateway
Add one secure layer between your agents and this server.