> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paymove.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> ## paymove integration rules for AI agents
>
> These rules are verified against the live API. Follow them exactly.
>
> 1. Amounts are INTEGERS in grosze (minor units). `1000` means 10.00 PLN. PLN is the only supported currency and there is no currency field in the API.
> 2. A float `price` (e.g. `12.99`) is SILENTLY TRUNCATED to 12 grosze and still returns HTTP 200. Always send an integer: `Math.round(pln * 100)`.
> 3. Authenticate with the `X-API-KEY` header. Never `Authorization: Bearer`. Sandbox keys start with `sk_test_`, production keys with `sk_live_`.
> 4. Server-side only. A call from a merchant page is rejected. Never put the key in frontend code.
> 5. Unknown request fields are silently ignored and still return HTTP 200 — a wrong body shape looks like success. Match the documented shape exactly.
> 6. A missing `externalId` returns HTTP 500 `Something went wrong`, not 400. A missing `price` or `details.returnUrl` returns HTTP 200 and a usable `redirectUrl` — no error at all. Validate the body yourself before sending it.
> 7. Always verify the `X-Paymove-Signature` header on incoming webhooks before trusting them: https://docs.paymove.io/en/webhook-signature.md
> 8. Errors are `{"status": <int>, "message": "<text>"}`. Branch on the HTTP status only — never on `message`, which is unstable and leaks internal class names.
> 9. There is no rate limiting, no HTTP 429, no HTTP 422, no `Idempotency-Key` header and no API versioning. Do not write code that handles them.
> 10. Re-POSTing an `externalId` that already exists returns HTTP 200 with the ORIGINAL `redirectUrl` and silently discards EVERY field you send — the new price, description and details are all ignored. Use `PATCH /api/pay/product/{productId}/subproduct/{externalId}` to change a price.
> 11. Webhooks fire only on `COMPLETED` by default, and `retries` defaults to `0` (no retries) unless you set it explicitly. Delivery counts as successful when the HTTP status equals `expectedCode` — the response body is never inspected.
> 12. Never fulfil an order on the `returnUrl` redirect. The checkout does not redirect there by itself: the customer has to click "back to shop", and inside the widget modal that redirect never happens. Fulfil only in the webhook handler, after verifying the signature.
> 13. Do not pin a version of `@paymove-io/sdk` — install the latest.
> 14. Full documentation index: https://docs.paymove.io/llms.txt · Copy-paste quickstart: https://docs.paymove.io/en/quickstart.md · Agent skill: https://docs.paymove.io/skill.md

# MCP

