Herkend.
MCP server · Dutch business data

Market research that
states its own confidence

Company records from the Dutch Business Register, combined with CBS demographics per neighbourhood. Every figure comes back with its denominator, a benchmark and a confidence rating — so an AI assistant never sounds more certain than the data allows.

MCP stands for Model Context Protocol, an open standard from Anthropic that lets an AI assistant query external data sources. Herkend is one such source: connect it to your AI client once, then ask ordinary questions about the Dutch market.

What this was built for

“Where is the best place to open a bakery?”

With the competition that question falls apart into three separate tools, and the entrepreneur is left to combine them — which nobody does. Here it is one conversation, and if you want it, one call: the whole study for one location in a single answer, with every part using the same catchment area.

The sample output below is Dutch, just as the server returns it. zekerheid = certainty · vrije tekst = free text · per 1000 inw = per 1,000 residents · landelijk = national · inwoners = residents · WOZ = official property valuation · ruimte = room · drukte = footfall · groei = growth · koopkracht = spending power · ontbreekt = missing · potentieel_euro = spending potential in euros · gecorrigeerd = corrected · inkomensindex = income index · bron = source · afgeleid uit de WOZ-waarde = derived from the property valuation · het CBS publiceert hier geen inkomen = CBS publishes no income here · adressen = addresses · objecten = units · grootste_object_m2 = largest unit in m² · m2_per_gebruiksdoel = m² per building use · fout = error · het punt ligt buiten Nederland = the point lies outside the Netherlands · controleer of ze niet verwisseld zijn = check whether they have been swapped.

1

Define the industry

An industry is delimited using our own reading of the free text the owner filed with the Chamber of Commerce, supplemented with external category sources. This step shows what each search strategy yields and whether your term has more than one meaning — a term like “barber” otherwise also finds the barber-supplies wholesaler.

herkend_resolve_branche("bakker")
→ categorie:   zekerheid hoog
  vrije tekst: zekerheid laag
2

Measure saturation

Not the count, but the count per thousand residents, set against the national figure — and now also against the official CBS count under the matching industry code, so you can see how well our wording covers that trade: 1.11 for bakers, 2.79 for clothing shops.

herkend_market_saturation(
  "bakker", "BU0363AB01")
→ 2,1 per 1000 inw
  landelijk 0,8  → +170%
  ijkpunt SBI 1071+4724: 1,11
3

See how big they are

Twelve bakeries of a hundred square metres is a different market from twelve of three hundred, and a saturation figure makes them look identical. The land registry gives the median floor area of the competition — and the share that has business premises at all rather than a registration at a home address. That varies enormously: 79% of supermarkets against 30% of hairdressers.

herkend_competitor_size(
  "kapper", "GM0014")
→ 318 zaken, 42% met winkelruimte
  mediaan 90 m2 (landelijk 97)
4

Draw the catchment

Not the municipal boundary, but who lives within a quarter of an hour’s drive. Over the real road network including one-way streets, because a municipal boundary is arbitrary with respect to where customers come from.

herkend_catchment(
  postcode="1016XE", minuten=15)
→ 995.065 inwoners, 544.800 hh
  556 buurten in 9 gemeenten
5

See who lives there

Age distribution, households, spending power, density and distance to amenities, from CBS per neighbourhood. Plus what actually happens to a business here: shoplifting and commercial burglary from police records, counted per hundred retail and hospitality businesses rather than per resident. That matters: with 3,197 shoplifting reports Amsterdam tops the country in absolute numbers, ranks 14th of 337 municipalities per thousand residents, and sits at index 1.16 per hundred retail and hospitality businesses — sixteen per cent above the national figure rather than far and away the worst.

herkend_area_profile("BU0363AB01")
→ 1.445 inwoners
  WOZ 481k (landelijk 398k)
6

See who is there by day

For a lunchroom, who lives there is the wrong number. Haarlemmermeer has 1.08 jobs per resident and Almere 0.34: one fills up in the morning, the other empties out. Below that sits a layer per address: 6,917 school addresses with 1,461,514 pupils — 6,060 of them primary schools with 1,354,324 pupils, the rest special education — with the forecast per school alongside. Footfall counts do not exist as open data; this is the closest thing to them.

