Back to Browse

Dk Regnskab MCP Server

Developer ToolsLow Risk10.0MCP RegistryLocal
Free

Server data from the Official MCP Registry

Key figures, history and all tagged facts from Danish companies' annual reports (XBRL).

About

Key figures, history and all tagged facts from Danish companies' annual reports (XBRL).

Security Report

10.0
Low Risk10.0Low Risk

Valid MCP server (2 strong, 2 medium validity signals). No known CVEs in dependencies. Package registry verified. Imported from the Official MCP Registry.

6 files analyzed · 1 issue found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

HTTP Network Access

Connects to external APIs or services over the internet.

file_system

Check that this permission is expected for this type of plugin.

What You'll Need

Set these up before or after installing:

Optional. CVR register system-to-system username, only needed for search_company.Optional

Environment variable: CVR_USER

Optional. CVR register system-to-system password, only needed for search_company.Required

Environment variable: CVR_PASSWORD

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-mikkelmanniche-dk-dk-regnskab-mcp": {
      "env": {
        "CVR_USER": "your-cvr-user-here",
        "CVR_PASSWORD": "your-cvr-password-here"
      },
      "args": [
        "-y",
        "dk-regnskab-mcp"
      ],
      "command": "npx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

dk-regnskab-mcp

CI Release License: MIT

Give Claude (or any MCP client) the published annual reports of Danish companies: key figures for the latest year and the year before, read straight from the XBRL filings at the Danish Business Authority (Erhvervsstyrelsen). No API key needed.

Works for small companies (Danish GAAP) and listed ones (IFRS/ESEF, back to 2015), separates group and parent figures in group reports, and explains gaps instead of guessing. Tested live against about 300 real filings.

"What were revenue and equity for CVR 24256790 last year, and how did they change?"

Quickstart

Requires Node.js 22.18 or newer. No API key needed.

Claude Code

claude mcp add dk-regnskab -- npx -y dk-regnskab-mcp

Claude Desktop: add this to claude_desktop_config.json:

{
  "mcpServers": {
    "dk-regnskab": { "command": "npx", "args": ["-y", "dk-regnskab-mcp"] }
  }
}

Cursor: the same block goes in ~/.cursor/mcp.json (or .cursor/mcp.json in a project). Other MCP clients: run npx -y dk-regnskab-mcp over stdio.

From source

git clone https://github.com/mikkelmanniche-dk/dk-regnskab-mcp
cd dk-regnskab-mcp && npm install && npm run build
claude mcp add dk-regnskab -- node /absolute/path/to/dk-regnskab-mcp/dist/index.js

Tools

ToolInputReturns
search_companyquery (name or CVR number), optional limitMatching companies with CVR number, status, company type, industry, address and employee size band; active, exactly named and larger companies first. Needs CVR credentials, see below
list_filingscvr, optional limit (1–50), optional yearPublished filings, newest first, with document links
get_financialscvr, optional year (the year the reporting period ends in), optional scope (group or parent)Company name, period, currency, auditor, key figures (current and previous year), whether it is a group report, notes on gaps, source document URL
get_financials_historycvr, optional years (1–15), optional scopeKey figures per reporting year, newest first
get_report_factscvr, optional year, scope, match (part of a concept name), limitEvery figure and text tagged in the annual report, e.g. staff costs or dividends

All tools are read-only, declare an output schema and return structured content.

Key figures: revenue, gross profit, operating profit, profit before tax, profit for the year, average employees, total assets, current assets, cash, equity, liabilities.

Company name search (optional)

search_company uses the CVR register, which requires system-to-system credentials. They are free: apply at the Danish Business Authority, then pass them to the server:

claude mcp add dk-regnskab -e CVR_USER=... -e CVR_PASSWORD=... -- npx -y dk-regnskab-mcp

Everything else works without them. Note that the register, like the filing index, only answers over plain HTTP, so the credentials are sent unencrypted. They only give read access to public company data.

