Skip to main content
Glama
M8T-Jacob

@m8t-jacob/mcp-polish-biz

by M8T-Jacob

@m8t-jacob/mcp-polish-biz

CI npm version npm downloads license: MIT

An MCP (Model Context Protocol) server that gives AI agents — Claude Desktop, Claude Code, Cursor, or any other MCP client — direct access to Polish business data: identifier validation, the VAT whitelist, EU VIES lookups, and NBP exchange rates.

It's a thin wiring layer: every tool delegates to a small, independently published, fully-tested package — @m8t-jacob/validate, @m8t-jacob/polish-registry, and @m8t-jacob/pln-utils — so this repo contains no domain logic of its own, just MCP tool definitions, zod input schemas, and error mapping.

  • Built on the official @modelcontextprotocol/sdk McpServer API

  • Runs over stdio — the transport used when an MCP client launches a server as a local subprocess (typically via npx)

  • Every tool validates its input with zod and never throws: failures come back as a normal tool result with isError: true, so one bad call can't crash the server

  • Strict TypeScript, ships dual ESM + CJS builds with .d.ts

  • 100% test coverage on tool handlers — dependencies are mocked, so the test suite makes zero real network calls

Install for Claude Desktop / Claude Code

Add this to your MCP client's configuration (for Claude Desktop, claude_desktop_config.json; for Claude Code, .mcp.json or via claude mcp add):

{
  "mcpServers": {
    "polish-biz": {
      "command": "npx",
      "args": ["-y", "@m8t-jacob/mcp-polish-biz"]
    }
  }
}

No API key or configuration is required — every underlying API (the VAT whitelist, VIES, and NBP) is free and public.

You can also run it directly to smoke-test it:

npx -y @m8t-jacob/mcp-polish-biz

It will sit waiting for JSON-RPC requests on stdin — that's expected; it's meant to be driven by an MCP client, not used interactively.

Related MCP server: Polish Business Intelligence MCP

Tools

Tool

Description

Backed by

validate_polish_id

Validate a NIP, PESEL, REGON, KRS, or IBAN/NRB and return its normalized form. Offline, no network.

@m8t-jacob/validate

check_vat_whitelist

Look up a NIP on the Polish VAT whitelist ("Biała lista podatników VAT"): status, name, accounts.

@m8t-jacob/polish-registry

check_vies

Validate an EU VAT number via VIES, returning company name/address when available.

@m8t-jacob/polish-registry

get_exchange_rate

Get the official NBP mid exchange rate for a currency against PLN, for today or a given date.

@m8t-jacob/pln-utils

convert_currency

Convert an amount between two currencies using NBP mid rates.

@m8t-jacob/pln-utils

validate_polish_id

{ "type": "nip", "value": "PL 526-000-12-46" }
{ "valid": true, "type": "nip", "normalized": "5260001246" }

type is one of nip, pesel, regon, krs, iban.

check_vat_whitelist

{ "nip": "5252445767", "date": "2026-07-13" }

Returns the WhitelistResult shape from @m8t-jacob/polish-registry (name, statusVat, regon, krs, accountNumbers, found, ...). date is optional (YYYY-MM-DD, defaults to today).

check_vies

{ "countryCode": "PL", "vatNumber": "5252445767" }

Returns the ViesResult shape (valid, name?, address?, countryCode, vatNumber, requestDate).

get_exchange_rate

{ "code": "USD", "date": "2025-01-15" }

Returns { code, rate, date, table }. date is optional.

convert_currency

{ "amount": 100, "from": "USD", "to": "EUR" }

Returns { amount, from, to, result, date? }. date is optional and, when given, is used for both legs of the conversion.

Programmatic use

The server can also be embedded directly, without going through stdio — useful for tests or for hosting it behind a different transport:

import { createServer, TOOLS } from '@m8t-jacob/mcp-polish-biz';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = createServer();
await server.connect(new StdioServerTransport());

TOOLS (also exported) is the array of { name, description, inputSchema, handler } this server registers — each handler can be called directly in tests without any transport, see examples/basic.ts.

🇵🇱 Po polsku

@m8t-jacob/mcp-polish-biz to serwer MCP (Model Context Protocol) dający agentom AI (Claude Desktop, Claude Code, Cursor) dostęp do polskich danych biznesowych: walidacji NIP/PESEL/REGON/KRS/IBAN, Białej listy podatników VAT, unijnego systemu VIES oraz kursów walut NBP. Cała logika domenowa pochodzi z trzech niezależnie opublikowanych pakietów (@m8t-jacob/validate, @m8t-jacob/polish-registry, @m8t-jacob/pln-utils) — ten serwer jest wyłącznie cienką warstwą narzędzi MCP nad nimi. Każde narzędzie waliduje dane wejściowe przez zod i nigdy nie rzuca wyjątku — błąd wraca jako zwykły wynik z isError: true, więc jedno nieudane wywołanie nie może zatrzymać całego serwera. Instalacja nie wymaga żadnego klucza API — wszystkie API źródłowe (Biała lista, VIES, NBP) są darmowe i publiczne.

