{"name":"io.github.foretak/registry-mcp","slug":"foretak-registry-mcp","title":"registry-mcp — national company registries","description":"The company registry MCP: brreg orgnr, Companies House, Bolagsverket organisationsnummer.","url":"https://mcp.market/server/foretak-registry-mcp","rating":null,"grade":"A","score":90,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":34,"stars":0,"forks":0,"downloads_week":164,"last_push_at":"2026-09-10T13:43:58.000Z","license":"MIT"},"uptime":{"percent":100,"checks":6,"ok":6,"last_checked_at":"2026-09-20T22:16:00.620Z","last_ok_at":"2026-09-20T22:16:00.620Z","latency_ms":222},"claimed":false,"transport":"mixed","callable_via_gateway":true,"default_price_micros":0,"repository":"https://github.com/foretak/registry-mcp","website":"https://api.foretak.dev","version":"0.4.2","remotes":[{"type":"streamable-http","url":"https://api.foretak.dev/mcp"}],"packages":[{"registryType":"pypi","registryBaseUrl":"https://pypi.org","identifier":"registry-mcp","version":"0.4.2","runtimeHint":"uvx","transport":{"type":"stdio"},"environmentVariables":[{"description":"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 blocked upstream.","format":"string","placeholder":"you@example.com","name":"REGISTRY_MCP_CONTACT_EMAIL"},{"description":"Path to the local SQLite response cache (24 h TTL). Defaults to ./data/cache.sqlite3.","format":"filepath","placeholder":"./data/cache.sqlite3","name":"REGISTRY_MCP_CACHE_PATH"},{"description":"Companies House REST API key, required for the United Kingdom (GB). Free from developer.company-information.service.gov.uk. Unset means GB lookups return an upstream_error naming this variable; every other country still answers.","format":"string","isSecret":true,"name":"COMPANIES_HOUSE_API_KEY"},{"description":"Bolagsverket OAuth 2 client id, required for Sweden (SE) together with BOLAGSVERKET_CLIENT_SECRET. Free, no contract: request both from Bolagsverket's kundanmälan form. Unset means SE lookups return an upstream_error naming both variables; every other country still answers.","format":"string","isSecret":true,"name":"BOLAGSVERKET_CLIENT_ID"},{"description":"Bolagsverket OAuth 2 client secret, the other half of BOLAGSVERKET_CLIENT_ID. Both are needed before Sweden (SE) can answer.","format":"string","isSecret":true,"name":"BOLAGSVERKET_CLIENT_SECRET"},{"description":"Which Bolagsverket environment the Swedish credentials belong to: 'production' (default) or 'test'. It selects the data host and the token host as a pair, so the two can never be mixed.","format":"string","name":"BOLAGSVERKET_ENVIRONMENT"}]},{"registryType":"npm","registryBaseUrl":"https://registry.npmjs.org","identifier":"registry-mcp","version":"0.4.2","runtimeHint":"npx","transport":{"type":"stdio"},"environmentVariables":[{"description":"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 blocked upstream.","format":"string","placeholder":"you@example.com","name":"REGISTRY_MCP_CONTACT_EMAIL"},{"description":"Companies House REST API key, required for the United Kingdom (GB). Free from developer.company-information.service.gov.uk. Unset means GB lookups return an upstream_error naming this variable; every other country still answers.","format":"string","isSecret":true,"name":"COMPANIES_HOUSE_API_KEY"},{"description":"Bolagsverket OAuth 2 client id, required for Sweden (SE) together with BOLAGSVERKET_CLIENT_SECRET. Free, no contract: request both from Bolagsverket's kundanmälan form. Unset means SE lookups return an upstream_error naming both variables; every other country still answers.","format":"string","isSecret":true,"name":"BOLAGSVERKET_CLIENT_ID"},{"description":"Bolagsverket OAuth 2 client secret, the other half of BOLAGSVERKET_CLIENT_ID. Both are needed before Sweden (SE) can answer.","format":"string","isSecret":true,"name":"BOLAGSVERKET_CLIENT_SECRET"},{"description":"Which Bolagsverket environment the Swedish credentials belong to: 'production' (default) or 'test'. It selects the data host and the token host as a pair, so the two can never be mixed.","format":"string","name":"BOLAGSVERKET_ENVIRONMENT"}]}],"tools":[{"name":"company_deadlines","description":"Give the next occurrence of each statutory filing deadline a company faces.\n\n`country=\"NO\"` covers the Norwegian calendar (Regnskapsregisteret, Skatteetaten) for a\ncompany looked up by organisasjonsnummer (orgnr, org.nr) in Brønnøysundregistrene /\nEnhetsregisteret (brreg): årsregnskap, generalforsamling, skattemelding,\naksjonærregisteroppgaven, mva-melding, a-melding. `country=\"GB\"` covers the two\nCompanies House obligations for a company number (CRN): the annual accounts filing and\nthe confirmation statement (CS01). `country=\"SE\"` covers the two Swedish obligations of\nan aktiebolag (AB) or ekonomisk förening (EK) looked up by organisationsnummer at\nBolagsverket: the ordinary general meeting (ordinarie bolagsstämma / årsstämma) at six\nmonths from the financial year end, and the annual report (årsredovisning) at seven,\nwhere the late-filing fee (förseningsavgift) begins.\n\nPass `today` (`YYYY-MM-DD`) for a reproducible answer; it defaults to the server's\ncurrent UTC date. Quote `due_date`, not `statutory_date`, and quote each deadline's\n`applies_because` rather than presenting a date as unconditional fact — that sentence\ncarries the legal form or flag the date rests on, its statute, any assumption still in\nit, and for the UK whether it is Companies House's own figure or one computed here.\n`days_until` goes negative for a filing Companies House still shows as overdue. Swedish\ndates assume a financial year ending 31 December unless you pass `include=[\"filings\"]`,\nwhich substitutes the year end of the last filed annual report where Bolagsverket's\ndocument list holds one; the filing date is an outer limit regardless, since a company\nwhose general meeting was earlier must file earlier. An empty `deadlines` list is a real\nanswer — a bankrupt, deleted or compulsorily-liquidated entity, a branch/sub-unit, or\nany company whose status is not active — and `notes` explains why.\n`registry://rules/{country}` carries each country's full deadline rules, roll-forward\ntreatment and legal sources. `rules_last_reviewed` names the date this country's\nstatutes and day-count arithmetic were last checked against the law — a deadline\ncomputed long after that date should be re-verified before anyone acts on it.\n\nErrors are the `{\"error\": {\"code\", \"message\", \"hint\"}}` envelope this server's\ninstructions set out code by code; `hint` names the next call. This tool looks the\nentity up first, so any `lookup_company` error code can surface here too.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"id":{"description":"The company's national identifier, normalised for you — a Norwegian organisasjonsnummer (orgnr), a Companies House company number (CRN), or a Swedish organisationsnummer or personnummer. Spaces, dots, hyphens, a NO...MVA suffix and a short CRN are accepted; list_countries gives each country's exact shape.","examples":["923609016","00445790"],"type":"string"},"country":{"default":"NO","description":"ISO-3166-1 alpha-2 — NO Norway, GB United Kingdom, SE Sweden. UK is not a country code here and is rejected. Call list_countries for the live set.","type":"string"},"today":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Date to compute deadlines from, YYYY-MM-DD; defaults to the server's current UTC date. Anything else is a bad_request naming the format.","examples":["2026-10-01"]},"include":{"default":[],"description":"Attachment names that can change a *computed* deadline — narrower than lookup_company's include. Today only 'filings': one extra upstream request for the entity's filing history, supplying a real financial year end where 31 December would otherwise be assumed. Empty by default; Norway and the United Kingdom accept it and it changes nothing for them today. Any other value — including one lookup_company accepts, such as 'charges' — is a bad_request naming this tool's allowed set.","examples":[["filings"],[]],"items":{"type":"string"},"type":"array"}},"required":["id"],"additionalProperties":false}},{"name":"fetch","description":"ChatGPT connector alias; other clients should prefer `lookup_company` plus\n`company_deadlines`, which return the CompanyReport and DeadlineReport shapes directly.\nTakes one `id` from `search` — \"{COUNTRY}:{identifier}\", e.g. \"NO:923609016\" — and\nreturns that company's register record and statutory filing deadlines as readable text,\nboth full JSON documents in `metadata`.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"id":{"description":"An `id` from a `search` result: '{COUNTRY}:{identifier}', e.g. 'NO:923609016' or 'GB:00445790'.","examples":["NO:923609016","GB:00445790"],"type":"string"}},"required":["id"],"additionalProperties":false}},{"name":"list_countries","description":"List every national company registry this service can answer for right now, with each\none's identifier scheme, source URL, licence, `supported_includes`, and whether the\nupstream register needs a credential (`requires_api_key`, `api_key_env`).\n\nCall it before your first lookup in a country you have not used here, whenever a user\nnames a country you are unsure of, or before guessing an `include` value — never\nhard-code a country list of your own, since it grows as modules are added. Stub modules\nare hidden; only registries that actually answer are listed. No error mode.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"additionalProperties":false}},{"name":"lookup_company","description":"Look up a company by its national identifier and get the full CompanyReport — legal\nform, status, address, VAT registration where the register publishes it, board and\naccounts duties, employees, and more.\n\n`country=\"NO\"` is the norway company lookup for the norwegian business registry:\nBrønnøysundregistrene / Enhetsregisteret (brreg), by organisasjonsnummer (orgnr,\norg.nr). `country=\"GB\"` is the uk company lookup at Companies House, by company number\n(company registration number, CRN) — \"UK\" is not a country code here. `country=\"SE\"` is\nthe swedish company lookup at Bolagsverket, by organisationsnummer or a sole trader's\n(enskild näringsidkare) personnummer, and by identifier only, since Bolagsverket's free\nAPI has no name search.\n\n`include=[...]` attaches seven second fetches, each with its own provenance and\n`null` unless you ask: `filings` (filing history — do they file, and on time),\n`charges` (registered mortgages and security interests), `insolvency` (winding-up\nand administration), `financials` (annual accounts — turnover, operating result,\nprofit, balance sheet: the solvency question), `lei` (the GLEIF Legal Entity\nIdentifier), `parents` (direct and ultimate parent — this entity's group — from\nGLEIF) and `peppol` (whether an e-invoice would reach them, ahead of Norway's 1\nJanuary 2027 EHF duty). The `include` argument explains each: what it returns, which\ncountries declare it, how to read its nulls.\n\nUse it once you have the identifier — from the user, an invoice, a contract, or a\n`search_company` hit's `id`. Read the returned `notes` before acting: it carries\ncaveats such as bankruptcy, dissolution, a deleted entity, an unclassified legal\nform, or an attachment whose own fetch failed.\n\nThis tool does not perform sanctions, PEP or adverse-media screening, and it does not\nverify bank account details — it returns identity and filing data from the national\nregister only, never a compliance clearance or a confirmed payment detail.\n\nErrors are the `{\"error\": {\"code\", \"message\", \"hint\"}}` envelope this server's\ninstructions set out code by code (D-007); `hint` names the next call. A failed\n*attachment* fetch is not one of them: the base report still comes back, that block\nis left `null`, and `notes` says which attachment failed and why.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"id":{"description":"The company's national identifier, normalised for you — a Norwegian organisasjonsnummer (orgnr), a Companies House company number (CRN), or a Swedish organisationsnummer or personnummer. Spaces, dots, hyphens, a NO...MVA suffix and a short CRN are accepted; list_countries gives each country's exact shape.","examples":["923609016","00445790"],"type":"string"},"country":{"default":"NO","description":"ISO-3166-1 alpha-2 — NO Norway, GB United Kingdom, SE Sweden. UK is not a country code here and is rejected. Call list_countries for the live set.","type":"string"},"include":{"default":[],"description":"Attachment names to fetch alongside the base report; empty by default, which costs exactly one upstream request. Each is a second, independent fetch attached at that name with its own provenance, null unless you ask, and this argument is where each of the seven is explained. 'filings' (every country): what the entity has filed, and when — Companies House the whole filing history, Bolagsverket the filed annual reports, Regnskapsregisteret the filed annual accounts; the block's notes says which, and total_count how many more the register holds. 'charges' (GB): registered mortgages and other security interests, in the register's own words. 'insolvency' (GB): winding-up and administration proceedings — a members' voluntary liquidation is a *solvent* wind-up, so is_liquidation: true is not by itself evidence of distress. 'financials' (NO and SE): the register's own figures for the latest filed accounting period — turnover, operating result, profit, balance sheet, equity, liabilities, each beside its currency, never a ratio or a verdict. Norway's come in the 'filings' fetch, Sweden's out of the entity's own filed K2 annual report. A null figure in a present block means the company did not report that line; an absent block means you did not ask, the fetch failed, or — Sweden — it has filed no digital annual report, and notes says which. Britain does not declare it, so 'financials' for GB is a bad_request, never an empty block. 'lei' (every country except Sweden, whose identifier can be a natural person's): the Legal Entity Identifier GLEIF, the Global LEI Foundation, publishes — CC0 and keyless; lei: null in a present block means GLEIF holds none. 'parents' (same countries as 'lei'): the direct and ultimate parent from GLEIF's Level 2 data — the entity that consolidates this one's accounts into its group, not necessarily its majority shareholder. Where GLEIF discloses none, that side carries the entity's own stated reason as a category word such as 'NATURAL_PERSONS' — never a name, and unverified. 'peppol' (Norway): whether an e-invoice can reach the entity over the Peppol network, read live from the SML/SMP walk the way ELMA resolves it, ahead of the 1 January 2027 EHF (Peppol BIS Billing 3.0) duty. registered: null means no authoritative answer — never read it as \"no\"; only an NXDOMAIN or an SMP 404 earns false. Read a country's supported_includes from list_countries first: a value it does not declare is a bad_request naming what it does support, never an empty result.","examples":[["filings"],["charges","insolvency"],["financials","lei"]],"items":{"type":"string"},"type":"array"}},"required":["id"],"additionalProperties":false}},{"name":"search","description":"ChatGPT connector alias; other clients should prefer `search_company`, which takes an\nexplicit `country` and returns the full SearchResult. One free-text query — a name, an\nidentifier, or either plus a country — across Norway, the United Kingdom and Sweden.\nReturns {\"results\": [{\"id\", \"title\", \"url\"}]}; pass a result's `id` to `fetch`.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"query":{"description":"A company name, a national identifier, or either plus a country.","examples":["Equinor","923609016","Tesco GB"],"type":"string"}},"required":["query"],"additionalProperties":false}},{"name":"search_company","description":"Search a national company register by name, when you have a name rather than an\nidentifier.\n\n`country=\"NO\"` searches Brønnøysundregistrene / Enhetsregisteret (brreg) — the norway\ncompany lookup for the norwegian business registry when the organisasjonsnummer (orgnr,\norg.nr) is not yet known; `country=\"GB\"` is the uk company search at Companies House,\nreturning each hit's company number (company registration number, CRN).\n\n**Sweden cannot be searched by name.** Bolagsverket's free API has four operations and\nnone takes a company name, so `country=\"SE\"` raises `not_implemented` — a fact about\nthe register, not a temporary gap, and it will not start working. Sweden supports\nlookup by identifier only: call `lookup_company` with the ten-digit\norganisationsnummer (or a sole trader's twelve-digit personnummer), or\n`validate_company_id` first to check the shape for free. Bolagsverket publishes the\nwhole register as bulk downloadable files for callers who must search by name.\n\nThen call `lookup_company` with the `id` of the right hit for the full report — a\nsearch hit is deliberately thin (name, legal form, status, city) and must not be acted\non directly. Hits arrive in the register's own relevance order, so read each hit's\n`confidence` rather than assuming the first row is best. Zero hits is not an error, and\n`hint` says what to try next — Norwegian names are registered upper-case and often carry\nan 'AS', 'ASA' or 'NUF' suffix, UK names a 'LIMITED', 'LTD', 'PLC' or 'LLP' one, worth\ndropping before concluding a company does not exist.\n\nErrors are the `{\"error\": {\"code\", \"message\", \"hint\"}}` envelope this server's\ninstructions set out code by code; `hint` names the next call. Call `list_countries`\nif you are unsure a country is supported.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"name":{"description":"Company name to search for, free text — not an identifier. Use lookup_company once you have the id of the right hit.","examples":["Equinor","Tesco"],"type":"string"},"country":{"default":"NO","description":"ISO-3166-1 alpha-2 — NO Norway, GB United Kingdom, SE Sweden. UK is not a country code here and is rejected. Call list_countries for the live set.","type":"string"},"limit":{"default":10,"description":"Maximum hits to return, 1-100; default 10. Outside that range is a bad_request, not a silent clamp.","examples":[10,50],"type":"integer"}},"required":["name"],"additionalProperties":false}},{"name":"validate_company_id","description":"Check whether a national company identifier is well-formed — no network call.\n\n`country=\"NO\"` checksum-checks a Norwegian organisasjonsnummer (orgnr, org.nr) for\nBrønnøysundregistrene / Enhetsregisteret (brreg) — the cheap norway company lookup\npre-check for the norwegian business registry. `country=\"GB\"` shape-checks and\nnormalises a UK company number (company registration number, CRN) for Companies House\n('445790' → '00445790', 'oc303675' → 'OC303675'); a CRN has no check digit, so a GB\n`valid: true` means the shape is right and nothing more. `country=\"SE\"` shape-checks and\nnormalises a Swedish organisationsnummer for Bolagsverket ('556016-0680' and\n'SE556016068001' both become '5560160680') and accepts a sole trader's twelve-digit\npersonnummer; Sweden's check digit is **not** enforced here (`registry://rules/SE` says\nwhy), so an `SE` `valid: true` means the shape is right, `reason` may carry a caveat,\nand the register's own verdict arrives on the lookup. It is the cheapest way to tell a\nten-digit Swedish organisationsnummer from a nine-digit Norwegian organisasjonsnummer.\n\nUse it on user input or a spreadsheet column before spending a real `lookup_company`\ncall, since it is instant and free.\n\nReturns a ValidationResult and never raises for a malformed identifier: `valid: false`\ncomes with `reason` and `hint` rather than a tool error — this tool answers a question,\nit does not fail on bad input (D-010). A valid identifier does not mean the entity\nexists; follow it with `lookup_company` if you need facts. The only error it raises is\n`unsupported_country`, in the usual `{\"error\": {\"code\", \"message\", \"hint\"}}` envelope —\ncall `list_countries`.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"id":{"description":"The company's national identifier, normalised for you — a Norwegian organisasjonsnummer (orgnr), a Companies House company number (CRN), or a Swedish organisationsnummer or personnummer. Spaces, dots, hyphens, a NO...MVA suffix and a short CRN are accepted; list_countries gives each country's exact shape.","examples":["923609016","00445790"],"type":"string"},"country":{"default":"NO","description":"ISO-3166-1 alpha-2 — NO Norway, GB United Kingdom, SE Sweden. UK is not a country code here and is rejected. Call list_countries for the live set.","type":"string"}},"required":["id"],"additionalProperties":false}}],"scan":{"score":90,"grade":"A","scanned_at":"2026-09-19T21:08:14.389Z","report":{"scannerVersion":"0.1.8","scannedAt":"2026-09-19T21:08:14.301Z","components":{"code":{"score":25,"max":25,"notes":["69 source files scanned","2 source files scanned"]},"reliability":{"score":20,"max":20,"notes":["remote reachable in 1044ms"]},"poisoning":{"score":13,"max":15,"notes":["7 tool descriptions checked"]},"auth":{"score":10,"max":15,"notes":["open endpoint, read-only tools"]},"maintenance":{"score":15,"max":15,"notes":["last push 9 days ago"]},"identity":{"score":7,"max":10,"notes":["registry namespace matches repository owner"]}},"findings":[{"id":"poison.long-description","severity":"low","component":"poisoning","title":"Unusually long tool description (over 2,000 characters)","evidence":"tool lookup_company: …Look up a company by its national identifier and get the full CompanyReport — legal form, status, address, VAT registration where the register publishes it, board and accounts duties, employees, and more. `country=\"NO\"` is the norway company lookup for the norwegian business registry: Brønnøysundregistrene / Enhetsregisteret (brreg), by organisasjonsnummer (orgnr, org.nr). `country=\"GB\"` is the uk company lookup at Companies House, by company number (company registration number, CRN) — \"UK\" is not a country code here. `country=\"SE\"` is the swedish company lookup at Bolagsverket, by organisationsnummer or a sole trader's (enskild näringsidkare) personnummer, and by identifier only, since Bolagsverket's free API has no name search. `include=[...]` attaches seven second fetches, each with its own provenance and `null` unless you ask: `filings` (filing history — do they file, and on time), `charges` (registered mortgages and security interests), `insolvency` (winding-up and administration), `financials` (annual accounts — turnover, operating result, profit, balance sheet: the solvency question), `lei` (the GLEIF Legal Entity Identifier), `parents` (direct and ultimate parent — this entity's group — from GLEIF) and `peppol` (whether an e-invoice would reach them, ahead of Norway's 1 January 2027 EHF duty). The `include` argument explains each: what it returns, which countries declare it, how to read its nulls. Use it once you have the identifier — from the user, an invoice, a contract, or a `search_company` hit's `id`. Read the returned `notes` before acting: it carries caveats such as bankruptcy, dissolution, a deleted entity, an unclassified legal form, or an attachment whose own fetch failed. This tool does not perform sanctions, PEP or adverse-media screening, and it does not verify bank account details — it returns identity and filing data from the national register only, never a compliance clearance or a confirmed payment detail. Errors are the `{\"error\": {\"code\", \"message\", \"hint\"}}` envelope this server's instructions set out code by code (D-007); `hint` names the next call. A failed *attachment* fetch is not one of them: the base report still comes back, that block is left `null`, and `notes` says which attachment failed and why.…"}],"inputs":{"probes":[{"url":"https://api.foretak.dev/mcp","reachable":true,"authRequired":false,"latencyMs":1044,"serverInfo":{"name":"registry-mcp","version":"0.4.2"}}],"packages":[{"registryType":"pypi","identifier":"registry-mcp","version":"0.4.2","found":true,"weeklyDownloads":98,"license":"MIT","dependencyCount":12,"publishedAt":"2026-09-10T07:41:47.831297Z","repositoryUrl":"https://github.com/foretak/registry-mcp"},{"registryType":"npm","identifier":"registry-mcp","version":"0.4.2","found":true,"license":"MIT","hasInstallScripts":false,"dependencyCount":0,"publishedAt":"2026-09-10T07:42:36.015Z","repositoryUrl":"git+https://github.com/foretak/registry-mcp.git","weeklyDownloads":66}],"repo":{"found":true,"owner":"foretak","repo":"registry-mcp","archived":false,"pushedAt":"2026-09-10T13:43:58Z","stars":0,"forks":0,"openIssues":3,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/324876927?v=4","ownerCreatedAt":"2026-09-04T10:46:14Z","license":"MIT"},"icon":{"url":"https://api.foretak.dev/icon.png","source":"registry","width":400,"height":400},"presence":{"stars":0,"forks":0,"downloadsWeek":164,"license":"MIT","lastPushAt":"2026-09-10T13:43:58.000Z","score":34}}}},"grade_history":[{"kind":"restore","fromGrade":"C","toGrade":"A","reason":"score 90: Unusually long tool description (over 2,000 characters)","createdAt":"2026-09-19T21:08:16.308Z"}],"reviews":[]}