The MCP server connects German insolvency announcements directly to AI agents. Claude, Cursor or your own agent can check a supplier, read a proceeding or monitor a customer inside a conversation, without anyone writing an API client.
Last updated: 2026-09-29
Keys are issued by hand. Tell us briefly what you want to build and which volume to expect, and access is usually live within one business day.
The Model Context Protocol is an open standard for how an AI agent reaches external tools and data. Instead of programming an interface, you add the server once to the agent's configuration. From then on the model knows which tools exist and calls them itself when the conversation needs them.
Our server exposes the same data as the REST API: announcements, company profiles, balance sheet figures, statistics and the watchlist. The difference is the framing. The tool descriptions are written so a model understands when an insolvency check makes sense, which details it has to ask for and where the limits of the data lie.
The address is https://germanyinsolvencies.com/api/mcp. It uses the same keys as the REST API. Operate both side by side and you will see the same watchlist in both worlds.
Typical questions an agent answers with it: "Is our supplier insolvent?", "Which of our 40 open invoices are affected by a proceeding?", "How many construction companies went bankrupt in Bavaria this quarter?"
The route is the same as for the REST API: keys are issued by hand. Use the contact form or write to [email protected] and say briefly which agent you want to connect and what it should do.
If you already have an API key, you do not need a second one: the same key opens the MCP server. Teams that want to hand the server to several people can receive several keys on one account on request, so it stays traceable who checked what.
The server speaks MCP over Streamable HTTP, the transport current clients use by default. No local process is needed, there is nothing to install.
Authentication uses the same header as the REST API: X-API-Key, alternatively Authorization: Bearer. Clients that only speak stdio reach the server through mcp-remote as a bridge, see the Claude Desktop configuration below.
Client and server negotiate the protocol version when connecting. We support the current revision and the one before it, so a client update never leads to a hard break.
curl https://germanyinsolvencies.com/api/mcp/health
In Claude Code one command is enough. The key should come from an environment variable, not from the clipboard.
claude mcp add --transport http insolvency \
https://germanyinsolvencies.com/api/mcp \
--header "X-API-Key: $INSOLVENCY_API_KEY"
Claude Desktop reads its server list from claude_desktop_config.json. The entry bridges to the HTTP transport via mcp-remote.
{
"mcpServers": {
"insolvency": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://germanyinsolvencies.com/api/mcp",
"--header", "X-API-Key:${INSOLVENCY_API_KEY}"
],
"env": { "INSOLVENCY_API_KEY": "YOUR_API_KEY" }
}
}
}
Cursor, Windsurf, Zed and most other clients take the server URL directly and allow their own headers, so no bridge is needed.
{
"mcpServers": {
"insolvency": {
"url": "https://germanyinsolvencies.com/api/mcp",
"headers": { "X-API-Key": "${env:INSOLVENCY_API_KEY}" }
}
}
}
After adding it, the client should show eleven tools. If the list stays empty, it is almost always the header: an expired or mistyped key produces an empty tool list rather than a visible error.
The server provides eleven tools. Writing tools are marked as such, so clients can ask for confirmation where they want to.
| Tool | Kind | Description |
|---|---|---|
| search_filings | read | Searches announcements by period, type, federal state, court or name. Returns a short summary per hit, the full text via get_filing. |
| get_filing | read | Returns one announcement with full text, court, case number and type. |
| check_counterparty | read | Checks one company for announcements and returns status, last announcement and match quality. The most important tool, see below. |
| search_companies | read | Finds company profiles by name, city, register number or status. |
| get_company | read | Returns a company profile with all linked announcements in chronological order. |
| get_financials | read | Returns published balance sheet figures of the last fiscal years. |
| get_stats | read | Counts announcements by day, month, federal state, court, type or legal form. |
| list_filing_types | read | Names the nine filing types with code, alias and meaning. Agents should call it once instead of guessing codes. |
| list_watchlist | read | Lists watched companies with the date of the last hit. |
| watch_company | write | Adds a company to the watchlist. |
| unwatch_company | write | Removes a company from the watchlist. |
All reading tools are idempotent and may be called without asking. watch_company and unwatch_company change your account and announce themselves to the client as writing tools.
The tool that matters is check_counterparty. Its schema is deliberately narrow: a name or a register number, optionally the city and a start date. The fewer decisions a model has to make, the less often it invents values.
{
"name": "check_counterparty",
"description": "Check whether a German company appears in official insolvency announcements. Use before extending credit, signing a supplier or chasing an overdue invoice. Prefer register number over name when you have it. Never guess a register number.",
"annotations": { "readOnlyHint": true },
"inputSchema": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "Company name as written on the invoice or contract." },
"city": { "type": "string", "description": "Registered seat, narrows ambiguous names." },
"register": { "type": "string", "description": "e.g. HRB 123456 B" },
"register_court": { "type": "string", "description": "e.g. Charlottenburg (Berlin)" },
"since": { "type": "string", "format": "date", "description": "Only filings on or after this date. Default: 3 years ago." }
},
"anyOf": [ { "required": ["name"] }, { "required": ["register"] } ]
}
}
The description tells the model explicitly to prefer the register number and never to guess one. A wrong register number leads to a confident "no announcement" for the wrong company, which is worse than an ambiguous answer.
If a name is not unique, the tool does not pick one but returns an error text with the candidates. The model then asks the user for the city or register number. This behaviour is intentional and is covered in the error handling section.
Without since, the tool looks back three years. Older proceedings are usually closed and no longer relevant for current decisions; if they are, pass an earlier date.
Tools answer on two tracks: a text block for the model and structuredContent for the client. The text block is worded so the model can pass it on to the user without having to interpret it first: company, register number, stage, court, case number, date.
{
"content": [
{
"type": "text",
"text": "Musterbau GmbH (HRB 123456 B, Berlin): insolvency proceedings OPENED on 2026-09-28 by Amtsgericht Charlottenburg, case 36a IN 4711/26. Earlier: protective measures on 2026-08-14. Source: official announcement."
},
{
"type": "resource_link",
"uri": "insolvency://filing/fil_8Kq2Zp4RwT",
"name": "Announcement 36a IN 4711/26",
"mimeType": "application/json"
}
],
"structuredContent": {
"match": "exact",
"company_id": "cmp_3n8Kd2ZpQv",
"status": "opened",
"filings": [
{ "id": "fil_8Kq2Zp4RwT", "date": "2026-09-28", "type_code": "2" },
{ "id": "fil_2Hd7Vb1Xe", "date": "2026-08-14", "type_code": "0" }
]
},
"isError": false
}
Full texts of announcements come back as resource links, not embedded. A client that wants to show the text resolves the link; one that does not keeps its context window small. A single announcement can be several thousand characters long.
In addition to tools, the server provides resources under the insolvency:// scheme. Clients that support resources can display them or attach them to the model without calling a tool.
insolvency://filing/{id} one announcement incl. full text
insolvency://company/{id} company profile and status
insolvency://company/{id}/filings all announcements of a company
insolvency://company/{id}/financials published balance sheet figures
insolvency://watchlist your watched companies
insolvency://types filing types with codes and aliases
The watchlist resource changes when a new announcement concerns a watched company. The server then sends a change notification, so clients can update their view.
For recurring tasks there are ready-made prompts. They collect what the task needs and then call the appropriate tools. In clients that support prompts they appear as quick commands.
{
"name": "counterparty_check",
"description": "Check a list of customers or suppliers for insolvency filings and summarise the risk.",
"arguments": [
{ "name": "companies", "description": "One company per line: name, city or register number.", "required": true },
{ "name": "since", "description": "Look-back start date, default 3 years.", "required": false }
]
}
Currently available are counterparty_check (check a list of companies), weekly_briefing (new announcements of the week for selected federal states or industries) and proceeding_timeline (history of a proceeding explained in plain language). If you prefer your own flow, ignore the prompts and call the tools directly.
This is what it looks like in practice. The agent checks three debtors, explains the results in plain terms, asks back where the name is ambiguous and then sets up the monitoring.
User: Can you check our three biggest open invoices? Musterbau GmbH
in Berlin, Nordlicht Handels GmbH and Beispiel Logistik in Hamburg.
Agent: [check_counterparty name="Musterbau GmbH" city="Berlin"]
[check_counterparty name="Nordlicht Handels GmbH"]
[check_counterparty name="Beispiel Logistik" city="Hamburg"]
Agent: Musterbau GmbH: proceedings were opened on 28 Sep 2026
(AG Charlottenburg, 36a IN 4711/26). Claims now have to be filed
with the insolvency administrator, direct payment is unlikely.
Beispiel Logistik UG: protective measures since 22 Sep 2026, a
preliminary administrator is appointed.
Nordlicht Handels GmbH: two companies with that name, neither has
a filing. Which city is yours?
User: Hamburg. And please watch all three from now on.
Agent: [watch_company name="Nordlicht Handels GmbH" city="Hamburg"]
[watch_company company_id="cmp_3n8Kd2ZpQv"]
[watch_company company_id="cmp_7Yb3Rt5Mn"]
Done. You will get a webhook as soon as a new announcement appears.
The important step is the third one: for an ambiguous name, the agent asks instead of choosing. That is exactly what the error text of the tool is designed for.
Each key carries permissions. By default it can read announcements, companies and statistics; writing to the watchlist must be enabled separately.
| Scope | Meaning |
|---|---|
| filings:read | Search and read announcements. |
| companies:read | Company profiles, balance sheet figures and the counterparty check. |
| stats:read | Aggregated statistics. |
| watchlist:write | Add and remove companies on the watchlist. |
Tools for which the key has no permission do not appear in the tool list at all. That is friendlier than an error mid-conversation, because the model then never offers something it cannot do anyway.
Errors come back as a normal tool result with isError: true, not as a protocol error. The text is addressed to the model and says what it should do next, so the agent can react sensibly inside the conversation.
{
"content": [
{
"type": "text",
"text": "No unique match: 2 companies are called \"Nordlicht Handels GmbH\" (Hamburg, Kiel). Ask the user for the city or the register number and call check_counterparty again. Do not pick one yourself."
}
],
"isError": true
}
Real protocol errors only occur with an invalid key, a missing permission or a malformed request. Everything that can go wrong on the content side, such as an ambiguous name, an unknown ID or a period that is too long, comes back as text.
The same limits apply as for the REST API: 120 tool calls per minute and key, at most 31 days per search in announcements, 24 months in statistics. For higher values an email is enough.
Exceeding a limit does not produce a hard error but a text result saying when it can continue. Agents should then wait rather than call again immediately.
The server returns public announcements, but they contain personal data. The same rules apply as for the REST API: deletion periods of the Insolvency Announcement Ordinance, no publication of announcements about private individuals, no automated decisions about natural persons based solely on this data.
An agent may summarise an announcement, but it does not replace legal advice. The tool texts therefore always name court and case number, so the user can check the original. We recommend that your agent also points this out when it derives recommendations for action.
What the agent sends to the server (company names, your references) is used only to answer the request and is not passed on. If your agent processes data about your customers, a data processing agreement is available.
The server runs on the same infrastructure as the REST API. Maintenance windows are announced by email to the stored address, and changes to tool schemas are additive only.
When a new tool is added, the server sends a change notification. Clients that react to it see the tool without restarting. Existing tools keep their names and their required fields.
Questions, higher limits, your own prompts or tools for a specific workflow: [email protected] or the contact form.
If you prefer to work against plain HTTP, the same data is documented as a REST interface in the API documentation. Both routes share keys, limits and contract.
Keys are issued by hand. Tell us briefly what you want to build and which volume to expect, and access is usually live within one business day.