# Register lookup (Beta)

> Connect an AI assistant to Register lookup, komplai's MCP server for CVR, Retsinformation, Danmarks Statistik and Folketinget, with a personal API key.

Register lookup is in (Beta). It is an MCP server that lets your AI assistant look up public Danish registers: CVR, Retsinformation, Danmarks Statistik and Folketinget. Every tool reads; none of them changes data. Register lookups use no AI and do not count towards AI usage or the organisation's monthly AI spending cap.

Register lookup has its own address and is not part of `api.komplai.dk`, so it has no page in the API reference. It speaks the Model Context Protocol over Streamable HTTP.

- **Address:** `https://mcp.komplai.dk/mcp`
- **Transport:** MCP Streamable HTTP, with POST, GET and DELETE on the same address
- **Authentication:** `Authorization: Bearer` with a personal API key (`kp_live_...`) that has the scope `mcp:read`

## Before you start

- Your organisation has Register lookup in its agreement, and an administrator has given you access to it under **Organisation › People › Tool access** in the hub.
- You have a personal API key with `mcp:read`. In the hub, open **Register lookup** (`/modules/mcp`) and choose **Create a key for Register lookup**, or create the key on the **API keys** page at [hub.komplai.dk/api-access](https://hub.komplai.dk/api-access). An organisation integration key (`kp_org_...`) is refused with `integration_not_permitted`.
- Use test data only while Register lookup is in beta.

## Connect VS Code

The **Register lookup** page in the hub shows the same configuration with a copy button. It contains no key.

1. Create a personal key with `mcp:read`.
2. In VS Code, run **MCP: Open User Configuration** and merge the configuration below into your existing settings.
3. Start the server. VS Code asks for the key in a hidden field, so it never ends up in a file.

```json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "komplai-api-key",
      "description": "komplai personal API key (mcp:read)",
      "password": true
    }
  ],
  "servers": {
    "komplai": {
      "type": "http",
      "url": "https://mcp.komplai.dk/mcp",
      "headers": {
        "Authorization": "Bearer ${input:komplai-api-key}"
      }
    }
  }
}
```

The configuration works in the VS Code extension host, not in Agent Host sessions. Other clients work if they support Streamable HTTP and a personal Bearer header; [MCP clients](https://developers.komplai.dk/guides/mcp-clients) covers them.

## Try it with curl

An MCP client does these steps for you. With curl you can see each one.

Start a session with `initialize`. `-i` shows the response headers, where `Mcp-Session-Id` carries the session's id:

```bash
curl -i https://mcp.komplai.dk/mcp \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2025-03-26", "capabilities": {}, "clientInfo": {"name": "curl", "version": "1"}}}'
```

Put the id in `KOMPLAI_MCP_SESSION_ID`, confirm the session with the `initialized` notification, and call a tool. This one searches Retsinformation:

```bash
curl https://mcp.komplai.dk/mcp \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Mcp-Session-Id: $KOMPLAI_MCP_SESSION_ID" \
  -H "MCP-Protocol-Version: 2025-03-26" \
  -d '{"jsonrpc": "2.0", "method": "notifications/initialized"}'

curl https://mcp.komplai.dk/mcp \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Mcp-Session-Id: $KOMPLAI_MCP_SESSION_ID" \
  -H "MCP-Protocol-Version: 2025-03-26" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "retsinfo_search", "arguments": {"query": "forvaltningsloven", "limit": 3}}}'
```

The answer arrives as a server-sent event: a `data:` line with the JSON-RPC result, whose `content` holds the tool's result as JSON text. `tools/list` instead of `tools/call` lists every tool with its input schema.

Close the session when you are done. Closing a session does not revoke the key.

```bash
curl -X DELETE https://mcp.komplai.dk/mcp \
  -H "Authorization: Bearer $KOMPLAI_TOKEN" \
  -H "Mcp-Session-Id: $KOMPLAI_MCP_SESSION_ID" \
  -H "MCP-Protocol-Version: 2025-03-26"
```

## Tools

| Tool | Register | What it returns | Where the lookup goes |
| --- | --- | --- | --- |
| `cvr_lookup` | CVR | A company by CVR number or name: name, address, industry code, employees, company type, bankruptcy flag and owners | cvrapi.dk |
| `retsinfo_search` | Retsinformation | Laws, executive orders and circulars as citations: title, type, ministry, date and link. Not the text of the law. | retsinformation.dk |
| `dst_find_tables` | Danmarks Statistik | Statistics tables by keyword, with id, coverage, unit and period | api.statbank.dk |
| `dst_describe_table` | Danmarks Statistik | A table's variables and the value codes each one accepts | api.statbank.dk |
| `dst_get_data` | Danmarks Statistik | Figures from a table for the variable codes you choose | api.statbank.dk |
| `oda_search_cases` | Folketinget | Parliamentary cases by title: type, status, resolution and last update | oda.ft.dk |
| `oda_get_entity` | Folketinget | Rows of Folketinget's open data: cases, documents, people and bodies, votes, sittings | oda.ft.dk |
| `komplai_detect` | Redact | Personal data in a text, found with rules only | Within the service |
| `komplai_redact` | Redact | The text with labels such as `[CPR-1]`, and the list of labels | Within the service |
| `komplai_rehydrate` | Redact | The text with the originals put back from the list of labels | Within the service |
| `list_connectors` | | Every connector on the server and where its data goes | |

- CVR is a public register, but for small companies the registered contact details and owner names belong to private individuals: treat them as personal data. When `marketing_protected` is true, the company has opted out of marketing use.
- The `komplai_` tools also need `redact:detect` on the same key and access to Redact in your organisation. They use rules only, so they do not find names. The server does not keep the list of labels: `komplai_rehydrate` needs the list that `komplai_redact` returned. `komplai_detect` and `komplai_redact` take up to 50,000 characters per call. For names and longer texts, use [Redact](https://developers.komplai.dk/tools/redact) through the API.

## Sessions and limits

- Every request, also GET and DELETE, carries the personal key. A key in the address is refused: the URL may have no query string.
- The first request is a POST with `initialize`. The session is bound to your organisation, to you and to the key; another key cannot use it. Revocation, expiry and withdrawn access are checked on every request and again when a tool runs.
- At most 5 sessions per key and 500 on the server. A session ends after 30 minutes without activity.
- A request body may have at most 4 MiB. The server has its own limit on HTTP requests per minute, and each tool call also counts against your account's request limits.

## When a request is refused

Refusals come as a JSON body with `error`:

| Status | `error` | What to do |
| --- | --- | --- |
| 400 | `query_credentials_not_supported` | Remove the query string. Send the key in the `Authorization` header. |
| 400 | `initialize_required` | Start a session with a POST of `initialize`. |
| 400 | `invalid_session` | Send `Mcp-Session-Id` once. |
| 401 | `api_key_required` | Send `Authorization: Bearer` with your personal key. |
| 401 | `invalid_api_key` | The key is unknown, expired or revoked. Create a new one. |
| 403 | `integration_not_permitted` | Use a personal key, not an organisation integration key. |
| 403 | `insufficient_scope` | Use a key with `mcp:read`. |
| 403 | `session_owner_mismatch` | The session belongs to another key. Start a new session. |
| 403 | `origin_refused` | The request came from a web page on an origin the server does not accept. |
| 404 | `unknown_session` | The session has ended. Start a new one with `initialize`. |
| 429 | `session_limit` | Close sessions you no longer use with DELETE, or wait for idle ones to end. |
| 429 | `rate_limited` | Wait a minute before you send more requests. |
| 503 | `account_access_unavailable` | Keys and access could not be checked. Try again shortly. |

A tool call that your account may not make right now, for example because your access was withdrawn or your request limit is reached, returns a tool result with `isError: true` whose text names the reason.

## Where data goes

- The lookup parameters go to the register you query, at the address in the table above. Access follows your personal key.
- The server runs on komplai's servers in Germany (EU). The `komplai_` tools process text there, in memory.
- Your organisation's Audit log holds the tool, who called it and usage metadata, never the lookup, the text, the list of labels or the key.
- Register lookups use no AI and do not count towards AI usage.

[Where data is processed](https://developers.komplai.dk/data-processing) describes every tool.

---

https://developers.komplai.dk/tools/register-lookup
