Skip to main content
Glama
jkbngb

agentic-firmenbuch

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
FIRMENBUCH_API_KEYYesAPI key for accessing the Austrian Firmenbuch HVD SOAP service

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
search_companiesA

Find or look up Austrian companies by name — START HERE for any company lookup.

    This is the primary entry point: search/find/look up companies by NAME (substring) or
    filter by location, industry, legal form, size or financials, ranked. Whenever the user
    names a company or wants a list of companies, call THIS tool first (you do not need the
    Firmenbuchnummer/FNR to search by name). Read-only.

    Parameters:
    - filters (optional): a SearchFilters object; every field is optional and AND-combined
      (name substring; legal_form; bundesland; oenace_section/division/group and the
      4-digit oenace_class for one exact activity (11.05 = breweries; list_sectors(query=…)
      resolves a category word to the code); size_gkl W/K/M/G; bilanzsumme / anlagevermoegen
      / revenue / equity_ratio / employees min+max ranges; growth_profile; has_guv;
      last_filing_year_min;
      founded_year_min/max; gf_age_min; status active/inactive/all). Omit for an unfiltered
      list. Full-name inputs like "Wien" or "GmbH" are mapped to stored codes automatically.
      equity_ratio_min/max are FRACTIONS of the Bilanzsumme (0.35 = 35 % Eigenkapitalquote);
      percent-style values (>1.5, up to 100) are auto-converted /100, so 35 and 0.35 both
      mean 35 %.
    - sort (optional): {field, descending}; the sort field for the founding year is
      "founded_year" (never founded_year_min); an unknown field is rejected with the list
      of valid ones. field in {bilanzsumme, anlagevermoegen, revenue, equity_ratio,
      employees, last_filing_year, founded_year, revenue_growth_1y, revenue_growth_3y,
      revenue_growth_5y}
      (Umsatzwachstum: 1y YoY, 3y/5y CAGR; only companies with a multi-year GuV have them, the
      rest sort last) (or "distance" with a near filter); default bilanzsumme
      descending. Companies missing the sort field sort last. An unknown sort field is
      rejected with the list of valid ones. With a `query`, the matched companies are
      relevance-ranked by DEFAULT; pass an explicit sort to order them by that metric instead
      (e.g. "die größten Medienhäuser" -> query + sort bilanzsumme). For an exhaustive
      "largest in sector X" ranking prefer a structured filter (oenace_*) over query, since a
      query returns a relevance shortlist, not the whole sector.
    - page (optional, default 1) and page_size (optional, default 25, clamped to 1..100).
    - after (optional): KEYSET paging for bulk extraction — pass "" to start, then feed the
      response's `next_after` back here for each next page (FNR-ordered, no offset ceiling); an
      empty page means done. Not combinable with `query`/`near` (ranking has no stable cursor).
      Prefer this over deep `page` for exporting a whole segment. Credit-metered accounts:
      keyset pages are EXTRACTION and cost 1 credit per returned company (same rate as
      export_companies_csv); normal `page` browsing costs 1 credit per started 25 rows.
    - exact_count (optional, default false): force an exact `total` in keyset mode (a full COUNT
      scan). In normal (offset) mode `total` is always exact already; `total_semantics` reports
      "exact" vs "page_only".

    Returns the total match count plus a COMPACT summary card per company on the page (name,
    legal_form, bundesland, size, Bilanzsumme, equity ratio, revenue, growth, has_guv, industry)
    — NOT the full record. Use to find/rank companies; for one company's full profile call
    get_company_details, for the complete record call get_full_record, for aggregates over a
    whole group call get_cohort_summary.

    Query recipes (pick ONE primary strategy per user intent):
    - Specific company by name: filters={"name": "<name>"} — substring, case-insensitive.
      Results are relevance-ordered (exact/prefix matches first) when the hit set is small
      (≤200); a broader name acts as a market screen and keeps the numeric sort.
    - Industry as a CONCEPT ("tech companies", "Metallverarbeiter"): use oenace_division /
      oenace_group (codes + German labels via describe_fields), NOT geschaeftszweig.
    - Industry by literal ACTIVITY TEXT: geschaeftszweig matches the Firmenbuch free-text
      description as substring ("anlagenbau" works; "technisch" won't — it's not semantic).
    - Free-text query: filters={"query": "<text>"} searches name + activity and combines with
      all structured filters; cards carry match_reason. Semantic activity recall is live — a
      concept query surfaces companies by what they DO even without the literal words, and the
      matched pool is relevance-ranked by default (pass an explicit sort to override).
    - Region: bundesland (broad) > city (exact town) > postal_code prefix. Radius: use
      near={"place":"Gmunden","radius_km":25} or near={"postal_code":"4810","radius_km":25};
      cards get distance_km and sort by distance. An ambiguous town name is rejected with the
      candidate PLZs.
    - Recent corporate EVENT ("companies that raised capital / changed management / were
      acquired / changed owners"): add event_signal + event_since to filters, e.g.
      filters={"oenace_division":"41","bilanzsumme_min":5000000,"event_signal":["capital_raise"],
      "event_since":"2024-01-01"}. Signal groups: "ownership_change" (Gesellschafter-
      Kapitaländerung, often a share transfer), "leadership_change", "capital_raise",
      "restructuring" (Verschmelzung/Spaltung/…), "new_company", "closure", "rebrand",
      "relocation". Combines with EVERY financial/profile filter; each returned card gains
      `events` (the triggering register changes, rich values on forward events) +
      latest_event_date. Default window 365 days. This is the deal-sourcing / sales-trigger
      surface. Pro. (For the raw cross-company event log use list_events; for counts
      get_event_stats.)
    - Zero hits? Read `relaxations` in the response and adjust THAT filter; do not retry
      blind variations. `applied_filters` echoes how your inputs were normalized.

    The response also carries has_more (another page exists) and, when total==0 with ≥2
    filters, relaxations (which single filter to drop, most-permissive first).
    Field reference: https://www.agentic-firmenbuch.at/felder.html
    
get_company_detailsA

Full served profile for one company by FNR. Read-only.

    Parameters:
    - fnr (required): Firmenbuchnummer, e.g. "123456a" (the `fnr` from a search card).
    - include (optional): which optional sections to serve, subset of
      ["bilanz", "guv", "ratios", "management", "events", "industry"]; omit for ALL sections
      (the full profile). Identity, location, company, size, filings and the financials
      scalars (latest values) are always included. Use this to keep the response small when
      you only need part of the profile.
    - history (optional, default true): false drops the per-metric year series (the latest
      values stay) — use get_company_history when you later need a specific trend.

    Null fields are omitted from the response (a missing key means "no data for this
    company"; describe_fields documents every field that CAN exist). Returns one company's
    identity, location, financials (per-year Bilanz + GuV), all computed ratios, growth,
    employees, filings, and management. Use when you already know the company
    (from search_companies); for the complete record (full position taxonomy, unknown-code
    passthrough, per-year lineage) use get_full_record; for specific metric trends use
    get_company_history.
    Field reference: https://www.agentic-firmenbuch.at/felder.html
    
describe_fieldsA

Catalog of every field the server can return, by tool tier (search card -> full profile -> full record), with code tables and availability/null rules. Read-only, no parameters.

    This describes the SCHEMA only (field names, types, code tables, null rules) so you can
    pick the right tool and interpret its output. It returns no company data itself; for that
    call search_companies (many) or get_company_details / get_full_record (one). Call this
    once up front when unsure what a field means or which tool to use.
    Human-readable version: https://www.agentic-firmenbuch.at/felder.html
get_company_historyA

Per-metric multi-year time series for one company — or a whole cohort. Read-only.

    Parameters:
    - fnr: Firmenbuchnummer, e.g. "123456a" (the `fnr` from a search card) — one company.
    - fnrs: list of up to 50 Firmenbuchnummern for a BATCH in one call (a Branchenradar
      over a 30-200 cohort pages through this instead of one call per company). Unknown
      numbers land in `result.not_found`; billing stays per company (1 credit each),
      only companies actually returned are charged. Pass fnr OR fnrs.
    - metrics (optional): list of metric names to return, e.g.
      ["bilanzsumme", "umsatzerloese", "eigenkapital"]; omit to get every available series.
      The card alias "revenue" is accepted for "umsatzerloese".

    Returns, per requested metric, the yearly values (year -> value) plus latest/latest_year
    (batch: the same shape per company under `result.companies`). Use when you need the
    trend of specific figures; for a full one-shot profile use get_company_details, for
    the complete record (all positions) use get_full_record.
    
get_full_recordA

Complete per-company record, the full superset we hold for one company. Read-only.

    Parameter:
    - fnr (required): Firmenbuchnummer, e.g. "123456a" (the `fnr` from a search card).

    Returns everything: every position's full per-year history, unknown-code passthrough
    (nothing dropped), completeness flags, guv_years, and lineage (§5.1). This is the heaviest
    read. Use it when you need raw completeness; for the normal curated profile use
    get_company_details, for a single metric's trend use get_company_history.
    
get_documentA

Get a time-limited download link to a company's official Jahresabschluss document. Read-only.

    Parameter:
    - doc_key (required): a filing's `document_ref` ("{fnr}:{stichtag}") from
      get_company_details, a bare FNR (-> latest filing), or a legacy doc_key.

    Returns `download.url`, a signed link valid for 15 minutes (900 s; the exact expiry is
    `download.expires_at` / `expires_in_seconds` in the response — open it promptly, don't
    expect bytes inline), plus the `financial_institution` flag + caveat for banks/insurers,
    whose figures live only in the PDF. If the PDF is not in the archive yet it is fetched
    on demand from the register (the first call for a year can take up to ~1 minute);
    `download` is null only when the register itself holds no document for that filing. Use to
    fetch the original filing artifact; for the already-parsed figures use
    get_company_details / get_full_record instead of downloading.
get_document_textA

Return the TEXT of a company's official Jahresabschluss filing so you can read the Anhang, Lagebericht and positions directly (XML filings are flattened to "label: value" lines, PDF filings are text-extracted). Read-only.

    Parameters:
    - doc_key (required): a filing's `document_ref` ("{fnr}:{stichtag}") from
      list_documents / get_company_details, or a bare FNR (-> latest filing).
    - max_chars (optional, default 40000, max 120000): cap on the returned text;
      `truncated` tells you when the document is longer.

    Use for questions about the wording of a filing ("Was steht im Lagebericht zum
    Ausblick?", "Welche Risiken nennt der Anhang?"). For the parsed figures use
    get_company_details; for a download link use get_document. Cite the Stichtag.
search_personsA

Find the companies a person represents (Geschäftsführung, Vorstand, Prokura, Aufsichtsrat) by NAME over the official register roster. Read-only, public data only.

    Parameters:
    - name (required, min. 3 characters): part of the person's name, case-insensitive
      ("Pöpperl", "Christian Pöpperl").
    - limit (optional, default 50, max 200): maximum companies scanned.

    Returns `persons[]` grouped by the exact name found, each with `companies[]`
    ({fnr, name, city, role}). Name equality is not identity: say so when several people
    share a name. Use for "Welche Firmen führt X?"; for a company's own officers use
    get_company_details.
list_sectorsA

Valid filter values for search_companies, with company counts. Read-only.

    Optional `query`: a German category word or phrase ("Brauereien", "Steuerberater",
    "Softwarefirma") -> `matches` with the ÖNACE level, code, official label, an activity
    concept and the search_companies filter to use (oenace_section/division/group). Use this
    instead of guessing a code; a concept-only match means "use filters.query".

    Returns the legal-form (Rechtsform) codes and the size-class (`gkl`: W/K/M/G) values
    present in the served dataset, each with its count. Call this first to discover the real
    `legal_form` / `size_gkl` values to pass to search_companies or get_cohort_summary, instead
    of guessing codes. For region/format coverage instead, use get_coverage.
    
get_cohort_summaryA

Aggregate statistics for a cohort of companies. Read-only.

    Parameters:
    - dimension (required): which axis defines the cohort, one of "gkl" (size class),
      "bundesland" (federal state), or "legal_form" (Rechtsform). The search-filter alias
      "size_gkl" is accepted for "gkl".
    - value (required): the cohort value on that axis, e.g. dimension="bundesland",
      value="Wien" (full name or the code "W" both work); dimension="gkl", value="M".
      Use list_sectors to see valid legal_form / gkl values.

    Returns cohort counts plus distribution statistics (e.g. Bilanzsumme median; the exact
    median is skipped for very large cohorts to keep the request fast), NOT per-company rows.
    Use for "what does group X look like in aggregate"; for the individual companies use
    search_companies, for one company use get_company_details.
    
find_peersA

Find the companies most similar in size to a given one. Read-only.

    Parameters:
    - fnr (required): the reference company's Firmenbuchnummer, e.g. "123456a".
    - n (optional, default 10, clamped to 1..50): how many peers to return.

    Returns up to `n` companies in the SAME size class (`gkl`) as the reference, preferring
    the same ÖNACE industry as SPECIFICALLY as possible: the cascade class -> group ->
    division -> section widens only when a level has too few companies, and any remaining
    slots are filled with the nearest same-size companies from other industries — closest by
    Bilanzsumme within the class and group levels; on broader levels a reference with a
    registered activity text gets the most similar activities first. Each is a compact card
    like search_companies. The response
    carries `same_sector_level` ("class"/"group"/"division"/"section"/null: how specific the
    industry match is), `same_sector_count`, and an explicit `note` when the match is only
    section-wide or the list is (partly) a pure size-neighbourhood — so you never mistake
    same-size-different-industry rows for a sector benchmark (e.g. holdings whose stated
    industry differs from the group's). The reference company is excluded; an empty list means
    the FNR is unknown or has no Bilanzsumme to rank against. Recency: only companies whose
    last Jahresabschluss is from the current year minus 3 or later qualify; when fewer than
    `n` class/group-level peers exist in that window it widens once to minus 5 and the `note`
    says so (`peer_recency` = {years, min_year, widened}); every peer row carries
    `latest_year`. For a strict industry benchmark, filter search_companies by oenace_* + size
    instead; for group aggregates use get_cohort_summary.
    
benchmark_companyA

Where one company stands in its peer group — a composite over find_peers + the company's precomputed size-peer percentiles. Read-only. Pro.

    Parameters:
    - fnr (required): the company's Firmenbuchnummer, e.g. "123456a" (an "AT:" prefix is
      tolerated).
    - n (optional, default 10, clamped 1..50): how many peers to include.

    Returns the company's headline metrics (bilanzsumme, revenue, equity_ratio, growth_profile),
    its `percentiles` WITHIN its UGB size class (100 = top of the class; available for
    bilanzsumme and equity_ratio), and the nearest peers (same size class, same ÖNACE section
    preferred, recent filers only: last Jahresabschluss within 3 years, widened once to 5 when
    too few exist, see `peer_recency` + `peers_note`; each peer carries `latest_year`). Use for
    "how does X compare to its peers"; for the raw peer list use find_peers, for whole-cohort
    aggregates use get_cohort_summary.
    
list_documentsA

List a company's available official documents, newest first. Read-only, metadata only.

    Parameter:
    - fnr (required): Firmenbuchnummer, e.g. "123456a" (an "AT:" prefix is tolerated).

    Returns ONE merged chronology, strictly newest-first: every entry is
    {type, stichtag, financial_year, document_ref, format, parsed, note?}. Two types:
    `annual_financial_statement` (a filed Jahresabschluss; `parsed=true` means figures are
    served) and `abschluss_document_pdf` (an Abschluss-carrying PDF the register holds beyond
    the plain filing — Konzernabschluss, HV-Protokoll m. Jahresabschluss, Lagebericht — with
    its `dokumentart` label; always `parsed=false`). A Konzernabschluss next to the same
    year's Jahresabschluss is a DIFFERENT document, not a duplicate. Years held only as PDF
    appear with `parsed=false` + a `note` — no extracted figures, but the original stays
    downloadable (an honest gap, never silent). Pass any entry's `document_ref`
    ("{fnr}:{stichtag}") to get_document for a signed download link. No download link and no
    personal data here — use get_document for the file, get_company_details for the figures.
    
list_eventsA

Cross-company feed of register CHANGES (Vollzuege), newest first — the market-watch / deal-sourcing surface. Read-only. Pro.

    Answers "which companies changed X, where, since when" in one call — e.g. management
    changes, capital increases, relocations across a region or industry, or a watchlist of FNs.
    For the change history of ONE known company, use get_company_details (its `events[]`).

    Parameters (all optional, AND-combined):
    - types: DETAILED (with before/after values), forward from 2026-07-01: "name_change",
      "seat_change", "legal_form_change", "capital_change", "management_change". COARSE
      historical (type + date only, source=change_feed, back to ~2020): "founding", "deletion",
      "merger",
      "split", "conversion", "contribution", "consolidation", "division",
      "shareholder_capital_change", "management_join", "management_leave". Omit for all. The
      M&A/restructuring types (merger/split/conversion/…) + capital_change + deletion are the
      deal- and distress-signal surface.
    - since / until: ISO dates ("2024-01-01"). Default window: the last 30 days.
    - bundesland: full name ("Wien") or code; oenace_section (letter) / oenace_division
      (2-digit); legal_form ("GmbH" or a Firmenbuch code) — same facets as search_companies.
    - fnrs: restrict to these Firmenbuchnummern (a watchlist).
    - page (1), page_size (25, max 100).

    Returns {total, page, page_size, since, until, events:[{fnr, name, date, type, description,
    source, capital_from, capital_to, managers_added, managers_removed, bundesland,
    industry_section}]}. `source` is "change_feed" for the coarse historical events (no
    before/after values) vs the detailed daily-diff events. An empty result means no matching
    change in the window (not missing data).
    Field reference: https://www.agentic-firmenbuch.at/felder.html
    
get_event_statsA

Aggregate counts of register changes by type and by Bundesland over a window. Read-only. Pro. Use for market-watch dashboards ("how many capital increases in OÖ this month"); for the individual changes use list_events.

    Parameters (all optional): since / until (default last 30 days); bundesland; oenace_section;
    oenace_division; legal_form — same facets as list_events. Returns {since, until, total,
    by_type, by_bundesland}. Forward-only from 2026-07-01.
    
get_coverageA

How much of the register we actually serve, as an aggregate dashboard. Read-only, no parameters.

    Returns coverage counts broken down by data availability — companies with parsed XML
    financials vs PDF-only (linked but not machine-readable) vs none — and by format/status, so
    you can gauge what share of the universe has usable financials. It is a dataset-wide
    overview (served O(1) from a precomputed stats doc), NOT per-company data, no filters. Use
    for "how complete is the data"; for the valid filter values use list_sectors, for one
    group's aggregate figures use get_cohort_summary.
    
get_my_usageA

Your own API-key usage: call count and weighted compute-units, per tool. Read-only.

    Parameter:
    - window (optional, default "today"): one of "today", "yesterday", "month_to_date",
      "last_30_days", "all".

    Returns only the calling key's own usage (totals + per-tool breakdown) for that window,
    plus `plan` (the plan in force). Credit-metered accounts additionally get `credits_used`
    (credits charged in the window), `credits_remaining` (current balance) and the `credits`
    block with per-lot detail — for them, Credits are the billing unit (calls/compute_units
    are internal telemetry; failed attempts cost 0). Free-plan keys use this to check their
    consumption against the monthly free quotas. Never another user's data and never the
    e-mail behind the key.
export_companies_csvA

Export a whole search result set as ONE downloadable CSV file (a lead list) instead of paging through search_companies 25 rows at a time. Read-only over company data; each call writes a new short-lived export file (auto-deleted after ~1 day).

    Use this when the user wants a list to open in Excel / import elsewhere ("exportiere",
    "als CSV/Liste", "alle GmbHs in … herunterladen"). For browsing or ranking on screen use
    search_companies; for one company's full profile use get_company_details.

    Parameters:
    - filters (optional): a SearchFilters object — EXACTLY the same filters as search_companies
      (name; legal_form; bundesland/city/postal_code; near radius; oenace_division/group /
      geschaeftszweig; size_gkl; bilanzsumme / revenue / equity_ratio / employees ranges
      (equity_ratio as a fraction, 0.35 = 35 %; percent values auto-converted);
      growth_profile; founded/last-filing years; gf_age_min; manager_name; status). AND-joined.
    - sort (optional): {field, descending}, same fields as search_companies (default bilanzsumme
      descending; "distance" with a near filter).
    - max_rows (optional, default 1000, hard maximum 10000): row ceiling. Free plan is capped at
      100 rows with basic columns only. For a set larger than 10000, refine the filters
      (Bundesland/Branche/Größe) and export in parts.

    CSV format: semicolon-separated, UTF-8 with BOM (opens cleanly in Excel-DE, umlauts intact).
    Columns are exactly the search card fields: fnr, name, legal_form, street, postal_code,
    city, bundesland, industry_section, oenace_division(+label), geschaeftszweig, size_gkl,
    bilanzsumme_latest, equity_ratio_latest, revenue_latest, growth_profile, manager_name, and
    distance_km when a near filter is used. Empty values are blank cells. No fields beyond the
    card — the same personal-data gating applies.

    Returns {rows, download_url, expires_minutes (60), columns, truncated, note}. The
    download_url is a signed link valid for 60 minutes (3600 s; exact expiry in
    `download.expires_at` — open it promptly, don't expect bytes inline); the underlying
    file is deleted after about one day. When the result was capped (truncated=true), the
    note says so and asks you to refine.
    Field reference: https://www.agentic-firmenbuch.at/felder.html
    

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.6/5.0

Scored across 18 tools

Disambiguation4/5

The set covers distinct operations (search, profile, history, documents, events, peers, aggregates), but the three company-record tools get_full_record, get_company_details, and get_company_history overlap in scope, requiring careful reading to choose correctly. The descriptions explicitly disambiguate, so an attentive agent can avoid misselection.

Naming Consistency5/5

All 18 tools use snake_case with a predictable verb_noun pattern (get_, list_, search_, find_, export_, describe_, benchmark_). No camelCase or mixed conventions; the naming is consistent throughout.

Tool Count4/5

18 tools for a rich read-only register API with search, profile, documents, events, persons, benchmarks, and meta endpoints is slightly above the typical 3–15 range but each tool appears to serve a distinct capability. No obvious redundant tools, though the number is on the heavy side.

Completeness5/5

The surface covers company lookup, detailed profiles, full records, multi-year histories, document metadata, text extraction, download links, person search, sector filters, cohort aggregates, peer benchmarks, event feeds/stats, coverage, and usage. For a read-only Firmenbuch API, this is comprehensive with no obvious dead ends.

Maintenance

ActivitySlowing
ResponsivenessResponsive