How it works

flowchart LR
  C[Claude / MCP client] -- stdio --> S[dk-regnskab-mcp]
  S -- "search by CVR" --> I[(distribution.virk.dk<br/>filing index)]
  S -- "download XBRL (gzip)" --> D[(Filing documents)]
  S --> P[Parse contexts & facts<br/>by namespace, not prefix]
  P --> F[Key figures + notes]

Pitfalls it handles

Real Danish filings are messier than the taxonomy suggests. The parser was built against actual filings:

  • Dimensional facts are not totals. A filing reports equity once in total and again per component (share capital, retained earnings). Only dimensionless contexts are used, so share capital is never reported as equity.
  • Conflicting values. Some filings report two different values for the same fact and period (e.g. 0 and 1 employees). The figure is left empty with a note instead of guessed.
  • Missing revenue is usually legal. Most small companies (reporting class B) may omit revenue and report gross profit. The result says so.
  • Namespace prefixes vary between filings, so concepts are matched by namespace URI.
  • Documents are gzip-compressed without saying so. Detected by magic bytes.
  • The document named "AARSRAPPORT" is not always the one with the numbers. Every XML document in a filing is parsed, and the one that yields the most figures wins.
  • Group reports hold two sets of figures. A parent company's report often includes the consolidated group too, and Danish GAAP and IFRS mark them in opposite ways. The group is returned by default; scope: "parent" gives the parent alone. Mixing them up can turn a group loss into a parent profit.
  • Balance check. If total assets don't equal liabilities and equity for the chosen scope, the result says so.
  • A last quarter next to the full year. Some annual reports also tag Q4, with the same end date as the year. The longest period wins.
  • Three generations of IFRS. ESEF (2021 onwards), the Danish IFRS extension before that (revenue as NetSales), and the 2011 IFRS taxonomy in filings before 2016. All three are read.
  • Currency comes from the figures themselves. Maersk reports in USD but mentions DKK elsewhere in the filing.
  • Old reports sit far down the list. Listed companies publish 4–5 filings a year, so a chosen year is filtered in the index, not in the first page of results. Interim reports that carry an annual-report document are skipped.
  • Company details can live in a sibling document, and some filers put HTML inside the company name. Both are handled.

Limitations

  • Name search needs CVR credentials (free, but you have to apply). Without them, look up the CVR number yourself, e.g. on datacvr.virk.dk.
  • Only companies that file machine-readable annual reports. Sole proprietorships and some other company types don't.
  • Only what the filer tagged: get_report_facts returns the tagged statements and details, not the untagged text of the notes or management's review.
  • IFRS filings don't tag the number of employees (it is text in the notes), so employees is empty for them.
  • The filing index answers over plain HTTP only, so the server must run locally or server-side, not in a browser.
  • Data terms: the filings are public data from the Danish Business Authority. Check their terms of use for your use case; this project does not make claims about them.

Tested against real filings

npm run measure runs the real tool path against about 300 companies that filed in the last year, plus a fixed set of large ones (LEGO, Arla, Carlsberg, Maersk, Novo Nordisk, older IFRS years, and a group report with both scopes). It needs network access and is not part of npm test.

Run on 25 September 2026 (v0.3.0): 311 lookups, 309 parsed, 2 companies without an XBRL annual report, 0 errors, 0 balance mismatches, median 118 ms per lookup.

Development

npm test          # parser tests against synthetic fixtures (no network)
npm run measure   # live check against real filings (network)
npm run typecheck
npm run build
npm run ci         # typecheck + test + build, som CI

Run npm run ci before merging; it mirrors .github/workflows/ci.yml. CI tests on Node 22 and 24; locally it runs on whichever Node you have.

Roadmap

  • Company name search via the CVR register
  • Multi-year history in one call
  • Published to npm and the official MCP Registry

License

MIT. Built by Mikkel Manniche.

Reviews

No reviews yet

Be the first to review this server!