Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

european-company-registers

ASecurity

Search public company registers across Europe for financial data (revenue, assets, earnings) AND structured register data (managing directors, share capital, purpose, legal form). Use when researching company financials, verifying leads, or enriching B2B data. Germany combines the Unternehmensregister (unternehmensregister.de) AND the Bundesanzeiger in parallel for Jahresabschlüsse (GJ 2022+ post-DiRUG lives only in the Unternehmensregister), PLUS a Handelsregister (handelsregister.de) path f...

2 stars
0 votes
0 copies
0 views
Added 9/28/2026
ai-agentspythongobashnodegitapi

Works with

cliapi

Security Analysis

A100/100

Scanned 9/28/2026

Install to Claude Code

$npx -y skills add tfbecker/european-company-registers --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of european-company-registers?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for european-company-registers
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tfbecker-european-company-registers/badge)](https://www.skillsdirectory.com/skills/tfbecker-european-company-registers)

More formats (shields.io, HTML) on the badges page.

Files
SKILL.md
---
name: european-company-registers
description: Search public company registers across Europe for financial data (revenue, assets, earnings) AND structured register data (managing directors, share capital, purpose, legal form). Use when researching company financials, verifying leads, or enriching B2B data. Germany combines the Unternehmensregister (unternehmensregister.de) AND the Bundesanzeiger in parallel for Jahresabschlüsse (GJ 2022+ post-DiRUG lives only in the Unternehmensregister), PLUS a Handelsregister (handelsregister.de) path for the structured register content, Geschäftsführer/Vorstand, Stammkapital, Sitz, Gegenstand, Prokura, Rechtsform, former names. France (free revenue + officers), Poland (KRS by name/number/NIP + filing history), UK. Trigger on: Unternehmensregister, Handelsregister, Bundesanzeiger, HRB, Geschäftsführer, Stammkapital, Gesellschafter, Jahresabschluss, Bilanz, Umsatz, KRS, SIREN, company financials.
---

# European Company Registers

Find financial data (revenue, assets, earnings) and register metadata for European companies.

## Running the scripts

Pure Node.js + Python, no build step. Point `REG` at this repo's `scripts/` directory (works
from any working directory):

```bash
REG="/path/to/european-company-registers/scripts"   # or ./scripts from the repo root
```

## Germany, the main path (Unternehmensregister + Bundesanzeiger)

Both sources are queried **in parallel**; listing is **CAPTCHA-free**. Commands:

```bash
node "$REG/de-combined.js" search  "Pergolux"                 # newest report only  (~0.4 s, default)
node "$REG/de-combined.js" search  "Pergolux" --all-ur        # all UR reports      (~0.5 s)
node "$REG/de-combined.js" search  "Pergolux" --all           # + Bundesanzeiger    (~1 s)
node "$REG/de-combined.js" report  "Pergolux"                 # ONE search + extract every free year's figures
node "$REG/de-combined.js" analyze "Pergolux" --year 2021     # one year's figures
```

**Pick the command by intent:**
- **"which years / how much revenue / analyse over all years"** → `report`. It searches once, then
  extracts the figures for the newest N years (default 5) in one process, routing each year to its
  source automatically. This is the efficient path, **don't loop `analyze` per year**.
- **just the listing** → `search` (add `--all-ur` for all years, `--all` to also confirm via Bundesanzeiger).
- **one specific year's figures** → `analyze --year YYYY`.

Flags: `--max-extract N` (report: how many newest years to extract, default 5) · `--years 2024,2023`
(only these) · `--no-ur` (skip the slow browser step; GJ 2022+ then listed only) · `--deep` (paginate
the UR, only for a fuzzy/surname search spanning many companies; a precise name is complete on 1 page) ·
`--index N` (pick the Nth company) · `-v` (keep raw payloads) · `--text-dir <dir>` / `--inline-text` /
`--no-save-text` (full report text is saved to `./register-texts/` by default, see *Full report text* below).

