@m8t-jacob/mcp-polish-biz
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@m8t-jacob/mcp-polish-bizValidate NIP 5260001246"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@m8t-jacob/mcp-polish-biz
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/sdkMcpServerAPIRuns 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
zodand never throws: failures come back as a normal tool result withisError: true, so one bad call can't crash the serverStrict TypeScript, ships dual ESM + CJS builds with
.d.ts100% 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-bizIt 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 a NIP, PESEL, REGON, KRS, or IBAN/NRB and return its normalized form. Offline, no network. |
|
| Look up a NIP on the Polish VAT whitelist ("Biała lista podatników VAT"): status, name, accounts. |
|
| Validate an EU VAT number via VIES, returning company name/address when available. |
|
| Get the official NBP mid exchange rate for a currency against PLN, for today or a given date. |
|
| Convert an amount between two currencies using NBP mid rates. |
|
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 toolscheck_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.
| Name | Required | Description | Default |
|---|---|---|---|
| nip | Yes | The contractor NIP (Polish tax id) to look up, in any common formatting. | |
| date | No | ISO date (YYYY-MM-DD) to query the registry as of. Defaults to today. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| vatNumber | Yes | The VAT number to validate, without the country prefix. | |
| countryCode | Yes | Two-letter EU member state code (e.g. "PL", "DE"), "EL" for Greece, or "XI" for Northern Ireland. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Target three-letter ISO 4217 currency code (e.g. "PLN"). | |
| date | No | ISO date (YYYY-MM-DD) to use for both legs of the conversion. Defaults to today. | |
| from | Yes | Source three-letter ISO 4217 currency code (e.g. "USD"). | |
| amount | Yes | The amount to convert, in the `from` currency. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Three-letter ISO 4217 currency code (e.g. "USD", "EUR"). | |
| date | No | ISO date (YYYY-MM-DD). Defaults to the current NBP table A rate. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | Which 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). | |
| value | Yes | The raw identifier value, in any common formatting (spaces, dashes, an optional "PL" prefix for NIP/IBAN). |
TDQS
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.
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.
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.
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.
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.
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.
5 tool updates
v0.1.0- First observed
check_vat_whitelist - First observed
check_vies - First observed
convert_currency - First observed
get_exchange_rate - First observed
validate_polish_id
TDQS
Scored across 5 tools
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.
All five tools follow a consistent lowercase snake_case verb_noun pattern (validate_, check_, get_, convert_), making the naming predictable and easy to understand.
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.
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
Related MCP Connectors
Verify Polish companies by NIP/KRS/REGON + EU VAT (VIES). 9 MCP tools, no key.
MCP server for 3M+ Polish companies — KRS & CEIDG financials, ownership, and industry search.
Polish company registry: 4.4M firms, KRS/REGON data, VAT white list checks, financial statements
Validate EU, UK, AU VAT numbers for AI agents. EU ViDA e-invoicing compliance.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server providing AI assistants access to Polish public registries (KRS, CEIDG) and statistical data (GUS BDL) for querying companies, sole proprietorships, and regional statistics.147MIT
- AlicenseAqualityBmaintenanceProvides AI agents with real-time access to Polish official data: VAT whitelist for company verification and NBP exchange rates, enabling checks on VAT status, company details, and currency conversion without API keys.5MIT
- AlicenseNot gradedqualityCmaintenanceMCP 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
- FlicenseAqualityCmaintenanceMCP 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-