Contributing

Contributions are welcome! See CONTRIBUTING.md for the development workflow and GOOD_FIRST_ISSUES.md for ideas if you're looking for a place to start. This project follows the Contributor Covenant.

License

MIT © 2026 Jakub Jagiełło

Available Tools

5 tools
check_vat_whitelistA

Look up a Polish contractor by NIP on the Ministry of Finance VAT whitelist ("Biała lista podatników VAT") to get their VAT registration status, legal name, REGON/KRS, and registered bank account numbers. Use this to verify a business partner before paying an invoice.

ParametersJSON Schema
NameRequiredDescriptionDefault
nipYesThe contractor NIP (Polish tax id) to look up, in any common formatting.
dateNoISO date (YYYY-MM-DD) to query the registry as of. Defaults to today.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description bears the full burden of behavioral disclosure. It clearly states the output data points (status, name, REGON/KRS, bank accounts), but it does not mention error behavior (e.g., NIP not found), response format, or whether the operation is purely read-only. This leaves important gaps for an agent, but it is not contradictory or misleading.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, both packed with relevant information. It front-loads the core purpose and usage context, with no wasted words. This is an excellent example of conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has only two parameters and no output schema, so the description must convey both purpose and return data. It lists the key return fields and gives a concrete use case. However, it does not describe the response structure, possible error cases, or the exact handling of the date parameter, which would make it fully complete. Still, it is adequate for a straightforward lookup tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides 100% coverage of parameter descriptions, so the baseline is 3. The description adds context about the purpose of the NIP and the use case, but it does not deepen the semantics of the 'date' parameter beyond what the schema states (ISO date, as-of date, defaults to today). Thus no additional value is added to justify a higher score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the specific action ('Look up a Polish contractor by NIP') and the resource (Ministry of Finance VAT whitelist). It also lists the exact data returned (VAT registration status, legal name, REGON/KRS, bank account numbers), which distinguishes it from sibling tools like check_vies or validate_polish_id.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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: 'Use this to verify a business partner before paying an invoice.' This provides a clear use case and context. It does not explicitly name alternatives or exclusions, but the specific mention of the Polish whitelist implies when this is appropriate versus other tools, so it earns a 4.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_viesA

Validate an EU VAT number via VIES (VAT Information Exchange System), the European Commission service that confirms whether a VAT number is currently registered, returning the company name/address when the member state provides them.

ParametersJSON Schema
NameRequiredDescriptionDefault
vatNumberYesThe VAT number to validate, without the country prefix.
countryCodeYesTwo-letter EU member state code (e.g. "PL", "DE"), "EL" for Greece, or "XI" for Northern Ireland.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does it well: it discloses that validation goes through VIES (an external EC service), that it checks current registration, and that company data is returned only when the member state provides it – a non-obvious behavior. It does not cover error handling or response format, but for a read-only check it is sufficiently transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one concise sentence, front-loaded with the action, and includes the important caveat about member state data provision without any filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with two parameters and no output schema, the description explains the purpose, external dependency, and variable return data. It does not specify the exact response structure for unregistered numbers, but the context provided is sufficient for basic operational understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Both parameters are fully described in the input schema (vatNumber without prefix, countryCode as two-letter EU code). The tool description adds no extra parameter semantics, but schema coverage is 100%, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'validate' with the resource 'EU VAT number via VIES', explains it confirms current registration, and mentions the return of company name/address when available. This clearly distinguishes it from sibling tools like validate_polish_id and check_vat_whitelist.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for EU VAT validation via VIES but does not explicitly discuss when to avoid it or mention alternative tools. Sibling tool names suggest alternatives, but the description itself lacks direct 'use this instead of X' guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_currencyA

Convert an amount between two currencies using official NBP mid exchange rates (via PLN as the intermediary), either for today or a specific date.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesTarget three-letter ISO 4217 currency code (e.g. "PLN").
dateNoISO date (YYYY-MM-DD) to use for both legs of the conversion. Defaults to today.
fromYesSource three-letter ISO 4217 currency code (e.g. "USD").
amountYesThe amount to convert, in the `from` currency.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full responsibility for behavioral disclosure. It adds value by revealing the PLN intermediary mechanism, but does not discuss error handling, rounding behavior, or rates availability on holidays/weekends, which are relevant for a currency conversion tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence that immediately names the action ('Convert an amount') and packs in the key details (rate source, intermediary, date flexibility) without extraneous words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core operation and a significant detail (PLN intermediary), but because there is no output schema, it omits any mention of the return format or behavior on invalid input. This is a moderate gap for a tool with four parameters and no structured output metadata.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides 100% coverage with clear parameter descriptions. The description adds the PLN intermediary detail, which clarifies how from/to interact, but it otherwise repeats the default-date information found in the schema, so the added value is modest.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool converts an amount between two currencies, using official NBP mid rates via PLN as intermediary. This distinguishes it from sibling tools like get_exchange_rate, which likely just retrieves a rate rather than performing a conversion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for currency conversion, and mentions flexibility for today or a specific date. However, it does not explicitly state when to use this tool versus get_exchange_rate, nor does it mention limitations such as unsupported currencies or rate availability.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_exchange_rateA