Nasz serwer [Model Context Protocol](https://modelcontextprotocol.io) pozwala dowolnemu
klientowi MCP (np. Claude Desktop, Claude Code, innym agentom LLM) łączyć się bezpośrednio z
agentem w Agent Panel, przeglądać katalog produktów i płacić za nie BLIK-iem w jego imieniu -
każda płatność jest osobno potwierdzana przez użytkownika kodem BLIK w aplikacji bankowej.

<Info>
  Serwer obsługuje też protokół [x402](https://www.x402.org/) do w pełni
  automatycznych płatności (bez potwierdzenia BLIK), ale to narzędzie jest na
  ten moment wyłączone - patrz sekcję [Dostępne narzędzia](#dostępne-narzędzia)
  poniżej.
</Info>

## 1. Klucz API

Każdy agent (portfel) ma własny klucz API, widoczny w Agent Panel w zakładce
**Ustawienia → Klucze API**. Klucz jest tworzony razem z portfelem agenta i wykorzystywany do
uwierzytelniania sesji MCP.

## 2. Uruchomienie serwera lokalnie

Serwer MCP to część `agent-facilitator` (`npm run mcp`, w Dockerze uruchamiany razem z
główną usługą - patrz `Dockerfile`). Musi mieć dostęp do dwóch rzeczy, żeby narzędzia
płatnicze działały:

| Zmienna             | Do czego służy                                                                                                       | Wartość domyślna (jeśli nieustawiona)      |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| `MONGO_URI`         | Baza z agentami/portfelami i katalogiem - **musi być ta sama**, z której korzysta Agent Panel                        | `mongodb://localhost:27017/?replicaSet=rs` |
| `DASHBOARD_API_URL` | Adres Agent Panel - tam żyje integracja z PAYTEL, `process_blik_payment`/`check_payment_status` wołają jego REST API | `http://localhost:3002`                    |

## 3. Konfiguracja klienta MCP

### Claude Code / Claude CLI

Najprostszy sposób - serwer wspiera natywny transport HTTP, więc nie jest potrzebny żaden
dodatkowy wrapper:

```bash theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
claude mcp add --transport http paymove-mcp http://localhost:4021/mcp \
  --header "x-api-key: <klucz-api-agenta>" \
  --scope user
```

* `--transport http` - wskazuje na Streamable HTTP (nie SSE, nie stdio)
* `http://localhost:4021/mcp` - adres serwera; w środowisku innym niż lokalne (staging/prod)
  podmień na właściwy host, na którym działa proces `npm run mcp` z `agent-facilitator`
  (domyślny port to `4021`, konfigurowalny przez zmienną `MCP_PORT`)
* `--header "x-api-key: ..."` - klucz API agenta z Agent Panel (krok 1)
* `--scope user` - serwer dostępny we wszystkich projektach danego użytkownika Claude Code
  (użyj `--scope project`, jeśli ma być widoczny tylko w jednym repo)

Po dodaniu serwer widoczny jest na liście `claude mcp list`, a narzędzia (`list_products`,
`process_blik_payment`, `check_payment_status`, `list_transactions`) - w rozmowie z Claude
Code.

### Custom connector (Claude.ai, Claude Desktop, Cowork, aplikacje mobilne)

Działa we wszystkich klientach Claude poza Claude Code, bez żadnej konfiguracji lokalnej.
Connector łączy się z serwerem z chmury Anthropic, nie z Twojego urządzenia, więc **serwer musi
mieć publiczny adres** - `localhost` nie zadziała. Do lokalnego developmentu użyj Claude Code
(sekcja wyżej).

1. Otwórz ustawienia connectorów:
   <br /> a) Free/Pro/Max: **Customize → Connectors → "Add custom connector"**.
   <br /> b) Team/Enterprise: Owner dodaje connector w **Organization settings →
   Connectors → Add → Custom → Web**, a każdy użytkownik włącza go potem u
   siebie w **Customize → Connectors**.
2. Podaj adres serwera: `https://<adres-serwera-mcp>/mcp`.
3. W **Request headers** dodaj nagłówek `x-api-key` z kluczem API agenta i zaznacz go
   jako **Required**.
4. Kliknij **Add**, a potem włącz connector w rozmowie przyciskiem **"+" → Connectors**.

<Info>
  Uwierzytelnianie przez nagłówki (**Request headers**) jest funkcją w becie i
  może nie być jeszcze widoczne na Twoim koncie - jeśli tak, poproś Anthropic o
  dostęp.
</Info>

## Dostępne narzędzia

* [`list_products`](#list_products)
* [`process_blik_payment`](#process_blik_payment)
* [`check_payment_status`](#check_payment_status)
* [`list_transactions`](#list_transactions)

<Info>
  Narzędzia `fetch_x402_resource` (automatyczna płatność x402 z salda portfela),
  `check_wallet_balance` (saldo portfela + status guardrails) oraz
  `buy_via_acp` (automatyczna płatność u merchanta Agentic Commerce Protocol,
  również z salda portfela) są tymczasowo wyłączone w kodzie serwera. MCP
  obsługuje obecnie wyłącznie katalog produktów i płatność BLIK, każdorazowo
  potwierdzaną przez użytkownika.
</Info>

### `list_products`

Zwraca katalog dostępnych produktów (`id`, nazwa, cena w PLN i w groszach). Nie przyjmuje
parametrów. `id` z odpowiedzi jest wymagany do wywołania `process_blik_payment`.

### `process_blik_payment`

Płaci BLIK-iem za wybrany produkt w imieniu agenta przypisanego do klucza API. To osobna,
świeża płatność potwierdzana kodem BLIK przy każdym zakupie - nie jest pobierana z żadnego
zgromadzonego wcześniej salda.

| Parametr            | Wymagany | Opis                                        |
| ------------------- | -------- | ------------------------------------------- |
| `productId`         | tak      | Identyfikator produktu z `list_products`    |
| `authorizationCode` | tak      | 6-cyfrowy kod BLIK podany przez użytkownika |

Cena jest pobierana samodzielnie z katalogu na podstawie `productId` (LLM nie podaje jej
ręcznie - eliminuje to błędy przy przeliczaniu na grosze). Narzędzie tylko **inicjuje**
płatność i zwraca `txId` oraz `externalId` - wynik nie jest jeszcze znany w tym momencie.

<Warning>
  Po `process_blik_payment` agent musi wywołać `check_payment_status` zanim
  poinformuje użytkownika o wyniku. Sam brak błędu przy inicjacji płatności nie
  oznacza sukcesu.
</Warning>

<Info>
  `txId` można pokazać użytkownikowi jako numer referencyjny. `externalId` jest
  wyłącznie techniczny - służy do wywołania `check_payment_status` i nie
  powinien być pokazywany ani wspominany użytkownikowi.
</Info>

### `check_payment_status`

Sprawdza rzeczywisty wynik wcześniej zainicjowanej płatności BLIK.

| Parametr     | Wymagany | Opis                                          |
| ------------ | -------- | --------------------------------------------- |
| `externalId` | tak      | Wartość zwrócona przez `process_blik_payment` |

Zwraca `status`: `pending`, `completed` albo `failed`. Dopóki status to `pending`, agent
powinien odczekać kilka sekund i sprawdzić ponownie (maks. ok. 10 razy) zamiast informować
użytkownika o wyniku.

### `list_transactions`

Zwraca historię transakcji portfela przypisanego do klucza API, od najnowszej. Obsługuje
opcjonalny zakres dat, np. żeby sprawdzić zakupy z konkretnego kwartału - samo `from` bez `to`
zwraca wszystko od podanej daty do dziś.

| Parametr | Wymagany | Opis                                                                               |
| -------- | -------- | ---------------------------------------------------------------------------------- |
| `limit`  | nie      | Maksymalna liczba transakcji (domyślnie 10, a 50 gdy podano `from`/`to`, maks. 50) |
| `from`   | nie      | Początek zakresu (włącznie), data ISO np. `2026-01-01`                             |
| `to`     | nie      | Koniec zakresu (włącznie), data ISO np. `2026-03-31`                               |
| `offset` | nie      | Liczba transakcji do pominięcia - do pobierania kolejnej strony wyników            |

Każdy wpis zawiera datę, status, nazwę produktu (jeśli dostępna), kwotę i `txId` - przydatne,
żeby agent mógł odpowiedzieć na pytania w stylu "co ostatnio kupiłem" albo "co kupiłem w Q1",
albo sprawdzić, czy dane zamówienie nie zostało już zrealizowane, zanim spróbuje zapłacić
ponownie.

<Info>
  Jeśli wyników jest więcej niż zwrócony limit, odpowiedź narzędzia zawiera na
  końcu informację, ile transakcji zostało jeszcze do pokazania. Agent powinien
  wtedy zapytać użytkownika, czy pokazać kolejne, a nie automatycznie pobierać
  wszystkie kolejne strony.
</Info>

<Warning>
  Guardrails (limity godzinowe/dobowe) można skonfigurować w ustawieniach
  portfela, ale nic w aplikacji nie sprawdza faktycznych wydatków względem tych
  limitów. Realną granicą jest dziś to, że każdą płatność musi osobno
  potwierdzić człowiek kodem BLIK.
</Warning>
