Trzy role — host, klient, serwer. Architektura MCP bez abstrakcji

przez Łukasz | cze 5, 2026

Gdy czytasz że „MCP łączy agenty z narzędziami”, masz wrażenie że to proste — agent po lewej, narzędzie po prawej, protokół w środku. Rzeczywistość jest nieco inna. Między agentem a narzędziem są trzy oddzielne byty z trzema oddzielnymi odpowiedzialnościami. Mylenie ich to najprostsza droga do architektury która działa „jakoś” ale jest niemożliwa do utrzymania.

Ten artykuł rozkłada architekturę MCP na trzy role, tłumaczy dlaczego każda jest osobna i co to znaczy w praktyce gdy budujesz własny serwer.

Zanim role — problem który MCP rozwiązuje

Wyobraź sobie że masz trzy aplikacje AI: Claude Desktop, Cursor i własnego agenta w n8n. Każda z nich chce mieć dostęp do tych samych narzędzi: Twoje repozytorium GitHub, baza danych Postgres, skrzynka Gmail.

Bez standardu: każda aplikacja implementuje osobną integrację z każdym narzędziem. Trzy aplikacje, trzy narzędzia — dziewięć osobnych konektorów. Każdy z własnym formatem, własnym auth, własną obsługą błędów. Zmienia się API GitHuba? Aktualizujesz trzy miejsca.

Z MCP: GitHub implementuje serwer MCP raz. Claude Desktop, Cursor i Twój n8n implementują klienta MCP raz. Każde nowe narzędzie z serwerem MCP jest od razu dostępne dla wszystkich klientów. Każdy nowy klient MCP od razu ma dostęp do wszystkich serwerów.

To jest rozwiązanie problemu N×M przez N+M. Ale żeby to działało, każda ze stron musi wiedzieć dokładnie jaka jest jej rola.

Rola 1: Host — ten który chce coś zrobić

Host to aplikacja która chce użyć możliwości zewnętrznych narzędzi. Claude Desktop jest hostem. Cursor jest hostem. Twój agent w n8n jest hostem. Twój własny skrypt Python który wywołuje Claude API i podłącza do niego narzędzia — też jest hostem.

Trzy odpowiedzialności hosta:

Zarządzanie połączeniami z serwerami MCP. Host decyduje z którymi serwerami MCP się połączy, utrzymuje te połączenia i zarządza ich cyklem życia. Gdy użytkownik dodaje nowy serwer MCP w Claude Desktop — to host tworzy nowe połączenie.

Koordynacja użycia narzędzi. Gdy model językowy decyduje że chce wywołać narzędzie (np. query_database), to host pośredniczy — przekazuje żądanie do właściwego klienta MCP, dostaje wynik, wkłada go z powrotem do kontekstu modelu.

Zgoda użytkownika. Specyfikacja MCP mówi wprost: host jest odpowiedzialny za uzyskanie explicite zgody użytkownika przed wykonaniem operacji przez narzędzie. Nie model, nie serwer — host. To ważne z perspektywy bezpieczeństwa — host jest miejscem gdzie człowiek wciąż ma kontrolę.

Kluczowa cecha hosta: jeden host może utrzymywać połączenia z wieloma serwerami MCP jednocześnie. Claude Desktop podłączony do GitHuba, Postgresa i Gmaila — to jeden host z trzema klientami.

Rola 2: Klient — warstwa protokołu

Klient to komponent wewnątrz hosta który obsługuje protokół MCP po stronie aplikacji. Jeden klient = jedno połączenie z jednym serwerem MCP.

To jest warstwa którą często pomijają opisy MCP — klient nie jest widoczny dla użytkownika i nie jest oddzielną aplikacją. Jest modułem w hoście.

Co klient robi:

Utrzymuje sesję z serwerem MCP. Po połączeniu klient i serwer wymieniają informacje o swoich możliwościach (capability negotiation) — serwer mówi jakie narzędzia oferuje, klient mówi co obsługuje.

Tłumaczy żądania hosta na wiadomości JSON-RPC. Gdy host chce wywołać narzędzie search_issues na serwerze GitHub, klient formatuje to jako poprawną wiadomość JSON-RPC 2.0 i wysyła.

Odbiera odpowiedzi i zwraca do hosta. Obsługuje błędy, timeouty, reconnect.

json
// Przykład — żądanie klienta do serwera (JSON-RPC 2.0)
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_issues",
    "arguments": {
      "query": "label:bug state:open",
      "repo": "webflux-pl/slownik"
    }
  }
}

Klient jest warstwą translacji — host myśli w kategoriach „chcę wywołać narzędzie X”, klient myśli w kategoriach „wyślij wiadomość JSON-RPC do serwera”.