herkend_location_score(
  "bakker", "BU0363AB01")
→ ruimte 0 · drukte 100
  groei 93 · koopkracht ontbreekt
7

Convert it to euros

Households times what a household nationally spends on that category. The correction for local income is measured, not assumed: bread scales at 0.45, clothing at 0.73, transport at 1.10. Even total spending scales at 0.57 rather than 1.00, because the savings rate rises with income — a correction that scales in direct proportion to income is too steep for every category.

8

Weigh it up

A score across four axes — and never the total alone, because the weights are a choice, not a measurement.

What this service does differently

No figure without its denominator

Someone looking for premises rarely trips over a number that is missing. They trip over a number that looks right. In three places this service refuses to hand you one — and tells you what does hold instead.

The neighbourhood where CBS publishes no income

Average income per neighbourhood appears in the CBS key figures only above two thousand residents: 1,950 of 14,574 neighbourhoods have one. None of the 3,739 with a hundred to five hundred residents, none of the 5,515 from there up to two thousand. Treat a neighbourhood without a figure as average and you have just called the Marnixbuurt average. The property valuation is there — for 12,781 neighbourhoods — and income tracks it: not one for one but to the power of a half, measured across the 1,949 neighbourhoods that carry both. So an index does come out, tagged with the fact that it came from the valuation. A derived 1.10 and a measured 1.10 otherwise look identical, and they are not equally solid.

herkend_spending_potential(
  "bakker", "BU0363AB01")
→ potentieel_euro         1.116.423
  …_gecorrigeerd            944.704
  inkomensindex               1,102
  inkomensindex_bron
    AFGELEID UIT DE WOZ-WAARDE
    (1,21 keer het landelijke
     gemiddelde) — het CBS
    publiceert hier geen inkomen

The sports hall that came back as an empty cell

The land registry knows eleven building uses and this service returned six. A 92,391 square metre sports complex therefore came back with an empty breakdown: all of its floor area sat under a use that was not on the list. That held for 77,138 addresses, and a reader cannot see the difference between “zero” and “not measured”. There are eleven now, with sport, care, assembly, education and detention added. And the registry's 999,999 code, which means “floor area unknown” but looks like a floor area, no longer enters a sum: 1,849 addresses carry it, together good for 68.3% of all residential floor area in the database.

herkend_postcode_profile("5612AW")
→ adressen 1, objecten 2
  grootste_object_m2     92.229
  m2_per_gebruiksdoel
    { "sport": 92.391 }

The answer that looked certain

At zero degrees north and zero degrees east — the coast of Ghana — the transit question named Berlin-Spandau as the nearest station, at zero metres, with 297 departures per working day. Twenty-five German stops had arrived in the import without coordinates and were stored as (0, 0). That answer is worse than none: it is confident, detailed and wrong. A point outside the Netherlands now returns an error, asking whether latitude and longitude have been swapped — by far the most common cause. The same goes for an average over three unlike things: CBS publishes the sports participation figure three times per municipality, for 18 and over, for 18 to 65 and for 65 and over. In Emmen that is 43.8, 48.3 and 33.2 per cent, and the service took whichever row the database happened to return first. And the zoning question now takes the most recent adopted plan rather than the smallest polygon: in Ysbrechtum ten square metres decided that a plan from 2019 beat one from 2023.

herkend_transit(latitude=0, longitude=0)
→ fout: "het punt (0.0, 0.0) ligt buiten
  Nederland. Latitude loopt hier van 50,7
  tot 53,6 en longitude van 3,2 tot 7,3;
  controleer of ze niet verwisseld zijn.
  Deze dienst heeft alleen Nederlandse
  data: buiten die grenzen is elk antwoord
  dat eruit komt toeval."

All three are the same choice. And some of the industries get an explanation instead of an empty cell for exactly that reason — that is what the next section is about.

Naming the industry

An industry here is a word list, not an official code

Type “bakker” or “bakkerij” — it makes no difference. The dictionary holds 701 entries for 123 industries and maps them all onto the same head term, including the words you want kept out: “kapper” excludes the barber-supplies wholesaler. What does matter is that a word list is not an official classification, and the service says so every time — for bakers our wording counts 1.11 times what CBS counts under codes 1071 and 4724, for clothing shops 2.79 times.

