toolfind_companies
groupFind and identify a company
endpointhttps://mcp.steadybase.io/mcp
FIND, RESOLVE OR LOAD COMPANIES. Four modes on one tool, by which argument you give, in this precedence: resolve, then bulk, then q, then query. (1) resolve is THE IDENTITY RESOLVER and wins over q and query. Give it an object of identifiers, any combination of account_id, cik, lei, ticker, exchange_ticker, domain, linkedin_company, legal_name (with country or state to disambiguate), parent_hint and duns, and you get back ONE account_id with method (which rung matched), confidence, corroborated_by, the account row, the corporate tree (parent, ultimate_parent, is_ultimate_parent) and the evidence list of every rung that was tried. A miss is an EXPLICIT no match: resolved false, reason no_match or ambiguous or conflict, and the nearest candidates so you can see what it nearly was. TWO CANDIDATES IS AMBIGUITY AND NEVER A MATCH: this tool does not promote a candidate into an answer, and you must not either. Send a stronger identifier or a jurisdiction and ask again. (2) external_id with external_system resolves YOUR OWN id (a Salesforce 18 character id, a CRM account key) through the same route, answered from your tenant's own id map first so a mapped id does not get re-matched. Both arguments go together, and the map read is scoped to the tenant your key resolves to; a key that is not mapped to a tenant is told so and the box is never called. (3) bulk true is THE ACCOUNT UNIVERSE, paged: identity only, no signal, no score, no tier, no tenant lens, in account_id order. Each row carries account_id, legal_name, display_name, primary_ticker, primary_domain, account_type, lifecycle_status, resolution_status, is_company, parent_account_id, ultimate_parent_id, depth, hq, sector, industry, exchange, employees_est, ir_url, identifiers (cik, lei, ticker, exchange_ticker, domain, linkedin_company, former_name, duns) and updated_at. Page on next_cursor until has_more is false; take deltas by passing since = the previous answer's as_of. include_unresolved adds the 209,093 EX-21 exhibit nodes we hold as evidence and have not identified (they come back resolution_status unresolved and is_company false, and they are NOT companies we assert exist under that name); the default scope without it is 10,140 resolved rows out of 219,233 total. book_only narrows to your own book. YOU DEDUPE ON account_id AND NOTHING ELSE. Ticker collisions (two companies that have held one symbol at different times), name variants, share classes and a subsidiary sharing its parent's domain are OURS to collapse and are already collapsed onto one account_id before a row leaves here. account_id is stable across a rename, a ticker change, an exchange move and an acquisition. Never dedupe on ticker or name. If two rows ever carry the same identifier under the same id_type, that is a bug to report to us, not a merge for you to perform. PAGE SIZE: the MCP page defaults to 200 rows and is capped at 500, because one tools/call result is one text block that lands whole in your context and 1,000 of these rows is about 200,000 tokens. The box itself will serve 5,000, so for the FIRST FULL LOAD of all 219,233 rows ask for the nightly export instead: one gzipped JSONL file per tenant in the private snapshots bucket, delivered by a presigned URL, built by the same function as this page so the two cannot drift. Use bulk for deltas and for reading a slice. (4) query is the PUBLIC DIRECTORY substring search over all 7,034 published companies by name, ticker or slug, case insensitive, exact ticker first, the same answer for every key: it returns slug (the durable key for the other company_* tools), name, ticker, url, page_url and the signal, quote and people counts. Use it when you have a company name and need the slug. (5) q is the IDENTIFIER LOOKUP behind your key: a domain, ticker, LEI or name, and each row is the company profile, account_id, name, legal_name, ticker, domain, sector, industry, exchange, cik, lei, hq_city, hq_state, hq_country, ir_url, linkedin_url, employees_est, on_book (whether that account sits on YOUR book), matched_on (which identifier hit) and identifiers (the rest of them). THE RECEIPT on a q row is cik and lei, the registry identifiers you can check the company against, plus ir_url and linkedin_url. include_tree true adds the corporate tree stats: parent, ultimate_parent, children_count, subsidiaries_count, and the people_count, roles_count, signals_count, documents_count and transcripts_count held. LIMITS: limit is max rows, default 10 and cap 100 on q and query, default 200 and cap 500 on bulk. The tenant on every keyed path is the one your key resolved to and cannot be overridden by an argument. bulk cannot be combined with resolve, q or query and says so rather than answering a narrower question. IT NEVER RETURNS an email, a phone, a tier, a score, a rank or any prioritisation of any kind.
arguments
| query | string | company name, ticker, or slug; case insensitive substring over the public directory |
| q | string | a domain, ticker, LEI or name to look up behind your key; answered with the company profile |
| include_tree | boolean | with q: add the corporate tree stats (parent, ultimate parent, child and subsidiary counts, and the people, roles, signals, documents and transcripts held) |
| resolve | object | THE RESOLVER, and it wins over q and query: an object of identifiers resolved to ONE account_id or to an explicit no match with candidates. Accepts account_id, cik, lei, ticker, exchange_ticker, domain, linkedin_company, legal_name, country, state, parent_hint, duns. Two candidates is ambiguity and never a match |
| external_id | string | YOUR OWN id for this company (a Salesforce id, a CRM key). Goes with external_system and is answered from your tenant's own id map first |
| external_system | string | the system external_id belongs to, for example salesforce. Required with external_id |
| bulk | boolean | true loads THE ACCOUNT UNIVERSE, paged: identity only, in account_id order, with next_cursor and has_more. Cannot be combined with resolve, q or query |
| cursor | string | with bulk: the account_id of the last row you read. Keyset paged, so a deep page costs the same as the first |
| since | string | with bulk: ISO date or timestamp, an inclusive floor on updated_at. For a delta pass the previous answer's as_of |
| include_unresolved | boolean | with bulk: add the 209,093 EX-21 exhibit nodes we hold as evidence and have not identified. They are evidence, not companies we assert exist |
| book_only | boolean | with bulk: only the accounts on your own book |
| limit | integer | max rows. q and query: default 10, cap 100. bulk: default 200, cap 500, because one tools/call result lands whole in your context |
install
claude mcp add --transport http steadybase https://mcp.steadybase.io/mcp --header "Authorization: Bearer $STEADYBASE_KEY"
call
curl -s https://api.steadybase.io/v1/mcp/call -H "Authorization: Bearer $STEADYBASE_KEY" -H "Content-Type: application/json" -d '{"tool":"find_companies"}' contract
| A quote comes with its receipt | Every returned statement carries the verbatim sentence and the URL it came from, and where the source is a transcript, the character offsets inside it. A statement with no receipt is not returned. |
| Empty is an answer | When there is no sourced statement, the skill returns nothing. It does not summarise, infer, or fill the gap from general knowledge. Handle the empty case rather than retrying until something appears. |
| No personal contact data | No email address, phone number, home address or personal social account is returned by any skill, at any tier. A person is a name, a professional role, a LinkedIn profile URL and the public record that puts them in that role. |
| No customer data crosses a key | A tenant-scoped skill reads only that tenant. Nothing about any customer appears on the public site or in another tenant answer. |
/skills/