Rola 3: Serwer — ten który umożliwia

Serwer MCP to program który wystawia możliwości dla agentów. Może działać jako lokalny proces (stdio), jako serwis webowy (Streamable HTTP), albo jako moduł wbudowany w aplikację.

Serwer MCP nie jest serwerem webowym w tradycyjnym sensie — nie obsługuje requestów HTTP od użytkowników. Obsługuje wyłącznie wiadomości JSON-RPC od klientów MCP.

Co serwer wystawia — trzy prymitywy:

Tools — funkcje które agent może wywołać. Każdy tool ma nazwę, opis i schemat parametrów wejściowych. Serwer GitHub może wystawiać narzędzia: list_repositories, search_issues, create_pull_request.

Resources — dane które agent może odczytać. Resources to kontekst: pliki, strony, dokumenty, dane z bazy. W przeciwieństwie do tools nie wykonują akcji — dostarczają informacji.

Prompts — szablony promptów dla konkretnych zadań. Rzadziej używane, ale pozwalają serwerowi proponować agentowi gotowe wzorce interakcji.

Webflux Słownik Agentic Web jako serwer MCP wystawia siedem narzędzi: get_term, search_term, list_clusters, get_cluster, get_by_layer, list_layers, create_term. Każdy z nich jest osobnym toolem z własnym schematem parametrów.

Odpowiedzialność serwera jest prosta: odpowiadaj na żądania klientów, wykonuj swoje narzędzia, zwracaj wyniki. Serwer nie wie nic o tym kto go wywołuje — czy to Claude, Cursor czy własny skrypt. Widzi tylko wiadomości JSON-RPC.

Relacja między rolami

┌─────────────────────────────────────────┐
│  HOST (np. Claude Desktop)              │
│                                         │
│  ┌──────────┐    ┌──────────┐           │
│  │ Klient 1 │    │ Klient 2 │  ...      │
│  └────┬─────┘    └────┬─────┘           │
└───────┼───────────────┼─────────────────┘
        │               │
        ▼               ▼
 ┌──────────┐    ┌──────────┐
 │ Serwer 1 │    │ Serwer 2 │
 │ (GitHub) │    │(Postgres)│
 └──────────┘    └──────────┘

Jeden host, wiele klientów. Jeden klient na jeden serwer. Serwery są niezależne od siebie.

To rozdzielenie ma konsekwencje praktyczne. Gdy GitHub zmieni swoje API, aktualizujesz tylko serwer MCP dla GitHuba — nie dotykasz hosta ani innych serwerów. Gdy pojawi się nowa aplikacja AI (nowy host), może od razu używać wszystkich istniejących serwerów MCP bez żadnych zmian po stronie serwerów.

Co to znaczy gdy coś nie działa

Trójpodział ról jest najważniejszy przy debugowaniu. Gdy Twój serwer MCP nie odpowiada:

Problem w serwerze: serwer nie startuje, crasha, nie odpowiada na initialize. Sprawdź logi serwera, nie hosta.

Problem w kliencie: połączenie się nawiązuje ale narzędzia nie są widoczne albo wywołania zwracają błędy. Sprawdź capability negotiation — czy klient i serwer mówią tym samym dialektem protokołu.

Problem w hoście: serwer działa, klient odpowiada, ale agent nie używa narzędzi albo używa ich błędnie. Sprawdź jak host prezentuje narzędzia modelowi językowemu — opisy narzędzi w system promptcie, logikę zgody użytkownika.

bash
# Prosty test — czy serwer MCP odpowiada na initialize
curl -X POST https://twoj-serwer-mcp/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-03-26",
      "capabilities": {},
      "clientInfo": {"name": "test", "version": "1.0"}
    }
  }'

Jeśli serwer odpowie poprawnym JSON z serverInfo i listą capabilities — serwer działa. Problem leży gdzie indziej.

W następnym artykule: serwer wie jakie ma role. Co dokładnie może wystawić? Resources, Tools i Prompts — trzy prymitywy MCP od środka.


Pojęcia ze słownika: MCP · JSON-RPC · Streamable HTTP · SSE · OAuth dla agentów

Spis treści

Kiedy nie budować agenta

Kiedy nie budować agenta

Cały ten hub uczy, jak budować agenty. Ten wpis jest o tym, że najczęściej nie powinieneś. Jest taka pokusa, która przychodzi po przeczytaniu kilku tekstów o agentach: zbudujmy agenta. Do obsługi maili. Do raportów. Do tego procesu, który teraz robi się ręcznie. Agent...