@foretak/brreg-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -0
- package/bin/brreg-mcp.js +112 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# @foretak/brreg-mcp
|
|
2
|
+
|
|
3
|
+
**MCP server for brreg — Norwegian company lookup in Brønnøysundregistrene / Enhetsregisteret by organisasjonsnummer (orgnr, org.nr).**
|
|
4
|
+
|
|
5
|
+
This is an **alias package**. It contains no logic: it launches the Python
|
|
6
|
+
server published on PyPI as [`brreg-mcp`](https://pypi.org/project/brreg-mcp/),
|
|
7
|
+
which is itself an alias of
|
|
8
|
+
[`registry-mcp`](https://pypi.org/project/registry-mcp/) — the same five tools,
|
|
9
|
+
the same entry point. Install whichever name you searched for; you get the same
|
|
10
|
+
server. You need **Python 3.12+** and one of **`uv`** or **`pipx`** on your PATH.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uvx brreg-mcp # identical to: uvx registry-mcp
|
|
14
|
+
npx -y @foretak/brreg-mcp # the same, launched from Node
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Add to Claude Code
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
claude mcp add brreg-mcp -- uvx brreg-mcp
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"mcpServers": {
|
|
26
|
+
"brreg-mcp": {
|
|
27
|
+
"command": "uvx",
|
|
28
|
+
"args": ["brreg-mcp"],
|
|
29
|
+
"env": { "REGISTRY_MCP_CONTACT_EMAIL": "you@example.com" }
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The same block works for Cursor (`~/.cursor/mcp.json`) and Claude Desktop
|
|
36
|
+
(`claude_desktop_config.json`). No install at all, using the hosted server:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
claude mcp add brreg-mcp --transport http https://api.foretak.dev/mcp
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Tools
|
|
43
|
+
|
|
44
|
+
| Tool | What it does |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `lookup_company(id, country="NO")` | Full report for one company by organisasjonsnummer |
|
|
47
|
+
| `search_company(name, country="NO", limit=10)` | Find a Norwegian company by name |
|
|
48
|
+
| `company_deadlines(id, country="NO", today=None)` | Årsregnskap, skattemelding, mva-melding, a-melding and the rest, next occurrence of each |
|
|
49
|
+
| `validate_company_id(id, country="NO")` | MOD11-validate an orgnr with no network call |
|
|
50
|
+
| `list_countries()` | Which national registries are supported |
|
|
51
|
+
|
|
52
|
+
```console
|
|
53
|
+
$ curl https://api.foretak.dev/v1/NO/company/923609016
|
|
54
|
+
{"country": "NO", "registry": "brreg", "id": "923609016", "name": "EQUINOR ASA",
|
|
55
|
+
"legal_form_code": "ASA", "status": "active", "vat_registered": true,
|
|
56
|
+
"vat_number": "NO923609016MVA", "employees": 21239, "license": "NLOD 2.0"}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Full documentation, REST endpoints, and the guide to adding another country:
|
|
60
|
+
**https://github.com/foretak/registry-mcp**
|
|
61
|
+
|
|
62
|
+
## Data source and licence
|
|
63
|
+
|
|
64
|
+
Data from Enhetsregisteret (Brønnøysundregistrene) under NLOD 2.0. Code MIT
|
|
65
|
+
licensed. Not affiliated with or endorsed by Brønnøysundregistrene.
|
package/bin/brreg-mcp.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* brreg-mcp — Node launcher for the Python MCP server.
|
|
4
|
+
*
|
|
5
|
+
* `brreg-mcp` is an alias of `registry-mcp`: the *same* server, published under
|
|
6
|
+
* the name an agent generates when it needs Norwegian company data (KEYWORDS.md
|
|
7
|
+
* §3). This launcher runs the identical Python console script, so the two
|
|
8
|
+
* commands are interchangeable — if they ever diverge, one of them is a bug.
|
|
9
|
+
*
|
|
10
|
+
* The npm package is scoped (`@foretak/brreg-mcp`) because the unscoped npm
|
|
11
|
+
* name `brreg-mcp` was already taken in April 2026 by an unrelated project
|
|
12
|
+
* (`hellosverre/brreg-mcp`). The *PyPI* name `brreg-mcp` is ours and is what
|
|
13
|
+
* SPEC below refers to; the `bin` name stays `brreg-mcp` either way. See
|
|
14
|
+
* SUBMISSIONS.md § Prerequisites.
|
|
15
|
+
*
|
|
16
|
+
* Pure stdio passthrough: the child inherits this process's stdin, stdout and
|
|
17
|
+
* stderr, so the JSON-RPC stream is never buffered, parsed or re-encoded here.
|
|
18
|
+
*
|
|
19
|
+
* Resolution order:
|
|
20
|
+
* 1. `uvx --from brreg-mcp==<version> brreg-mcp`
|
|
21
|
+
* 2. `pipx run --spec brreg-mcp==<version> brreg-mcp`
|
|
22
|
+
* 3. print an install hint on stderr and exit 1
|
|
23
|
+
*
|
|
24
|
+
* Availability is probed with `--version` *before* the real spawn, so a missing
|
|
25
|
+
* launcher never consumes a byte of the caller's stdin.
|
|
26
|
+
*
|
|
27
|
+
* Env:
|
|
28
|
+
* BRREG_MCP_SPEC override the Python requirement (a version specifier, a
|
|
29
|
+
* path to a wheel, or a VCS URL). Used by CI and for testing
|
|
30
|
+
* against a locally built wheel.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
"use strict";
|
|
34
|
+
|
|
35
|
+
const { spawn, spawnSync } = require("node:child_process");
|
|
36
|
+
|
|
37
|
+
const VERSION = require("../package.json").version;
|
|
38
|
+
const SPEC = process.env.BRREG_MCP_SPEC || `brreg-mcp==${VERSION}`;
|
|
39
|
+
const ARGS = process.argv.slice(2);
|
|
40
|
+
|
|
41
|
+
/** True if `cmd --version` runs and exits 0. Never touches stdin. */
|
|
42
|
+
function isAvailable(cmd) {
|
|
43
|
+
const probe = spawnSync(cmd, ["--version"], {
|
|
44
|
+
stdio: "ignore",
|
|
45
|
+
shell: process.platform === "win32",
|
|
46
|
+
});
|
|
47
|
+
return !probe.error && probe.status === 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const INSTALL_HINT = [
|
|
51
|
+
"brreg-mcp: no Python launcher found.",
|
|
52
|
+
"",
|
|
53
|
+
"This package is a thin wrapper around the Python MCP server on PyPI.",
|
|
54
|
+
"It needs Python 3.12+ and one of `uv` or `pipx` on your PATH.",
|
|
55
|
+
"",
|
|
56
|
+
" Install uv (recommended):",
|
|
57
|
+
" curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux",
|
|
58
|
+
" powershell -c \"irm https://astral.sh/uv/install.ps1 | iex\" # Windows",
|
|
59
|
+
"",
|
|
60
|
+
" ...or install pipx:",
|
|
61
|
+
" python3 -m pip install --user pipx",
|
|
62
|
+
"",
|
|
63
|
+
"Then re-run `npx brreg-mcp`, or skip Node entirely:",
|
|
64
|
+
" uvx brreg-mcp",
|
|
65
|
+
"",
|
|
66
|
+
"Or use the hosted server, which needs nothing installed at all:",
|
|
67
|
+
" claude mcp add brreg-mcp --transport http https://api.foretak.dev/mcp",
|
|
68
|
+
"",
|
|
69
|
+
"Docs: https://github.com/foretak/registry-mcp",
|
|
70
|
+
].join("\n");
|
|
71
|
+
|
|
72
|
+
/** Candidate launchers, in order of preference. */
|
|
73
|
+
const CANDIDATES = [
|
|
74
|
+
{ cmd: "uvx", args: ["--from", SPEC, "brreg-mcp", ...ARGS] },
|
|
75
|
+
{ cmd: "pipx", args: ["run", "--spec", SPEC, "brreg-mcp", ...ARGS] },
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
const chosen = CANDIDATES.find((c) => isAvailable(c.cmd));
|
|
79
|
+
|
|
80
|
+
if (!chosen) {
|
|
81
|
+
process.stderr.write(INSTALL_HINT + "\n");
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const child = spawn(chosen.cmd, chosen.args, {
|
|
86
|
+
stdio: "inherit",
|
|
87
|
+
shell: process.platform === "win32",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
child.on("error", (err) => {
|
|
91
|
+
process.stderr.write(
|
|
92
|
+
`brreg-mcp: failed to start \`${chosen.cmd}\`: ${err.message}\n\n` +
|
|
93
|
+
INSTALL_HINT +
|
|
94
|
+
"\n"
|
|
95
|
+
);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Forward the signals an MCP client uses to shut a stdio server down.
|
|
100
|
+
for (const sig of ["SIGINT", "SIGTERM", "SIGHUP"]) {
|
|
101
|
+
process.on(sig, () => {
|
|
102
|
+
if (!child.killed) child.kill(sig);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
child.on("exit", (code, signal) => {
|
|
107
|
+
if (signal) {
|
|
108
|
+
process.kill(process.pid, signal);
|
|
109
|
+
} else {
|
|
110
|
+
process.exit(code === null ? 1 : code);
|
|
111
|
+
}
|
|
112
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@foretak/brreg-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for brreg — look up Norwegian companies in Brønnøysundregistrene / Enhetsregisteret by organisasjonsnummer (orgnr, org.nr): status, VAT (MVA) registration and filing deadlines. Alias package for registry-mcp.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"brreg",
|
|
7
|
+
"brønnøysund",
|
|
8
|
+
"brønnøysundregistrene",
|
|
9
|
+
"bronnoysund",
|
|
10
|
+
"bronnoysundregistrene",
|
|
11
|
+
"enhetsregisteret",
|
|
12
|
+
"organisasjonsnummer",
|
|
13
|
+
"orgnr",
|
|
14
|
+
"org.nr",
|
|
15
|
+
"foretak",
|
|
16
|
+
"norway",
|
|
17
|
+
"norway-company-lookup",
|
|
18
|
+
"norwegian-business-registry",
|
|
19
|
+
"company-registry",
|
|
20
|
+
"company-lookup",
|
|
21
|
+
"company-data",
|
|
22
|
+
"business-registry",
|
|
23
|
+
"vat",
|
|
24
|
+
"mva",
|
|
25
|
+
"mcp",
|
|
26
|
+
"mcp-server",
|
|
27
|
+
"modelcontextprotocol",
|
|
28
|
+
"model-context-protocol",
|
|
29
|
+
"ai-agents"
|
|
30
|
+
],
|
|
31
|
+
"homepage": "https://github.com/foretak/registry-mcp#readme",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/foretak/registry-mcp/issues"
|
|
34
|
+
},
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"author": "Kim",
|
|
37
|
+
"type": "commonjs",
|
|
38
|
+
"bin": {
|
|
39
|
+
"brreg-mcp": "bin/brreg-mcp.js"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"bin/",
|
|
43
|
+
"README.md"
|
|
44
|
+
],
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "git+https://github.com/foretak/registry-mcp.git",
|
|
48
|
+
"directory": "packages/npm/brreg-mcp"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18"
|
|
52
|
+
},
|
|
53
|
+
"os": [
|
|
54
|
+
"darwin",
|
|
55
|
+
"linux",
|
|
56
|
+
"win32"
|
|
57
|
+
],
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"access": "public"
|
|
60
|
+
}
|
|
61
|
+
}
|