Get the official NBP (Narodowy Bank Polski) mid exchange rate for a currency against PLN, either for today or a specific date.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesThree-letter ISO 4217 currency code (e.g. "USD", "EUR").
dateNoISO date (YYYY-MM-DD). Defaults to the current NBP table A rate.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It adds useful context (source: NBP, type: mid rate, date options), but does not describe potential error conditions, handling of non-trading days, or response format. This is a read operation, but lacks deeper transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that is front-loaded with the key action and object. It contains no filler or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although no output schema exists, the description adequately covers the core purpose, the source, and the date parameter. However, it omits details about the response structure and error cases, which is acceptable given the tool's simplicity but leaves minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides complete descriptions for both parameters (code and date), covering 100% of the parameter documentation. The description merely paraphrases the date flexibility already in the schema and adds no new parameter-level detail, so it meets the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Get' and clearly identifies the resource as the 'NBP mid exchange rate for a currency against PLN', which distinguishes it from sibling tools like convert_currency. It also specifies the date scope (today or a specific date), making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for fetching NBP mid rates but does not explicitly state when to use it over alternatives like convert_currency or check_vies. There is no mention of excluded scenarios or prerequisites, so the guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_polish_idA

Validate a Polish identifier (NIP tax id, PESEL national id, REGON business registry id, KRS National Court Register number, or IBAN/NRB bank account) and return whether it is valid plus its normalized form. Purely local checksum validation — makes no network calls.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesWhich Polish identifier to validate: "nip" (tax id), "pesel" (national id), "regon" (business registry id), "krs" (National Court Register number), or "iban" (Polish IBAN/NRB bank account).
valueYesThe raw identifier value, in any common formatting (spaces, dashes, an optional "PL" prefix for NIP/IBAN).

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of disclosure. It clearly states the return behavior ('return whether it is valid plus its normalized form') and the network behavior ('Purely local checksum validation — makes no network calls'), which is valuable context beyond the schema. It does not describe error handling or edge cases, but for a validation tool the core behavior is well disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the primary purpose and immediately followed by a crucial behavioral note. Every word contributes value, with no repetition or filler, making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the moderate complexity (5 identifier types), detailed schema, and absence of output schema or annotations, the description covers the essential context: what it validates, what it returns, and that it is offline. It does not discuss potential error conditions or the exact format of the normalized form, but the schema and description together provide enough for an agent to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% coverage with detailed descriptions for both parameters, including the enum of identifier types and formatting flexibility. The description adds context about the overall outcome (validity + normalized form) but does not add parameter-specific details beyond the schema, 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Validate') and a specific resource ('Polish identifier') while enumerating all identifier types (NIP, PESEL, REGON, KRS, IBAN/NRB). It distinguishes itself from sibling network-based tools by explicitly noting 'Purely local checksum validation — makes no network calls', making it unmistakable what this tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool vs alternatives: for offline, checksum-based validation of Polish identifiers, as opposed to network-dependent services like check_vat_whitelist or check_vies. It clearly states 'makes no network calls', which helps an agent choose this tool for local validation. However, it does not explicitly name alternatives or list exclusions, so it stops short of full guideline clarity.

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.

  1. 5 tool updatesv0.1.0
    • First observedcheck_vat_whitelist
    • First observedcheck_vies
    • First observedconvert_currency
    • First observedget_exchange_rate
    • First observedvalidate_polish_id

TDQS

A4.2/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: local ID checksum validation, Polish VAT whitelist lookup, EU VIES validation, exchange rate retrieval, and currency conversion. The two exchange-related tools are distinct because one returns a rate and the other performs a conversion.

Naming Consistency5/5

All five tools follow a consistent lowercase snake_case verb_noun pattern (validate_, check_, get_, convert_), making the naming predictable and easy to understand.

Tool Count5/5

With 5 tools, the server is well-scoped for a niche Polish business utility. The count is neither thin nor excessive, and each tool serves a meaningful purpose.

Completeness5/5

The tool set covers core business needs: identifier validation, Polish and EU VAT verification, and currency exchange via official NBP rates. It provides complete workflows for vetting contractors and handling cross-currency transactions.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    MCP server providing AI assistants access to Polish public registries (KRS, CEIDG) and statistical data (GUS BDL) for querying companies, sole proprietorships, and regional statistics.
    14
    7
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for verifying Polish business entities from the National Court Register (KRS) and VAT White List. Allows querying by KRS, NIP, or REGON to retrieve official company data including name, address, board, and capital.
    Apache 2.0
  • F
    license
    A
    quality
    C
    maintenance
    MCP server providing access to Polish business registers (KRS, CRBR) via the rejestr.io API, enabling search, retrieval of organizations, beneficial owners, financial documents, and more.
    12
    -