Public alpha — everything is free and the monthly quotas are not enforced. Get one mail when the paid plan launches.

Documentation

Eight tools, synchronous calls, a stable set of error codes.

Connecting

Endpoint https://nbb-mcp.be/mcp
Transport MCP streamable HTTP (one endpoint, POST + SSE). Not the deprecated two-endpoint SSE transport.
Authentication Authorization: Bearer nbb_live_… on every request
Session Stateful: the server expects the normal initialize handshake.

The client-by-client setup guide is on your account page, next to your key. A request without a key gets 401 with a WWW-Authenticate header; a key over the rate limit gets 429 with Retry-After.

Tools

search_company billable

Resolve a company name to its Belgian enterprise (KBO/BCE) number, or list the names registered for a number.

Parameter Type Required Description
query string yes A name, part of a name, or an enterprise number in any notation (0403.170.701, BE0403170701, 403170701). An establishment unit number (2.xxx.xxx.xxx) returns the enterprise it belongs to. Typo-tolerant and language-agnostic; numbers bypass the fuzzy search.
language string no nl, fr, de or en. Only orders the returned names; filters nothing out.
limit integer no How many companies to return. Default 10, maximum 25.

Returns. Candidates best match first: kbo_number, every registered name with its type and language (a name of one of its establishment units carries that unit's establishment_number), and match_score (1.0 for a direct number hit). Plus warnings[], which explains an empty result or a failed mod-97 check digit.

get_annual_accounts billable

Fetch the annual accounts a company filed with the NBB: balance sheet, income statement, appropriation of results, social balance sheet and notes, each line with its official rubric code and a translated label.

Parameter Type Required Description
kbo_number string yes Belgian enterprise number in any notation. Not the name — call search_company first.
year integer no The calendar year the accounting exercise ends in. Omit for the most recent filing.
language string no Label language: nl, fr, de or en. Default nl. Figures are identical in every language.
detail string no How much to return: kpis for the key figures and ratios only (enough to compare companies), statements (default) for every statement and note line, full to add unmapped_facts.

Returns. The accounts in the same call: status "completed" with the parsed filing in result (or, with detail kpis, the key figures, ratios and flags in kpis), plus cached: true when it was served from cache. A request that cannot be served returns status "failed" with a stable error {code, message}.

check_xbrl_availability billable

List every annual account a company filed with the NBB and whether each is machine-readable (XBRL) or a PDF-only image — the years get_annual_accounts can serve.

Parameter Type Required Description
kbo_number string yes Belgian enterprise number in any notation. Not the name — call search_company first.
year integer no Restrict the list to one financial year. Omit to list everything the company ever filed.

Returns. Filings newest first, each with fiscal_year, reference_number, model_type, deposit_type, deposit_date and xbrl_available. xbrl_available true means get_annual_accounts serves it as structured data; false means the NBB holds only a PDF.

get_company_activities billable

List every NACE activity a company has registered at enterprise level: code, nomenclature version, classification and a readable description.

Parameter Type Required Description
kbo_number string yes Belgian enterprise number in any notation. Not the name — call search_company first.
language string no Description language: nl, fr, de or en. Default nl. All four are attempted; a missing description falls back to Dutch.

Returns. Every registered activity: code, nomenclature version (2003, 2008 or 2025), classification (main, secondary or ancillary) and a description. Activities registered on an establishment are not included, only ones at enterprise level. Plus warnings[], which explains an empty result or a language fallback.

get_registered_office billable

Fetch a company's registered office (registered seat) address as structured fields.

Parameter Type Required Description
kbo_number string yes Belgian enterprise number in any notation. Not the name — call search_company first.
language string no nl, fr, de or en. Default nl. Only Dutch and French exist in the source data: de and en are answered in Dutch, and warnings says so.

Returns. Street, house number, box, zipcode, municipality, country and extra info. Country is null for Belgian addresses. A struck-off seat is still returned, flagged in warnings[].

list_establishments billable

List a company's currently operating establishments, each with its establishment number, start date and structured address.

Parameter Type Required Description
kbo_number string yes Belgian enterprise number in any notation. Not the name — call search_company first.
language string no nl, fr, de or en. Default nl. Only Dutch and French exist in the source data: de and en are answered in Dutch, and warnings says so.

Returns. Every currently operating establishment, with its establishment number, start date and structured address. Establishments whose address has been struck off are excluded. Plus warnings[], which explains an empty result or a language fallback.

list_nace_codes not billable

Browse the NACEBEL activity classification one level at a time, to find the code that describes an activity such as "bakery". Free: the only tool that does not count against your quota.

Parameter Type Required Description
nace_code string no The code to list the children of, digits only and no dots, for example 47 or 4711. Omit it to start from the divisions at the top of the classification.
nace_version string no Which nomenclature to browse: 2025 (default), or 2008 or 2003 for the older ones a company may still be classified under.
language string no nl or fr, default nl. The KBO publishes NACE descriptions in those two languages only; de and en are answered in Dutch, and warnings says so.

Returns. nace_version, parent_code (the code drilled into, absent at the top), level (what codes[] contains: division, group, class, subclass or detail) and codes[] with code, level and description. Plus warnings[], which explains a fallback or an empty result.

find_companies_by_activity billable

Find companies by NACE activity code, postal code or municipality — the reverse of the per-company tools. At least one of nace_code, zipcode or municipality is required; given several, they are ANDed, and a company matches if any of its addresses (registered office or an establishment) falls in the area. Only companies currently active in the register are returned.

Parameter Type Required Description
nace_code string no NACEBEL activity code, digits only and no dots, for example 4711, from list_nace_codes. Optional on its own, but at least one of nace_code, zipcode or municipality must be given.
nace_version string no Which nomenclature the code is from: 2025 (default), 2008 or 2003.
zipcode string no Belgian postal code, four digits. Optional on its own, but at least one of nace_code, zipcode or municipality must be given.
municipality string no Municipality name in Dutch or French (Gent, Gand), or one of a handful of English names (Ghent, Antwerp, Brussels, Ostend, Mechlin, Tournai); resolved to the postal codes it covers. Optional on its own, but at least one of nace_code, zipcode or municipality must be given.
activity_role string no main to return only companies with nace_code as a main activity, any (default) to include secondary and ancillary ones.
entity_type string no legal for companies and other legal persons, natural for sole traders, any (default).
location_match string no Which address has to be in the searched place: seat (registered office), establishment (an establishment unit) or any (default).
page integer no Page to return, counting from 1. Default 1.
page_size integer no Companies per page. Default 10, maximum 100.
language string no nl, fr, de or en. Only chooses which registered name is shown; never affects which companies match.

Returns. filters (echoing nace_code, nace_version, zipcodes[] — the postal codes actually searched, which is how a municipality name is reported back — municipality, activity_role, entity_type and location_match), page, page_size, has_more and companies[]: kbo_number, name, entity_type, legal_form, start_date, main_activities[], matched_activity_role, match_source (enterprise or establishment), seat_zipcode and matched_zipcode. No total count: counting every match costs a second pass and tells a caller reading one page nothing useful. Plus warnings[].

How long a call takes

get_annual_accounts answers in the call itself: fetching a filing means calling the National Bank, downloading the deposit and parsing XBRL, and all of that happens while your client waits.

A fresh filing usually takes a few seconds, occasionally up to a minute when the National Bank is slow. Wait for the answer rather than retrying — a retry is a second billable call for the same work.

A filing that has been fetched before comes back instantly with status: "completed" and cached: true. Results are cached per deposit and never expire, because a filed annual account is immutable — a correction is a new deposit with its own reference, and that is what the server picks up.

Error codes

A failed get_annual_accounts call carries error.code, and these strings are stable — a client may branch on them.

Code Meaning What to do
no_accounts_found The NBB has no accepted filing for this company, or none for the year you asked for. The message lists the years that do exist. Retry with one of the years from the message, or tell the user there is nothing to show. Retrying the same request will not help.
pdf_fallback_required The filing exists but only as a PDF (older or non-standardised deposits), or in a taxonomy version this server cannot map yet. Reading PDF filings with an LLM is in progress and not yet available. Call check_xbrl_availability to find the years that are machine-readable, and tell the user the filing exists but cannot be read yet.
nbb_unavailable The National Bank's service was unreachable or answered 429/5xx after our own retries. Transient. Retrying in a few minutes is worth it — this is the one code where that is true.
nbb_error The NBB answered, but with something unusable (a 4xx that is not a missing format). Do not retry. Report the message; if it repeats for a company that should have accounts, it is a bug on our side.
deposit_unreadable The deposit downloaded but could not be parsed as XBRL. Asking the same question again is reasonable; if it keeps failing, the filing itself is the problem.
nbb_not_configured This instance has no NBB subscription key configured. Nothing a client can do; it means the deployment is incomplete.

Errors that are not failed calls

Bad input and an exhausted quota come back as a tool error (MCP isError: true) with an explanatory message rather than as a failed result — there is nothing with a stable code to branch on, only something for the model to fix or report.

Situation Response
Monthly quota reached Tool error naming the limit and where to upgrade (/pricing). The refused call itself is recorded but not charged.
Filing exists only as a PDF The call fails with pdf_fallback_required: reading PDF filings with an LLM is in progress and not yet available. check_xbrl_availability shows which years are machine-readable.
Not a valid enterprise number Tool error naming the problem and suggesting search_company.
Missing or invalid API key HTTP 401 before MCP sees the request.
Too many requests HTTP 429 with Retry-After, at 30 requests per minute (burst 10) per key.

Limits

Limit Value
Requests per minute per key 30
Burst 10

There is no monthly quota in force during the alpha: calls are counted, never refused. The per-key rate limit above stays, because it protects the data source rather than revenue. The quotas that apply at launch are not decided yet.

The result JSON

Every completed get_annual_accounts result has the same shape:

Field Contents
meta Identifiers, filing and response language, model type, taxonomy version, data_source, confidence, caveats, and the current and previous period dates.
identification Name, address and legal form as filed.
statements[] Stable ids balance_sheet_assets, balance_sheet_liabilities, income_statement, appropriation, social_balance; rows are {code, label, level, current, previous}.
notes[] The note sections of the filing, same row shape.
unmapped_facts[] Facts we could not tie to a rubric code, returned with detail full (the default, statements, only counts them in meta.unmapped_fact_count). Never empty out of laziness and never silently dropped — if something is missing from the statements, it is here.

Languages

language accepts nl, fr, de and en, and defaults to nl. Labels come from the National Bank's own taxonomy label linkbases, not from a translation engine, so they match the wording on the official forms.

If a label is missing in the language you asked for, the response falls back in order: requested language → the language the filing was submitted in → nl → fr → en. The figures never change with the language, and meta.response_language tells you what you actually got.

The website itself is published in Dutch, French and English. It follows your browser's language preference; the switcher in the navigation overrides it for the page you are on, and nothing about that choice is stored.

Data sources and caveats

meta.data_source says how a result was produced, and it is the field to read before trusting a number:

data_source What it means Confidence
xbrl Parsed from the XBRL instance the company filed. Figures and rubric codes are exactly what was deposited. Authoritative
pdf_llm Reserved for filings read from a PDF by an LLM into the same JSON shape. That feature is in progress: no result carries this value today, and a PDF-only filing fails with <code>pdf_fallback_required</code> instead. Heuristic — meta.confidence will carry a balance-check score and meta.caveats will say the numbers were read from a document.

Known caveats