dk-regnskab-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@dk-regnskab-mcpWhat were revenue and equity for CVR 24256790 last year?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
dk-regnskab-mcp
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.
"What were revenue and equity for CVR 24256790 last year, and how did they change?"
Quickstart
Requires Node.js 22.18 or newer.
git clone https://github.com/mikkelmanniche-dk/dk-regnskab-mcp
cd dk-regnskab-mcp && npm install && npm run buildClaude Code
claude mcp add dk-regnskab -- node /absolute/path/to/dk-regnskab-mcp/dist/index.jsClaude Desktop: add this to claude_desktop_config.json:
{
"mcpServers": {
"dk-regnskab": { "command": "node", "args": ["/absolute/path/to/dk-regnskab-mcp/dist/index.js"] }
}
}Related MCP server: Register UZ MCP Server
Tools
Tool | Input | Returns |
|
| Company name, period, currency, auditor, key figures (current and previous year), notes on gaps, source document URL |
|
| Published filings, newest first, with document links |
Key figures: revenue, gross profit, operating profit, profit before tax, profit for the year, average employees, total assets, current assets, cash, equity, liabilities.
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.
Two taxonomies. Danish GAAP for most companies, IFRS (ESEF) for listed ones. Both are supported.
Limitations
Lookup by CVR number only. Searching by company name needs the CVR register, which requires an approved account for system-to-system access. Planned.
Only companies that file machine-readable annual reports. Sole proprietorships and some other company types don't.
Key figures only, not the full statements, notes or management's review.
Group vs. parent figures in IFRS filings are not yet distinguished beyond ignoring dimensional contexts.
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.
Development
npm test # parser tests against synthetic fixtures (no network)
npm run typecheck
npm run buildRoadmap
Company name search via the CVR register
Group vs. parent figures for IFRS filings
Multi-year history in one call
Publish to npm for
npxusage
License
MIT. Built by Mikkel Manniche.
Available Tools
2 toolsget_financialsGet key financials from an annual reportA
Read a Danish company's published annual report (XBRL) and return key figures for the reporting year and the year before: revenue, gross profit, profit, equity, assets, cash, employees, plus auditor. Values are in the filing's currency (usually DKK). Small companies often omit revenue legally; notes explain gaps and conflicts instead of guessing.
| Name | Required | Description | Default |
|---|---|---|---|
| cvr | Yes | Danish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted). | |
| year | No | Calendar year the reporting period ends in. Omit for the latest annual report. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses that values use the filing currency, often DKK, and that revenue may be legally omitted by small companies—with notes explaining gaps and conflicts instead of guessing. This goes beyond input mechanics, though it does not specify behavior for missing filings or errors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: the first states the action and result, the second clarifies currency, and the third handles edge cases around omitted revenue and guessing. The key information is front-loaded, and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description enumerates all returned fields, explains the two-year comparison, and covers the main edge case. The two parameters are fully documented in the schema, so an agent has enough information to invoke the tool correctly and interpret the results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes both parameters fully, with 100% coverage, so the baseline is 3. The description adds useful output context such as 'reporting year and the year before' and currency, but it does not add new per-parameter constraints or syntax beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Read a Danish company's published annual report (XBRL)' and return key figures. It clearly enumerates the outputs, making it easy to distinguish from the sibling tool list_filings, which is about discovering filings rather than extracting financials.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the context clear: use this when you need key financial numbers from a Danish annual report, including the prior-year comparison and currency behavior. It does not explicitly name list_filings as an alternative or state when not to use this tool, so exclusions are absent, but the intended use is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_filingsList published filingsA
List what a Danish company has published with the Danish Business Authority (Erhvervsstyrelsen): annual reports, half-year reports and their documents, newest first.
| Name | Required | Description | Default |
|---|---|---|---|
| cvr | Yes | Danish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted). | |
| limit | No | How many filings to return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses only the ordering behavior ('newest first') but omits other behavioral traits such as pagination, error handling for invalid CVR, empty results, or the exact response structure. Given the lack of annotations, this is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the primary action and resource, includes relevant details (filing types, ordering) without redundancy or fluff. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (2 params, no nested objects), but with no output schema and no annotations, the description should provide more context on return format or edge cases. It covers the core behavior but leaves an agent without details on what the response looks like or how failures are handled. Adequate for basic invocation, not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for both parameters (cvr and limit), including format and constraints. The description itself adds no parameter information beyond what the schema already provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), a clear resource (filings published by a Danish company), and enumerates the types (annual reports, half-year reports, their documents) plus ordering (newest first). It inherently distinguishes from the sibling get_financials, which likely focuses on financial figures rather than filings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies its purpose clearly but never explicitly names alternatives or gives when-to-use/when-not-to-use guidance. An agent could infer that this tool is for listing filings while get_financials handles financial data, but no direct comparison or exclusion is stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
get_financials - First observed
list_filings
TDQS
Scored across 2 tools
The two tools have clearly distinct purposes: one lists filings, the other extracts financial data from a specific filing. There is no overlap or ambiguity between them.
Both tool names follow a consistent verb_noun pattern (list_ and get_), which is predictable and aligned with common conventions.
With only two tools, the server feels very thin. While the tools are individually useful, the set is minimal and likely insufficient for comprehensive company data retrieval, missing operations like searching or fetching specific filing documents.
The domain appears to be company financial data from the Danish Business Authority, but the surface is incomplete: there is no way to search companies, list companies, fetch raw documents, or get detailed financial statements. The existing tools cover listing and reading key figures, but many obvious workflows (e.g., retrieving a specific filing's full details) are missing.
Maintenance
Related MCP Connectors
Agent-native SEC filing data: statements assembled, filings read and synthesized. No API key.
Query financial statements, KPIs, ratios, cash forecasts and budgets from your general ledger
Normalized SEC EDGAR fundamentals. 3 of 6 tools free; the rest $0.04-$0.10 per call in USDC.
Citable US facts w/ curated query templates: SEC financials, bank call reports, nonprofits. No key.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceProvides comprehensive Norwegian business intelligence through Brønnøysund and Statistics Norway APIs, enabling company search, financial analysis, ownership mapping, market research, and automated financial data extraction.-
- AlicenseAqualityDmaintenanceEnables access to Slovak Registry of Financial Statements data, allowing users to search companies, retrieve financial reports, balance sheets, income statements, and analyze Slovak business financial data through natural language queries.252MIT
- FlicenseNot gradedqualityDmaintenanceEnables querying and analyzing XBRL financial data through natural language, using an API key for authentication.5 npm1-
- AlicenseAqualityDmaintenanceEnables AI assistants to search and look up Danish and Norwegian company registry (CVR) data, including company details, bankruptcy status, and more.24 npmMIT