### Why two sources (DiRUG)

Publication of Jahresabschlüsse for fiscal years **beginning after 31.12.2021** moved from the
Bundesanzeiger to the Unternehmensregister. So **GJ 2022+ lives only in the Unternehmensregister**;
a Bundesanzeiger-only scrape is ~3 years stale. The UR listing is a superset (both sources, tagged
`sources`), so it drives the listing; the Bundesanzeiger adds the report URLs whose figures the
CAPTCHA+LLM extractor reads **for free**.

### Figure extraction, both sources, all years (no paywall)

- **Listing** (`search`) never touches a CAPTCHA.
- **GJ ≤2021 (Bundesanzeiger)**, HTTP path; the report's image CAPTCHA is read by **Claude Haiku**
  (vision), the text extracted by **Claude Sonnet**. Fast-ish (~20 s/year).
- **GJ 2022+ (Unternehmensregister)**, the published Jahresabschluss is **free** but behind a
  "Ich bin ein Mensch" checkbox (Friendly-Captcha, no payment/login). `ur_fetch_document.py` drives
  a **stealth browser** to solve the checkbox and read the text, then the LLM extracts the figures.
  Slower (~15-20 s/year + one browser launch); `report` does all UR years in **one** browser session
  and extracts them **concurrently**. Use `--no-ur` to skip it.
- Only *deposited* (`hinterlegte`) statements of tiny companies are fee-based, those stay listed-only.

Needs a logged-in `claude` CLI (auto-detected, or set `CLAUDE_BIN`) and, for GJ 2022+, a stealth
browser (see *Requirements* in the README; override its location with `COMPANY_REGISTERS_BROWSER`
and its Python with `UR_PYTHON`). Never exports `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL`. Model
overrides: `BA_CAPTCHA_MODEL`, `BA_EXTRACT_MODEL`.

Per-year `status` in `report`: `extracted` · `listed_only` (beyond `--max-extract`) ·
`gated_skipped` (`--no-ur`) · `extraction_failed`.

### Full report text, scraped AND saved by default

`report`/`analyze` don't just distill figures, they **keep the full document text** (the whole
Jahresabschluss / Lagebericht / Anhang scraped from either source, the same text the extractor reads)
so nothing has to be re-scraped later. By **default** each extracted year is written to one UTF-8
`.txt` file (with a short provenance header) under **`./register-texts/`**:

```
register-texts/<Court>_<Register>_GJ<Year>_<source>.txt
# e.g. Bad-Oeynhausen_HRB-7371_GJ2024_unternehmensregister.txt
```

Each extracted year in the JSON then carries `report_chars` and `report_text_file`; the top level of
a `report` result adds `text_dir` and `saved_text_count`.

- `--text-dir <dir>`, where to write (default `./register-texts`; env `REGISTER_TEXT_DIR`).
- `--inline-text`, also embed the full text in the JSON as `report_text` (heavy; off by default).
- `--no-save-text`, figures only, don't write files.

The saved text carries the qualitative content the figures can't: **Lagebericht** (strategy, outlook,
risks, only larger companies file one), **Anhang** (Beteiligungen/ownership, related parties, a
Gewinnabführungsvertrag, contingent liabilities). For Kleinstkapitalgesellschaften it's essentially
just the bare balance sheet. `search` never fetches documents, so it writes nothing.

### Output

`search` → companies with `euid`, `register`/`register_number` (HRB), `court`, `state`, and `reports[]`
of `{fiscal_year, report_name, date, sources, free_extract}` (encrypted payloads stripped unless `-v`).
`report`/`analyze` → per year `financial_data`: `revenue, total_assets, earnings, equity, liabilities,
inventory, receivables, cash, fixed_assets, gross_profit, material_expenses, personnel_expenses,
operating_result, employees, fiscal_year, is_group_report, currency`. Plus, per extracted year,
`report_chars` + `report_text_file` (and `report_text` with `--inline-text`); see *Full report text* above.

