Skip to main content
Glama
minghsuy

ctscout

by minghsuy

Look up one LEI's record, or the LEIs published under a legal name

ctscout_lookup_lei
Read-onlyIdempotent

Look up a Legal Entity Identifier (LEI) record by LEI or find LEIs for a legal entity name.

Instructions

Read the ctscout research product's entity index: one LEI's record (GET /lei/{lei}), or the LEIs filed under a legal name (GET /lei?name=). Free, and it debits no quota — every answer is a precomputed object published by the ctscout-research refresh, not a live query.

Args (exactly one of lei / name; passing both is rejected before any network call):

  • lei (string, optional): an ISO 17442 LEI — 18 uppercase alphanumerics plus 2 check digits, e.g. '549300NDMY0KJK0ZLW17'.

  • name (string, optional): a legal entity name, 1–200 chars, e.g. 'Cloudflare, Inc.'.

  • response_format ('markdown' | 'json', default 'markdown'): output format.

Returns (on success, structuredContent follows the declared outputSchema; a failed call — 400, 404, 503, timeout — is isError with no structuredContent, so never dereference snapshot on it). One tool, two answer shapes; name_match is the discriminator, present only on the by-name answer:

  • By LEI: { "lei": string, "legal_name": string, // GLEIF's legal name "country": string, // GLEIF's country "isin_count": number, // ISINs mapped to this LEI in GLEIF's ISIN-to-LEI file "apex_count": number, // apex domains attributed to this LEI "first_seen": string, "last_seen": string, // warehouse observation window over those apexes "sample_domains": [string], // hash-chosen sample, whatever size the export published — NOT a ranking, not a complete list "vendors_confirmed": [string] // vendor SLUGS: pass one to ctscout_vendor_customers }

  • By name: { "query": string, "name_match": "exact" | "normalized" | "none", "normalizer_mismatch": null | { "index": string, "lookup": string }, // null: the API's normalizer keyed the index. Set: the two versions differ, so a "none" may be a spelling miss under this API. Absent: an API that predates the check. "leis": [string], // capped at "limit" (20) "lei_count": number, // matches BEFORE the cap — can exceed leis.length "limit": number, "truncated": boolean }

  • Both also carry "as_of" / "product_version" (the export version), "snapshot_dates" (the dated GLEIF / ISIN / ELF / Wikidata snapshot and the PSL bundle each join read), and this server's "snapshot" / "snapshot_source" ("product" when the API reported the version, "unavailable" when it did not — then snapshot is null and freshness is unknown, never "current").

What name_match: "none" means (important):

  • It does NOT mean this company has no LEI. The name index is keyed by the research normalizer's form of the GLEIF legal name; the two spellings the route tries (the lowercased, trimmed query and its locale-suffix normalization) are not the index's normalizer, so a real entity can miss on a spelling.

  • Retry with the exact GLEIF legal name, or look the entity up by LEI. Do not report a "none" as an absent LEI.

Vocabulary: a domain is ATTRIBUTED to an entity — that is what the certificate and DNS evidence names, not an ownership claim. A vendor in vendors_confirmed is CONFIRMED, which has a specific meaning: a vendor is confirmed when a hostname it certified resolves onto a domain it certifies and the customer's own www does not, or another organization certifies the apex.

Examples:

  • Use when: "What does ctscout know about LEI 549300NDMY0KJK0ZLW17?" -> { lei: "549300NDMY0KJK0ZLW17" }

  • Use when: "Which LEIs are filed under 'Cloudflare, Inc.'?" -> { name: "Cloudflare, Inc." }

  • Don't use when: you want the domains attributed to a company by cert subject — that is ctscout_search_company against the warehouse, a different index with different coverage.

Coverage & freshness:

  • The product covers LEIs with at least one attributed apex in the research build, so a 404 means "not in this published version", not "no such LEI". An entity has an LEI at all only where a regulator or a counterparty required one, so an absent LEI is not an absent entity either.

  • The export is republished by the ctscout-research refresh, so these answers move on that cadence — slower than the /scan warehouse, which syncs daily. Read "snapshot" for the version actually answered from.

  • Before the first publish the route answers HTTP 503 and this tool returns a plain "not published yet" error. That is expected, not a fault in the query.

Corrections:

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
leiNoA single LEI (ISO 17442: 18 uppercase alphanumerics + 2 check digits), e.g. '549300NDMY0KJK0ZLW17'. Give lei or name, not both.
nameNoA legal entity name to look up in the name index, e.g. 'Cloudflare, Inc.'. Give lei or name, not both.
response_formatNoOutput format: 'markdown' for the record or the name-match list, 'json' for the raw API response.markdown

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
leiNoBy-LEI answer: the LEI the record is filed under.
leisNoBy-name answer: matching LEIs, capped at `limit`. lei_count is the total.
as_ofNoThe product version this answer was read from.
limitNoBy-name answer: the cap applied to `leis`.
queryNoBy-name answer: the name as submitted.
countryNoBy-LEI answer: GLEIF's country for the entity.
snapshotYesThe research product version (YYYY-MM-DD) this answer was read from — the `as_of` of the export the ctscout-research refresh published. null when the API response carried none.
last_seenNoBy-LEI answer: latest warehouse observation across this LEI's apexes.
lei_countNoBy-name answer: matches before the cap.
truncatedNoBy-name answer: true when lei_count exceeds limit.
apex_countNoBy-LEI answer: apex domains attributed to this LEI in the research build.
first_seenNoBy-LEI answer: earliest warehouse observation across this LEI's apexes.
isin_countNoBy-LEI answer: ISINs mapped to this LEI in GLEIF's ISIN-to-LEI file.
legal_nameNoBy-LEI answer: GLEIF's legal name for the entity.
name_matchNoBy-name answer, and the discriminator between the two shapes: 'exact' | 'normalized' | 'none'. 'none' means neither spelling tried hit the index, NOT that the entity has no LEI.
sample_domainsNoBy-LEI answer: a hash-chosen sample of the attributed apexes — whatever size the research export published, not a ranking and not a complete list. apex_count is the total; the markdown says so if it lists fewer than the sample carries.
snapshot_datesNoPer-source provenance from the product manifest: elf, gleif, isin, psl, wikidata. Values are the dated snapshot each join read (psl is a bundle identifier, not a date).
product_versionNoSame value as as_of; the manifest's version.
snapshot_sourceYes'product' = the API response carried the export's as_of; 'unavailable' = it did not, snapshot is null and must be treated as unknown, never as current.
truncation_noteNoWritten by this MCP server, never by the API: present only when a list above was shortened to stay under the response character limit, naming each shortened list and the length the API actually sent. Absent means no list was cut here.
vendors_confirmedNoBy-LEI answer: vendor slugs confirmed on this LEI's domains. Pass one to ctscout_vendor_customers.
normalizer_mismatchNoBy-name answer: null when the API's normalizer is the one the index was keyed with. Otherwise { index, lookup } names the two versions: the normalized spellings are then not the index's keys, and a 'none' may be a spelling miss under this API rather than an absent name. Absent from an API that predates the check.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv0.6.0

TDQS

A5/5.0
Behavior5/5

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

The description goes well beyond the readOnly/idempotent/openWorld annotations by explaining error semantics ('404 means not in this published version'), the 503 'not published yet' case, the absence of quota debits, and the fact that answers come from a precomputed export rather than a live query. It does not contradict any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every section serves a distinct purpose: purpose, arguments, return shapes, meaning of 'none', vocabulary, examples, coverage, and corrections. It is front-loaded with the essential purpose and organized with headers and code blocks, so the length is appropriate for the complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It fully specifies both return shapes, the name_match discriminator, error behavior, snapshot/freshness semantics, and even correction channels. Given the tool's non-obvious 'none' semantics and dual lookup modes, nothing needed to call it correctly appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All three parameters are individually described in the schema, and the description adds practical constraints: exactly one of lei/name must be given, passing both is rejected before network access, and the response_format enum is explained with its two possible values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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

The description states a specific verb ('Read'), resource ('ctscout research product's entity index'), and scope ('one LEI's record' or 'LEIs filed under a legal name'). It also explicitly differentiates from the sibling tool ctscout_search_company, so an agent can select it without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit use cases ('Use when:') and non-use cases ('Don't use when:') with concrete examples. It also provides guidance on retrying when name_match is 'none' and explains the exact one-of constraint, so when and how to invoke it are clear.

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