74 industries with a demand side

What a household nationally spends on that category per year, from the national accounts. Bread 1,163 euros, clothing 2,467, books and stationery 482, dentist and physiotherapy together 1,024, childcare 665. Times the households in the catchment, and corrected for local income and household size.

And 46 without — with the reason

For the others the figure does not exist. You get no empty cell but the reason, and the denominator that does hold. Three kinds of reason, below.

The customer is not a household

A cleaning firm lives off offices, schools and care homes. Software, management consultancy and accountancy sit here too. The denominator is then the number of businesses in the area and their floor area, not the number of households.

CBS counts it together with something far bigger

A bicycle sits with the cars under “vehicle purchases”: 1,885 euros per household per year, and that is overwhelmingly cars. A taxi ride sits with trains, buses and plane tickets: 1,371 euros. A pot an order of magnitude too large is not an answer.

The market runs through insurance or a housing stock

GP care goes through the basic health insurance and barely shows up in household consumption; the demand side of a practice is the number of residents. The work of a plumber, painter or electrician comes largely from housing associations and new construction — households themselves spend 399 euros a year on maintaining their own home — so the denominator is the housing stock.

And one industry with no catchment at all

A webshop. Its market is the whole country and so is its competition, so spending potential within a ten-minute drive says nothing about it. You are told that, too, instead of getting a number.

A reason instead of an empty cell is the same choice as the betrouwbaarheid field: a model that knows why a figure is missing does not invent one.

The design principle

Every figure carries its own uncertainty

A dashboard shows “12 physiotherapy practices” and the reader supplies the doubt themselves. A language model handed a bare number has no such instinct and presents it as fact. That is why no aggregate leaves this server without an envelope.

{
  "aantal": 3,
  "noemer": "vestigingen in branche 'kapper' in Marnixbuurt-Noord
              (BU0363AB01, buurt), exclusief VvE's, holdings,
              inschrijvingen zonder eigen vestiging en records
              zonder bruikbaar adres",
  "genormaliseerd": { "per_1000_inwoners": 2.076,
                      "landelijk_per_1000": 2.05 },
  "betrouwbaarheid": "laag",
  "kanttekening": "N=3 is te klein om iets over de markt te zeggen;
                   branche-afbakening gebeurt op categorie- en vrije
                   tekst, niet op een gesloten bedrijfsindeling…",
  "bron": ["KVK Handelsregister", "CBS Kerncijfers Wijken en Buurten 2025"]
}

The field names come back in Dutch, exactly as the server sends them. aantal = count · noemer = denominator, what exactly was counted · genormaliseerd = normalised, per 1,000 residents next to the national figure · betrouwbaarheid = confidence, one of hoog (high), midden (medium) or laag (low) · kanttekening = caveat, written in Dutch · bron = source.

That betrouwbaarheid field is the product. A model that knows how certain a figure is gives a better answer than a dashboard that merely displays it.

What you can ask

39 tools, in the order you ask them

You need not know a single tool name: you ask in plain language and your client picks. They are listed here so you can see up front whether your question is covered. Want the whole study in one go? That is herkend_location_report — eight blocks in one answer, all over the same catchment area.

Who is registered here

9

“Who sits at this address, whose number is this, which branches does this chain have?”

  • herkend_find_company
  • herkend_search_companies
  • herkend_lookup_phone
  • herkend_companies_nearby
  • herkend_similar_companies
  • herkend_enrich_batch
  • herkend_find_by_social
  • herkend_company_group
  • herkend_address_profile

How crowded is the market

8

“How many competitors are there, how big are they, and where is the gap?”

  • herkend_resolve_branche
  • herkend_market_saturation
  • herkend_competitor_size
  • herkend_competition_radius
  • herkend_white_spots
  • herkend_colocation
  • herkend_compare_areas
  • herkend_location_score

Who lives and works there

9

“Who are my customers within a quarter-hour drive, and what do they spend?”

  • herkend_catchment
  • herkend_area_profile
  • herkend_postcode_profile
  • herkend_amenities
  • herkend_amenity_rings
  • herkend_transit
  • herkend_daytime_population
  • herkend_region_outlook
  • herkend_spending_potential

