Polish Business Intelligence MCP
# 🇵🇱 Polish Business Intelligence MCP
> **Language:** **English** · [🇵🇱 Polski](./README.pl.md)
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that gives any AI agent (Claude, Cursor, Copilot) instant, live access to two official Polish data sources: the **Ministry of Finance VAT whitelist (Biała Lista)** and the **National Bank of Poland (NBP) exchange rates**. No API keys, no signup, no scraping.
[](https://github.com/neflingcreations/PBI-MCP/actions/workflows/ci.yml)


---
## Why this exists
Large language models don't have live access to the Polish VAT registry or to official exchange rates. That data changes daily and sits behind government APIs the model was never trained on. This server closes the gap. Once it's connected, your agent can check whether a Polish company is a registered VAT payer, pull its registered address and bank accounts, and convert money at the official central-bank rate, all in real time.
It wraps two free, public, no-auth APIs:
| Source | What it provides |
| --- | --- |
| [**Biała Lista**](https://wl-api.mf.gov.pl/) (Ministry of Finance VAT whitelist) | Look up a company by **NIP** (tax ID): name, VAT status, address, registration date, bank accounts |
| [**NBP**](https://api.nbp.pl/) (National Bank of Poland) | Official PLN exchange rates (kurs średni) for around 40 currencies |
> **Why live data matters**
> AI models confidently produce plausible-looking data, a valid NIP in the right format, that can still be wrong. The only way to be sure is to ask the authoritative source. That's what this server does, on every call.
---
## Tools
| Tool | What it does | Key inputs |
| --- | --- | --- |
| `lookup_company` | Full company lookup on the VAT whitelist: name, VAT status, address, registration date, bank accounts | `nip` |
| `check_vat_status` | Quick yes / no / exempt answer to "is this NIP an active VAT payer?". Handy for "can I trust this invoice?" | `nip` |
| `get_all_rates` | All current PLN rates from NBP Table A (EUR, USD, GBP, CHF, JPY, CZK, and more) | _optional_ `date` |
| `get_currency_rate` | Official NBP mid rate for one currency (Table A, falling back to Table B for exotics) | `currency_code`, _optional_ `date` |
| `convert_currency` | Convert between PLN and any currency, or cross-rate two currencies through PLN | `amount`, `from_currency`, `to_currency`, _optional_ `date` |
Every tool returns clean, human-readable text (never raw JSON), and it never throws. Errors come back as friendly messages the agent can act on.
---
## Quick install
Requires [**uv**](https://docs.astral.sh/uv/) and Python 3.11+.
```bash
git clone https://github.com/neflingcreations/PBI-MCP.git
cd PBI-MCP
uv sync
```
### Claude Desktop / Claude Code config
Add this to your MCP config (Claude Desktop: `claude_desktop_config.json`):
```json
{
"mcpServers": {
"polish-business": {
"command": "uv",
"args": ["run", "polish-business-mcp"],
"cwd": "/path/to/PBI-MCP"
}
}
}
```
Restart the client and the five tools show up automatically.
---
## Example agent interactions
Once connected, your agent can answer questions it couldn't before:
> **"Is the company with NIP 951-238-16-07 a registered VAT payer?"**
> → calls `check_vat_status("9512381607")` →
> `YES: BOOKSY INTERNATIONAL SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ (NIP 9512381607) is an ACTIVE VAT payer (status: Czynny).`
> **"Look up NIP 9512381607 and give me their address and bank accounts."**
> → calls `lookup_company("9512381607")` → returns the company name, VAT status, registered address (UL. PROSTA 67, Warszawa), registration date, and the list of whitelisted bank accounts.
> **"What's today's EUR/PLN rate from the NBP?"**
> → calls `get_currency_rate("EUR")` →
> `EUR (euro): 4.2531 PLN per 1 EUR. Effective date 2026-06-26. Official NBP mid-market rate.`
> **"Convert 1500 PLN to GBP at the official rate."**
> → calls `convert_currency(1500, "PLN", "GBP")` → returns the converted amount, the GBP rate used, and the effective date.
---
## API sources
- **Biała Lista** (VAT whitelist), Ministry of Finance: https://wl-api.mf.gov.pl/
- **NBP** exchange rates, National Bank of Poland: https://api.nbp.pl/
Both are free, public, and need no authentication. The Biała Lista lookup always sends today's date, which the API requires. NBP only publishes rates on banking days, so a weekend request comes back with the most recent rate, and the tool shows the actual effective date it used.
---
## Local development
```bash
uv sync # install deps (incl. dev group)
uv run pytest # run tests (HTTP fully mocked, no network)
uv run ruff check . # lint
uv run mcp dev src/polish_business_mcp/server.py # open the MCP Inspector and call tools by hand
uv run polish-business-mcp # run the server over stdio (it waits on stdin, which is normal)
```
The test suite mocks every HTTP call with [`respx`](https://lundberg.github.io/respx/), so it runs offline and gives the same result every time.
---
## Roadmap
- `lookup_by_regon`: the Biała Lista API also accepts **REGON** (a 9- or 14-digit company ID).
- `lookup_companies_batch`: the batch endpoint (`/api/search/nips/`) checks up to 30 NIPs in one call.
- Historical VAT-status checks for a given date.
---
## Development
Built with an AI-assisted workflow (Claude Code). The architecture, API integration, and verification decisions were all made and reviewed by hand, and every tool was tested live against the real Polish APIs before release.
## License
MIT. See [`LICENSE`](./LICENSE).
TDQS
Scored across 5 tools
lookup_company and check_vat_status both operate on NIP numbers and return VAT-related information, which could cause initial confusion, but their scope is clearly different: full company details vs. a quick yes/no status. The three exchange-rate tools are each well-differentiated.
All tool names follow a consistent verb_noun snake_case pattern: lookup_company, check_vat_status, get_all_rates, get_currency_rate, convert_currency. The verbs are all actions and the nouns clearly indicate the target, making the naming predictable and readable.
With 5 tools across two related but distinct subdomains (VAT whitelist and exchange rates), the set is well-scoped. Each tool serves a clear purpose, and the count is neither bloated nor too sparse for the apparent functionality.
The VAT domain is covered with a full lookup and a fast status check; the exchange-rate domain is covered with all rates, a single rate, and conversion. Historical date support is included, and there are no obvious missing operations for the stated business intelligence purpose.