brreg-mcp-server
MCP server for querying the Norwegian Brønnøysundregistrene business register, including companies, roles, subunits, and annual accounts, with built-in guards against common data traps like retired NACE codes and withheld employee counts.
README
brreg-mcp-server
The Norwegian business register for AI agents — companies, roles, subunits and annual accounts — with the register's silent traps encoded as guards.
Brønnøysundregistrene's API is free, public and keyless. Fetching from it is easy — a 40-line script does it, faster than any MCP will. The problem is that the register lies quietly, and every trap returns a plausible number instead of an error:
naeringskode=96.02 → totalElements: 0 # "no hairdressers in Oslo"?
naeringskode=96.210 → totalElements: 1283 # the code was renumbered. No error. No warning.
That is the whole reason this exists.
✨ Features
- Annual accounts (
regnskapsregisteret) — no other public brreg MCP covers them. - Retired-NACE guard — a zero result arrives with a hint naming the current code and its live match count. The query is never silently rewritten.
filed_no_revenue_line— holding companies filedriftsinntekter: {}(the key is absent, not zero, and not""). Arevenue >= Xfilter silently deletes every one of them; this status is how you notice.employees_min/employees_max— brreg hides every headcount below 5 from the payload, so filtering on theantallAnsattefield silently drops the small companies. The range filter sees them (219 Oslo hairdressers have 1–4 staff).antallAnsatte: nullmeans withheld, not unknown.INNHresolution — sole proprietorships have no board and no daglig leder. Looking only forDAGL/LEDEmakes ~78% of Norwegian small business look contactless.- VAT-sector warning —
registrertIMvaregisteretcosts ~a third of results in 96.x/93.x and deletes ~98% of genuine clinics under NACE 86.* (health is VAT-exempt by law). valutanever assumed — Equinor files in USD.- Privacy by default — no personal names unless you ask; birth dates never, even if you do.
- Contact data —
epostadresse,mobil,telefon,hjemmeside: sparse (~1 in 3 units) but real. For a sole proprietorship they are a private individual's personal details, and the tool says so. - Bulk by array — one call for many orgnrs, per-item partial success.
- No cache, no state, no telemetry — one outbound host,
data.brreg.no.
📋 Available Tools
| Tool | Does | Key params |
|---|---|---|
get_units |
Look up companies/branches by orgnr; resolves main-vs-branch for you and returns unit_type, contact fields, and is_natural_person |
orgnrs |
search_units |
Search by industry, municipality, name, org form, VAT or employee range; carries the guards | nace, kommune, navn, org_form, registrertIMvaregisteret, employees_min, employees_max, strict_location, cap |
get_roles |
Board, management and sole-proprietor owner. Structure only by default | orgnrs, include_persons |
get_financials |
Annual accounts, as a discriminated union you must read before the numbers | orgnrs, statement_type |
🚀 Quick Start
npm install && npm run build
npm run dev:mock # real offline mode — no network, every guard live
--mock is not a stub: it swaps the socket, not the code path, and its dataset is the register's traps (a USD filer, a holding company with no revenue line, an ENK, a dissolved unit, a 410, a retired NACE code). Everything on this page reproduces offline.
⌨️ CLI
The same handlers the MCP registers, over argv — src/cli.ts dispatches the identical buildTools() array, so a finding from one surface holds for the other.
brreg get_units --orgnrs 923609016
brreg search_units --nace 96.02 --kommune 0301 # watch it catch the retired code
brreg get_financials --orgnrs 918035443
brreg reference # field glossary + statutory sources
brreg self-test --mock # proves the install works offline
stdout is one JSON object (with elapsed_sec); diagnostics on stderr; usage errors exit 2, upstream failures exit 1. --orgnrs a --orgnrs b and --orgnrs a,b both work — bulk is the intended shape.
📚 Skill
skills/brreg/SKILL.md carries the domain knowledge an agent can't infer from a successful response — which silences are meaningful and which plausible number is wrong. The tools' guards always fire; the skill is what lets an agent go past the four tools when the question needs it.
🖥️ Claude Desktop
Download the .mcpb from Releases and double-click it. No terminal, no Node install, no API key — brreg needs no credentials.
<details> <summary>Claude Code / Cursor / any stdio client</summary>
dist/ is not committed, so build it once:
git clone https://github.com/nordio-ai/brreg-mcp-server
cd brreg-mcp-server && npm ci && npm run build
.mcp.json is committed and works when the client's working directory is the repo:
{ "mcpServers": { "brreg": { "command": "node", "args": ["./dist/stdio.js"] } } }
From anywhere else, give an absolute path to dist/stdio.js — the relative form above resolves against the client's cwd, not this file.
</details>
💬 Try it
"Look up 923609016 and tell me what the accounts say."
"Find hairdressers in Oslo, NACE 96.02." — watch it catch the retired code
"Which of these 50 companies has a real operator and filed accounts?"
🔍 Read this before trusting a number
| You see | It means |
|---|---|
total: 0 |
Maybe not "none exist." Check hints — the NACE code may be retired. |
driftsinntekter: null + filed_no_revenue_line |
Accounts filed, no operating revenue line. A holding company. Not zero revenue. |
status: not_applicable |
An ENK. Sole proprietorships never file. Not a red flag. |
antallAnsatte: null |
Withheld, not unknown — brreg never shows a value below 5. Use employees_min/employees_max to filter; antallAnsatte_reported says whether a hidden count exists. |
valuta: "USD" |
It happens. Never compare revenue across companies without reading it. |
deleted vs gone vs not_found |
Dissolved · removed on legal grounds · never existed. Three different facts. |
Read brreg://reference for the field glossary (with statutory sources), the retired-NACE table, and role codes.
📂 Paths & state
None. No config, no cache, no logs on disk, no state directory. Every read is live.
That is deliberate. brreg's documentation treats HTTP 410 as "en forespørsel om at eventuelle kopier/cacher også fjerner den aktuelle enheten" — an instruction to purge, not a status code. A cache is exactly what turns that into an obligation you can silently fail: the request that would reveal the erasure is the one a cache promises not to make. For an interactive connector caching buys almost nothing, so there isn't any — and a test fails if someone adds one.
🔄 Updating
Re-download the .mcpb from Releases. Version lives in package.json; see CHANGELOG.md.
Scope
Interactive discovery and targeted enrichment — tens to a couple of hundred results. Register-scale extraction (thousands of rows) is a non-goal: an MCP returns data through the model's context window, so a script will always win at that size. Use the API directly.
Also out of scope: kunngjøringer (no open REST API exists), fødselsnummer (needs Maskinporten), writes (brreg is read-only), and anything feeding a creditworthiness decision (that engages EU AI Act Annex III 5(b)).
Licence
MIT. Not affiliated with Brønnøysundregistrene.
Data © Brønnøysundregistrene, NLOD 2.0. NLOD is a copyright licence and explicitly excludes personal data — it is not a legal basis for processing the names in this register. If you bulk-harvest role data, you are the controller: you need your own basis (GDPR Art 6(1)(f)), an Art 14 notice at first contact, and an Art 21(2) suppression list. And note that ENK names are people — foretaksnavneloven §2-2 requires a sole proprietorship's registered name to contain the owner's surname, and ~74% of the register are ENKs.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。