Which premises

4

“How many square metres is this, is catering allowed here, and which premises fit my requirements?”

  • herkend_building
  • herkend_floorspace
  • herkend_zoning
  • herkend_find_premises

Is the market moving

4

“Are businesses opening or closing, and how long does one last here?”

  • herkend_market_dynamics
  • herkend_industry_trend
  • herkend_survival_odds
  • herkend_opening_hours

The whole study in one call

1

“Do all of the above, for this trade in this spot.”

  • herkend_location_report

What the dataset does not know

4

“How solid is this figure, and where does the series break?”

  • herkend_count_companies
  • herkend_data_coverage
  • herkend_digital_presence
  • herkend_series_breaks
Before you start

What this service does not know

Four things, and they are here because knowing them makes for better questions. None of them is a hedge: all four were measured, and the figure is right there.

The register counts registrations, not competitors

It holds 3,858,162 establishments — the entire Dutch Chamber of Commerce register, so a count from it IS a national count. But a registration is not the same as a shop a customer walks into. Nationally 66.50% of the register sits at an address the buildings register knows only as a home. That varies enormously by trade: 11.5% for supermarkets, 58% for hairdressers, 91.7% for taxi firms. Ten taxi firms in a neighbourhood are nine living rooms. That is why every saturation figure carries this share alongside it — without it two trades cannot be compared.

There are no footfall counts

They do not exist as open data at the level of a single establishment, and that was measured: 0.62% of retail and hospitality establishments have a traffic counting point within a hundred metres, and in the busiest shopping centres — 1,371 establishments — it is 0.00%. Exactly where the passer-by IS the market, there is nothing. What does exist: departures per stop, population density, and jobs per neighbourhood. Ask about footfall and you get those three with the difference spelled out, not an estimate that looks precise.

There are no rents or transaction prices

For commercial space they are not public. Looked up and written down: zero hits across 5,956 CBS tables and 825 third-party tables, zero datasets on data.overheid.nl, and the land registry charges EUR 1.81 per commercial transaction. What you do get per address is the floor area, the use class and what the zoning plan allows. A price you will have to source yourself; we will not invent one.

The register is complete, the enrichment is not

Of all establishments 32.99% have a phone number and 27.87% a website. An empty field means “not found”, not “does not exist”, so judge such percentages against the group where something can be found rather than against the whole register. herkend_data_coverage gives those denominators per field, and every answer carries its own coverage.

What is above is why this service exists, not a disclaimer beneath it. A dashboard that leaves these four out looks more certain and is not.

How to connect

The server lives at https://mcp.herkend.nl/bedrijfsdata. You add it to your client as an external MCP server; after that you just ask your questions in the conversation.

  1. 1 If your client can open a browser — Claude, ChatGPT, Cursor, VS Code, Claude Code — you sign in with your Herkend account. You create no key yourself and copy nothing.
  2. 2 Working with curl, n8n or a server without a desktop? There is a personal key you send in the X-API-Key header.
  3. 3 Per connection you get 500 calls an hour and 50 MB of response per day. A thorough location study costs ten to thirty calls.
  4. 4 Looking first without connecting anything works too: the playground on mcp.herkend.nl runs the read-only tools, sixty questions an hour, no account.
The full manual, per client
What is inside

This build

3,858,162

establishments — the entire Business Register

1,272,877

with a phone number (32.99%)

14,729

CBS neighbourhoods with demographics

39

tools

8,026,974

buildings with floor area and use

2,587,453

zoning polygons

6,917

school addresses with pupil counts

2,104,524

CBS series values across 21 tables

This server is a proof of concept. You connect with a Herkend account; right now (September 2026) we charge nothing. There is a brake, though: 500 calls per hour and 50 MB of response per day per connection. A thorough location study costs ten to thirty calls, so a conversation never hits it; pulling the whole register does. The current limits are listed in limits.json, and they can change while this is a proof of concept.

Further reading

The manual

This page is the story. The manual on mcp.herkend.nl is the reference, and you can fire a question at it without connecting anything first.

The manual is in Dutch, like the field names the server returns.