## Germany, Handelsregister (structured register content)

Separate from the Jahresabschluss path above. Gives the **register content**, not financials:
Rechtsform, Sitz + Geschäftsanschrift, Gegenstand, Stamm-/Grundkapital, Vertretungsregelung,
**Geschäftsführer / Vorstand**, Prokura, and former names. Free since the DiRUG reform (AD).

```bash
node "$REG/de-handelsregister.js" search  "Holz-Richter"                       # register entries: name, HRB, court, seat, status, former names
node "$REG/de-handelsregister.js" details "Holz-Richter GmbH" --hrb 37497 --court Köln   # AD → structured JSON
```

- `search` drives handelsregister.de (stealth browser; the site is a stateful JSF app, no
  bot-protection) and returns the matching register rows, **always match a company by its HRB**,
  never a fixed position (the result order isn't stable).
- `details` downloads the AD ("Aktueller Abdruck"), runs `pdftotext`, and parses the standard
  numbered sections into JSON (`share_capital`, `managing_directors[]` with birth dates, `prokura[]`,
  `legal_form`, `purpose`, `seat`, …).
- **Rate limit:** handelsregister.de throttles *document* retrieval, after a few AD downloads in a
  short window it routes to an error page (the helper retries, then returns `reason:"throttled"`).
  `search` is not throttled. Retry `details` after a short cooldown.
- Needs the stealth browser (override its Python with `CLOAK_PYTHON`) and `pdftotext` (poppler).

## Other countries

```bash
node "$REG/gb-companies-house.js" search "Tesco"        # UK , company / filings <number> also (needs key)
node "$REG/fr-inpi.js"            analyze "Carrefour"   # FR , analyze accepts a name OR a <siren>
node "$REG/pl-krs.js"             search  "CD PROJEKT"  # PL , company <krs> · nip <nip> · analyze <krs|nip>
# Or the unified dispatcher (de routes to de-combined.js):
node "$REG/search.js" --country fr --name "Carrefour"
```

- **France (INPI/RNE)**, `recherche-entreprises.api.gouv.fr`, **free, no key**. Returns real
  **revenue** (`ca`) + **earnings** (`resultat_net`) per year and the **officers** (`dirigeants`)
  for the many companies in the open financial-ratios dataset, plus full metadata. `analyze` takes a
  name (picks the best-matching real entity) or a SIREN. An optional free `INPI_API_TOKEN` adds
  balance-sheet depth (total assets/equity); revenue works without it.
- **Poland (KRS)**, the official Ministry-of-Justice API by **KRS number** is the reliable core
  (`company <krs>` / `analyze <krs>`): name, legal form, NIP/REGON, seat, **share capital**, purpose
  (PKD), management board (names GDPR-masked), and the **filed annual-statement list** (periods +
  dates). `nip <nip>` resolves a tax id → KRS via the MF whitelist. `search "name"` uses the stealth
  browser (the portal is Incapsula-protected) and returns tagged `{krs, name, city, register}`
  candidates → then `analyze <krs>`. Figure extraction from the e-sprawozdania (JPK XML) is
  session-gated and not implemented; the filing list + repository link are returned.
- **UK (Companies House)**, free API, balance-sheet metadata; needs `COMPANIES_HOUSE_API_KEY`.
  Parsed financial figures require XBRL (not implemented, see ROADMAP.md).

**Not supported (paid only):** Austria, Spain, Netherlands.

## Setup (non-German keys)

Keys are read from environment variables, or a local `config/keys.json` (git-ignored). Never hardcode.

```json
{ "COMPANIES_HOUSE_API_KEY": "…",   // UK, free at developer.company-information.service.gov.uk
  "INPI_API_TOKEN": "…" }           // France, optional (basic search works without)
```

Poland needs no key. Germany needs no key beyond the logged-in `claude` CLI.

Attribution

tfbeckertfbecker
View sourceMore from tfbecker →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1074701 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

695601 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

691 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →