{
  "markdown": "# agentic-firmenbuch\n\n> **Austria's entire company register, queryable by AI agents in plain language.** Official master data, annual accounts and key ratios for every firm – served over MCP, answered on real numbers instead of hallucinations.\n\n**[Try the playground](https://www.agentic-firmenbuch.at/playground.html)** &nbsp;·&nbsp; **[Get a free key](https://www.agentic-firmenbuch.at)** &nbsp;·&nbsp; **[Quickstart ↓](#quickstart)**\n\nA live, automated data product over the Austrian **Firmenbuch** (free EU **HVD** / High Value Datasets), served through a **multi-tenant MCP server**. A deterministic Azure pipeline pulls the published Jahresabschluss (annual financial statement) filings from the official register, parses them, consolidates per company, computes ratios/growth/trends, and serves the result to MCP clients. The whole register holds ~640k legal entities; the served slice is currently ~341k and grows as the backfill progresses. **Version 1** = facts + clean derivations only (no scoring, no third-party enrichment, no NACE, no AI summaries).\n\n> **Also available: Germany and the wider DACH region.** Alongside this Austrian product, a unified **`agentic-register`** endpoint serves both the Austrian **Firmenbuch** and the German **Handelsregister / Unternehmensregister** over a single MCP. It is listed in the official MCP registry as **`io.github.jkbngb/handelsregister`** (spec: [`handelsregister.server.json`](handelsregister.server.json)) and reachable at `https://register.agentic-firmenbuch.at/mcp` with the same free API key. A search returns matches from both countries, tagged by `country` (`AT` / `DE`).\n\n## Quickstart\n\n**Use the hosted service** – query official Firmenbuch data from an MCP client that accepts an HTTP header key (Claude Code, VS Code with GitHub Copilot, Cursor, …):\n\n1. Get a free API key at **[agentic-firmenbuch.at](https://www.agentic-firmenbuch.at)** – just a verified email.\n2. Add the server. **Claude Code** (terminal), one line:\n   ```bash\n   claude mcp add --scope user --transport http agentic-firmenbuch https://mcp.agentic-firmenbuch.at/mcp --header \"X-API-Key: <your-key>\"\n   ```\n   **GitHub Copilot / VS Code**: `code --add-mcp \"{\\\"name\\\":\\\"agentic-firmenbuch\\\",\\\"type\\\":\\\"http\\\",\\\"url\\\":\\\"https://mcp.agentic-firmenbuch.at/mcp\\\",\\\"headers\\\":{\\\"X-API-Key\\\":\\\"<your-key>\\\"}}\"`. Any other HTTP-MCP-Header client: URL `https://mcp.agentic-firmenbuch.at/mcp`, header `X-API-Key: <your-key>`.\n3. Ask in natural language, e.g. *\"Aktive GmbHs in Oberösterreich mit Bilanzsumme über 5 Mio. €, sortiert nach Umsatz.\"* The agent calls `search_companies` / `get_company_details` and answers with official data – no SDK required.\n\n> **Claude Cowork & claude.ai** (sandboxed clients) don't take the API-key header – they connect via `Settings → Connectors → Add custom connector` with the URL `https://mcp.agentic-firmenbuch.at/mcp` and a one-time email login (OAuth, no key). Step-by-step with screenshots: **[agentic-firmenbuch.at/cowork.html](https://www.agentic-firmenbuch.at/cowork.html)**.\n\nPrefer to try before signing up? Use the **[playground](https://www.agentic-firmenbuch.at/playground.html)**.\n\n**Or run the pipeline yourself** – clone, `uv sync`, `uv run pytest` (offline, no Azure). See [Develop](#develop).\n\n## Available MCP tools\n| Tool | Purpose |\n|---|---|\n| `search_companies` | Filter / rank Austrian companies by region, size, balance-sheet total, equity ratio, revenue, growth profile, management age, last filing year, status. Returns a compact result card per match. |\n| `get_company_details` | Full served profile of one company: identity, location, founding/filing years, size class, multi-year balance sheet + P&L, 13 computed ratios, growth, management, list of filings. |\n| `get_full_record` | Superset of `get_company_details`: full 317-position UGB taxonomy, passthrough unknown codes, completeness, GuV-years, signatories history, derivations registry. |\n| `get_company_history` | Filing-by-filing time series of every reported position for one company. |\n| `find_peers` | K-nearest peer set for a company within its size class / region. |\n| `get_cohort_summary` | Aggregate statistics (counts, percentiles, distributions) for a filtered cohort. |\n| `get_coverage` | Per-Bundesland / per-Rechtsform / per-size-class coverage statistics for the served dataset. |\n| `list_sectors` | Available legal-form (`Rechtsform`) and Bundesland codes for use in filters. |\n| `describe_fields` | Self-describing field dictionary with type + null-rules + EBIT/EBITDA definition. |\n| `get_document` | Fetch the URL/blob key for an original filed annual statement (XML or PDF). |\n\nAll tools return a **processed derivative of official Austrian Firmenbuch data** (source: BMJ – Justiz, CC BY 4.0). Concretely: we ingest the published filings from the register, parse and consolidate them, compute ratios, and serve that from our own database — no web scraping, no LLM-generated summaries, no third-party data mixed in (V1). Every response carries `provenance.data_version` + `built_at` and names the original source, so the agent can attribute it correctly; for the authoritative record, the official Firmenbuch always governs.\n\n**Currently served**: ~341,000 active legal entities across all Rechtsformen (GmbH, AG, KG, OG, EU, Genossenschaft, Privatstiftung, SE …). The full register has ~640,000 entities; the gap is companies without a published Jahresabschluss plus inactive/deleted entries, which are added step by step.\n\n## Documentation\n\nFull index with the versioning convention (shipped `_v1` specs vs. the forward\n[`ROADMAP.md`](ROADMAP.md) + V2 design spec): **[docs/README.md](docs/README.md)**.\nThe headline documents:\n\n| Doc | What it is |\n|---|---|\n| [docs/pipeline-step-samples.md](docs/pipeline-step-samples.md) | File format + golden sample for every pipeline stage. |\n| [docs/FIELD_REFERENCE.md](docs/FIELD_REFERENCE.md) | **Served field dictionary** – every field each MCP tool returns, with type + null rules. Public page: [felder.html](https://www.agentic-firmenbuch.at/felder.html). |\n| [ROADMAP.md](ROADMAP.md) | Forward plan – status/priorities and the V2 direction (banks/insurers, GISA, Ediktsdatei). |\n| [docs/appendix_position_mapping.json](docs/appendix_position_mapping.json) | Full 317-entry canonical position taxonomy → copied into `products/agentic-firmenbuch/packages/core_at/…/mapping/`. |\n| [docs/reference/](docs/reference/) | Official source material (API reference, JAb 4.0 XSDs/Excel). |\n\n## Monorepo layout (`agentic-first`)\n\nThis repository is the **`agentic-first`** monorepo umbrella. It separates **source-agnostic\nshared code** from **per-source products**, so another source-specific product can be added without\ntouching the Austrian pipeline:\n\n```\nagentic-first/                       (this repo)\n├── packages/                        SHARED — source-agnostic, zero Firmenbuch/UGB knowledge\n│   ├── core/    (fbl_core)          lineage/meta + metric contracts, config, storage clients\n│   └── auth/    (fbl_auth)          signup, token issue/validate, metering, 00_accounts\n└── products/\n    └── agentic-firmenbuch/           AUSTRIA product (live) — README below\n        ├── packages/\n        │   ├── core_at/  (fbl_core_at)   UGB taxonomy, Firmenbuch domain models, ÖNACE, FI dirs\n        │   ├── firmenbuch_client, 99_registry, 90_ingest, 70_parse,\n        │   │   50_consolidate, 30_derive, 10_present, mcp_server, orchestration\n        │   └── …\n        └── tests/                   AT integration tests + golden fixtures\n```\n\nAdditional source-specific products are added in their **own separate repositories** that consume\n`packages/{core,auth}` as a dependency (they are not scaffolded here). The precise\n1:1 / adapt / product-local reuse boundary is the **reuse table (Appendix R)** of the technical spec, and the generic recipe is in\n[docs/monorepo/ADDING_A_PRODUCT.md](docs/monorepo/ADDING_A_PRODUCT.md).\n\n**Product READMEs:** [agentic-firmenbuch](products/agentic-firmenbuch/README.md) · shared [`core`](packages/core/README.md) · [`auth`](packages/auth/README.md)\n\n## Pipeline (numbered layers, `90 → 10`)\n```\n99_registry (foundation: all companies)  →  90_raw (Blob)  →  70_parsed (Blob)  →  50_consolidated  →  30_derived  →  10_presentation  →  MCP\n                                                                        (Cosmos)            (Cosmos)        (Cosmos)\n   side: 00_accounts (MCP signup) · 00_directories (register-based FI flag, OeNB)   reserved for v2: 40_enriched, 20_scored\n```\n`90_raw` is the **immutable source of truth** (every downloaded XML/PDF, kept forever). `70_parsed`\nis a **write-through cache** of the per-filing `ParsedFiling` JSON – always re-derivable from raw,\nso safe to drop/rebuild; it exists so a reprocess (re-consolidate/derive after a logic change)\n**skips re-parsing** all filings, and so the lineage `inputs[]` in each consolidated doc resolve to a\nreal parsed document. `50/30/10` are the queryable Cosmos layers; `10_presentation` is what the MCP\nserves.\n\n## LAYER_MAP – which code owns which layer\nEach pipeline-stage package directory is **prefixed with its layer number** so the\nowner of every data layer is obvious. (Python module names can't start with a digit, so\nthe importable package keeps its `fbl_*` name; the number is also exposed as a `LAYER`\nconstant in each stage package.)\n\nAll AT stage packages live under `products/agentic-firmenbuch/packages/` (abbreviated `…/` below).\n\n| Layer | Package (dir) | import | Store / container | Pydantic model | Sample |\n|---|---|---|---|---|---|\n| `99_registry` | [`…/99_registry`](products/agentic-firmenbuch/packages/99_registry/README.md) | `fbl_registry` | Cosmos `99_registry` | `RegistryDoc` | §15a.0 doc |\n| `90_raw` | [`…/90_ingest`](products/agentic-firmenbuch/packages/90_ingest/README.md) | `fbl_ingest` | Blob `90-raw` | raw `Meta` + manifest | [Stage 0](docs/pipeline-step-samples.md) |\n| `70_parsed` | [`…/70_parse`](products/agentic-firmenbuch/packages/70_parse/README.md) | `fbl_parse` | Blob `70-parsed` | `ParsedFiling` | [Stage 1](docs/pipeline-step-samples.md) |\n| `50_consolidated` | [`…/50_consolidate`](products/agentic-firmenbuch/packages/50_consolidate/README.md) | `fbl_consolidate` | Cosmos `50_consolidated` | `ConsolidatedCompany` | [Stage 2](docs/pipeline-step-samples.md) |\n| `30_derived` | [`…/30_derive`](products/agentic-firmenbuch/packages/30_derive/README.md) | `fbl_derive` | Cosmos `30_derived` | `DerivedCompany` | [Stage 3](docs/pipeline-step-samples.md) |\n| `10_presentation` | [`…/10_present`](products/agentic-firmenbuch/packages/10_present/README.md) | `fbl_present` | Cosmos `10_presentation` | `PresentedCompany` | [Stage 4](docs/pipeline-step-samples.md) |\n\n**Un-numbered.** Shared (in `packages/`): [`core`](packages/core/README.md) (`fbl_core`,\nsource-agnostic lineage/meta + metric contracts, config, storage) and\n[`auth`](packages/auth/README.md) (`fbl_auth`, `00_accounts`). AT-specific (in\n`products/agentic-firmenbuch/packages/`): [`core_at`](products/agentic-firmenbuch/packages/core_at/README.md)\n(`fbl_core_at`, UGB taxonomy + Firmenbuch domain models + ÖNACE + FI directories),\n[`firmenbuch_client`](products/agentic-firmenbuch/packages/firmenbuch_client/README.md)\n(`fbl_firmenbuch_client`, HVD SOAP adapter),\n[`orchestration`](products/agentic-firmenbuch/packages/orchestration/README.md)\n(`fbl_orchestration`, the `--mode` Job entrypoint),\n[`mcp_server`](products/agentic-firmenbuch/packages/mcp_server/README.md)\n(`fbl_mcp_server`, serving). Plus [`products/agentic-firmenbuch/tests/`](products/agentic-firmenbuch/tests/README.md) (fixtures),\n`docs/` (incl. [API probe findings](docs/API_PROBE_FINDINGS.md)).\n\n## Build status – Version 1 complete ✅\nAll ten §15 build stages are implemented, each committed in order, each with a passing\nDefinition of Done. **`ruff` + `mypy --strict` + `pytest` (with an 80% coverage gate) are\ngreen** in CI. The HVD API was live-probed (§16 resolved) and the full chain\nraw→present was verified on live data end-to-end.\n\n- **Stage 10:** an auth-restricted **coverage** tool (XML vs PDF-only vs none, by\n  format/status – §11) and **GitHub Actions CI** (`uv sync` → ruff → ruff format →\n  `mypy --strict` → pytest with an 80% coverage gate, plus a Bicep-compile job).\n\n**What's left to operate** (not code): provision Azure (`infra/setup.sh`, billable),\npush the FIRMENBUCH_API_KEY to Key Vault, build/push images, then run the Initial Load\n(`sync-registry → backfill-ingest → backfill-process`) and enable the daily cron.\n\n## Develop\n```bash\nuv sync                            # create the workspace venv\nuv run pytest                      # all fixture/unit/integration tests (offline)\nuv run mypy packages products      # strict types (shared + products)\nuv run ruff check packages products  # lint\n```\n**True end-to-end (live):** a separate, env-flag-guarded test runs a few real FNRs\nthrough every layer (API → `90_raw` → … → `10_presentation` → MCP). Skipped by default.\n```bash\nFBL_E2E=1 uv run pytest products/agentic-firmenbuch/tests/e2e -q  # needs FIRMENBUCH_API_KEY\n```\nSee [`products/agentic-firmenbuch/tests/e2e/`](products/agentic-firmenbuch/tests/e2e/README.md). It uses in-memory stores + a tiny real pull –\n**no Azure, no full backfill** (deployment is manual after review).\n\n## License & data\n\nLicensed under the **MIT License** (see [`LICENSE`](LICENSE)).\n\nThe data originates from the **Austrian Firmenbuch** (BMJ – Justiz), an EU High Value Dataset\nlicensed under **CC BY 4.0**. Any redistribution of the data must keep the attribution\n*\"Quelle: Österreichisches Firmenbuch / BMJ – Justiz (CC BY 4.0)\"* (see [`NOTICE`](NOTICE)).\n\n## Disclaimer – no warranty, use at your own risk\n\nThis software and any data it produces are provided **\"AS IS\", WITHOUT WARRANTY OF ANY KIND**,\nexpress or implied (see the MIT License). The processed data is derived automatically from the\npublic Firmenbuch and is provided **without any guarantee of correctness, completeness, timeliness,\nor fitness for a particular purpose**. It is **not** legal, tax, or financial advice and does **not**\nreplace an official Firmenbuch extract – the official register always prevails.\n\n**Use of this software and the data is entirely at your own risk.** To the maximum extent permitted\nby law, the authors and copyright holders accept **no liability** for any direct, indirect,\nincidental, or consequential damages arising from its use. You are responsible for complying with\nthe CC BY 4.0 attribution requirement and all applicable data-protection, competition, and copyright\nlaw when using or redistributing the data.\n",
  "bytes": 14636,
  "sha": "ff73643b843deed80b2600dda57f77c137894c1cfa590d284a4d31a5dd3f1d69",
  "repo_slug": "jkbngb/agentic-firmenbuch",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_jkbngb_handelsregister_58bdf6b7/readme"
}