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.
“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.
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 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 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) 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 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) 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 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.
Weigh it up
A score across four axes — and never the total alone, because the weights are a choice, not a measurement.
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.
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.
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.
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_companyherkend_search_companiesherkend_lookup_phoneherkend_companies_nearbyherkend_similar_companiesherkend_enrich_batchherkend_find_by_socialherkend_company_groupherkend_address_profile
How crowded is the market
8“How many competitors are there, how big are they, and where is the gap?”
herkend_resolve_brancheherkend_market_saturationherkend_competitor_sizeherkend_competition_radiusherkend_white_spotsherkend_colocationherkend_compare_areasherkend_location_score
Who lives and works there
9“Who are my customers within a quarter-hour drive, and what do they spend?”
herkend_catchmentherkend_area_profileherkend_postcode_profileherkend_amenitiesherkend_amenity_ringsherkend_transitherkend_daytime_populationherkend_region_outlookherkend_spending_potential
Which premises
4“How many square metres is this, is catering allowed here, and which premises fit my requirements?”
herkend_buildingherkend_floorspaceherkend_zoningherkend_find_premises
Is the market moving
4“Are businesses opening or closing, and how long does one last here?”
herkend_market_dynamicsherkend_industry_trendherkend_survival_oddsherkend_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_companiesherkend_data_coverageherkend_digital_presenceherkend_series_breaks
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 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 Working with curl, n8n or a server without a desktop? There is a personal key you send in the
X-API-Keyheader. - 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 Looking first without connecting anything works too: the playground on mcp.herkend.nl runs the read-only tools, sixty questions an hour, no account.
This build
establishments — the entire Business Register
with a phone number (32.99%)
CBS neighbourhoods with demographics
tools
buildings with floor area and use
zoning polygons
school addresses with pupil counts
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.
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.
Every tool with its parameters
Each tool expanded: what it takes, what it returns and what it is not meant for.
Try it without a key
A playground with the read-only analysis tools, sixty questions an hour, no account.
What the dataset does not know
The limits of the wording and the coverage, with the figures alongside.
Where it all comes from
Every source with its reference date and licence: KVK, CBS, BAG, DUO, police, NDW.
The manual is in Dutch, like the field names the server returns.