Tool calling vs MCP: co jest czym i kiedy nie potrzebujesz serwera MCP
Damian GębalaAutorTool calling i MCP to nie konkurenci, tylko dwie warstwy tej samej pracy. Tool calling (function calling) to mechanizm, przez który model językowy wzywa funkcję, którą wcześniej dałeś mu w swojej aplikacji. MCP (Model Context Protocol) to standard podłączania narzędzi, których nie pisałeś: serwer wystawia katalog, a klient AI sam go odkrywa. Jeśli Twój agent działa w jednej aplikacji i korzysta z kilku narzędzi, serwer MCP jest zbędny. Jeśli te same narzędzia mają działać w kilku edytorach i procesach naraz, bez MCP piszesz tę samą integrację po raz N.
Czym naprawdę jest tool calling
Oficjalna dokumentacja OpenAI definiuje to tak: function calling daje modelom „a powerful and flexible way to interface with external systems and access data outside their training data”. Kluczowe słowo brzmi: twoja aplikacja udostępnia funkcję, a model tylko wskazuje, którą z nich chce teraz użyć.
Cały mechanizm ma pięć kroków: wysyłasz do modelu listę narzędzi, model zwraca prośbę o wywołanie, po Twojej stronie uruchamiasz kod, wysyłasz wynik z powrotem i dostajesz odpowiedź (albo kolejne wywołanie). To ostatnie zdanie jest najczęściej źródłem nieporozumień - funkcji nie wykonuje model. Wykonuje ją Twój kod, w Twoim środowisku, na Twoim serwerze. Model jedynie wypełnia argumenty i decyduje, kiedy sięgnąć po narzędzie.
Opis narzędzia jest zwykłym schematem JSON: nazwa, opis po co to, lista parametrów, co jest wymagane. Na tej samej zasadzie działa ChatGPT podpięty do własnej aplikacji przez n8n - model dostaje opis narzędzi, n8n wykonuje to, co model poprosi.
Czym jest MCP i czym różni się od gołego function calling
MCP to otwarty standard, który pozwala aplikacjom AI łączyć się z zewnętrznymi narzędziami, danymi i usługami przez protokół klient-serwer zbudowany na JSON-RPC 2.0. Anthropic wypuścił go jako open source w listopadzie 2024, a od grudnia 2025 rozwija go fundacja Agentic AI Foundation przy Linux Foundation. Od tego czasu działał już w kilku edytorach narzędziowych i w popularnych klientach AI.
Różnica dotyczy tego, gdzie leży definicja narzędzia. Przy gołym function calling Ty piszesz schemat w kodzie aplikacji. Przy MCP piszesz serwer, który sam deklaruje, co potrafi, a aplikacja po podłączeniu pyta go o katalog przez tools/list i samo tłumaczy to na format, którego oczekuje model.
MCP rozwiązuje tzw. problem NxM, gdzie N to liczba aplikacji, a M to liczba systemów, do których muszą sięgnąć. Przy trzech aplikacjach i trzech źródłach danych to dziewięć osobnych integracji do utrzymania - przy samym MCP zostaje jedna.
W praktyce oba mechanizmy pracują razem. Wzorzec wygląda tak: klient MCP odkrywa narzędzia serwera i tłumaczy ich schematy na format wywołania funkcji, model proponuje wywołanie, klient wykonuje je na serwerze i zwraca wynik. W tym układzie MCP jest granicą integracji z serwerem, a function calling - granicą rozmowy z modelem. W praktyce większość systemów używa obu naraz, a wybór sprowadza się do pytania, czy potrzebujesz tej drugiej warstwy.
Trzy prymitywy, trzy różne osoby, które je wyzwalają
MCP nie ogranicza się do narzędzi. Różni je to, kto decyduje o użyciu:
| Prymityw | Co to jest | Kto decyduje o wywołaniu |
|---|---|---|
| tools | Funkcje, które model wywołuje, żeby pytać system lub działać w nim | Model: kiedy, z jakimi argumentami, w jakiej kolejności |
| resources | Dane tylko do odczytu, wskazane adresem URI, tekstowe lub binarne | Aplikacja: co trafia do kontekstu modelu i kiedy |
| prompts | Szablony rozmów wywoływane jak polecenia ukośnikiem | Użytkownik: kiedy je odpala |
Warto zapamiętać to rozróżnienie, bo wyjaśnia większość sporów o MCP: narzędzia są pod kontrolą modelu, zasoby - aplikacji, a szablony - człowieka. Dopisanie do serwera zasobów nie jest więc sposobem na „więcej możliwości dla modelu”, tylko na więcej danych, które Ty zdecydujesz, że mu podasz.
Kiedy gołe function calling wystarczy
Są trzy sytuacje, w których serwer MCP to zwykła zbędność:
Masz jedną aplikację i kilka narzędzi. Jeśli model ma zrobić jedno zadanie w jednym procesie, własne schematy JSON i własna pętla wykonawcza są najkrótszą drogą. Dodanie warstwy protokołu oznacza dodatkowy kod do utrzymania i testowania, a korzyść jest czysto teoretyczna.
Nie ma wymogu współpracy z innymi hostami. Jeśli narzędzia mają działać wyłącznie w Twoim asystencie, nie ma z kim się integrować. Wybór protokołu przy braku wymagań interoperacyjności to decyzja o utrzymaniu dodatkowej warstwy bez powodu.
Wywołanie jest jednorazowe i nieinteraktywne. Skrypt uruchamiany w cronie, zadanie w CI albo wywołanie w Lambda nie mają klienta, który utrzymałby połączenie. Uruchamianie serwera MCP po to, by zrobić jedno zapytanie, to czysty narzut protokołu.
Podobnie wygląda sprawa kompozycji w stylu uniksowym: narzędzie | jq | awk działa w powłoce, a w MCP takie łączenie nie ma odpowiednika. Dlatego wybór warstwy wykonawczej bywa tak samo ważny jak wybór technologii. Duże serwery i dostawcy często dostarczają obie powierzchnie naraz - GitHub ma gh i serwer MCP, AWS ma CLI i wdraża integracje MCP, Postgres ma psql i adaptery MCP. Wybór zależy od tego, kto woła: człowiek w terminalu czy agent w rozmowie.
Kiedy MCP się opłaca
Są cztery powody, dla których warstwa MCP zwraca koszt:
Narzędzie ma być widoczne z wnętrza edytora AI. Claude Desktop, Cursor i Zed mówią po protokole. Jeśli chcesz, żeby ktoś użył Twojego narzędzia z poziomu rozmowy z asystentem, a nie z terminala, MCP jest jedyną powierzchnią, która nie wymaga przeskakiwania do konsoli.
Agent wybiera spośród dziesiątek narzędzi. Manifest MCP opisuje sam siebie, więc klient nie musi za każdym razem uruchamiać polecenia pomocy, żeby zrozumieć, co narzędzie robi. Każde takie rozpoznanie to tokeny i czas w każdej turze rozmowy.
Wyniki są duże. Drzewo plików, długi log, lista rekordów - MCP potrafi strumieniować i stronicować, zamiast wlewać całość do okna kontekstu naraz.
Ten sam zestaw narzędzi ma działać w kilku miejscach. To jest właściwy powód do MCP i jedyny, który przechodzi test kosztu. Jeden serwer, kilka klientów, jedna definicja zamiast kopii w każdym projekcie.
Do tego dochodzi aspekt niezawodności: według badania Anthropic z 2025 roku, przywołanego przez Unblocked, agenci ze strukturalnym manifestem narzędzi popełniali o 38% mniej błędów wywołania niż agenci wydający komendy powłoki. Ta liczba pochodzi z wtórnego źródła, nie z pierwotnego raportu, więc traktuję ją jako wskazówkę, nie dowód.
Sześć pytań, które rozstrzygają
Zanim napiszesz pierwszy plik serwera, odpowiedz sobie wprost:
- Czy narzędzia mają działać w więcej niż jednym hoście albo procesie? Jeśli nie - pisz function calling.
- Czy ktoś ma móc je znaleźć i podłączyć bez Twojego kodu? Jeśli nie - manifest jest niepotrzebny.
- Czy agent musi wybierać narzędzie spośród dużego zestawu w trakcie rozmowy?
- Czy wyniki są na tyle duże, że wlewanie ich do kontekstu jest realnym problemem?
- Czy chcesz oddzielić logikę biznesową od warstwy transportu - i masz na to budżet w godzinach?
- Czy rozumiesz, że po podłączeniu zewnętrznego serwera dobra reputacja dostawcy staje się Twoim problemem bezpieczeństwa?
Ostatnie pytanie nie jest retoryczne. Interoperacyjność ułatwia połączenie, ale nie buduje zaufania - i to jest najczęstsze miejsce, w którym projekty MCP się psują, bo zaufanie zakłada się domyślnie, a odmawia się go dopiero po incydencie.
Minimalna definicja narzędzia po obu stronach
W gołym function calling definicja wygląda tak (uproszczony przykład z dokumentacji OpenAI):
{
"type": "function",
"function": {
"name": "get_horoscope",
"description": "Get today's horoscope for an astrological sign.",
"parameters": {
"type": "object",
"properties": {
"sign": { "type": "string" }
},
"required": ["sign"],
"additionalProperties": false
},
"strict": true
}
}
Po stronie modelu dostajesz tablicę tool_calls, w której każdy element niesie nazwę funkcji, surowy ciąg argumentów i identyfikator wywołania. Odpowiedź odsyłasz jako wiadomość w roli tool z tym samym identyfikatorem.
Warto włączyć strict - dokumentacja zaleca to wprost. Tryb ten wymaga, żeby additionalProperties miał wartość false i żeby wszystkie pola z properties były oznaczone jako wymagane; pole opcjonalne deklarujesz, dodając null do typu. Dwa warianty sterowania wywołaniem: tool_choice: "auto" (model sam decyduje), "required" (musi wywołać), wskazanie konkretnej funkcji albo "none". Gdy zależy Ci na jednym wywołaniu na turę, ustaw parallel_tool_calls na false.
Po stronie Gemini schemat wygląda inaczej - functionDeclarations z innym zestawem atrybutów, w którym część typowych uwag JSON Schema po prostu nie działa. To samo pojęcie, inny format: przy przenoszeniu narzędzia między dostawcami licz się z przepisaniem definicji, nie z podpięciem czegoś.
Serwer MCP w Pythonie wygląda krócej, bo sam deklaruje prymitywy:
@mcp.tool()
def get_stock_price(symbol: str) -> float:
"""Retrieve the current stock price for the given ticker symbol."""
@mcp.resource("stock://{symbol}")
def stock_resource(symbol: str) -> str:
"""Expose stock price data as a resource."""
@mcp.prompt("stock_analysis_prompt")
def stock_analysis(symbol: str, period: str = "1mo"):
"""Build a prompt for analyzing a stock's recent performance."""
Zwróć uwagę na to, czego tu nie ma. Nie ma pętli wywołań, nie ma obsługi błędów, nie ma walidacji argumentów, nie ma decyzji, co wolno, a czego nie. Serwer odpowiada wyłącznie za to, że coś potrafi. Reszta po Twojej stronie.
Ile to kosztuje: tokeny, sekundy i pamięć
Każda definicja narzędzia wchodzi do wiadomości systemowej i jest rozliczana jak zwykłe tokeny wejściowe. To nie jest darmowy dodatek do promptu - płacisz za każde żądanie, w którym manifest jest obecny.
OpenAI zaleca trzymać poniżej 20 funkcji dostępnych na początku tury, zaznaczając wyraźnie, że to miękka sugestia, a nie limit API. Przy dużych zestawach dokumentacja proponuje mechanizm odroczonego ładowania narzędzi, który polega na tym, że model dostaje w kontekście tylko te definicje, które pasują do pytania użytkownika. Szacunek, jaki podaje jedno z wtórnych opracowań: system z 50 definicjami dokłada 3000-5000 tokenów do każdego żądania, a dobór dynamiczny sprowadza to do 5-10 definicji.
Uwaga na rozrzut, którego tu nie ma: twardego limitu liczby definicji narzędzi dla modeli Anthropic ani Gemini nie znalazłem w żadnym sprawdzonym źródle. Nikt nie publikuje takiej liczby, więc nikt jej nie zgadnie.
Koszt czasowy jest w pewnym sensie łatwiejszy do oszacowania. Jedno wywołanie narzędzia to jedna inferencja modelu, wykonanie funkcji i kolejna inferencja przy interpretacji wyniku. Zadanie z pięcioma kolejnymi wywołaniami potrafi zająć 15-30 sekund.
Narzut samego MCP podaje utcp.io - dostawca protokołu konkurencyjnego, więc podaję te liczby z nazwiskiem autora, nie jako niezależny benchmark. Dla prostego wywołania API: 50 ms bezpośrednio wobec 75 ms przez serwer MCP, czyli około 50% narzutu. Zasoby: 50-200 MB pamięci i 5-15% CPU na serwer oraz podwójne skoki sieciowe. Teoria tej granicy jest słuszna - protokół musi dodać parsowanie i hop sieciowy. Praktycznie: przy jednym zapytaniu nie zauważysz tego, przy setkach równoległych już tak.
Serwer bez uwierzytelnienia to nie jest teoria
Ekosystem jest młody, a liczby z zakresu bezpieczeństwa są konkretne. Skan Censys z kwietnia 2026 wykrył ponad 12 520 serwerów MCP wystawionych wprost do internetu, większość bez jakiegokolwiek uwierzytelniania. Analiza Wiz Research z lipca 2026 pokazała, że około 70% wystawionych serwerów odpowiadało pełnym katalogiem narzędzi na anonimowe wywołanie, a niemal wszystkie działały na wersji protokołu sprzed wprowadzenia autoryzacji.
Testy Equixly z marca 2025 objęły open-source serwery: 43% było podatnych na wstrzyknięcie poleceń, 22% na path traversal, czyli odczyt dowolnych plików na serwerze. Wyszukiwanie CVE w 2025 i 2026 roku daje serię o podobnym podpisie: MCP Inspector z oceną 9,4, biblioteka mcp-remote z 9,6 przy ponad 437 tysiącach pobrań (używana m.in. przez Cloudflare i Hugging Face) oraz nginx-ui z 9,8 przy ponad 2600 wystawionych instancjach. Wspólnym mianownikiem była niedostateczna obsługa komunikacji przez potok stdio - temat, który Anthropic otworzył zbiorczo w kwietniu 2026.
Problem dotyczy też łańcucha dostaw, nie tylko samego protokołu. W październiku 2025 roku opublikowano złośliwą szesnastą wersję serwera Postmark po piętnastu wersjach legalnych, z cichą eksfiltracją poczty. W lutym 2026 do publicznych rejestrów trafiła trojanizowana klonowa wersja serwera dla urządzenia Oura, kradnąca dane logowania i portfele kryptowalut. Osobna historia: wykorzystanie path traversal w konfiguracji platformy Smithery pozwoliło przejąć API tokeny i skompromitować ponad 3000 hostowanych serwerów. Szerzej o warstwę ochrony agenta pisałem przy prompt injection w agentach AI - zasada najmniejszych uprawnień i człowiek w pętli działają tak samo przy MCP.
Wniosek jest prosty: sam fakt, że serwer jest napisany w Pythonie, jest jedynym argumentem, by go podłączyć. Prawidłowe pytania brzmią: kto go napisał, kto go utrzymuje, jakie ma uprawnienia i czy w ogóle widział ktoś jego kod.
Co zostaje Twoją odpowiedzialnością w obu przypadkach
Tutaj oba podejścia wracają do wspólnego mianownika. Niezależnie od tego, czy piszesz schemat w kodzie, czy wdrażasz serwer, odpowiedzialność za autoryzację, walidację wejścia, zgodę użytkownika, kontrolę skutków ubocznych, walidację wyjścia, limity czasu, logowanie i obsługę awarii zostaje po Twojej stronie. Protokół tego nie przenosi.
Dwie rzeczy warto jednak zrobić inaczej. Pierwsza: logika biznesowa nie powinna mieszkać w warstwie transportu. Jeśli serwer MCP zawiera walidację, ponawianie i autoryzację, a obok powstaje CLI, logika się rozdziela i po roku masz dwie różne wersje tej samej reguły. Rdzeń powinien być wspólny, a powierzchnie cienkie.
Druga: argumenty wygenerowane przez model traktuj tak podejrzliwie, jak dane od użytkownika. Model może wybrać właściwe narzędzie i wypełnić je złośliwą zawartością, jeśli w danych wejściowych siedzią ukryte instrukcje. Każdy parametr przechodzi walidację przed wykonaniem.
Przy wdrażaniu własnego serwera warto od razu zacząć od własnego API z zabezpieczeniem żądania, a dopiero potem dokładać warstwę MCP. Jeśli nie umiesz bezpiecznie wystawić prostego webhooka, dodanie protokołu tylko powiększy powierzchnię ataku.
Uwaga na wersję: protokół zmienia się szybko
MCP jest wersjonowane datą, nie numerem, i to ma realne konsekwencje dla wdrożenia. Rewizja z 28 lipca 2026 roku usunęła sesje i handshake inicjalizujący - protokół jest bezstanowy, a każde żądanie niesie wersję i możliwości klienta w polu _meta. Serwer może być statystyczny albo poziomy, bo każda instancja obsłuży każde żądanie. Do tego doszły wymagane nagłówki Mcp-Method i Mcp-Name, żeby load balancery routowały ruch bez czytania treści wiadomości. Trzy wcześniejsze funkcje - Sampling, Roots i Logging - są wycofywane, ale z oknem kompatybilności co najmniej 12 miesięcy.
Dwie praktyczne konsekwencje. Po pierwsze, dokumentacja i blogi z 2025 roku opisują stan sprzed tych zmian, więc przykład znaleziony w sieci może nie działać. Po drugie, przed wdrożeniem sprawdź, jakiej wersji protokołu używa serwer, z którym chcesz rozmawiać - starsza wersja po prostu nie ma mechanizmu autoryzacji, nawet jeśli nowa go ma.
Przy planowaniu wdrożenia w n8n przydatna będzie też konfiguracja połączenia Claude'a z automatyzacją przez MCP, a przy projektowaniu samego agenta - pamięć, narzędzia i pętla zgody człowieka.
Od czego zacząć w firmie
Najkrótsza reguła, która działa w obie strony: zacznij od jednego procesu, w którym agent ma dwa, trzy narzędzia i jednego użytkownika. Opisz je jako zwykłe schematy JSON, wykonuj w swoim kodzie, ogranicz tokeny uprawnieniami i loguj każde wywołanie z argumentami. Dopiero kiedy pojawi się realna potrzeba - drugi host, drugie środowisko, ktoś z zewnątrz chce się podpiąć - wtedy dostajesz specyfikację serwera MCP i masz już działające narzędzia, które tylko opakowujesz.
Dopisanie warstwy MCP do działającego systemu jest tanie. Przepisywanie całej integracji na nową, bo zbudowaliśmy ją od zera po stronie niewłaściwej, jest nie. Dlatego wybór między function calling a MCP to w pierwszej kolejności decyzja o kolejności pracy, a dopiero potem decyzja techniczna.
Jeśli zastanawiasz się, który z Twoich procesów nadaje się na taki pilot, napisz do mnie - zwykle odpowiadam tego samego dnia. Od pierwszej rozmowy przez konkretny zakres i wycenę na piśmie do wdrożenia, z jednym numerem telefonu, jeśli coś się posypie.