Skip to main content
Glama

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

Related MCP server: Register UZ MCP Server

Tools

Tool

Input

Returns

search_company

query (name or CVR number), optional limit

Matching companies with CVR number, status, company type, industry and address. Needs CVR credentials, see below

list_filings

cvr, optional limit (1–50), optional year

Published filings, newest first, with document links

get_financials

cvr, 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_history

cvr, optional years (1–15), optional scope

Key figures per reporting year, newest first

get_report_facts

cvr, optional year, scope, match (part of a concept name), limit

Every 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

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.

Available Tools

5 tools
get_financialsGet key financials from an annual reportA
Read-onlyIdempotent

Read one annual report (XBRL) of a Danish company and return its key figures for that year and the year before: revenue, gross profit, operating profit, profit, equity, assets, cash, employees, plus company name, period, currency and auditor. Use it for one year's headline numbers; use get_financials_history for a trend over several years and get_report_facts for any other line item. Group reports default to the consolidated group. Values are in the filing's currency (usually DKK); a missing figure is null and notes say why (small companies may legally omit revenue). found=false when the company has no machine-readable annual report for that year.

ParametersJSON Schema
NameRequiredDescriptionDefault
cvrYesDanish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted), e.g. "24256790".
yearNoCalendar year the reporting period ends in (a 2024/25 financial year ending June 2025 is 2025). Omit for the latest annual report.
scopeNoFor group reports (koncernregnskab): "group" = the consolidated group, "parent" = the parent company alone. Ignored for single companies.group

Output Schema

ParametersJSON Schema
NameRequiredDescription
cvrNo
nameNo
foundYes
notesNoGaps, conflicts and caveats found in the filing, in plain English.
scopeNoWhose figures these are; "company" for a report without a group.
periodNoReporting period, ISO dates.
sourceNoThe filing document the figures were read from.
auditorNo
figuresNoKey figures; current = this report's year, previous = the year before.
messageNoWhy nothing was found (only when found=false).
currencyNo
taxonomyNo
reportTypeNo
groupReportNo
previousPeriodNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds valuable behavioral context beyond annotations: it explains missing figures are null with notes, small companies may omit revenue, and found=false indicates no machine-readable report. It does not contradict annotations and enriches the agent's understanding of edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and efficient. It front-loads the core purpose, then lists the return fields, then gives usage guidance, and finally notes edge cases. Every sentence contributes necessary information without redundancy, achieving conciseness while being thorough.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, so return structure is documented there. The description covers all essential aspects: what it returns, when to use it versus siblings, default scope, currency, missing-value behavior, and the found=false condition. It is complete for an agent to decide when to call it and what to expect, without needing external details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so parameters are fully documented in the schema. The description does not add significant extra semantics beyond what the schema already provides; it reiterates defaults and formats. Given the high coverage, a baseline of 3 is appropriate, as the description adds minimal value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads one annual report and returns specific key figures, naming the exact financial items. It explicitly distinguishes from siblings by saying 'Use it for one year's headline numbers; use get_financials_history for a trend over several years and get_report_facts for any other line item.' This makes the purpose unambiguous and differentiates it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to use this tool versus alternatives: 'Use it for one year's headline numbers; use get_financials_history for a trend over several years and get_report_facts for any other line item.' It also explains the default scope for group reports and notes that omitted year retrieves the latest report, giving clear context for invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_financials_historyGet key financials over several yearsA
Read-onlyIdempotent

Return the same key figures as get_financials for each of a Danish company's latest annual reports, one row per reporting year, newest first. Use it for trends and growth; use get_financials when one year (with its previous-year comparison and auditor) is enough. Reads one filing per year, so it is slower than get_financials. A corrected report replaces the original; years without a machine-readable report are skipped.

ParametersJSON Schema
NameRequiredDescriptionDefault
cvrYesDanish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted), e.g. "24256790".
scopeNoFor group reports (koncernregnskab): "group" = the consolidated group, "parent" = the parent company alone. Ignored for single companies.group
yearsNoHow many reporting years to return, counting back from the latest.

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
yearsYesNewest first; empty when the company has no machine-readable annual reports.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, openWorld, idempotent, and non-destructive behavior ascending. The description adds valuable behavioral context beyond these: it reads one filing per year, is slower than get_financials, corrected reports replace originals, and years without machine-readable reports are skipped. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The primary purpose and output shape are front-loaded, followed by usage guidance and behavioral caveats. Every sentence adds distinct value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description fully covers purpose, output ordering, usage boundaries, performance, data-correctness behavior, and skipped years. The input schema documents all parameters, annotations cover safety and idempotency, and an output schema exists, so an agent has enough to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter (cvr, scope, years) already thoroughly documented including format, defaults, constraints, and semantics. The description adds output-shape context but not additional parameter meaning, 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the specific verb 'Return', the resource ('a Danish company's latest annual reports'), and the output shape ('one row per reporting year, newest first'). It also explicitly distinguishes itself from get_financials by naming the sibling and the difference in scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit usage guidance: use this tool for trends and growth, and use get_financials when a single year with previous-year comparison and auditor is sufficient. Also gives practical caveats about speed and skipped years, leaving little to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_report_factsGet all tagged figures from an annual reportA
Read-onlyIdempotent

Return every figure and text the company tagged in one annual report (XBRL), not only the key figures: e.g. staff costs, depreciation, receivables, dividends, the auditor's opinion. Use it when get_financials doesn't have the line item you need; filter with match to keep the answer short. Concepts are the taxonomy's own English names (fsa = Danish GAAP, ifrs = IFRS, gsd/cmn = general details). Breakdowns by dimension are left out; long texts are cut at 500 characters.

ParametersJSON Schema
NameRequiredDescriptionDefault
cvrYesDanish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted), e.g. "24256790".
yearNoCalendar year the reporting period ends in (a 2024/25 financial year ending June 2025 is 2025). Omit for the latest annual report.
limitNoMaximum number of facts to return; total says how many matched.
matchNoOnly concepts whose name contains this text, case-insensitive, e.g. "Employee" or "Dividend".
scopeNoFor group reports (koncernregnskab): "group" = the consolidated group, "parent" = the parent company alone. Ignored for single companies.group

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameNo
factsNo
foundYes
scopeNoWhose figures these are; "company" for a report without a group.
totalNoFacts matching the filter, before limit.
periodNoReporting period, ISO dates.
sourceNoThe filing document the figures were read from.
messageNoWhy nothing was found (only when found=false).

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even though annotations already mark the tool as read-only and idempotent, the description adds meaningful behavioral details: concepts use taxonomy-specific English names (fsa, ifrs, gsd/cmn), breakdowns by dimension are omitted, and long texts are truncated at 500 characters. These disclosures go well beyond the structured annotations and help set expectations for output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three focused sentences with no filler. The main purpose is front-loaded, followed by when-to-use guidance, then important behavioral caveats. Every sentence contributes distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With full schema coverage, read-only annotations, and a declared output schema in context, the description covers all material usage aspects: what is returned, how it differs from get_financials, how to limit output via match, and the XBRL taxonomy behavior. No critical guidance is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% parameter coverage, so a baseline of 3 is appropriate. The description adds extra semantic value for `match` and returned concepts by explaining that concept names come from the taxonomy (fsa = Danish GAAP, ifrs = IFRS, gsd/cmn = general details). This helps the agent craft match filters and interpret results, though it does not fully reshape parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description says exactly what the tool does with a specific verb and resource: 'Return every figure and text the company tagged in one annual report (XBRL), not only the key figures.' It also distinguishes itself from get_financials by emphasizing that it returns all tagged facts, not just key figures, and gives concrete examples like staff costs and auditor's opinion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent when to use this tool: 'Use it when get_financials doesn't have the line item you need.' It also provides a practical usage tip ('filter with match to keep the answer short'), which directly helps the agent decide how to call it.

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
Read-onlyIdempotent

List what a Danish company has filed with the Danish Business Authority (Erhvervsstyrelsen): annual reports, interim reports and their documents (PDF, XBRL), newest first. Use it to see which years are available or to get document links; use get_financials for the figures themselves. Returns an empty list for a CVR number with no filings (e.g. sole proprietorships). No paging: raise limit or set year to reach older filings.

ParametersJSON Schema
NameRequiredDescriptionDefault
cvrYesDanish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted), e.g. "24256790".
yearNoOnly filings whose reporting period ends in this calendar year. Omit for all years.
limitNoHow many filings to return, newest first.

Output Schema

ParametersJSON Schema
NameRequiredDescription
cvrYes
filingsYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive behavior. The description adds valuable behavioral context beyond that: results are newest first, an empty list is returned for CVR numbers with no filings, and there is no paging, so callers should raise the limit or set a year to reach older filings.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded: it states the primary purpose first, then adds usage guidance, an edge case, and a pagination note. Every sentence contributes useful information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers what the tool returns, the main use cases, how it differs from a key sibling, empty-result behavior, and pagination limitations. Since an output schema exists, return value details are already covered structurally, so nothing essential is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and every parameter already has a meaningful description in the schema. The tool description does not add much beyond what the schema states, 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and a specific resource (filings with the Danish Business Authority), and enumerates the content (annual reports, interim reports, PDF, XBRL). It also distinguishes itself from the sibling get_financials by clarifying it returns filings and document links, not financial figures.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use this tool: to see which years are available or get document links. It also names the alternative get_financials for figures, giving a clear when-not-to-use signal. Additional behavior around empty results and pagination further guides usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_companySearch Danish companies by nameA
Read-onlyIdempotent

