Firmaradar
The Firmaradar server provides comprehensive access to Norwegian company, ownership, financial, and compliance data for AI agents via ~25 MCP tools.
Company Search & Profiles
Search by name, NACE code, location, status, size, and founding date
Retrieve full profiles including organization form, employees, address, financials, owners, roles, and announcements
Find related companies via shared persons, addresses, or ultimate owners
Compare up to 5 companies side-by-side on key financial metrics
Monitor recent changes (announcements, role/ownership movements) for companies or persons
Ownership & Corporate Structure
Get ownership trees (upstream/UBO, downstream, or both) with full group hierarchy
Include personal shareholders and filter by minimum share percentage
Retrieve current and historic roles (board members, CEO, prokura, revisor)
Get group-wide public grants (konsernstøtte: Innovasjon Norge, SkatteFUNN, etc.)
Financial Data
Up to 20 years of revenue, operating results, equity, debt, and employee counts
Public tax list data (income, wealth, tax paid) per year
Person Lookup (requires full access tier)
Search persons by name (fuzzy matching), get profiles with address and birth year
List all company roles (current and historic) and shareholdings held by a person
Risk Scoring & Distress Assessment
Company risk score (0–100, lav/moderat/høy/kritisk) with component breakdown
Bulk risk scores for up to 50 companies in one call
Foretak i vanskeligheter (FIV) assessment under NUES criteria — single or bulk (up to 50)
Risk signals: bankruptcy/distress flags, capital-loss warnings, role changes, KYC anomalies
One-time disclaimer confirmation required before using risk scoring tools
AML / KYC / Compliance
PEP/sanctions screening against OFAC, EU, and UN lists with audit trail (stored 60 months)
Structured AML risk score (0–100) with factor breakdown and auditable report
Industry Analysis & Announcements
List all companies in a NACE sector with filters for status, location, and size
Search BRREG announcements (bankruptcies, mergers, ownership changes) by type, date, NACE, or location
Firmaradar MCP-server
Slå opp norske selskaper, eierstrukturer, konsernhierarkier og roller direkte fra Claude, ChatGPT, Cursor, Codex, Gemini og andre MCP-kompatible agenter.
Koble til (anbefalt) → · Verktøykatalog · Kom i gang · Prising · Dokumentasjon
Hva er dette?
Firmaradar er Norges agentiske infrastruktur for selskapsdata. Denne MCP-serveren gir AI-agenten din direkte tilgang til:
Mer enn 2 millioner norske enheter (BRREG-grunnregister, oppdatert daglig)
Aksjeeierregisteret fra Skatteetaten (eierandeler ned til person-nivå, opp gjennom hele konsernet)
Roller (styre, daglig leder, prokura) med historikk
Regnskap (årsregnskap, mellombalanser, signaler)
Kunngjøringer fra Brønnøysund og KYC-flagg
AML/PEP-screening med revisjonsspor
NACE-bransjeovervåkning (varsling ved nystiftet selskap i bransje og geografi)
Bygget for produksjon: OAuth 2.0 og DCR (Claude Mobile og Web støttes), API-nøkkel som alternativ (Cursor og Codex), loggført per kall, DSAR-eksport og GDPR-pseudonymisering på serversiden.
Related MCP server: CompanyIQ MCP Server
Kom i gang
Anbefalt — OAuth (Claude Web, Claude Mobile, Claude Desktop)
Lim inn denne adressen som tilkobling i klienten din. Du logger inn via firmaradar.no-konto og velger hvilken API-nøkkel agenten skal bruke.
https://mcp.firmaradar.no/mcpDetaljert veiledning per klient: firmaradar.no/koble-til-agent
Cursor, Codex eller andre — API-nøkkel via stdio
Hvis klienten din ikke støtter ekstern MCP, kan du kjøre serveren lokalt:
pip install firmaradar-mcp~/.cursor/mcp.json eller ~/.codex/config.toml:
{
"mcpServers": {
"firmaradar": {
"command": "firmaradar-mcp",
"env": {
"FIRMARADAR_API_KEY": "din-nøkkel-fra-firmaradar.no/min-side/api-keys",
"FIRMARADAR_API_BASE": "https://firmaradar.no"
}
}
}
}Hent API-nøkkel: firmaradar.no/min-side/api-keys (krever konto).
Verktøykatalog
35 verktøy — Python-pakka (firmaradar-mcp på PyPI) og remote-serveren (mcp.firmaradar.no) eksponerer alle:
Selskaps-oppslag
firmaradar_search_companies— søk på navn eller orgnrfirmaradar_get_company— full profil (organisasjonsform, NACE, ansatte, adresse, regnskap, eiere, roller)firmaradar_get_company_ownership— konsernhierarki opp og ned, eierandeler, person-nivåfirmaradar_get_company_roles— styre, daglig leder, prokura (med fratrådt-historikk)firmaradar_get_company_financials— årsregnskap, nøkkeltall og signalerfirmaradar_get_company_announcements— BRREG-kunngjøringer (vedtak, fusjoner, oppløsninger)firmaradar_get_company_signals— risikoflagg, KYC-flagg, insolvensfirmaradar_get_company_ip— IP-portefølje fra Patentstyret: patenter, varemerker og design (totaler, aktive, enkeltrettigheter med status og lenke)firmaradar_find_related_companies— finn relaterte selskaper via eierskap, roller eller adressefirmaradar_find_shared_connections— skjulte koblinger på tvers av 2–10 selskaper (felles styre, adresse, eiere/morselskap, sirkulært eierskap) med risikonivå og graf
Person-oppslag (krever full tilgang)
firmaradar_search_persons— navne-søk med toleranse for skrivefeilfirmaradar_get_person— profil med adresse og fødselsårfirmaradar_get_person_companies— alle selskaper personen eier eller har rolle ifirmaradar_get_person_roles— aktive og historiske roller
KYC og AML
firmaradar_check_aml_pep— full AML/PEP-screening med sanksjonslister og revisjonssporfirmaradar_get_aml_score— strukturert AML-risikoscore (0–100) med revisjonssporfirmaradar_start_aml_report— start en asynkron, revisjonssikker AML-rapport (for tunge eierstrukturer eller mange parallelle screeninger); lagret 60 mnd per hvitvaskingsloven §35firmaradar_get_aml_report— hent status og resultat (score, nivå, lenke) for en asynkron AML-rapport viareport_idfirmaradar_check_konkurs_eksponering— screen en person på navn for konkurseksponering: lederverv i selskaper som senere gikk konkurs, tidsvektet (review-flagg, ikke dom)
Bransje, overvåkning og abonnement
firmaradar_list_companies_in_nace— alle selskaper i en NACE-kode med geografisk filterfirmaradar_list_nace_codes— søk og bla i NACE-katalogen (SSB/BRREG); slå opp riktig kode, eller konverter EU NACE Rev. 2 → norske underkoderfirmaradar_get_recent_changes— endringer siste N dager for et orgnrfirmaradar_search_announcements— fritekst-søk i BRREG-kunngjøringerfirmaradar_compare_companies— sammenlikne flere selskaper side om sidefirmaradar_add_company_monitoring— legg et selskap til overvåkning; varsel ved kunngjøringer, statusendring (konkurs/oppløsning), eierskifte eller nye offentlige tilskuddfirmaradar_subscribe_nace— abonner på bransjeovervåkning (NACE) med webhook ved hendelser i bransjen; filtrer på hendelsestype, geografi og størrelsefirmaradar_list_my_subscriptions— list dine NACE-abonnement (id, kode, webhook, filtre, status)firmaradar_delete_subscription— slett ett NACE-abonnement på id (idempotent)
Risiko, FIV og konsern
firmaradar_get_risk_score— transparent selskaps-risikoscore (0–100) med komponent-breakdownfirmaradar_get_risk_score_bulk— risikoscore for en portefølje orgnr i ett kallfirmaradar_check_foretak_i_vanskeligheter— lovbestemt «foretak i vanskeligheter» (FIV)-vurderingfirmaradar_check_fiv_bulk— FIV-status for en portefølje orgnr i ett kallfirmaradar_get_konsernstotte— offentlig støtte gjennom konsernet (tre-struktur)firmaradar_confirm_risk_score_disclaimer— bekreft pre-screening-disclaimer før risk-score-verktøyene
Valuta
firmaradar_convert_nok— konverter NOK-beløp til EUR/USD/GBP/SEK/DKK med dagskurser fra Norges Bank (NOK-originalen bevares alltid)
Full API-referanse og eksempel-prompter: firmaradar.no/dokumentasjon
Priser
Vi tilbyr én plattformavgift (99 kr/mnd) + per-kall-prising. MCP-kallene har en egen pakke (mcp_full) som er rabattert for agentbruk siden agenter genererer høyere volum enn manuelle API-integrasjoner.
Detaljert prising: firmaradar.no/prising
Hvorfor åpen kildekode?
Transparens — du kan lese hver verktøy-modul og se nøyaktig hva agenten sender til Firmaradar.
Tillit gjennom gjennomgang — koden er Apache 2.0. Gå gjennom den selv, eller lås til en spesifikk versjon.
Bidrag velkommen — vi tar imot pull requests som forbedrer skjemaer eller legger til kompatibilitets-lag for nye klienter.
Backend (firmaradar.no) er proprietær fordi den eier dataflyten og lisensieringen mot Skatteetaten og Brønnøysund.
Sikkerhet og GDPR
OAuth 2.0 og PKCE (RFC 7636), Dynamic Client Registration (RFC 7591), Protected Resource Metadata (RFC 9728)
Alle delegerte tokens er lagret i PostgreSQL, knyttet eksplisitt til en API-nøkkel kunden valgte, og kan tilbakekalles uavhengig
Loggføring per kall (kunde-id, nøkkel-id, endepunkt og status) — eksporteres via DSAR-rapport
Person-data pseudonymiseres på serversiden; sikkerhetskopier er kryptert og lagres eksternt
Hele sikkerhets-policyen: firmaradar.no/personvern
Støtte og spørsmål
Feil i denne MCP-serveren → GitHub Issues
Spørsmål om data eller priser → kontakt Firmaradar
Salg eller partnerskap → lars@firmaradar.no
Mappestruktur
tools/mcp_server/
├── README.md — denne filen
└── python/ — pip-pakken «firmaradar-mcp» (PyPI)
├── pyproject.toml
├── firmaradar_mcp/
│ ├── server.py — MCP stdio og ekstern (streamable-HTTP)
│ ├── remote_server.py — OAuth 2.0 og DCR for Claude Mobile/Web
│ ├── client.py — REST-API-wrapper
│ └── tools/ — 35 verktøy-moduler
└── tests/Bygget av Firmaradar AS — agentisk infrastruktur for norske selskapsdata.
firmaradar.no · Prising · Dokumentasjon · Personvern
Available Tools
35 toolsfirmaradar_add_company_monitoringAdd Company to MonitoringAIdempotentInspect
Add a Norwegian company (by 9-digit orgnr) to the user's company-monitoring list. The user is then alerted when announcements, status changes (bankruptcy/dissolution), ownership changes or new public grants are registered for that company. New targets monitor ALL announcement categories by default; keep ip_alerts=true (default) to also turn on IP-change alerts when the account has the IP-monitoring add-on, or set ip_alerts=false to skip them. 409 if already monitored (idempotent — no duplicate). 403 (monitoring_cap_reached) if the account's company has hit its per-company monitoring cap — tell the user to contact Firmaradar to expand it. Requires a user whose plan has Firmaovervakning enabled. Call only when the user has asked to monitor a specific company.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | Norwegian organisation number (9 digits) to add to monitoring. | |
| ip_alerts | No | Also enable IP-change alerts for this company. Default true = monitor everything. Requires the IP-monitoring add-on (ip_overvakning) on the account; without it the company is still monitored for all announcement/status/ownership changes, but IP alerts stay off. Set false to skip IP alerts. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | True when the company was added. |
| raw | No | |
| orgnr | No | |
| ip_alerts_enabled | No | Whether IP-change alerts were turned on (false without the add-on). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description reveals side effects (user alerts on announcements/status/ownership changes), idempotency, 409 and 403 error conditions, and the IP-alert behavior depending on add-on. This is rich behavioral context that annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though lengthy, each sentence carries operational value: purpose, consequences, parameter guidance, errors, prerequisites, and trigger condition. It is front-loaded with the core action and structured logically, earning its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, behavior, parameter semantics, error handling, prerequisites, and usage conditions. With an output schema present, return values need not be described. No critical gaps exist for this tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage with detailed descriptions for orgmr and ip_alerts. The tool description mostly reiterates or paraphrases the schema text, adding no novel parameter-level semantics beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific verb+resource: 'Add a Norwegian company (by 9-digit orgnr) to the user's company-monitoring list.' It distinguishes itself from sibling tools, which are mostly read/search operations, by describing a write action (adding to monitoring).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use: 'Call only when the user has asked to monitor a specific company.' It also gives prerequisites (plan with Firmaovervakning) and error-handling guidance (409, 403 cap reached), leaving little ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_check_aml_pepAML / PEP ScreeningAInspect
Screen ONE natural PERSON's full name against sanctions (OFAC, EU, UN) and PEP lists. IMPORTANT — this is a PERSON tool only. Do NOT pass a company name, an organisation number (orgnr), or any non-person string here. For company-level AML risk use firmaradar_get_aml_score (by orgnr); to screen a company's owners/officers, first resolve the people via firmaradar_get_company_roles / firmaradar_get_company_ownership, then screen each PERSON name with this tool. Compliance-critical: PII-sensitive, requires a signed DPA and a legitimate purpose per call (free-text purpose parameter). Audit-logged for 60 months. Rate-limited to 50 calls / 30 min per API-key. Returns structured hits with category, sources, and match-ratio (default min 0.85).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Full name of ONE natural PERSON to screen (e.g. 'Ola Nordmann'). NOT a company name or orgnr — for company AML use firmaradar_get_aml_score instead. | |
| purpose | Yes | Legitimate purpose for this AML/PEP screening (free text, e.g. 'KYC verification for new customer acme-as'). Logged in compliance audit for 60 months. | |
| kategori | No | both | |
| birth_year | No | ||
| min_match_ratio | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| hits | Yes | |
| note | No | |
| hit_count | Yes | |
| query_name | Yes | |
| query_too_short | No | |
| query_birth_year | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate readOnlyHint=false, destructiveHint=false, etc., but the description adds critical operational context: PII-sensitive, requires signed DPA, legitimate purpose per call, audit-logged for 60 months, rate-limited to 50 calls/30 min, and returns structured hits with category/sources/match-ratio. This goes far beyond the basic safety flags.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but every sentence contributes a distinct fact: scope restriction, alternative tools, compliance prerequisites, audit/rate limits, and output expectations. It is front-loaded with the core purpose and reads efficiently without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a PII-sensitive compliance tool with 5 parameters and no nested objects, the description fully covers usage boundaries, workflow alternatives, legal prerequisites, rate limits, and a summary of return values. The output schema handles return structure details, so the description is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 40%, so the description must compensate. It adds semantic value by explaining `name` must be a single person, `purpose` is free-text compliance justification, and `min_match_ratio` defaults to 0.85. However, it does not clarify `kategori` or `birth_year` beyond schema defaults, leaving some burden unmet.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb and resource: 'Screen ONE natural PERSON's full name against sanctions (OFAC, EU, UN) and PEP lists.' It clearly scopes the tool to natural persons and explicitly distinguishes it from sibling company-focused AML tools such as firmaradar_get_aml_score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use and when-not-to-use guidance: do NOT pass company names or orgnr, and for company-level risk use firmaradar_get_aml_score. It also prescribes a workflow for company owner/officer screening by first resolving people via get_company_roles/get_company_ownership, then screening each person.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_check_fiv_bulkBulk Check Companies in Difficulty (FIV)ARead-onlyIdempotentInspect
Bulk-endpoint for portfolio-screening of 'foretak i vanskeligheter' (financially distressed companies per NUES rules a-e). Max 50 orgnr per call. Each orgnr counts as one unit against your quota. Compliance-gates (ENK blocking, invalid orgnr) are returned per orgnr in the result list instead of failing the whole call — check each result's error field. Use for screening supplier lists, credit-portfolios, or EU state-aid eligibility on multiple companies at once.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnrs | Yes | List of 1-50 nine-digit Norwegian organization numbers. Each orgnr counts as one unit against your quota. | |
| skip_freshness | No | If True, accept FIV-data even if the underlying regnskap- or BRREG-snapshot is older than the normal freshness window. Use sparingly — recommended only for retrospective screening. |
Output Schema
| Name | Required | Description |
|---|---|---|
| _meta | Yes | Aggregate count status for the whole bulk call. |
| results | No | |
| summary | No | Human-readable markdown table of the per-company FIV verdicts. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses quota unit consumption, per-org error handling ('check each result's error field'), and the max 50 restriction. These are key behavioral details not present in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences and dense with useful information, front-loading the purpose. It avoids fluff, though it is slightly longer than strictly necessary because some details repeat schema constraints.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the description correctly focuses on operational context: quota, error handling, and use cases. It is complete for a bulk-check tool with strong annotations and schema coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description reinforces the quota semantics but adds little beyond what the schema provides, meriting the baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool is a bulk endpoint for screening 'foretak i vanskeligheter' (distressed companies), immediately distinguishing it from the singular sibling tool. It specifies the exact domain (NUES rules a-e) and the scope (portfolio screening).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use for screening supplier lists, credit-portfolios, or EU state-aid eligibility on multiple companies at once', giving clear use cases. It does not explicitly say when NOT to use it or mention the singular alternative, but the 'bulk' framing implies the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_check_foretak_i_vanskeligheterCheck Company in Difficulty (FIV)ARead-onlyIdempotentInspect
Assess whether a Norwegian company qualifies as foretak i vanskeligheter (a 'company in difficulty') under NUES criteria a-e. Returns which criteria triggered, the overall distress status, and a data-completeness confidence score — a deterministic distress classification, not a raw registry flag. Use for EU state-aid eligibility, credit assessment, and supplier-risk screening.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit norwegian organization number. |
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | |
| as_of | No | |
| orgnr | Yes | |
| score | Yes | Confidence-weighted distress score in [0.0, 1.0]. |
| status | Yes | One of: not_distressed, insufficient_data, not_distressed_partial, exempt_young_company, distressed. |
| confidence | Yes | Data-completeness confidence in [0.0, 1.0]. |
| rules_fired | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only and idempotent behavior. The description adds meaningful context by noting the result is a deterministic classification rather than a raw registry flag, and mentions a data-completeness confidence score. This goes beyond structured data without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, stating the purpose, output, and use cases in two sentences without redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with an output schema, the description covers purpose, output, and use cases adequately. It lacks details on data sources or edge cases, but these are not critical given the tool's simplicity and annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage for the single parameter is 100%, and the description adds no supplementary parameter details. With full schema coverage, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool assesses Norwegian company qualification under NUES criteria a-e and returns a deterministic classification. It distinguishes from raw registry flags but does not explicitly name sibling tools, so it falls short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases (EU state-aid eligibility, credit assessment, supplier-risk screening) but does not specify when not to use or mention alternative tools. This is clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_check_konkurs_eksponeringBankruptcy Exposure Screening (by Name)ARead-onlyIdempotentInspect
Screen a person by NAME for bankruptcy exposure ('konkursgjenganger'): leadership roles (chair / managing director) held in companies that later went bankrupt, tenure-weighted, from the dated role history. Use this for HISTORICAL leaders who are no longer in any role index and so cannot be reached via search_persons/get_person. The match is name-based (no national ID), so a hit is a REVIEW FLAG to verify (birth year / address), not a verdict. PII-sensitive — requires the search_full_enabled tier.
| Name | Required | Description | Default |
|---|---|---|---|
| navn | Yes | Full name to screen (min 2 characters), e.g. 'Karl Petter Ulriksen'. | |
| purpose | No | Purpose-of-processing string for the F10.11 audit trail. Required when calling against accounts with purpose-confirmation. |
Output Schema
| Name | Required | Description |
|---|---|---|
| navn | Yes | |
| note | No | |
| foretak | No | |
| antall_konkursforetak | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive behavior. The description adds substantial context beyond annotations: PII-sensitive nature, required access tier, name-based matching (no national ID), and the fact that results are review flags. This discloses operational and privacy implications not visible in structured metadata. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact yet information-dense. Each sentence serves a distinct purpose: core function, when to use, limitation/caveat, and access requirement. No fluff, properly front-loaded with the main verb and resource.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the existence of an output schema, the description fully covers what an agent needs: function, target use case, alternatives, result interpretation, PII/tier constraints, and parameter context. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by emphasizing that matching is name-based with no national ID, clarifying the 'navn' parameter's limitations and the purpose parameter's audit-trail role. This extra context justifies a slight bump above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool screens a person by name for bankruptcy exposure, specifically leadership roles in bankrupt companies, tenure-weighted. It distinguishes from siblings by explicitly mentioning historical leaders not reachable via search_persons/get_person, making the purpose specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use this tool: for HISTORICAL leaders no longer in any role index, and names the alternatives (search_persons, get_person). It also provides important interpretation guidance (hit is a review flag, not a verdict), which is essential for proper usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_compare_companiesCompare CompaniesARead-onlyIdempotentInspect
Compare key financial metrics of up to 5 Norwegian companies side-by-side across the last N years (default 5). Use for competitor analysis, benchmark research or 'which of these three companies is the strongest?' Amounts are in each company's reporting currency (see the currencies field; NOK for most Norwegian companies) — check it before comparing absolute amounts. antall_ansatte is a CURRENT-value register attribute with no per-year history: read it from the top-level antall_ansatte field ({orgnr: headcount}); its rows in comparison are always null.
| Name | Required | Description | Default |
|---|---|---|---|
| years | No | ||
| orgnrs | Yes | 1-5 orgnr to compare side-by-side. | |
| metrics | No | Optional subset of metrics: omsetning, driftsresultat, aarsresultat, sum_egenkapital, sum_gjeld, antall_ansatte. Omit for the standard set. |
Output Schema
| Name | Required | Description |
|---|---|---|
| years | Yes | |
| orgnrs | Yes | |
| summary | No | |
| comparison | Yes | {<metric>: {<orgnr>: [<value_per_year>, ...]}}. For `antall_ansatte` the per-year lists are always null — headcount does not exist per fiscal year; use the top-level `antall_ansatte` field instead. |
| currencies | No | {<orgnr>: [<ISO 4217 currency per year, aligned with `years`>]}. None for years without data. Amounts in `comparison` are in the company's reporting currency for that year (NOK for most Norwegian companies) — do not compare amounts across different currencies without converting. |
| computed_at | Yes | |
| antall_ansatte | No | {<orgnr>: <current headcount|null>}. Present only when `antall_ansatte` is in the requested metric set. CURRENT value from Enhetsregisteret (the register attribute has no per-year history), mirroring `companies[].antall_ansatte` on the server-side compare endpoint. Null when unknown. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive behavior, lowering the bar. The description goes beyond annotations by warning that amounts are in each company's reporting currency (check `currencies`) and explaining that `antall_ansatte` is a current-value field with null comparison rows. These are critical behavioral caveats that prevent misinterpretation of results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences, each serving a distinct purpose: purpose/scope, use cases, currency warning, and antall_ansatte caveat. It is front-loaded with the primary action and avoids fluff. Every sentence adds value, making it appropriately sized for a tool with these complexities.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (comparison, variable years, metric subset, currency differences, headcount quirk), the description covers all key non-obvious aspects. An output schema exists, so the return structure is already documented; the description adds the necessary caveats about currencies and `antall_ansatte` that schema alone would not convey.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67% (years lacks description). The description adds meaning to `years` by clarifying it means 'last N years' and emphasizes the side-by-side comparison. It also reinforces `metrics` semantics by listing valid metric names and the special handling of `antall_ansatte`. This partially compensates for the schema gap, though not fully for `years`.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool compares key financial metrics of up to 5 Norwegian companies side-by-side over a configurable number of years. This specific verb+resource+scope distinguishes it from siblings like get_company_financials (single-company) and search_companies (search). The intended use cases (competitor analysis, benchmark research) further clarify its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use for competitor analysis, benchmark research or "which of these three companies is the strongest?"' which provides clear when-to-use guidance. However, it does not explicitly mention when not to use it or name alternative tools for single-company financials, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_confirm_risk_score_disclaimerConfirm Risk-Score DisclaimerAIdempotentInspect
Confirm the pre-screening disclaimer required by firmaradar_get_risk_score. This is a one-time confirmation per Firmaradar user (not per agent and not per call); it is permanent and audit-logged. Requires an OAuth token tied to a user whose plan has risk scoring enabled. Idempotent — if the user has already confirmed, the existing confirmation is returned (same audit_id). The confirmation declares that risk scoring is used only for legitimate purposes (KYC, credit pre-screening, due diligence, supplier screening) and NOT as a substitute for a formal credit assessment or an automated adverse decision. The disclaimer text and version are embedded in this tool and sent to the backend as an explicit string match, so an agent cannot confirm a version it has not seen. Call this tool only when the user has explicitly instructed you to confirm the disclaimer on their behalf.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | |
| version | Yes | Disclaimer version that was confirmed (e.g. 'v1'). |
| audit_id | No | ID of the audit row in ``extension_kundebekreftelse_event``. |
| confirmed | Yes | True if the disclaimer is confirmed for the user. |
| idempotent | No | True if the confirmation already existed (no new row written). |
| confirmed_at | No | ISO timestamp of the confirmation. |
| confirmed_by_user_id | Yes | ID of the Firmaradar user the confirmation is registered against. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the idempotentHint annotation by detailing exact behaviors: one-time confirmation per user (not per agent/call), permanence, audit-logging, returning the same audit_id on repeat calls, and the embedded disclaimer text preventing confirmation of unseen versions. It also states the OAuth/plan requirement and the legal declaration content, providing full behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph but front-loads the primary purpose and then covers necessary details: scope, permissions, idempotency, legal content, and usage instruction. Every sentence contributes meaningful information, though it is somewhat dense and could be broken into bullet-like sections for readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a confirmation tool with legal implications, the description is very complete. It covers when to invoke, authorization requirements, idempotency, audit behavior, the specific disclaimer content, and the version-matching mechanism. The presence of an output schema means return values need not be explained, so no gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters, the baseline is 4. The description adds value by explaining that the disclaimer text and version are embedded in the tool handler, so the agent does not need to guess or hardcode them. This clarifies the purpose of having no inputs and preempts potential confusion.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action ('Confirm the pre-screening disclaimer') and explicitly ties it to firmaradar_get_risk_score, clearly distinguishing this tool from its siblings. It also states the one-time, permanent nature, which adds purpose clarity beyond the title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear guidance: 'Call this tool only when the user has explicitly instructed you to confirm the disclaimer on their behalf.' It also mentions that it is 'required by firmaradar_get_risk_score' and notes prerequisites such as an OAuth token and plan with risk scoring enabled. However, it does not explicitly name alternatives or exclusion conditions, though none seem necessary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_convert_nokConvert NOK to Foreign CurrencyARead-onlyIdempotentInspect
Convert a NOK amount to a foreign currency (EUR, USD, GBP, SEK, DKK) using daily exchange rates from Norges Bank (the Norwegian central bank). Firmaradar's financial figures are reported in NOK; use this to express them in another currency for international workflows. The NOK original is always preserved in the response. Omit amount_nok to fetch just the current rate.
| Name | Required | Description | Default |
|---|---|---|---|
| amount_nok | No | Amount in NOK to convert. Omit to fetch only the current rate (the response 'amount' will be null). | |
| to_currency | Yes | Target ISO 4217 currency code. Supported: EUR, USD, GBP, SEK, DKK. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rate | Yes | Multiplier applied: amount = amount_nok * rate (target units per NOK). |
| amount | No | Converted amount in the target currency. |
| source | No | Rate source. |
| currency | Yes | Target currency (ISO 4217). |
| rate_date | No | ISO date of the Norges Bank observation. |
| amount_nok | No | The original NOK amount (preserved, unchanged). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds valuable context: daily rates from Norges Bank, preservation of the NOK original in the response, and the behavior when amount_nok is omitted. It doesn't cover edge cases like rate unavailability, but that's acceptable given annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: purpose and currencies, use-case context, and rate-only mode. It is front-loaded with the core action and remains compact without unnecessary filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (2 params, 1 required) and has an output schema, so return values are covered. The description provides all essential context: data source, use case, currency support, and a special mode. No gaps remain for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both amount_nok and to_currency are already well-documented in the schema. The description mostly restates these details (supported currencies, omitting amount_nok) and adds the rate-source context, but doesn't significantly extend parameter-level meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool converts NOK amounts to specific foreign currencies (EUR, USD, GBP, SEK, DKK) using Norges Bank rates. It is distinct from all sibling tools, which focus on company, person, or AML data, and the verb 'convert' precisely describes the action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context on when to use the tool: to express Firmaradar's NOK-reporting financial figures in another currency for international workflows. It also explains how to fetch just the current rate by omitting amount_nok, but it doesn't explicitly state when not to use it or mention alternatives, though none exist among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_delete_subscriptionDelete Industry SubscriptionADestructiveIdempotentInspect
Delete one NACE industry-monitoring subscription by its id (from list_my_subscriptions); Firmaradar then stops delivering webhooks for that industry. The subscription must belong to the authenticated user. Idempotent — deleting an id that is already gone returns already_absent=true rather than an error. Reversible only by re-subscribing. Call only when the user has asked to stop monitoring an industry.
| Name | Required | Description | Default |
|---|---|---|---|
| subscription_id | Yes | The id of the subscription to delete (from list_my_subscriptions). Must belong to the authenticated user. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | The id that was targeted. |
| raw | No | |
| deleted | Yes | True if the subscription was removed. |
| already_absent | No | True if no subscription with that id existed for the user (nothing to delete). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (destructiveHint, idempotentHint, readOnlyHint), the description discloses that webhooks will stop, idempotent behavior returns already_absent=true, and reversibility is only via re-subscribing. It also asserts ownership requirements, adding context beyond the structured metadata.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the core action. Each sentence adds value: purpose, side effect, idempotency, reversibility, and usage trigger. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple deletion tool with one parameter and an output schema, the description fully covers the behavioral contract: what happens, idempotency, reversibility, and ownership validation. It is complete without requiring the agent to infer missing context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description for subscription_id already provides full coverage (100%), including source (from list_my_subscriptions) and ownership requirement. The description adds no new parameter meaning beyond what the schema states, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: 'Delete one NACE industry-monitoring subscription by its id,' specifying the resource and scope. It distinguishes the tool from siblings like subscribe_nace and list_my_subscriptions by focusing on deletion and the consequence of stopping webhook delivery.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Call only when the user has asked to stop monitoring an industry.' It also instructs the agent to obtain the id from list_my_subscriptions, making the integration context clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_aml_reportGet AML Report Status / ResultARead-onlyIdempotentInspect
Poll the status and result of an asynchronous AML report started with start_aml_report. Pass the report_id; returns status (pending/running/done/failed). When status is 'done' it includes the AML risk score (0-100), level (low/medium/high) and links to the stored report; when 'failed' it includes the error reason. Poll periodically until the status is terminal (done/failed).
| Name | Required | Description | Default |
|---|---|---|---|
| report_id | Yes | The report_id returned by `start_aml_report`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | |
| error | No | Failure reason (only when status='failed'). |
| level | No | low/medium/high (only when status='done'). |
| orgnr | No | |
| score | No | AML risk score 0-100 (only when status='done'). |
| status | Yes | One of: pending, running, done, failed. |
| report_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive traits, but the description adds critical behavioral context: the asynchronous status states (pending/running/done/failed), what data appears in each terminal state, and the error reason on failure. This goes beyond annotations and fully informs the agent of the polling semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences: first identifies purpose, second details response states, third gives usage advice. Every sentence earns its place with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, annotations, and a parameter-rich sibling set. The description covers the full polling flow, return values in both terminal states, and polling cadence, making it complete for an agent to use without additional context. The linkage to start_aml_report completes the workflow picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes report_id as 'The report_id returned by start_aml_report,' achieving 100% coverage. The description reinforces this by saying 'Pass the report_id' but adds no new meaning beyond the schema. Baseline 3 is appropriate given schema completeness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Poll' and clearly identifies the resource: 'status and result of an asynchronous AML report started with start_aml_report.' It distinguishes itself from sibling tools like get_aml_score and check_aml_pep by focusing on the async report lifecycle.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the tool is for polling an async report initiated by start_aml_report and explicitly instructs to 'Poll periodically until the status is terminal (done/failed).' While it doesn't name alternative tools, the usage context is clear and paired with the start command, giving sufficient guidance without needing exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_aml_scoreGet Company AML Risk ScoreAInspect
Structured COMPANY AML risk score (0-100) with named level (low/medium/high), by orgnr. This is the primary tool for 'what is the AML risk / AML score of company X'. Call it ONCE per company — it ALREADY screens the company's key persons and beneficial owners against PEP and sanctions lists internally and folds that into the score. You normally do NOT need to call check_aml_pep per owner/officer afterwards; do that only for ad-hoc screening of one specific named individual you need extra detail on. Complements check_aml_pep (binary match data for a single PERSON name). Generates an auditable AML report on the backend (rapport_id stored for 60 months per Hvitvaskingsloven §35); factor-level detail lives in the stored report links. The report is generated asynchronously — for very large/complex ownership structures the result can come back with level='pending' and a rapport_id; poll get_aml_report with that id until status is 'done'.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit norwegian organization number. | |
| purpose | No | Purpose of the screening — recorded for audit trail. | kyc_onboarding |
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | |
| level | Yes | One of: low, medium, high — or 'pending' when the report is still generating (poll `get_aml_report` with rapport_id). |
| orgnr | Yes | |
| score | Yes | AML risk score 0-100 (higher = riskier). |
| factors | No | Always empty for the async report flow — factor detail lives in the stored report (json_url/pdf_url in `raw` when done). |
| rapport_id | No | Persistent report-id for compliance audit (retrievable later). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (all false), the description discloses significant behavioral traits: it internally screens key persons and beneficial owners against PEP/sanctions, folds that into the score, generates an auditable report stored for 60 months, and may return asynchronously with a pending state. This is rich, safety-relevant context that the annotations do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph, but every sentence adds essential information: primary use, anti-pattern avoidance, backend report generation, async behavior, and polling. It is front-loaded with the core purpose and remains readable despite its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the tool (async report generation, legal retention, interplay with sibling tools) and that an output schema exists, the description covers all the contextual ground needed. It addresses the likely edge case of pending results and directs the agent to the correct follow-up tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents both parameters (orgnr and purpose) with descriptions and an enum for purpose. The description only mentions 'by orgnr' and adds no additional parameter-level detail beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a structured COMPANY AML risk score (0-100) with a named level, keyed by orgnr. It explicitly identifies itself as the primary tool for 'what is the AML risk / AML score of company X', which differentiates it from siblings like check_aml_pep.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description tells the agent exactly when to use this tool, instructs to call it ONCE per company, and explicitly says not to call check_aml_pep afterwards except for ad-hoc individual screening. It also provides guidance on what to do when the result is pending: poll get_aml_report with the rapport_id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_companyGet Company ProfileARead-onlyIdempotentInspect
Fetch the full profile for one Norwegian company by orgnr: name, group structure, ownership data, grants, recent BRREG announcements and financial metrics. Opt-in fields add deeper enrichment — notably fields=['ip'] for the company's intellectual-property portfolio (patents, trademarks and designs from Patentstyret). The primary 'show me this company' tool — use after search_companies returns an orgnr. Sourced from the official Norwegian registers (BRREG Enhetsregisteret + Skatteetaten + Patentstyret) and refreshed daily. The result includes a canonical Firmaradar url.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | Norwegian organisation number — exactly 9 digits. | |
| fields | No | Subset of sections to include. Omit to get the default profile. Notable opt-in sections: `ip` — intellectual-property portfolio (patents, trademarks and designs from Patentstyret); `group` — full group structure; `owners`/`business_owners`/`full_owners` — ownership tiers; `grants` — public grants; `changes` — recent register changes; `financial_metrics` — accounting figures. | |
| owners | No | Owner-tier requested. 'full' requires Full eierskapsoversikt tier. | |
| include_financial_metrics | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Canonical Firmaradar source URL for this company — cite this. |
| navn | No | |
| eiere | No | |
| orgnr | Yes | |
| source | No | Authoritative source name. |
| summary | No | Human-readable summary (LLM-friendly). |
| endringer | No | |
| tildelinger | No | |
| ip_rettigheter | No | |
| konsernstruktur | No | |
| brreg_tildelinger | No | |
| financial_metrics | No | |
| foretaksklassifisering | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description adds valuable behavioral context beyond that: data sourced from official Norwegian registers (BRREG, Skatteetaten, Patentstyret), daily refresh, and inclusion of a canonical Firmaradar URL. It does not contradict annotations, and the added sourcing/freshness info gives the agent a clearer picture of what to expect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: primary action + resource first, then a compact list of included content, then a note on opt-in fields, then usage context, then data provenance, then a final output detail. Every sentence earns its place with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (so return values are defined), the description covers the key contextual elements: input required (orgnr), optional params and their purpose, the canonical pre-condition (use after search_companies), data source and refresh cadence, and an output detail (URL). For a read-only, idempotent tool, this is a complete picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 75%, so baseline is around 3. The description adds meaning above the schema, notably by calling out `fields=['ip']` as a notable opt-in and explaining what it returns (patents, trademarks, designs from Patentstyret). It also clarifies the default profile vs. opt-in sections, making the `fields` parameter more understandable than the raw enum list alone. This compensates for the moderate schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Fetch the full profile for one Norwegian company by orgnr' and enumerates the content (name, group structure, ownership, grants, BRREG announcements, financial metrics). It also positions itself as 'The primary show me this company tool,' clearly distinguishing it from focused sibling tools like firmaradar_get_company_ip or firmaradar_get_company_financials.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'use after search_companies returns an orgnr,' giving a clear workflow context. It also explains that opt-in `fields` allow deeper enrichment, implying when you might want specific sections. However, it does not explicitly state when NOT to use this tool in favor of a more focused sibling tool (e.g., for IP-only lookups), which would make the guidance fully comprehensive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_company_announcementsGet Company AnnouncementsARead-onlyIdempotentInspect
List BRREG kunngjøringer (official announcements) for a Norwegian company: bankruptcy, mergers, demergers, ownership changes, address changes, etc. Free-text fields are wrapped in tags to prevent prompt injection from BRREG-sourced text.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit orgnr. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| items | Yes | |
| orgnr | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is known. The description adds valuable context about untrusted_content wrapping to prevent prompt injection from BRREG-sourced text, which is not captured in annotations and is crucial for handling external data. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the main purpose and examples, followed by a necessary security detail. No wasted words, and the structure is clear and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a single simple parameter, an output schema (so return values are covered), and annotations covering safety. The description sufficiently covers purpose, scope, and the critical untrusted-content handling, making it complete for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only one parameter (orgnr) and 100% schema description coverage (stating '9-digit orgnr'), the schema fully explains the parameter. The tool description does not add param-specific details, but given the high schema coverage, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists BRREG official announcements for a Norwegian company, with concrete examples (bankruptcy, mergers, demergers, ownership changes, address changes). This specifies the verb ('List'), the resource ('BRREG kunngjøringer'), and the scope (for a company), distinguishing it from sibling tools like firmaradar_search_announcements.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies usage: when you have a Norwegian orgnr and need official announcements for that specific company. It does not explicitly mention alternatives or when-not-to-use, but the context is clear and the sibling named firmaradar_search_announcements suggests a search-oriented alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_company_financialsGet Company FinancialsARead-onlyIdempotentInspect
Fetch the last N years (default 5) of financial metrics for a Norwegian company: revenue, operating result, equity, debt, employees. Use when the user asks 'how is X AS doing financially?' or 'show me the revenue trend'. Figures come from the official annual accounts filed with BRREG. Amounts are in the company's reporting currency — check the valuta field (NOK for most companies, but e.g. USD for some international groups; 'MIXED' means the currency changed within the series).
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit orgnr. | |
| years | No | ||
| regnskapstype | No | SELSKAP | |
| skip_freshness | No | Skip the inline freshness fetch (faster, but may return stale data). |
Output Schema
| Name | Required | Description |
|---|---|---|
| orgnr | Yes | |
| years | Yes | |
| valuta | No | Reporting currency across the series (ISO 4217, e.g. 'NOK' or 'USD'). 'MIXED' when the years are filed in different currencies — then check valuta per year before comparing amounts across years. |
| summary | No | |
| freshness | No | |
| regnskapstype | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds meaningful context: data source (official BRREG annual accounts), currency handling (valuta field, MIXED meaning), and the metric set. This goes beyond the annotations, though it doesn't discuss rate limits or auth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each contributing distinct value: purpose and metrics, usage triggers, and source/currency caveat. It is front-loaded with the main action and has no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only financial retrieval tool with an output schema present, the description adequately covers data source, currency pitfalls, and usage context. The main gap is the unexplained regnskapstype parameter, which could affect whether company or consolidated figures are returned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 50% (orgnr and skip_freshness have inline descriptions, years and regnskapstype do not). The description only restates the default of 5 years and does not explain the regnskapstype enum (SELSKAP vs KONSERN), so an agent gets little additional parameter understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Fetch') and clearly specifies the resource ('financial metrics for a Norwegian company') along with the key metrics (revenue, operating result, equity, debt, employees). This distinguishes it from sibling tools like get_company (general info) and get_company_signals (signals/risk).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states 'Use when the user asks...' with concrete example queries, providing clear context for when to invoke this tool. However, it does not mention when not to use it or point to alternative tools, so it falls short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_company_ipGet Company IP RightsARead-onlyIdempotentInspect
Intellectual-property portfolio for a Norwegian company (by orgnr), sourced from Patentstyret: patents, trademarks and designs — totals, active counts, and a list of individual rights (registration number, date, status, expiry date where applicable, title and a link to the Patentstyret case). Use this for ANY question about a company's patents, trademarks, designs or IP rights — Firmaradar covers this. The rights list is ordered newest-first, so the first N entries are the newest rights. Look up the orgnr via search_companies first if you only have a name.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | Norwegian organisation number — exactly 9 digits. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Canonical Firmaradar source URL. |
| navn | No | |
| orgnr | Yes | |
| rights | No | |
| source | No | Authoritative source. |
| designs | No | |
| patents | No | |
| summary | No | |
| available | No | Whether Patentstyret IP data was found. |
| trademarks | No | |
| rights_more | No | Antall rettigheter ut over `rights`-lista. |
| designs_active | No | |
| patents_active | No | |
| trademarks_active | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so no safety concerns. The description adds meaningful behavioral details: data source (Patentstyret), the ordering of the rights list (newest-first), the included fields (registration number, date, status, expiry date, title, link). It also clarifies that 'expiry date where applicable' indicates conditional fields, which goes beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although the description is fairly long, it is efficiently structured into meaningful sentences. It front-loads the core content (portfolio composition and source), then provides usage guidance and ordering details. No sentence is redundant; each adds value to the user's understanding of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one parameter, a full output schema, and helpful annotations, the description covers everything an agent needs: what data is returned, the source, the ordering, and the required lookup workflow. It doesn't describe error conditions or pagination, but for a simple read-only lookup this is not necessary. The output schema presumably supplies the rest, making the description complete for this complexity level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema alone covers 100% of the parameter (orgnr) with a clear description ('exactly 9 digits'). The description adds a minor workflow tip about using search_companies to obtain the orgnr, but doesn't provide additional format or syntax details. Thus the parameter semantics are adequately handled by the schema, with a slight enhancement from the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns an intellectual-property portfolio (patents, trademarks, designs) for a Norwegian company, sourced from Patentstyret, with totals, active counts, and a list of rights. It distinguishes from siblings like get_company_financials or get_company by explicitly targeting IP matters. The verb 'get' and resource are specific, and the usage statement 'Use this for ANY question about a company's patents, trademarks, designs or IP rights' reinforces its dedicated role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage guidance: 'Use this for ANY question about a company's patents, trademarks, designs or IP rights — Firmaradar covers this.' It also advises looking up orgnr via search_companies if only a name is available, which is a clear prerequisite. It doesn't name alternative tools for non-IP queries, but the positive guidance is strong enough to distinguish it from siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_company_ownershipGet Company OwnershipARead-onlyIdempotentInspect
Get the ownership tree for a Norwegian company: who they own (direction=down), who owns them (direction=up / UBO), or both. Use when the user asks 'who owns X AS?' or to map a corporate group. Ownership comes from Skatteetaten's Aksjeeierbok (the official shareholder register) and reflects the latest filed holdings. The result contains ownership edges, percentages and company identifiers for the requested traversal direction.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Max recursion depth. | |
| orgnr | Yes | Norwegian organisation number — 9 digits. | |
| direction | No | 'down' = who this company owns. 'up' = who owns this company (UBO). 'both' = both trees. | down |
| min_share_pct | No | Drop branches where ownership < this percentage. | |
| include_persons | No | Include personal shareholders (requires Full eierskapsoversikt tier). |
Output Schema
| Name | Required | Description |
|---|---|---|
| tree | Yes | |
| depth | Yes | |
| orgnr | Yes | |
| summary | No | |
| direction | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description adds valuable behavioral context: the data comes from Skatteetaten's Aksjeeierbok, reflects the latest filed holdings, and the result contains ownership edges, percentages, and identifiers. It goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, all purposeful and front-loaded: the first states the core function, the second gives usage, the third names the source, and the fourth describes the result shape. No fluff or redundant restatement of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 params, output schema present), the description covers purpose, usage, data provenance, and result content. Annotations handle safety semantics. Nothing critical is missing for an ownership-tree lookup tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not introduce any parameter meaning beyond what the schema already provides; it only restates the direction concept. It does not add syntax, format, or additional constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Get the ownership tree for a Norwegian company' and immediately disambiguates direction: who they own (down), who owns them (up/UBO), or both. It also includes concrete use cases ('who owns X AS?') and names the data source, clearly distinguishing this from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is given: 'Use when the user asks "who owns X AS?" or to map a corporate group.' This clearly states when to use the tool, but it stops short of naming alternative tools or stating when not to use it, so it doesn't earn a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_company_rolesGet Company RolesARead-onlyIdempotentInspect
List board members, daglig leder, signature holders, prokura and revisor for a Norwegian company. Set include_historic=true for people who previously held roles. Use when the user asks 'who runs X AS?' or 'who is on the board?' Roles come live from BRREG (the official enterprise register) and include role type and available appointment or resignation dates.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit orgnr. | |
| role_type | No | Filter on a single role type. Omit to get all roles. | |
| include_historic | No | Include roles that have ended. |
Output Schema
| Name | Required | Description |
|---|---|---|
| orgnr | Yes | |
| roles | Yes | |
| total_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/idempotentHint annotations, the description reveals that roles come live from BRREG (official enterprise register) and include appointment/resignation dates. This adds meaningful behavioral context not available in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no fluff: it states what is returned, how to get historic roles, and when to use it, plus a note on the data source. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description covers the essential context: purpose, example triggers, a parameter usage tip, and the live BRREG data source. It is complete for this tool's simplicity and leaves deeper return details to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter already has a clear description (9-digit orgnr, role_type filter, include_historic boolean). The description adds minimal extra value by rephrasing include_historic as 'people who previously held roles', but does not meaningfully enhance the schema-provided semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists specific roles (board members, daglig leder, signature holders, prokura, revisor) for a Norwegian company. This specific verb+resource combination distinguishes it from general company lookup tools like firmaradar_get_company.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit user query examples ('who runs X AS?', 'who is on the board?') for when to use the tool. It also gives a conditional for using include_historic, but does not mention when not to use it or alternative sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_company_signalsGet Company Risk SignalsARead-onlyIdempotentInspect
Aggregated risk and growth signals for one company: bankruptcy/distress score, capital-loss flags, M&A interim-balance signals, KYC announcement anomalies, NAV hiring/growth signal, and merger/demerger (fusjon/fisjon) relations plus authoritative voluntary-org (Frivillighetsregister) status. Use as the second step after get_company to evaluate whether a company needs deeper due diligence.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit orgnr. | |
| since | No | ISO 8601 date — only signals on/after this date. Defaults to 90 days back. |
Output Schema
| Name | Required | Description |
|---|---|---|
| orgnr | Yes | |
| fusjon | No | Merger/demerger relations: inbound (companies merged into this orgnr) + outbound (companies this orgnr was merged into), with dates. |
| hiring | No | NAV Arbeidsplassen hiring/growth signal: active_postings, positions_active, postings_30d/90d, burst_score, is_hiring_burst. |
| summary | No | |
| kyc_signals | No | |
| frivillighet | No | Authoritative Frivillighetsregister (voluntary-org) membership: registered, registreringsdato, kategorier. Omitted when the source is off. |
| generated_at | No | |
| distress_score | No | |
| distress_reasons | No | |
| distress_category | No | |
| interim_balance_signal | No | |
| recent_role_changes_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds useful context about the kinds of signals aggregated but does not disclose additional behavioral traits such as pagination, response size, or authorization requirements. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: the first is a dense but informative list of signal categories, the second gives a clear usage directive. It is longer than minimal but every segment adds value; could be slightly more scannable but is not bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and annotations cover safety, the description gives sufficient context for an agent to select the tool and know when to invoke it. It stops short of contrasting with closely related risk tools, but overall it is complete enough for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both orgnr and since already described in the input schema. The description adds only that the tool works for 'one company' (matching orgnr) and does not enhance the meaning of the 'since' parameter beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as returning 'aggregated risk and growth signals for one company' and enumerates the specific signal categories (bankruptcy/distress, capital-loss, M&A, KYC, NAV, merger/demerger, Frivillighetsregister). This specificity distinguishes it from sibling tools like get_risk_score or check_foretak_i_vanskeligheter.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides a usage context: 'Use as the second step after get_company to evaluate whether a company needs deeper due diligence.' However, it does not mention when to avoid this tool in favor of more specialized siblings like get_risk_score or check_foretak_i_vanskeligheter.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_konsernstotteGet Group Support (Konsernstøtte)ARead-onlyIdempotentInspect
Tree-structured overview of public grants (Innovasjon Norge, SkatteFUNN, BRREG støtteregister, Prosjektbanken) for a Norwegian company and its konsern. Returns selskap_stotte per node (støtte to that specific company) and konsern_aggregat (sum across the full hierarchy). NOTE: SkatteFUNN never reports amounts — use antall_prosjekter as the primary activity KPI since total_belop_nok excludes SkatteFUNN by source design. Use for due-diligence, state-aid compliance checks, or competitive intelligence.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit norwegian organization number (typically konsern-toppen). |
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | |
| barn | No | |
| navn | Yes | |
| orgnr | Yes | |
| selskap_stotte | No | |
| konsern_aggregat | No | |
| antall_underselskaper | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint=true and idempotentHint=true annotations, the description adds valuable behavioral context: it clarifies the tree structure, names the returned fields, and warns that SkatteFUNN never reports amounts, suggesting antall_prosjekter as the primary KPI and noting that total_belop_nok excludes SkatteFUNN by design. This materially helps the agent interpret results correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (three sentences) and front-loaded with the core purpose. Every sentence adds value: the overview, the SkatteFUNN caveat, and the use cases. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the return structure (selskap_stotte and konsern_aggregat), covers the critical source-data caveat, and states intended use cases. Combined with the existing output schema and annotations, the agent has enough context to use the tool effectively without additional documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the parameter description already specifies '9-digit norwegian organization number (typically konsern-toppen).' The description adds 'and its konsern' but does not provide additional parameter-level detail beyond the schema. With such high schema coverage, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Tree-structured overview of public grants' and lists specific sources (Innovasjon Norge, SkatteFUNN, BRREG støtteregister, Prosjektbanken), clearly distinguishing it from sibling tools that cover company signals, financials, or ownership. It also specifies the scope ('for a Norwegian company and its konsern') and the two return fields, making the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states use cases: 'Use for due-diligence, state-aid compliance checks, or competitive intelligence.' It does not mention when not to use it or alternatives, but the context is clear enough for an agent to decide when to invoke this tool. The SkatteFUNN note also provides interpretive guidance, shifting the score toward the higher end.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_personGet Person ProfileARead-onlyIdempotentInspect
Aggregated person profile: name, birth year, active roles, shareholdings and any AML/PEP risk hits. Also returns konkurs_eksponering — leadership roles the person held in companies that later went bankrupt (tenure-weighted, from the dated role history). That match is name-based (no national ID), so it is a REVIEW FLAG to verify, not a verdict. Note: this profile lookup does NOT run a PEP/sanctions screening — an empty aml_pep_hits is not a clean bill; use firmaradar_check_aml_pep for an actual screening. Strict PII-sensitive — requires search_full_enabled tier and F10.11 purpose confirmation. Minors are blocked except for super-admin accounts.
| Name | Required | Description | Default |
|---|---|---|---|
| purpose | No | Purpose-of-processing string for the F10.11 audit trail. Required when calling against accounts with purpose-confirmation. | |
| person_id | Yes | Person ID — either `person-YYYY-[24 hex]` (from `search_persons` shareholders) or `role-[24 hex]` (from `search_persons` role_persons). |
Output Schema
| Name | Required | Description |
|---|---|---|
| navn | Yes | |
| summary | No | |
| person_id | Yes | |
| birth_year | No | |
| active_roles | No | |
| aml_pep_hits | No | |
| aml_pep_note | No | |
| shareholdings | No | |
| konkurs_eksponering | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint/idempotent annotations by disclosing PII sensitivity, required access tiers, purpose confirmation, minor restrictions, and the name-based matching limitation of konkurs_eksponering. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: an aggregated summary, a detailed caveat about name-based matching, an explicit non-screening warning with alternative, and access restrictions. Slightly long but dense and well-structured with front-loaded core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema already present and strong annotations, the description fully covers access control, data limitations, alternative tools, and matching caveats. Nothing critical is missing for an agent to decide on and invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds contextual meaning by explaining the purpose parameter's audit-trail role and the source formats for person_id, reinforcing and expanding on the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Aggregated person profile' followed by concrete contents (name, birth year, active roles, shareholdings, AML/PEP hits). It also distinguishes itself from siblings by explicitly stating it does NOT run PEP/sanctions screening and directing to firmaradar_check_aml_pep.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-not-to-use guidance: 'does NOT run a PEP/sanctions screening' and names the alternative tool. It also states access requirements (search_full_enabled tier, F10.11 purpose confirmation, minor blocking), giving the agent clear conditions for use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_person_companiesGet Person's CompaniesARead-onlyIdempotentInspect
List all Norwegian companies where the given person holds shares. Use when the user asks 'what does Person A own?' Pass the owner_person_key returned by search_persons.
| Name | Required | Description | Default |
|---|---|---|---|
| person_key | Yes | Shareholder key, format `person-YYYY-[24 hex]`. Obtain from `search_persons` shareholders[] results. | |
| include_historic | No | Reserved for future support; currently only current holdings are returned. |
Output Schema
| Name | Required | Description |
|---|---|---|
| navn | Yes | |
| person_key | Yes | |
| shareholdings | Yes | |
| total_companies | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description need not repeat safety. It adds the Norwegian scope and shareholding semantics, but no additional behavioral traits such as pagination or output details. The include_historic limitation is documented in the schema, not the description. With annotations covering safety, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no waste. The verb-action is front-loaded, followed by usage trigger and key provenance. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema, full parameter documentation, and annotations, the description provides complete context for tool selection and invocation. It covers what the tool does, when to use it, and how to obtain the required key. No critical gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so a baseline of 3 is warranted. The description adds value by explaining the person_key is obtained from search_persons, which is practical guidance beyond the schema's format description. The include_historic parameter is fully described in the schema with its future-reserved status, so no further compensation needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List all Norwegian companies where the given person holds shares' with a specific verb, resource, and scope. This distinguishes it from sibling tools like get_person_roles or get_company_ownership by focusing on shareholdings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when the user asks "what does Person A own?"' and instructs to pass the owner_person_key from search_persons. This gives clear usage context, though it does not name alternative tools for exclusion, which would have made it a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_person_rolesGet Person RolesARead-onlyIdempotentInspect
List all company roles (styreleder, daglig leder, etc.) held by a person, current and historic. Use when the user asks 'what roles does Person A hold?' Pass the role_person_id returned by search_persons.
| Name | Required | Description | Default |
|---|---|---|---|
| role_person_id | Yes | Stable role-person ID, format `role-[24 hex chars]`. Obtain from `search_persons` role_persons[] results. | |
| include_historic | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| navn | Yes | |
| roles | Yes | |
| total_roles | Yes | |
| role_person_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior. The description adds behavioral context beyond annotations by specifying that results include both current and historic roles, and by noting the dependency on a search_persons result. This is useful context, though it does not disclose pagination or output size limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loads the purpose, and includes a specific usage trigger. Every word earns its place; there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with an output schema present and rich annotations, the description is complete. It states the purpose, when to use it, and the key parameter source. The output schema handles return-value details, so no further description is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 50%: role_person_id has a description, but include_historic does not. The description compensates by explaining the source and usage of role_person_id ('Pass the role_person_id returned by search_persons') and implicitly covers include_historic with 'current and historic.' However, it does not explicitly mention the parameter name or how to disable historic results.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'List all company roles (styreleder, daglig leder, etc.) held by a person, current and historic.' It uses a specific verb and resource, and explicitly distinguishes from sibling tools by specifying 'held by a person' and providing a sample user query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Use when the user asks 'what roles does Person A hold?'' It also provides a prerequisite and sourcing instruction: 'Pass the role_person_id returned by search_persons.' This tells the agent exactly when and how to invoke the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_recent_changesGet Recent ChangesARead-onlyIdempotentInspect
List changes (kunngjøringer for companies; role + ownership movements for persons) in the last N days. Use when monitoring a target entity for triggers ('has anything changed for X AS in the last month?'). Pair with subscribe_company for push notifications.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Orgnr (9 digits) or person_id depending on entity_type. | |
| days | No | ||
| category | No | Optional kunngjøring (announcement) category filter. Values are Norwegian: konkurs (bankruptcy), fusjon (merger), eierbytte (change of ownership), ... | |
| entity_type | Yes | 'company' = orgnr; 'person' = person_id. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| count | Yes | |
| items | Yes | |
| since | Yes | |
| until | Yes | |
| entity_type | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the tool as read-only, idempotent, and non-destructive, so the bar for behavioral disclosure is lower. The description adds value by specifying the types of changes returned (kunngjøringer for companies, role and ownership movements for persons), which goes beyond the annotations to clarify the informational content.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly concise, using two sentences that front-load the main action and usage context. Every sentence contributes value, covering purpose, use case, and a pairing suggestion (even if imperfect), with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and clear annotations, the description covers the core function and usage context adequately. It is slightly incomplete due to the misleading 'subscribe_company' reference and not mentioning that the response structure differs between company and person types, but the output schema likely handles that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high (75%), with clear descriptions for id, category, and entity_type, and days is defined by its min/max and default. The description does not add significant parameter-level meaning beyond reinforcing the 'last N days' concept, so it does not compensate for any schema gaps (days lacks a textual description).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('List changes'), specifies the resource types (companies and persons), and defines the scope (last N days). It also differentiates from siblings by covering both kunngjøringer and role/ownership movements, which is not offered by a single sibling tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit use case ('monitoring a target entity for triggers') with a concrete example query, which is helpful. However, it incorrectly references a non-existent sibling tool ('subscribe_company') for push notifications, potentially misleading the agent to look for a tool that does not exist among the provided siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_risk_scoreGet Company Risk ScoreARead-onlyIdempotentInspect
Structured risk score (0-100) with named level (lav/moderat/høy/kritisk) and component breakdown for a Norwegian COMPANY's financial health. Combines distress classification, BRREG status, age, capital signals and other factors into one comparable score. Returns blocked_enk error for sole-proprietorships (ENK).
SCOPE: Company financial health only. NOT a personal credit check on owners or officers. For full KYC pre-screening, combine with firmaradar_get_aml_score (PEP/sanctions on key persons).
Requires a one-time pre-screening-disclaimer confirmation. If this returns HTTP 403 with error_code kundebekreftelse_required or disclaimer_required, inform the user that confirmation is required. Call firmaradar_confirm_risk_score_disclaimer only after the user has explicitly instructed you to confirm the disclaimer. The confirmation is per OAuth user, not per call, and is permanent and audit-logged. Alternatively the user can confirm manually at https://firmaradar.no/minbedrift/utvidelser/risikoscoring — both paths write to the same audit table.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit norwegian organization number. |
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | |
| level | Yes | Norwegian risk level — one of: lav (low), moderat (moderate), høy (high), kritisk (critical). |
| orgnr | Yes | |
| score | Yes | Risk score on the 0-100 scale (higher = riskier). |
| sources | No | |
| data_gaps | No | |
| components | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses the one-time disclaimer requirement, the exact error_code values that trigger the confirmation flow, the per-OAuth-user permanence, and that confirmation is audit-logged. It also notes the blocked_enk error for sole proprietorships, adding valuable behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized with a clear opening, bolded scope line, and a dedicated instructions paragraph. While longer than minimal, every sentence conveys operational detail (auth flow, error handling, alternative tools) without unnecessary filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Descriptions includes the output components (score, level, breakdown), error behavior, authentication prerequisite, and cross-references to related tools. With an output schema already present, the description fully covers operational and contextual needs for an agent to select and invoke this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single 'orgnr' parameter, so the baseline applies. The description mentions 'Norwegian company' and sole-proprietorship limitations but does not add substantive details about the orgnr format beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it provides a structured risk score (0-100) with named levels and component breakdown for a Norwegian company's financial health. It explicitly differentiates from personal credit checks and points to firmaradar_get_aml_score for KYC pre-screening, making the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool (company financial health) vs. alternatives (AML score for PEP/sanctions). It also gives precise instructions for handling 403 errors by prompting user confirmation and calling the disclaimer-confirmation tool only after explicit user instruction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_get_risk_score_bulkBulk Company Risk ScoresARead-onlyIdempotentInspect
Bulk-endpoint for portfolio-screening of risikoscore (0-100 with named level lav/moderat/høy/kritisk + component breakdown) on up to 50 Norwegian companies in one call. Each orgnr counts as one unit against your quota. Compliance-gates (ENK/NUF blocking, customer-confirmation required, extension disabled) are returned per orgnr in the result list instead of failing the whole call — check each result's error field. Use for credit-decision screening, supplier-portfolio review, and KYC risk triage at scale.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnrs | Yes | List of 1-50 nine-digit Norwegian organization numbers. Each orgnr counts as one unit against your quota. |
Output Schema
| Name | Required | Description |
|---|---|---|
| _meta | Yes | Aggregate count status for the whole bulk call. |
| results | No | |
| summary | No | Human-readable markdown table of the per-company scores. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=true, idempotent=true, destructive=false. The description adds valuable behavioral context beyond annotations: quota consumption ('Each orgnr counts as one unit against your quota'), per-item error handling ('Compliance-gates ... are returned per orgnr ... check each result's error field'), and output structure ('component breakdown'). This significantly enhances understanding of how the tool behaves in bulk and partial-failure scenarios.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-organized: a single sentence establishes what the tool does, followed by a second sentence covering quota, compliance gates, and use cases. Every sentence adds substantive information without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all key aspects: the purpose, the input constraints, the output scale and components, the quota behavior, the per-item error handling, and the intended use cases. With annotations and an output schema present, this description is sufficiently complete for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, as the single parameter `orgnrs` is fully documented with format, min/max items, and quota impact. The description repeats this info ('up to 50 Norwegian companies') but does not add additional parameter-level semantics beyond what the schema already provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is a bulk endpoint for portfolio-screening of risk scores for up to 50 Norwegian companies, with specific output details (0-100 scale, named levels, component breakdown). It distinguishes itself from the singular risk score tool by emphasizing the bulk nature and scale.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly lists use cases: 'credit-decision screening, supplier-portfolio review, and KYC risk triage at scale.' It does not explicitly name alternatives or one-off exclusions, but the bulk context implies it is for multiple companies, and the sibling tool firmaradar_get_risk_score is available for single queries. This provides clear context without formal exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_list_companies_in_naceList Companies by Industry (NACE)ARead-onlyIdempotentInspect
List Norwegian companies in a specific NACE industry code (or code prefix), optionally filtered by status, kommune and size. Useful for sector analysis ('all active restaurants in Oslo with > 5 employees').
NACE format warning: Use the EU NACE Rev. 2 format with a trailing zero (e.g. 62.100, 62.200, 58.290). The Norwegian SN2007 format (62.01, 62.02) returns 0 hits — we do not store SN2007. If you are unsure about a code, call firmaradar_list_nace_codes first. Backed by the official Norwegian register (BRREG) and refreshed daily. Use stiftet_etter for newly-founded-company queries.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | NACE code or prefix. Norwegian BRREG uses 5-digit SN2007 codes internally (e.g. '56.110' for restaurants, '47.111' for grocery stores). Any prefix works: '56' matches all serving (2-digit), '56.1' matches restaurants/cafes (3-digit), '56.11' matches restaurant operations (4-digit), '56.110' matches the most specific level (5-digit). If a 4-digit code yields no results, try appending '0' (e.g. '56.110' instead of '56.10'). | |
| limit | No | ||
| cursor | No | ||
| status | No | ||
| kommune | No | Norwegian kommunenummer — EXACTLY 4 digits, zero-padded. Examples: '0301' = Oslo, '4601' = Bergen, '5001' = Trondheim, '1103' = Stavanger. Kommune-NAMES are NOT accepted — translate the name to kommunenummer first. | |
| max_ansatte | No | ||
| min_ansatte | No | ||
| stiftet_for | No | ISO 8601 date (YYYY-MM-DD) — only companies founded on/before this date. | |
| stiftet_etter | No | ISO 8601 date (YYYY-MM-DD) — only companies founded on/after this date. Use for 'newly founded companies in this industry' queries (industry monitoring). |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| catalog | No | |
| nace_code | Yes | |
| next_cursor | No | |
| total_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so safety is covered. The description adds high-value behavioral disclosure: the EU NACE Rev. 2 trailing-zero requirement, the warning that SN2007 format returns 0 hits, the BRREG data source, and daily refresh frequency. This goes well beyond the annotations and shapes agent behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but every sentence earns its place: the example, format warning, alternative-tool pointer, and data-source note are all actionable. Bold text and a clean structure make it scannable without being verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values are already documented. The description covers the crucial NACE-format trap, data freshness, and a concrete use case, which is sufficient for a 9-parameter tool. It could mention pagination behavior more explicitly, but the schema's cursor parameter and output schema reduce the need.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 44%, but the description compensates by explaining NACE format in context and pointing to stiftet_etter for new-company queries. It also gives a concrete example that maps to status, kommune, and min_ansatte. It doesn't elaborate on limit or cursor, but those are straightforward and the schema provides enough defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') with a clear resource ('Norwegian companies in a specific NACE industry code') and mentions optional filters, giving the agent a precise picture. It also distinguishes itself from a sibling tool by referencing firmaradar_list_nace_codes for code lookups, which prevents confusion about scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides concrete usage context with a sector-analysis example ('all active restaurants in Oslo with > 5 employees') and advises calling firmaradar_list_nace_codes when unsure about a code. It also recommends stiftet_etter for newly-founded-company queries. It does not explicitly contrast with firmaradar_search_companies, but the guidance is clear enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_list_my_subscriptionsList My Industry SubscriptionsARead-onlyIdempotentInspect
List the NACE industry-monitoring subscriptions of the authenticated Firmaradar user (created via subscribe_nace or the portal). Returns each subscription's id, NACE code, webhook URL, event filters, aggregation mode, geographic/size filters and active state. Use the returned id with delete_subscription to remove one. Encrypted bearer tokens are never returned (only has_bearer_token).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| items | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the bar is lower. The description adds valuable context: the exact fields returned, the fact that encrypted bearer tokens are never returned (only has_bearer_token), and scoping to the authenticated user via Bearer token. This goes beyond the annotations without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: purpose+origin, return fields, and deletion instruction+security note. It is concise and well-structured without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (0 params), the presence of an output schema, and annotations covering safety, the description provides sufficient extra context: lifecycle relationships, return field highlights, and auth scoping. It is complete for this use case.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema description explains 'No parameters — scoped to the authenticated user via the Bearer token.' The tool description itself doesn't add param semantics, but the baseline for 0 params is 4, and the schema description covers the rationale.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List the NACE industry-monitoring subscriptions of the authenticated Firmaradar user', using a specific verb and resource. It distinguishes itself from sibling tools like subscribe_nace, delete_subscription, and list_nace_codes by focusing on the user's subscriptions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context by noting subscriptions are 'created via subscribe_nace or the portal' and instructs to 'use the returned id with delete_subscription to remove one'. This contextualizes the tool within a subscription lifecycle, though it lacks explicit 'when not to use' or alternative-for-the-same-task guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_list_nace_codesSearch NACE Industry CodesARead-onlyIdempotentInspect
Search and browse the Norwegian NACE industry-code catalogue. Use this to resolve the exact code before calling subscribe_nace (industry monitoring) or list_companies_in_nace. Free-text search with q ('restaurant', 'programvare'), drill the hierarchy with parent (omit for the top-level sections A–U), or convert an EU NACE Rev. 2 code to the Norwegian 5-digit sub-codes with eu. Each hit includes the Norwegian and (when available) English label plus company counts. Backed by the official catalogue (SSB/BRREG), refreshed daily.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Free-text search on the Norwegian industry label (e.g. 'restaurant', 'programvare', 'bygg'). Returns the best-matching NACE codes ranked by relevance. | |
| eu | No | An EU NACE Rev. 2 code (e.g. '47.11', '62.01') — returns the Norwegian 5-digit sub-codes the register actually uses. Use this when you have an EU/international code and need the Norwegian equivalent before subscribing or listing companies. | |
| limit | No | ||
| parent | No | Return the direct children of this code to drill down the hierarchy: a section letter ('G'), a 2-digit group ('47'), a 3-digit ('47.1') or 4-digit ('47.11') code. Omit to list the top-level sections (A–U). |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| items | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already declaring readOnlyHint=true and idempotentHint=true, the description adds valuable behavioral context: it specifies what each hit contains (Norwegian and English labels, company counts), the data source (official catalogue SSB/BRREG), and refresh frequency (daily). This goes beyond the annotations and helps the agent understand the tool's output and reliability.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loaded with the core purpose, followed by usage guidance and output details. Every sentence earns its place – no filler, redundant phrasing, or repetition of schema information. It is concise yet packed with actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (4 parameters, output schema exists, annotations provided), the description is remarkably complete: it covers purpose, when-to-use, three usage modes, return elements, data source, and update cycle. The only unmentioned aspect is pagination or limit behavior, but the output schema likely covers return structure, so no critical gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75% (q, eu, parent have descriptions; limit does not). The description reinforces and enriches parameter meaning by explaining q as free-text search with examples, eu as a converter to Norwegian 5-digit sub-codes, and parent as a hierarchy drill-down with examples. It does not mention limit, but that parameter is self-explanatory, so the added value over the schema is solid, though not exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Search and browse the Norwegian NACE industry-code catalogue.' It uses a specific verb and resource, and distinguishes itself from sibling tools by explicitly positioning it as a precursor to subscribe_nace and list_companies_in_nace, making its role unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'Use this to resolve the exact code before calling subscribe_nace (industry monitoring) or list_companies_in_nace.' It also details three distinct usage modes (q, parent, eu) with examples, giving clear direction on how to invoke the tool for different scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_search_announcementsSearch AnnouncementsARead-onlyIdempotentInspect
Search BRREG kunngjøringer across all Norwegian companies — filter by type (konkurs, fusjon, ...), date range, NACE-code, or location. Use for trend analysis ('all konkurser in restaurant sector last quarter') or radar-style monitoring.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Free-text on company name. | |
| nace | No | NACE code or prefix. Norwegian BRREG uses 5-digit SN2007 codes internally (e.g. '56.110'). Any prefix works (2-5 digits). If a 4-digit code yields no results, append '0' for the 5-digit form. | |
| type | No | Kunngjøring (announcement) type/category. Values are Norwegian: konkurs (bankruptcy), fusjon (merger), fisjon (demerger), eierbytte (change of ownership), ... | |
| fylke | No | Norwegian fylkenummer — EXACTLY 2 digits, zero-padded (e.g. '03' = Oslo). NAMES not accepted. | |
| limit | No | ||
| cursor | No | ||
| kommune | No | Norwegian kommunenummer — EXACTLY 4 digits, zero-padded (e.g. '0301' = Oslo). NAMES not accepted. | |
| to_date | No | ISO date — inclusive upper bound. | |
| from_date | No | ISO date — inclusive lower bound. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| filter | Yes | |
| next_cursor | No | |
| total_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds context about the broad cross-company scope and the use for monitoring, but does not disclose details like pagination behavior, response shape, or rate limits beyond what the schema and output schema imply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core action and scope, followed by concrete use-case examples. Every word earns its place; no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 9 parameters, existing annotations, and an output schema, the description covers the tool's purpose, filters, and typical use cases. It does not mention pagination or how limit/cursor work, but those are partially evident from the schema and output schema, making it reasonably complete for a search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 78%, so most parameters are already documented. The description adds a high-level grouping of filter types (type, date range, NACE-code, location) but does not provide additional semantics for q, limit, or cursor, nor does it explain edge cases like the NACE prefix behavior (which the schema already covers).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches BRREG kunngjøringer across all Norwegian companies, with a specific verb ('Search') and resource scope. It distinguishes itself from siblings like firmaradar_get_company_announcements by emphasizing 'all Norwegian companies' and the filter dimensions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly recommends this tool for trend analysis and radar-style monitoring with concrete examples ('all konkurser in restaurant sector last quarter'). However, it does not mention exclusions or alternative tools for single-company announcement lookups, so it lacks explicit when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_search_companiesSearch CompaniesARead-onlyIdempotentInspect
Search Norwegian companies with filters (name, NACE, location, status, employees, revenue range, founding date). Returns paginated list of candidate orgnr to investigate further. Use when you have a description and need to find matching companies; use get_company once you have a specific orgnr. Revenue filtering excludes companies with no reported NOK revenue figure — see min_omsetning_nok. Backed by the official Norwegian company register (BRREG). Each hit includes a canonical Firmaradar url and the fields that matched the requested filters.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Free-text search across company names. | |
| nace | No | NACE code or prefix. Norwegian BRREG uses 5-digit SN2007 codes internally (e.g. '56.110' for restaurants, '47.111' for grocery stores). Any prefix works: '47' matches all retail (2-digit), '47.1' matches food/beverage retail (3-digit), '47.11' matches grocery stores (4-digit), '47.111' is the most specific (5-digit). If a 4-digit code yields no results, try appending '0' for the 5-digit form (e.g. '56.110' instead of '56.10'). | |
| fylke | No | Norwegian fylkenummer — EXACTLY 2 digits, zero-padded. Examples: '03' = Oslo, '11' = Rogaland, '15' = Møre og Romsdal. Fylke-NAMES are NOT accepted — translate first. | |
| limit | No | ||
| cursor | No | Opaque pagination cursor from previous call. | |
| status | No | Filter on company status. | |
| kommune | No | Norwegian kommunenummer — EXACTLY 4 digits, zero-padded. Examples: '0301' = Oslo, '4601' = Bergen, '5001' = Trondheim, '1103' = Stavanger. Kommune-NAMES are NOT accepted — translate the name to kommunenummer first. | |
| max_ansatte | No | ||
| min_ansatte | No | ||
| stiftet_for | No | ISO 8601 date — only companies founded on/before. | |
| stiftet_etter | No | ISO 8601 date — only companies founded on/after. | |
| max_omsetning_nok | No | Maximum annual revenue (driftsinntekter) in NOK — same source and same exclusion rule as min_omsetning_nok. | |
| min_omsetning_nok | No | Minimum annual revenue (driftsinntekter) in NOK, from the company's own accounts (not consolidated/group figures), latest year with a reported figure. NOTE: companies with no reported revenue are EXCLUDED from the results when this filter is set, as are accounts reported in a foreign currency. Must be combined with at least one of q/nace/kommune. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | |
| next_cursor | No | |
| total_count | No | |
| omsetning_filter_note | No | Set only when a revenue range was requested: explains that companies without a reported NOK revenue figure were excluded, so an empty result may mean missing accounts rather than no matching companies. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds valuable context beyond those annotations: pagination, the revenue exclusion rule, the BRREG data source, and that each hit includes a canonical URL and matching fields. This goes beyond the safety profile annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is composed of five dense sentences, each carrying unique information. It is front-loaded with purpose, then results, usage, caveat, and data source. While not overly long, a few details could be trimmed without loss, so not a perfect 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter search tool with an output schema and detailed annotations, the description covers purpose, usage, a key exclusion behavior, data source, and return value highlights. It does not repeat return-value structure (thanks to output schema) but is sufficiently complete for an agent to select and invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 77%, and the schema itself contains detailed parameter descriptions (e.g., NACE prefix matching, exact fylke format, min_omsetning exclusion rule). The tool description adds little new parameter-level meaning beyond referencing the revenue exclusion caveat already present in the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with 'Search Norwegian companies with filters' which is a specific verb+resource+scope. It clearly distinguishes itself from sibling tools by stating 'use `get_company` once you have a specific orgnr' and describing the result as 'paginated list of candidate orgnr to investigate further.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided: 'Use when you have a description and need to find matching companies; use `get_company` once you have a specific orgnr.' This also serves as a when-not instruction, naming the alternative tool. Additionally, the revenue filter caveat tells the agent when results will be excluded.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_search_personsSearch PersonsARead-onlyIdempotentInspect
Search for Norwegian persons in the shareholder/role-holder dataset by name. PII-sensitive — requires the search_full_enabled tier. Returns separate shareholder and role-holder hit lists with stable IDs that can be passed to get_person_companies and get_person_roles.
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Name to search (min 2 characters). | |
| limit | No | ||
| birth_year | No | Filter on birth year (helps disambiguate common names). | |
| kommune_hint | No | Optional kommune name to help disambiguate matches. |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | |
| role_persons | Yes | |
| shareholders | Yes | |
| role_persons_count | Yes | |
| shareholders_count | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the description adds value beyond that by disclosing PII sensitivity, the required access tier, and the structure of results (separate hit lists with stable IDs). This provides useful operational context not present in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loads the core action, and includes only essential details (PII, tier, output usage). No redundant content, every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists and annotations cover safety, the description sufficiently covers the tool's complexity: it names the dataset, access constraint, PII sensitivity, result types, and downstream usage. No critical contextual gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 75% (q, birth_year, kommune_hint have descriptions, limit does not). The description does not add parameter-specific meaning beyond what the schema provides, so it relies on the schema's adequate descriptions. Baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches for Norwegian persons in the shareholder/role-holder dataset by name, distinguishing it from sibling tools like firmaradar_search_companies. It also specifies the return types (shareholder and role-holder hit lists), leaving no ambiguity about the tool's purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context by noting the PII-sensitive tier requirement and that returned stable IDs can be passed to get_person_companies and get_person_roles. However, it does not explicitly state when to prefer this over alternatives like search_companies or get_person, so it stops short of full exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_start_aml_reportStart AML Report (Async)AInspect
Start generating an AML risk report ASYNCHRONOUSLY for a Norwegian company. Returns immediately with a report_id and status 'pending' — the report is built in the background. Poll get_aml_report with the report_id until status is 'done' (then read score/level/factors) or 'failed'. Use this instead of get_aml_score for large/complex ownership structures that may otherwise time out, or to start many screenings in parallel. Generates an auditable report stored for 60 months per Hvitvaskingsloven §35.
| Name | Required | Description | Default |
|---|---|---|---|
| orgnr | Yes | 9-digit norwegian organization number. | |
| purpose | No | Purpose of the screening — recorded for audit trail. | kyc_onboarding |
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | |
| orgnr | Yes | |
| status | Yes | One of: pending, running, done, failed (starts at 'pending'). |
| report_id | Yes | Job/report id — poll with `get_aml_report` until status is 'done' or 'failed'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are sparse (readOnly=false, destructive=false, idempotent=false), so the description carries the burden. It fully discloses the async nature, immediate return with pending status, background processing, polling requirements, success/failure states, auditable report storage for 60 months, and legal basis (Hvitvaskingsloven §35). No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences deliver complete information: the action and async behavior, polling instructions with statuses, and usage alternatives plus a regulatory retention note. Every sentence earns its place with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all necessary context: async operation, polling workflow, when to prefer over `get_aml_score`, parallel screening use case, and report retention. The output schema exists to define return values, so the description does not need to do so. The sibling list confirms `get_aml_report` exists, aligning with the polling reference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage with clear descriptions for both `orgnr` (9-digit Norwegian organization number) and `purpose` (Purpose of screening — recorded for audit trail). The description adds no additional parameter-level detail beyond what the schema provides, but it does reinforce the audit purpose context. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs and resources: 'Start generating an AML risk report ASYNCHRONOUSLY for a Norwegian company'. It clearly distinguishes from siblings by explicitly referencing `get_aml_score` as the synchronous alternative and `get_aml_report` for polling, making the tool's unique role evident.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Use this instead of `get_aml_score` for large/complex ownership structures that may otherwise time out, or to start many screenings in parallel.' It also provides the polling workflow with `get_aml_report`, including status handling and how to interpret results.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
firmaradar_subscribe_naceSubscribe to Industry Monitoring (NACE)AIdempotentInspect
Subscribe to industry (NACE) monitoring: when any Norwegian company in the chosen industry triggers a monitored event (new announcement, status change such as bankruptcy/dissolution, or ownership update), Firmaradar delivers a webhook to your URL. Use list_nace_codes first to resolve the exact code. A subscription on a parent code matches all child codes. Restrict events (e.g. ['status_changed']) and use geographic/size filters to cut volume in large industries, or pick a digest aggregation_mode. Idempotent — upserted on (user, nace_code), so re-subscribing the same code updates it. Requires a user whose plan has Firmaovervakning enabled. Call only when the user has asked to set up industry monitoring.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | HTTPS webhook URL that receives a POST for each matched event. Omit only if you intend to add it later via the portal. | |
| events | No | Which event types to deliver. Omit for all of them. Restrict to e.g. ['status_changed'] to receive only bankruptcy/dissolution signals and cut volume dramatically in large industries. | |
| aktivert | No | Whether the subscription is active immediately (default true). | |
| nace_code | Yes | The NACE code to monitor. Accepts a section letter ('G'), a group ('47'), or a more specific code ('47.110'). Resolve the exact code first with list_nace_codes if unsure. A subscription on a parent code also matches events in all child codes. | |
| min_ansatte | No | Optional size filter: only companies with at least this many employees. | |
| bearer_token | No | Optional bearer token Firmaradar sends as `Authorization: Bearer <token>` when calling your webhook URL, so your endpoint can authenticate the delivery. Stored encrypted. | |
| fylke_filter | No | Optional geographic filter: only companies in these fylker (county numbers). | |
| kommune_filter | No | Optional geographic filter: only companies in these kommuner (4-digit kommunenummer). | |
| landsdel_filter | No | Optional geographic filter: only companies in these landsdeler. | |
| aggregation_mode | No | Delivery cadence. 'real_time' (default) posts each event immediately. 'hourly_digest' / 'daily_digest' batch events to reduce noise in high-volume industries. | real_time |
| min_omsetning_nok | No | Optional size filter: only companies with at least this much revenue (NOK). |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | ID of the created/updated subscription. |
| raw | No | |
| url | No | |
| events | No | |
| aktivert | No | |
| nace_code | No | |
| created_at | No | |
| updated_at | No | |
| aggregation_mode | No | |
| aggregation_mode_en | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (idempotentHint=true), the description explains the upsert-on-(user, nace_code) behavior, parent-code child-code matching, plan requirement (Firmaovervakning), webhook POST behavior, and optional bearer token. This adds substantial behavioral context not present in the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact yet information-dense, with every sentence providing actionable guidance. It is front-loaded with the core purpose and then efficiently covers prerequisites, matching behavior, filtering, idempotency, and permissions without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter subscription tool, the description covers all key aspects: what events are monitored, how to use NACE codes, filtering strategies, aggregation modes, authorization, idempotency, and prerequisites. With an output schema present, not detailing return values is acceptable, and the description still gives a complete operational picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and each parameter already has a descriptive schema entry. The description adds extra strategic semantics, such as 'restrict events to cut volume', 'use geographic/size filters to cut volume', and parent-code expansion, which enriches beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Subscribe to industry (NACE) monitoring') and clearly states the resource (industry/NACE codes) and the delivery mechanism (webhook on monitored events). It differentiates from sibling tools like firmaradar_add_company_monitoring by focusing on industry-level rather than company-level monitoring.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage guidance: call list_nace_codes first to resolve codes, call only when the user requests industry monitoring, restrict events and use filters for high-volume industries, and choose aggregation_mode for digest delivery. It also implies a clear alternative by contrasting with company monitoring via its title and scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.3- Changed
firmaradar_get_company4 fields changed- removed
Input schema / properties / fields / anyOfRemoved value: -[ - { - "items": { - "enum": [ - "group", - "owners", - "business_owners", - "full_owners", - "grants", - "brreg_grants", - "ip", - "changes", - "financial_metrics" - ], - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - removed
Input schema / properties / fields / defaultRemoved value: -null - added
Input schema / properties / fields / itemsAdded value: +{ + "enum": [ + "group", + "owners", + "business_owners", + "full_owners", + "grants", + "brreg_grants", + "ip", + "changes", + "financial_metrics" + ], + "type": "string" +} - added
Input schema / properties / fields / typeAdded value: +"array"
- Changed
firmaradar_subscribe_nace4 fields changed- removed
Input schema / properties / events / anyOfRemoved value: -[ - { - "items": { - "enum": [ - "created", - "updated", - "deleted", - "status_changed" - ], - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -] - removed
Input schema / properties / events / defaultRemoved value: -null - added
Input schema / properties / events / itemsAdded value: +{ + "enum": [ + "created", + "updated", + "deleted", + "status_changed" + ], + "type": "string" +} - added
Input schema / properties / events / typeAdded value: +"array"
36 tool updates
v0.1.2- Added
firmaradar_add_company_monitoring - Changed
firmaradar_check_aml_pep2 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"Full name to screen."New value: +"Full name of ONE natural PERSON to screen (e.g. 'Ola Nordmann'). NOT a company name or orgnr — for company AML use firmaradar_get_aml_score instead." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "AmlPepHit": { + "properties": { + "ekstern_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ekstern Id" + }, + "embete": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Embete" + }, + "entitet_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Entitet Type" + }, + "fodselsdato": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Fodselsdato" + }, + "fodselsdato_mangler": { + "default": false, + "title": "Fodselsdato Mangler", + "type": "boolean" + }, + "kategori": { + "title": "Kategori", + "type": "string" + }, + "kilder": { + "items": { + "type": "string" + }, + "title": "Kilder", + "type": "array" + }, + "match_ratio": { + "title": "Match Ratio", + "type": "number" + }, + "match_type": { + "title": "Match Type", + "type": "string" + }, + "matchgrunnlag": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Matchgrunnlag" + }, + "pep_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Pep Status" + }, + "pep_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Pep Type" + }, + "primart_navn": { + "title": "Primart Navn", + "type": "string" + }, + "relasjon": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Relasjon" + }, + "relasjon_innenfor_direktivet": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Relasjon Innenfor Direktivet" + }, + "relasjon_kode": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Relasjon Kode" + }, + "verv_fra": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verv Fra" + }, + "verv_historikk": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "title": "Verv Historikk", + "type": "array" + }, + "verv_til": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verv Til" + }, + "weak_match": { + "default": false, + "title": "Weak Match", + "type": "boolean" + } + }, + "required": [ + "primart_navn", + "kategori", + "match_ratio", + "match_type" + ], + "title": "AmlPepHit", + "type": "object" + } + }, + "properties": { + "hit_count": { + "title": "Hit Count", + "type": "integer" + }, + "hits": { + "items": { + "$ref": "#/$defs/AmlPepHit" + }, + "title": "Hits", + "type": "array" + }, + "note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Note" + }, + "query_birth_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Query Birth Year" + }, + "query_name": { + "title": "Query Name", + "type": "string" + }, + "query_too_short": { + "default": false, + "title": "Query Too Short", + "type": "boolean" + } + }, + "required": [ + "query_name", + "hits", + "hit_count" + ], + "type": "object" +}
- Changed
firmaradar_check_fiv_bulk1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "BulkFivResult": { + "description": "Per-orgnr resultat i bulk-FIV-respons.", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Feiltype hvis evaluering ikke kunne fullføres: invalid_orgnr, blocked_enk, extension_disabled, etc. Body inneholder også detaljerte feilmeldinger.", + "title": "Error" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "raw": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Raw" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "FIV (foretak i vanskeligheter / company-in-difficulty) status when available: not_distressed, distressed, insufficient_data, exempt_young_company, not_distressed_partial. Absent when error is set.", + "title": "Status" + } + }, + "required": [ + "orgnr" + ], + "title": "BulkFivResult", + "type": "object" + }, + "BulkMeta": { + "properties": { + "failed": { + "title": "Failed", + "type": "integer" + }, + "successful": { + "title": "Successful", + "type": "integer" + }, + "total_requested": { + "title": "Total Requested", + "type": "integer" + } + }, + "required": [ + "total_requested", + "successful", + "failed" + ], + "title": "BulkMeta", + "type": "object" + } + }, + "properties": { + "_meta": { + "$ref": "#/$defs/BulkMeta", + "description": "Aggregate count status for the whole bulk call." + }, + "results": { + "items": { + "$ref": "#/$defs/BulkFivResult" + }, + "title": "Results", + "type": "array" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Human-readable markdown table of the per-company FIV verdicts.", + "title": "Summary" + } + }, + "required": [ + "_meta" + ], + "type": "object" +}
- Changed
firmaradar_check_foretak_i_vanskeligheter1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "FivRule": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Description" + }, + "rule_id": { + "title": "Rule Id", + "type": "string" + }, + "severity": { + "title": "Severity", + "type": "string" + } + }, + "required": [ + "rule_id", + "severity" + ], + "title": "FivRule", + "type": "object" + } + }, + "properties": { + "as_of": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "As Of" + }, + "confidence": { + "description": "Data-completeness confidence in [0.0, 1.0].", + "title": "Confidence", + "type": "number" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "raw": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Raw" + }, + "rules_fired": { + "items": { + "$ref": "#/$defs/FivRule" + }, + "title": "Rules Fired", + "type": "array" + }, + "score": { + "description": "Confidence-weighted distress score in [0.0, 1.0].", + "title": "Score", + "type": "number" + }, + "status": { + "description": "One of: not_distressed, insufficient_data, not_distressed_partial, exempt_young_company, distressed.", + "title": "Status", + "type": "string" + } + }, + "required": [ + "orgnr", + "status", + "score", + "confidence" + ], + "type": "object" +}
- Added
firmaradar_check_konkurs_eksponering - Changed
firmaradar_compare_companies1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "antall_ansatte": { + "anyOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "{<orgnr>: <current headcount|null>}. Present only when `antall_ansatte` is in the requested metric set. CURRENT value from Enhetsregisteret (the register attribute has no per-year history), mirroring `companies[].antall_ansatte` on the server-side compare endpoint. Null when unknown.", + "title": "Antall Ansatte" + }, + "comparison": { + "additionalProperties": { + "additionalProperties": { + "items": {}, + "type": "array" + }, + "type": "object" + }, + "description": "{<metric>: {<orgnr>: [<value_per_year>, ...]}}. For `antall_ansatte` the per-year lists are always null — headcount does not exist per fiscal year; use the top-level `antall_ansatte` field instead.", + "title": "Comparison", + "type": "object" + }, + "computed_at": { + "title": "Computed At", + "type": "string" + }, + "currencies": { + "anyOf": [ + { + "additionalProperties": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "type": "array" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "{<orgnr>: [<ISO 4217 currency per year, aligned with `years`>]}. None for years without data. Amounts in `comparison` are in the company's reporting currency for that year (NOK for most Norwegian companies) — do not compare amounts across different currencies without converting.", + "title": "Currencies" + }, + "orgnrs": { + "items": { + "type": "string" + }, + "title": "Orgnrs", + "type": "array" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Summary" + }, + "years": { + "items": { + "type": "integer" + }, + "title": "Years", + "type": "array" + } + }, + "required": [ + "orgnrs", + "years", + "comparison", + "computed_at" + ], + "type": "object" +}
- Changed
firmaradar_confirm_risk_score_disclaimer1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "audit_id": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "ID of the audit row in ``extension_kundebekreftelse_event``.", + "title": "Audit Id" + }, + "confirmed": { + "description": "True if the disclaimer is confirmed for the user.", + "title": "Confirmed", + "type": "boolean" + }, + "confirmed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "ISO timestamp of the confirmation.", + "title": "Confirmed At" + }, + "confirmed_by_user_id": { + "description": "ID of the Firmaradar user the confirmation is registered against.", + "title": "Confirmed By User Id", + "type": "integer" + }, + "idempotent": { + "default": false, + "description": "True if the confirmation already existed (no new row written).", + "title": "Idempotent", + "type": "boolean" + }, + "raw": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Raw" + }, + "version": { + "description": "Disclaimer version that was confirmed (e.g. 'v1').", + "title": "Version", + "type": "string" + } + }, + "required": [ + "confirmed", + "version", + "confirmed_by_user_id" + ], + "type": "object" +}
- Added
firmaradar_convert_nok - Added
firmaradar_delete_subscription - Changed
firmaradar_find_related_companies2 fields changed- changed
Input schema / properties / via / descriptionPrevious value: -"'person' = shared board members/shareholders. 'address' = same forretningsadresse. 'owner' = same ultimate beneficial owner (heavier — owner-graph traversal)."New value: +"'person' = shared board members/shareholders. 'address' = same forretningsadresse. 'owner' = shares significant owners (>=10%) via the shareholder-book ownership graph (heavier — owner-graph traversal)." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "RelatedCompany": { + "properties": { + "navn": { + "title": "Navn", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "relation_strength": { + "description": "Higher = stronger relation.", + "title": "Relation Strength", + "type": "integer" + }, + "shared_entities": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "title": "Shared Entities", + "type": "array" + } + }, + "required": [ + "orgnr", + "navn", + "relation_strength" + ], + "title": "RelatedCompany", + "type": "object" + } + }, + "properties": { + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "related": { + "items": { + "$ref": "#/$defs/RelatedCompany" + }, + "title": "Related", + "type": "array" + }, + "total_count": { + "title": "Total Count", + "type": "integer" + }, + "via": { + "title": "Via", + "type": "string" + } + }, + "required": [ + "orgnr", + "via", + "related", + "total_count" + ], + "type": "object" +}
- Added
firmaradar_find_shared_connections - Added
firmaradar_get_aml_report - Changed
firmaradar_get_aml_score1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "AmlFactor": { + "properties": { + "details": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Details" + }, + "id": { + "title": "Id", + "type": "string" + }, + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "triggered": { + "title": "Triggered", + "type": "boolean" + }, + "weight": { + "title": "Weight", + "type": "integer" + } + }, + "required": [ + "id", + "weight", + "triggered" + ], + "title": "AmlFactor", + "type": "object" + } + }, + "properties": { + "factors": { + "description": "Always empty for the async report flow — factor detail lives in the stored report (json_url/pdf_url in `raw` when done).", + "items": { + "$ref": "#/$defs/AmlFactor" + }, + "title": "Factors", + "type": "array" + }, + "level": { + "description": "One of: low, medium, high — or 'pending' when the report is still generating (poll `get_aml_report` with rapport_id).", + "title": "Level", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "rapport_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Persistent report-id for compliance audit (retrievable later).", + "title": "Rapport Id" + }, + "raw": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Raw" + }, + "score": { + "description": "AML risk score 0-100 (higher = riskier).", + "title": "Score", + "type": "integer" + } + }, + "required": [ + "orgnr", + "score", + "level" + ], + "type": "object" +}
- Changed
firmaradar_get_company3 fields changed- changed
Input schema / properties / fields / anyOfPrevious value: -[ - { - "items": { - "enum": [ - "group", - "owners", - "business_owners", - "full_owners", - "grants", - "brreg_grants", - "changes", - "financial_metrics" - ], - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } -]New value: +[ + { + "items": { + "enum": [ + "group", + "owners", + "business_owners", + "full_owners", + "grants", + "brreg_grants", + "ip", + "changes", + "financial_metrics" + ], + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } +] - changed
Input schema / properties / fields / descriptionPrevious value: -"Subset of sections to include. Omit to get the default profile."New value: +"Subset of sections to include. Omit to get the default profile. Notable opt-in sections: `ip` — intellectual-property portfolio (patents, trademarks and designs from Patentstyret); `group` — full group structure; `owners`/`business_owners`/`full_owners` — ownership tiers; `grants` — public grants; `changes` — recent register changes; `financial_metrics` — accounting figures." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "brreg_tildelinger": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Brreg Tildelinger" + }, + "eiere": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Eiere" + }, + "endringer": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Endringer" + }, + "financial_metrics": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Financial Metrics" + }, + "foretaksklassifisering": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Foretaksklassifisering" + }, + "ip_rettigheter": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ip Rettigheter" + }, + "konsernstruktur": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Konsernstruktur" + }, + "navn": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Navn" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "source": { + "default": "Firmaradar", + "description": "Authoritative source name.", + "title": "Source", + "type": "string" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Human-readable summary (LLM-friendly).", + "title": "Summary" + }, + "tildelinger": { + "anyOf": [ + { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Tildelinger" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Canonical Firmaradar source URL for this company — cite this.", + "title": "Url" + } + }, + "required": [ + "orgnr" + ], + "type": "object" +}
- Changed
firmaradar_get_company_announcements1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "Announcement": { + "properties": { + "category": { + "description": "Normalised Norwegian category: 'konkurs' (bankruptcy), 'fusjon' (merger), 'fisjon' (demerger), 'eierbytte' (change of ownership), 'aarsregnskap' (annual accounts), ...", + "title": "Category", + "type": "string" + }, + "dato": { + "description": "ISO 8601 date (YYYY-MM-DD).", + "title": "Dato", + "type": "string" + }, + "hendelse_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hendelse Type" + }, + "kunngjoring_type": { + "description": "Raw BRREG label, e.g. 'Konkursåpning' (bankruptcy opening).", + "title": "Kunngjoring Type", + "type": "string" + }, + "navn": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Navn" + } + }, + "required": [ + "dato", + "kunngjoring_type", + "category" + ], + "title": "Announcement", + "type": "object" + } + }, + "properties": { + "count": { + "title": "Count", + "type": "integer" + }, + "items": { + "items": { + "$ref": "#/$defs/Announcement" + }, + "title": "Items", + "type": "array" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + } + }, + "required": [ + "orgnr", + "count", + "items" + ], + "type": "object" +}
- Changed
firmaradar_get_company_financials1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "FinancialYear": { + "properties": { + "aar": { + "title": "Aar", + "type": "integer" + }, + "aarsresultat": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Aarsresultat" + }, + "antall_ansatte": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Antall Ansatte" + }, + "driftsresultat": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Driftsresultat" + }, + "omsetning": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Omsetning" + }, + "raw": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Raw" + }, + "sum_egenkapital": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sum Egenkapital" + }, + "sum_gjeld": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sum Gjeld" + }, + "valuta": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Reporting currency for this year (ISO 4217). None means NOK.", + "title": "Valuta" + } + }, + "required": [ + "aar" + ], + "title": "FinancialYear", + "type": "object" + } + }, + "properties": { + "freshness": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Freshness" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "regnskapstype": { + "title": "Regnskapstype", + "type": "string" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Summary" + }, + "valuta": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Reporting currency across the series (ISO 4217, e.g. 'NOK' or 'USD'). 'MIXED' when the years are filed in different currencies — then check valuta per year before comparing amounts across years.", + "title": "Valuta" + }, + "years": { + "items": { + "$ref": "#/$defs/FinancialYear" + }, + "title": "Years", + "type": "array" + } + }, + "required": [ + "orgnr", + "regnskapstype", + "years" + ], + "type": "object" +}
- Added
firmaradar_get_company_ip - Changed
firmaradar_get_company_ownership1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "depth": { + "title": "Depth", + "type": "integer" + }, + "direction": { + "title": "Direction", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Summary" + }, + "tree": { + "additionalProperties": true, + "title": "Tree", + "type": "object" + } + }, + "required": [ + "orgnr", + "direction", + "depth", + "tree" + ], + "type": "object" +}
- Changed
firmaradar_get_company_roles1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "CompanyRole": { + "properties": { + "fodselsaar": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Fodselsaar" + }, + "fra_dato": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Fra Dato" + }, + "navn": { + "title": "Navn", + "type": "string" + }, + "role_person_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Stable ID — pass to `get_person_roles` for more.", + "title": "Role Person Id" + }, + "rolle_type": { + "title": "Rolle Type", + "type": "string" + }, + "signatur_alene": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Signatur Alene" + }, + "til_dato": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Til Dato" + } + }, + "required": [ + "rolle_type", + "navn" + ], + "title": "CompanyRole", + "type": "object" + } + }, + "properties": { + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "roles": { + "items": { + "$ref": "#/$defs/CompanyRole" + }, + "title": "Roles", + "type": "array" + }, + "total_count": { + "title": "Total Count", + "type": "integer" + } + }, + "required": [ + "orgnr", + "roles", + "total_count" + ], + "type": "object" +}
- Changed
firmaradar_get_company_signals1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "KycSignal": { + "properties": { + "kategori": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Kategori" + }, + "kunngjoring_dato": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Kunngjoring Dato" + }, + "payload": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Payload" + }, + "type": { + "title": "Type", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "KycSignal", + "type": "object" + } + }, + "properties": { + "distress_category": { + "anyOf": [ + { + "enum": [ + "green", + "yellow", + "red", + "unknown" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Distress Category" + }, + "distress_reasons": { + "items": { + "type": "string" + }, + "title": "Distress Reasons", + "type": "array" + }, + "distress_score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Distress Score" + }, + "frivillighet": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Authoritative Frivillighetsregister (voluntary-org) membership: registered, registreringsdato, kategorier. Omitted when the source is off.", + "title": "Frivillighet" + }, + "fusjon": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Merger/demerger relations: inbound (companies merged into this orgnr) + outbound (companies this orgnr was merged into), with dates.", + "title": "Fusjon" + }, + "generated_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Generated At" + }, + "hiring": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "NAV Arbeidsplassen hiring/growth signal: active_postings, positions_active, postings_30d/90d, burst_score, is_hiring_burst.", + "title": "Hiring" + }, + "interim_balance_signal": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Interim Balance Signal" + }, + "kyc_signals": { + "items": { + "$ref": "#/$defs/KycSignal" + }, + "title": "Kyc Signals", + "type": "array" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "recent_role_changes_count": { + "default": 0, + "title": "Recent Role Changes Count", + "type": "integer" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Summary" + } + }, + "required": [ + "orgnr" + ], + "type": "object" +}
- Changed
firmaradar_get_konsernstotte1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "KonsernAggregat": { + "description": "Aggregert sum av selskapsstøtte for alle selskap i konsernet.\n\n\"Konsernstøtte\" er per definisjon en utledet KPI — ingen kilde gir\nstøtte til et konsern direkte. Aggregatet summerer\n:class:`SelskapStotte` for hvert selskap i hierarkiet.", + "properties": { + "andre": { + "default": 0, + "title": "Andre", + "type": "integer" + }, + "antall_prosjekter": { + "default": 0, + "title": "Antall Prosjekter", + "type": "integer" + }, + "antall_selskaper": { + "default": 0, + "title": "Antall Selskaper", + "type": "integer" + }, + "innovasjon_norge": { + "default": 0, + "title": "Innovasjon Norge", + "type": "integer" + }, + "skattefunn": { + "default": 0, + "title": "Skattefunn", + "type": "integer" + }, + "total_belop_nok": { + "default": 0, + "title": "Total Belop Nok", + "type": "number" + } + }, + "title": "KonsernAggregat", + "type": "object" + }, + "KonsernNode": { + "properties": { + "antall_underselskaper": { + "default": 0, + "title": "Antall Underselskaper", + "type": "integer" + }, + "barn": { + "items": {}, + "title": "Barn", + "type": "array" + }, + "navn": { + "title": "Navn", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "selskap_stotte": { + "$ref": "#/$defs/SelskapStotte" + } + }, + "required": [ + "orgnr", + "navn" + ], + "title": "KonsernNode", + "type": "object" + }, + "SelskapStotte": { + "description": "Støtte gitt direkte til *ett* selskap.\n\nSkatteFUNN/Innovasjon Norge gir aldri støtte til konsern, kun til\nindividuelle selskap (#134, 2026-05-27). Aggregeringen på tvers av\nkonsernhierarkiet finner du i :class:`KonsernAggregat`.", + "properties": { + "andre": { + "default": 0, + "title": "Andre", + "type": "integer" + }, + "antall_prosjekter": { + "default": 0, + "title": "Antall Prosjekter", + "type": "integer" + }, + "innovasjon_norge": { + "default": 0, + "title": "Innovasjon Norge", + "type": "integer" + }, + "skattefunn": { + "default": 0, + "title": "Skattefunn", + "type": "integer" + }, + "total_belop_nok": { + "default": 0, + "title": "Total Belop Nok", + "type": "number" + } + }, + "title": "SelskapStotte", + "type": "object" + } + }, + "properties": { + "antall_underselskaper": { + "default": 0, + "title": "Antall Underselskaper", + "type": "integer" + }, + "barn": { + "items": { + "$ref": "#/$defs/KonsernNode" + }, + "title": "Barn", + "type": "array" + }, + "konsern_aggregat": { + "$ref": "#/$defs/KonsernAggregat" + }, + "navn": { + "title": "Navn", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "raw": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Raw" + }, + "selskap_stotte": { + "$ref": "#/$defs/SelskapStotte" + } + }, + "required": [ + "orgnr", + "navn" + ], + "type": "object" +}
- Changed
firmaradar_get_person1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "active_roles": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "title": "Active Roles", + "type": "array" + }, + "aml_pep_hits": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "title": "Aml Pep Hits", + "type": "array" + }, + "aml_pep_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Aml Pep Note" + }, + "birth_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Birth Year" + }, + "konkurs_eksponering": { + "additionalProperties": true, + "title": "Konkurs Eksponering", + "type": "object" + }, + "navn": { + "title": "Navn", + "type": "string" + }, + "person_id": { + "title": "Person Id", + "type": "string" + }, + "shareholdings": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "title": "Shareholdings", + "type": "array" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Summary" + } + }, + "required": [ + "person_id", + "navn" + ], + "type": "object" +}
- Changed
firmaradar_get_person_companies1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "Shareholding": { + "properties": { + "antall_aksjer": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Antall Aksjer" + }, + "eierandel_prosent": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Eierandel Prosent" + }, + "navn": { + "title": "Navn", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + } + }, + "required": [ + "orgnr", + "navn" + ], + "title": "Shareholding", + "type": "object" + } + }, + "properties": { + "navn": { + "title": "Navn", + "type": "string" + }, + "person_key": { + "title": "Person Key", + "type": "string" + }, + "shareholdings": { + "items": { + "$ref": "#/$defs/Shareholding" + }, + "title": "Shareholdings", + "type": "array" + }, + "total_companies": { + "title": "Total Companies", + "type": "integer" + } + }, + "required": [ + "person_key", + "navn", + "shareholdings", + "total_companies" + ], + "type": "object" +}
- Changed
firmaradar_get_person_roles1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "CompanyRole": { + "properties": { + "fra_dato": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Fra Dato" + }, + "navn": { + "title": "Navn", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "rolle_type": { + "title": "Rolle Type", + "type": "string" + }, + "til_dato": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Til Dato" + } + }, + "required": [ + "orgnr", + "navn", + "rolle_type" + ], + "title": "CompanyRole", + "type": "object" + } + }, + "properties": { + "navn": { + "title": "Navn", + "type": "string" + }, + "role_person_id": { + "title": "Role Person Id", + "type": "string" + }, + "roles": { + "items": { + "$ref": "#/$defs/CompanyRole" + }, + "title": "Roles", + "type": "array" + }, + "total_roles": { + "title": "Total Roles", + "type": "integer" + } + }, + "required": [ + "role_person_id", + "navn", + "roles", + "total_roles" + ], + "type": "object" +}
- Changed
firmaradar_get_recent_changes2 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Optional kunngjøring-category filter (konkurs, fusjon, eierbytte, ...)."New value: +"Optional kunngjøring (announcement) category filter. Values are Norwegian: konkurs (bankruptcy), fusjon (merger), eierbytte (change of ownership), ..." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "ChangeItem": { + "properties": { + "category": { + "title": "Category", + "type": "string" + }, + "dato": { + "title": "Dato", + "type": "string" + }, + "payload": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Payload" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Summary" + } + }, + "required": [ + "dato", + "category" + ], + "title": "ChangeItem", + "type": "object" + } + }, + "properties": { + "count": { + "title": "Count", + "type": "integer" + }, + "entity_type": { + "title": "Entity Type", + "type": "string" + }, + "id": { + "title": "Id", + "type": "string" + }, + "items": { + "items": { + "$ref": "#/$defs/ChangeItem" + }, + "title": "Items", + "type": "array" + }, + "since": { + "title": "Since", + "type": "string" + }, + "until": { + "title": "Until", + "type": "string" + } + }, + "required": [ + "entity_type", + "id", + "since", + "until", + "count", + "items" + ], + "type": "object" +}
- Changed
firmaradar_get_risk_score1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "RiskComponent": { + "properties": { + "id": { + "title": "Id", + "type": "string" + }, + "label": { + "title": "Label", + "type": "string" + }, + "max": { + "title": "Max", + "type": "number" + }, + "points": { + "title": "Points", + "type": "number" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Status" + } + }, + "required": [ + "id", + "label", + "points", + "max" + ], + "title": "RiskComponent", + "type": "object" + } + }, + "properties": { + "components": { + "items": { + "$ref": "#/$defs/RiskComponent" + }, + "title": "Components", + "type": "array" + }, + "data_gaps": { + "items": { + "type": "string" + }, + "title": "Data Gaps", + "type": "array" + }, + "level": { + "description": "Norwegian risk level — one of: lav (low), moderat (moderate), høy (high), kritisk (critical).", + "title": "Level", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "raw": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Raw" + }, + "score": { + "description": "Risk score on the 0-100 scale (higher = riskier).", + "title": "Score", + "type": "number" + }, + "sources": { + "items": { + "type": "string" + }, + "title": "Sources", + "type": "array" + } + }, + "required": [ + "orgnr", + "score", + "level" + ], + "type": "object" +}
- Changed
firmaradar_get_risk_score_bulk1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "BulkMeta": { + "properties": { + "failed": { + "title": "Failed", + "type": "integer" + }, + "successful": { + "title": "Successful", + "type": "integer" + }, + "total_requested": { + "title": "Total Requested", + "type": "integer" + } + }, + "required": [ + "total_requested", + "successful", + "failed" + ], + "title": "BulkMeta", + "type": "object" + }, + "BulkRiskScoreResult": { + "description": "Per-orgnr resultat i bulk-risikoscoring-respons.", + "properties": { + "components": { + "items": { + "$ref": "#/$defs/RiskComponentBrief" + }, + "title": "Components", + "type": "array" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Feiltype hvis scoring ikke kunne fullføres: invalid_orgnr, blocked_enk, enk_not_supported, extension_disabled, confirmation_required, etc. Body inneholder også detaljer.", + "title": "Error" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "raw": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Raw" + }, + "risk_level": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Norwegian risk level — one of: lav (low), moderat (moderate), høy (high), kritisk (critical). None on error.", + "title": "Risk Level" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + } + }, + "required": [ + "orgnr" + ], + "title": "BulkRiskScoreResult", + "type": "object" + }, + "RiskComponentBrief": { + "properties": { + "id": { + "title": "Id", + "type": "string" + }, + "label": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Label" + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max" + }, + "points": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Points" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Status" + } + }, + "required": [ + "id" + ], + "title": "RiskComponentBrief", + "type": "object" + } + }, + "properties": { + "_meta": { + "$ref": "#/$defs/BulkMeta", + "description": "Aggregate count status for the whole bulk call." + }, + "results": { + "items": { + "$ref": "#/$defs/BulkRiskScoreResult" + }, + "title": "Results", + "type": "array" + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Human-readable markdown table of the per-company scores.", + "title": "Summary" + } + }, + "required": [ + "_meta" + ], + "type": "object" +}
- Removed
firmaradar_get_skattelister - Changed
firmaradar_list_companies_in_nace3 fields changed- added
Input schema / properties / stiftet_etterAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "ISO 8601 date (YYYY-MM-DD) — only companies founded on/after this date. Use for 'newly founded companies in this industry' queries (industry monitoring).", + "title": "Stiftet Etter" +} - added
Input schema / properties / stiftet_forAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "ISO 8601 date (YYYY-MM-DD) — only companies founded on/before this date.", + "title": "Stiftet For" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "NaceCatalogInfo": { + "description": "Aggregat-counts fra ``nace_code`` (oppdateres nattlig).\n\nDet totale antallet norske selskaper i koden, splittet i aktive (ikke\nkonkurs/avvikling) og total (alle inkl. konkurs/avvikling). Disse er\nrullet opp i NACE-hierarkiet, så også foreldre-koder (eks. ``62``,\n``62.1``, ``62.10``) har realistiske counts.\n\n``company_count`` er en legacy-alias for ``company_count_active`` for\nback-compat — den eldre API-en lagret kun aktive selskaper i denne\nkolonnen.", + "properties": { + "company_count": { + "title": "Company Count", + "type": "integer" + }, + "company_count_active": { + "title": "Company Count Active", + "type": "integer" + }, + "company_count_total": { + "title": "Company Count Total", + "type": "integer" + }, + "label_no": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Label No" + }, + "level": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Level" + }, + "parent_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Parent Code" + } + }, + "required": [ + "company_count", + "company_count_active", + "company_count_total" + ], + "title": "NaceCatalogInfo", + "type": "object" + }, + "NaceCompanyHit": { + "properties": { + "antall_ansatte": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Antall Ansatte" + }, + "kommune": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Kommune" + }, + "naeringskode": { + "title": "Naeringskode", + "type": "string" + }, + "navn": { + "title": "Navn", + "type": "string" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Status" + }, + "stiftelsesdato": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Stiftelsesdato" + } + }, + "required": [ + "orgnr", + "navn", + "naeringskode" + ], + "title": "NaceCompanyHit", + "type": "object" + } + }, + "properties": { + "catalog": { + "anyOf": [ + { + "$ref": "#/$defs/NaceCatalogInfo" + }, + { + "type": "null" + } + ], + "default": null + }, + "items": { + "items": { + "$ref": "#/$defs/NaceCompanyHit" + }, + "title": "Items", + "type": "array" + }, + "nace_code": { + "title": "Nace Code", + "type": "string" + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Next Cursor" + }, + "total_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total Count" + } + }, + "required": [ + "nace_code", + "items" + ], + "type": "object" +}
- Added
firmaradar_list_my_subscriptions - Added
firmaradar_list_nace_codes - Changed
firmaradar_search_announcements2 fields changed- changed
Input schema / properties / type / descriptionPrevious value: -"Kunngjøring type/category: konkurs, fusjon, fisjon, eierbytte, ..."New value: +"Kunngjøring (announcement) type/category. Values are Norwegian: konkurs (bankruptcy), fusjon (merger), fisjon (demerger), eierbytte (change of ownership), ..." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "AnnouncementHit": { + "properties": { + "category": { + "title": "Category", + "type": "string" + }, + "dato": { + "title": "Dato", + "type": "string" + }, + "hendelse_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hendelse Type" + }, + "kunngjoring_type": { + "title": "Kunngjoring Type", + "type": "string" + }, + "navn": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Navn" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "payload_summary": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Payload Summary" + } + }, + "required": [ + "orgnr", + "dato", + "kunngjoring_type", + "category" + ], + "title": "AnnouncementHit", + "type": "object" + } + }, + "properties": { + "filter": { + "additionalProperties": true, + "title": "Filter", + "type": "object" + }, + "items": { + "items": { + "$ref": "#/$defs/AnnouncementHit" + }, + "title": "Items", + "type": "array" + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Next Cursor" + }, + "total_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total Count" + } + }, + "required": [ + "filter", + "items" + ], + "type": "object" +}
- Changed
firmaradar_search_companies3 fields changed- added
Input schema / properties / max_omsetning_nok / descriptionAdded value: +"Maximum annual revenue (driftsinntekter) in NOK — same source and same exclusion rule as min_omsetning_nok." - added
Input schema / properties / min_omsetning_nok / descriptionAdded value: +"Minimum annual revenue (driftsinntekter) in NOK, from the company's own accounts (not consolidated/group figures), latest year with a reported figure. NOTE: companies with no reported revenue are EXCLUDED from the results when this filter is set, as are accounts reported in a foreign currency. Must be combined with at least one of q/nace/kommune." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "CompanyHit": { + "properties": { + "antall_ansatte": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Antall Ansatte" + }, + "kommune": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Kommune" + }, + "naeringskode": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Naeringskode" + }, + "navn": { + "title": "Navn", + "type": "string" + }, + "organisasjonsform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Organisasjonsform" + }, + "orgnr": { + "title": "Orgnr", + "type": "string" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Status" + }, + "stiftelsesdato": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Stiftelsesdato" + } + }, + "required": [ + "orgnr", + "navn" + ], + "title": "CompanyHit", + "type": "object" + } + }, + "properties": { + "items": { + "items": { + "$ref": "#/$defs/CompanyHit" + }, + "title": "Items", + "type": "array" + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Next Cursor" + }, + "omsetning_filter_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Set only when a revenue range was requested: explains that companies without a reported NOK revenue figure were excluded, so an empty result may mean missing accounts rather than no matching companies.", + "title": "Omsetning Filter Note" + }, + "total_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total Count" + } + }, + "required": [ + "items" + ], + "type": "object" +}
- Changed
firmaradar_search_persons1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$defs": { + "RolePersonHit": { + "properties": { + "active_company_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Active Company Count" + }, + "birth_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Birth Year" + }, + "company_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Company Count" + }, + "name": { + "title": "Name", + "type": "string" + }, + "role_person_id": { + "description": "Stable key — pass to `get_person_roles`.", + "title": "Role Person Id", + "type": "string" + } + }, + "required": [ + "role_person_id", + "name" + ], + "title": "RolePersonHit", + "type": "object" + }, + "ShareholderHit": { + "properties": { + "birth_year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Birth Year" + }, + "country_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Country Code" + }, + "owner_name": { + "title": "Owner Name", + "type": "string" + }, + "owner_person_key": { + "description": "Stable key — pass to `get_person_companies`.", + "title": "Owner Person Key", + "type": "string" + }, + "poststed": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poststed" + }, + "shareholding_count": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Shareholding Count" + } + }, + "required": [ + "owner_person_key", + "owner_name" + ], + "title": "ShareholderHit", + "type": "object" + } + }, + "properties": { + "query": { + "title": "Query", + "type": "string" + }, + "role_persons": { + "items": { + "$ref": "#/$defs/RolePersonHit" + }, + "title": "Role Persons", + "type": "array" + }, + "role_persons_count": { + "title": "Role Persons Count", + "type": "integer" + }, + "shareholders": { + "items": { + "$ref": "#/$defs/ShareholderHit" + }, + "title": "Shareholders", + "type": "array" + }, + "shareholders_count": { + "title": "Shareholders Count", + "type": "integer" + } + }, + "required": [ + "query", + "shareholders", + "shareholders_count", + "role_persons", + "role_persons_count" + ], + "type": "object" +}
- Added
firmaradar_start_aml_report - Added
firmaradar_subscribe_nace
25 tool updates
v0.1.0- First observed
firmaradar_check_aml_pep - First observed
firmaradar_check_fiv_bulk - First observed
firmaradar_check_foretak_i_vanskeligheter - First observed
firmaradar_compare_companies - First observed
firmaradar_confirm_risk_score_disclaimer - First observed
firmaradar_find_related_companies - First observed
firmaradar_get_aml_score - First observed
firmaradar_get_company - First observed
firmaradar_get_company_announcements - First observed
firmaradar_get_company_financials - First observed
firmaradar_get_company_ownership - First observed
firmaradar_get_company_roles - First observed
firmaradar_get_company_signals - First observed
firmaradar_get_konsernstotte - First observed
firmaradar_get_person - First observed
firmaradar_get_person_companies - First observed
firmaradar_get_person_roles - First observed
firmaradar_get_recent_changes - First observed
firmaradar_get_risk_score - First observed
firmaradar_get_risk_score_bulk - First observed
firmaradar_get_skattelister - First observed
firmaradar_list_companies_in_nace - First observed
firmaradar_search_announcements - First observed
firmaradar_search_companies - First observed
firmaradar_search_persons
TDQS
Scored across 35 tools
The tool set is largely well separated by resource and action, and the descriptions include useful cross-references such as 'use get_company before get_company_signals' and 'use get_aml_score instead of check_aml_pep for company AML'. However, several tools overlap in purpose—search_companies vs list_companies_in_nace, get_company vs get_company_signals, get_aml_score vs start_aml_report/get_aml_report, and find_related_companies vs find_shared_connections—so an agent must read carefully to choose correctly.
Every tool uses the firmaradar_ prefix followed by a consistent verb_noun pattern: get_, search_, list_, check_, find_, compare_, subscribe_, add_, delete_, start_, and confirm_. The naming is highly predictable and uniform, with only minor abbreviation variation such as check_fiv_bulk.
35 tools is a large surface for an agent to navigate, and the count is inflated by bulk variants, async AML report tools, and several overlapping search/get tools. While the broad Norwegian business-data domain justifies some size, this is above the 'heavy' threshold and will make tool selection harder.
The suite covers the main Norwegian company-data lifecycle: search/get companies, financials, ownership, roles, announcements, IP, grants, risk, AML, person lookups, and monitoring. Major gaps are the inability to list or delete company-level monitoring (only NACE subscriptions have list/delete), and somewhat awkward async/sync AML workflow. Overall these are minor gaps in an otherwise comprehensive domain.
Maintenance
Related MCP Connectors
Nordic company intelligence: look up companies, AI summaries, scores and signals via MCP.
UBO, sanctions & ownership graph. 23 tools, 130.7M entities, 31 registries.
Compliance infrastructure API connecting AI agents to Norwegian government systems (Altinn, BRREG).
Live data from 27 official national company registries. Unmodified. For KYB and due diligence.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables comprehensive access to the Norwegian Business Registry API for querying company information, board members, subsidiaries, organizational data, and voluntary organizations. Provides real-time access to over 1 million registered Norwegian entities with detailed corporate structure and governance data.155 npm8MIT
- FlicenseNot gradedqualityNot gradedmaintenanceProvides comprehensive Norwegian business intelligence through Brønnøysund and Statistics Norway APIs, enabling company search, financial analysis, ownership mapping, market research, and automated financial data extraction.-
- AlicenseNot gradedqualityAmaintenanceMCP server for Nordic company registries. Verify companies, check board members, signing authority, and financial data across Norway, Denmark, Finland, and Sweden using official public APIs. 23 tools covering search, details, roles, and batch lookups.198Apache 2.0
- AlicenseAqualityBmaintenanceExposes 29 official business-registry actors as MCP tools for KYC/AML, beneficial-owner (UBO), credit-risk and adverse-media workflows across 11 jurisdictions (EU, US, UAE). Sourced via Apify; pay-per-result.386MIT