registry-mcp
A company registry for AI agents — an MCP server and REST API over national business registries, any country.
First module: Norway — brreg / Brønnøysundregistrene / Enhetsregisteret. Look up a company by organisasjonsnummer (orgnr, org.nr), search by name, check MVA / VAT registration, and compute statutory filing deadlines. Also published as brreg-mcp, an alias package that installs exactly this server.
Status: pre-release (
0.1.0). The five tools and their response shapes are frozen; the hosted API atapi.foretak.devgoes live with the first release.
Add to Claude Code
claude mcp add registry-mcp --transport http https://api.foretak.dev/mcp
Or run it locally over stdio, no install step:
claude mcp add registry-mcp -- uvx registry-mcp
What it returns
$ curl https://api.foretak.dev/v1/NO/company/923609016
{
"country": "NO", "registry": "brreg",
"id": "923609016", "id_formatted": "923 609 016", "id_scheme": "organisasjonsnummer",
"name": "EQUINOR ASA",
"legal_form_code": "ASA", "legal_form": "Public limited company", "legal_form_local": "Allmennaksjeselskap",
"status": "active", "is_active": true, "registered_at": "1995-03-12",
"vat_registered": true, "vat_number": "NO923609016MVA", "vat_registered_at": "1989-07-01",
"employees": 21239, "share_capital": 5976872600.0, "share_capital_currency": "NOK",
"business_address": {"lines": ["Forusbeen 50"], "postal_code": "4035", "city": "STAVANGER"},
"source": "Enhetsregisteret (Brønnøysundregistrene)", "license": "NLOD 2.0"
}
Abridged — the full CompanyReport also carries previous_names, industry_codes, registers, purpose, parent_id, confidence, cached, fetched_at and notes. Every field is documented in llms-full.txt §5.
Tools
| Tool | What it does |
|---|---|
lookup_company(id, country="NO") |
Full CompanyReport for one company by national identifier |
search_company(name, country="NO", limit=10) |
SearchResult — candidates with identifiers, best first |
company_deadlines(id, country="NO", today=None) |
DeadlineReport — the next occurrence of each statutory filing obligation |
validate_company_id(id, country="NO") |
ValidationResult — checksum-validate an identifier with no network call |
list_countries() |
Which national registries are supported right now |
Plus the resource registry://rules/{country} (identifier rules, legal forms, deadline rules — read once instead of validating in a loop) and the prompt explain_company.
Configuration
Claude Code — .mcp.json in the project root
{
"mcpServers": {
"registry-mcp": {
"command": "uvx",
"args": ["registry-mcp"],
"env": { "REGISTRY_MCP_CONTACT_EMAIL": "you@example.com" }
}
}
}
Cursor — ~/.cursor/mcp.json (or .cursor/mcp.json in the project)
{
"mcpServers": {
"registry-mcp": {
"command": "uvx",
"args": ["registry-mcp"],
"env": { "REGISTRY_MCP_CONTACT_EMAIL": "you@example.com" }
}
}
}
Claude Desktop — claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"registry-mcp": {
"command": "uvx",
"args": ["registry-mcp"],
"env": { "REGISTRY_MCP_CONTACT_EMAIL": "you@example.com" }
}
}
}
npm instead of uvx — same server, Node launcher
{
"mcpServers": {
"registry-mcp": { "command": "npx", "args": ["-y", "registry-mcp"] }
}
}
npx registry-mcp shells out to uvx registry-mcp (falling back to pipx run registry-mcp), so Python 3.12+ and one of uv or pipx must be present.
Hosted, no local install — Streamable HTTP
{
"mcpServers": {
"registry-mcp": { "type": "http", "url": "https://api.foretak.dev/mcp" }
}
}
Environment variables — both optional:
| Variable | Meaning |
|---|---|
REGISTRY_MCP_CONTACT_EMAIL |
Contact address sent in the User-Agent to the national registry, as Brønnøysundregistrene asks of API clients. Unset means an anonymous client, which may be throttled or blocked upstream. |
REGISTRY_MCP_CACHE_PATH |
Path to the local SQLite response cache (24 h TTL). Defaults to ./data/cache.sqlite3. |
REST
Every tool has a REST twin returning the identical JSON document.
# One company by organisasjonsnummer
curl https://api.foretak.dev/v1/NO/company/923609016
# Search by name
curl "https://api.foretak.dev/v1/NO/search?q=equinor&limit=5"
# Statutory filing deadlines, from a date you choose
curl "https://api.foretak.dev/v1/NO/company/923609016/deadlines?today=2026-01-15"
# Checksum-validate an identifier — no upstream call, instant
curl https://api.foretak.dev/v1/NO/validate/923609016
# Which countries are live
curl https://api.foretak.dev/v1/countries
Machine-readable docs: /llms.txt, /llms-full.txt, /openapi.json.
Adding your country
Norway is one folder. Copy src/registry_mcp/registries/xx/ to registries/<cc>/, implement four methods, add one import line — nothing in core/ changes, and both surfaces plus the manifests light up for the new country automatically.
→ CONTRIBUTING.md — "Add your country", and the new country issue template to claim one first.
Development
uv sync --all-extras
uv run pytest # `-m "not live"` to skip the tests that hit the real registry
uv run mypy .
uv run ruff check .
Layout:
src/registry_mcp/core/ country-neutral models, Registry ABC, rules, date helpers
src/registry_mcp/registries/ one folder per country — no/ (Norway), xx/ (template)
src/registry_mcp/api/ FastAPI REST surface
src/registry_mcp/mcp/ FastMCP server (stdio + Streamable HTTP at /mcp)
Documents
NORBIZ_SPEC.md— technical spec of the Norwegian moduleDECISIONS.md— interface and schema decisionsKEYWORDS.md— the canonical alias listSUBMISSIONS.md— registry submission statuslegal/terms.md— terms of use and data attribution
Data source and licence
Norwegian data comes from Enhetsregisteret (Brønnøysundregistrene), published under NLOD 2.0; every response carries source, source_url and license so the attribution travels with the data. This project's own code is MIT licensed. Not affiliated with or endorsed by Brønnøysundregistrene.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file registry_mcp-0.1.0.tar.gz.
File metadata
- Download URL: registry_mcp-0.1.0.tar.gz
- Upload date:
- Size: 348.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5994d0515d6a2f99b4907a4177b44e0115f06b551499196b2392079139635ca7
|
|
| MD5 |
bfbfd1f2d2c4654a807be8e939a3c477
|
|
| BLAKE2b-256 |
b682fcb2f1b9c9b3d3f9efa373cd0b071c44cdd634c3786c510d26374c2fd8fd
|
File details
Details for the file registry_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: registry_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 83.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a608acdf5fd72e40b499737b6add48d4bd9b4b8594265eb3e2f2eacce690625
|
|
| MD5 |
eed397250023868fb563dc830d426608
|
|
| BLAKE2b-256 |
e0ad7c26f0a173a1c1018a6103ceb4f7e2d080c373d4e57748e6cf490daf62b0
|