Find a Danish company's CVR number by name (or check a CVR number) in the CVR register. Use it first when you only have a name; every other tool needs the CVR number. Matches all words of the query against current company names; returns name, status, company type, industry and address. Needs CVR_USER and CVR_PASSWORD in the server's environment (free system-to-system access to the CVR register); without them it returns an error saying how to get access.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of companies to return.
queryYesCompany name or part of it, e.g. "Carlsberg" or "lego a/s". An 8-digit CVR number looks up that company.

Output Schema

ParametersJSON Schema
NameRequiredDescription
companiesYesBest matches first; empty when nothing matches.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, so safety is covered. The description adds valuable behavioral context: it matches all words of the query against current company names, returns specific fields (name, status, type, industry, address), and discloses the CVR_USER/CVR_PASSWORD requirement with the error message on failure. This goes beyond annotations and is highly informative.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place: purpose and use case, matching behavior and return fields, and authentication requirement. The most critical info (use first, needs CVR number) is front-loaded. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with an output schema and annotations covering safety, the description is complete. It covers when to use, what it does, what it returns, authentication prerequisites, and error behavior. Nothing essential is missing for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaning by explaining that the query can be a company name or an 8-digit CVR number, and that it matches all words. It also clarifies the return fields. This adds value beyond the schema, though it doesn't dive into edge cases or matching nuances, so 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: finding a Danish company's CVR number by name, and also checking a CVR number. It explicitly distinguishes itself from siblings by noting that 'every other tool needs the CVR number', positioning this as the entry point. This is a specific verb+resource with clear differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to use this tool ('Use it first when you only have a name') and explains that all other tools require the CVR number, making the selection logic unambiguous. It also mentions the authentication prerequisite and the error behavior, which helps the agent anticipate failure modes.

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.

  1. 5 tool updatesv0.3.1
    • Changedget_financials4 fields changed
      • changedInput schema / properties / cvr / description
        Previous value: -"Danish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted)."New value: +"Danish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted), e.g. \"24256790\"."
      • changedInput schema / properties / scope / description
        Previous value: -"For group reports (koncernregnskab): the consolidated group, or the parent company alone. Ignored for single companies."New value: +"For group reports (koncernregnskab): \"group\" = the consolidated group, \"parent\" = the parent company alone. Ignored for single companies."
      • changedInput schema / properties / year / description
        Previous value: -"Calendar year the reporting period ends in. Omit for the latest annual report."New value: +"Calendar year the reporting period ends in (a 2024/25 financial year ending June 2025 is 2025). Omit for the latest annual report."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "auditor": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "assistance": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "firm": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        }
        +      },
        +      "required": [
        +        "firm",
        +        "assistance"
        +      ],
        +      "type": "object"
        +    },
        +    "currency": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "cvr": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "figures": {
        +      "description": "Key figures; current = this report's year, previous = the year before.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "current": {
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          },
        +          "key": {
        +            "type": "string"
        +          },
        +          "label": {
        +            "type": "string"
        +          },
        +          "previous": {
        +            "type": [
        +              "number",
        +              "null"
        +            ]
        +          }
        +        },
        +        "required": [
        +          "key",
        +          "label",
        +          "current",
        +          "previous"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "found": {
        +      "type": "boolean"
        +    },
        +    "groupReport": {
        +      "type": "boolean"
        +    },
        +    "message": {
        +      "description": "Why nothing was found (only when found=false).",
        +      "type": "string"
        +    },
        +    "name": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "notes": {
        +      "description": "Gaps, conflicts and caveats found in the filing, in plain English.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "period": {
        +      "anyOf": [
        +        {
        +          "additionalProperties": false,
        +          "properties": {
        +            "end": {
        +              "type": "string"
        +            },
        +            "start": {
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "start",
        +            "end"
        +          ],
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Reporting period, ISO dates."
        +    },
        +    "previousPeriod": {
        +      "anyOf": [
        +        {
        +          "additionalProperties": false,
        +          "properties": {
        +            "end": {
        +              "type": [
        +                "string",
        +                "null"
        +              ]
        +            },
        +            "start": {
        +              "type": [
        +                "string",
        +                "null"
        +              ]
        +            }
        +          },
        +          "required": [
        +            "start",
        +            "end"
        +          ],
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "reportType": {
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "scope": {
        +      "description": "Whose figures these are; \"company\" for a report without a group.",
        +      "enum": [
        +        "group",
        +        "parent",
        +        "company"
        +      ],
        +      "type": "string"
        +    },
        +    "source": {
        +      "additionalProperties": false,
        +      "description": "The filing document the figures were read from.",
        +      "properties": {
        +        "documentType": {
        +          "type": "string"
        +        },
        +        "publishedAt": {
        +          "type": [
        +            "string",
        +            "null"
        +          ]
        +        },
        +        "url": {
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "publishedAt",
        +        "documentType",
        +        "url"
        +      ],
        +      "type": "object"
        +    },
        +    "taxonomy": {
        +      "enum": [
        +        "danish-gaap",
        +        "ifrs",
        +        "unknown"
        +      ],
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "found"
        +  ],
        +  "type": "object"
        +}
    • Addedget_financials_history
    • Addedget_report_facts
    • Changedlist_filings4 fields changed
      • changedInput schema / properties / cvr / description
        Previous value: -"Danish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted)."New value: +"Danish CVR number, 8 digits (spaces, dashes and a DK prefix are accepted), e.g. \"24256790\"."
      • changedInput schema / properties / limit / description
        Previous value: -"How many filings to return."New value: +"How many filings to return, newest first."
      • addedInput schema / properties / year
        Added value: +{
        +  "description": "Only filings whose reporting period ends in this calendar year. Omit for all years.",
        +  "maximum": 2100,
        +  "minimum": 2012,
        +  "type": "integer"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "cvr": {
        +      "type": "string"
        +    },
        +    "filings": {
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "correction": {
        +            "description": "True when this filing corrects (omgørelse) an earlier one.",
        +            "type": "boolean"
        +          },
        +          "cvr": {
        +            "type": "string"
        +          },
        +          "documents": {
        +            "items": {
        +              "additionalProperties": false,
        +              "properties": {
        +                "mimeType": {
        +                  "type": "string"
        +                },
        +                "type": {
        +                  "description": "e.g. AARSRAPPORT, AARSRAPPORT_ESEF, HALVAARSRAPPORT.",
        +                  "type": "string"
        +                },
        +                "url": {
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "type",
        +                "mimeType",
        +                "url"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "periodEnd": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "periodStart": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "publishedAt": {
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          },
        +          "type": {
        +            "description": "Filing type; \"regnskab\" for financial reports.",
        +            "type": [
        +              "string",
        +              "null"
        +            ]
        +          }
        +        },
        +        "required": [
        +          "cvr",
        +          "type",
        +          "periodStart",
        +          "periodEnd",
        +          "publishedAt",
        +          "correction",
        +          "documents"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "cvr",
        +    "filings"
        +  ],
        +  "type": "object"
        +}
    • Addedsearch_company
  2. 1 tool updatev0.2.0
    • Changedget_financials1 field changed
      • addedInput schema / properties / scope
        Added value: +{
        +  "default": "group",
        +  "description": "For group reports (koncernregnskab): the consolidated group, or the parent company alone. Ignored for single companies.",
        +  "enum": [
        +    "group",
        +    "parent"
        +  ],
        +  "type": "string"
        +}
  3. 2 tool updatesv0.1.0
    • First observedget_financials
    • First observedlist_filings

TDQS

A4.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct role: search_company finds the CVR number, list_filings shows available filings, get_financials gives one year's key figures, get_financials_history gives trends, and get_report_facts covers any other line item. The descriptions cross-reference each other explicitly, so an agent can easily select the right tool.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern: get_, search_, list_. Even though the verbs vary, the structure is uniform and the nouns clearly reflect the resource being acted on (financials, company, filings, facts). No mixed casing or inconsistent conventions.

Tool Count5/5

Five tools is an ideal size for a read-only financial data server. Each tool covers a distinct, necessary operation without redundancy or bloat, and the set feels purpose-built rather than padded.

Completeness5/5

The tool surface covers the full research workflow: identify the company, list available filings, retrieve summary figures, view historical trends, and extract arbitrary detailed facts. There are no obvious dead ends—even document links are provided via list_filings, and get_report_facts can access any XBRL-tagged line item.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides 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.
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables 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.
    25
    2
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables querying and analyzing XBRL financial data through natural language, using an API key for authentication.
    9 npm
    1
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to search and look up Danish and Norwegian company registry (CVR) data, including company details, bankruptcy status, and more.
    2
    9 npm
    MIT