Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik11 min czytania

FastMCP, serwery MCP w Pythonie bez boilerplate

FastMCP buduje serwery i klienty MCP w Pythonie z dekoratorow. Wersje, kompozycja serwerow, integracja z OpenAPI, uwierzytelnianie i testowanie.

FastMCP, najszybsza droga do serwera MCP w Pythonie

FastMCP zamienia zwykłą funkcję Pythona w narzędzie dostępne dla modelu. Schemat argumentów powstaje z adnotacji typów, opis z dokumentacji funkcji, a warstwa transportowa, walidacja i zgodność z protokołem są po stronie biblioteki. Piszesz logikę, reszta jest doklejona.

Skąd wzięły się dwie wersje i po co to wiedzieć

Historia projektu tłumaczy zamieszanie, na które trafisz przy szukaniu materiałów.

Pierwsza wersja FastMCP okazała się na tyle wygodna, że w 2024 roku trafiła do oficjalnego zestawu deweloperskiego dla Pythona. Kod korzystający z mcp.server.fastmcp to właśnie ona, ale ta ścieżka importu została w gałęzi 1.x, która od końca lipca 2026 roku dostaje już tylko poprawki bezpieczeństwa. W drugiej wersji oficjalnego zestawu klasa nazywa się MCPServer i mieszka w mcp.server.mcpserver, więc starsze przykłady z sieci przestają się kompilować po aktualizacji.

Projekt rozwijał się jednak dalej jako osobny pakiet i to on ma dziś funkcje, których w wersji wbudowanej nie ma: składanie serwerów, generowanie serwera z opisu OpenAPI oraz pośredniczenie w wywołaniach do innych serwerów. Klient i uwierzytelnianie były kiedyś na tej liście, ale druga wersja oficjalnego zestawu, wydana 28 lipca 2026 roku, dołożyła jedno i drugie, więc to już nie jest argument przy wyborze.

Praktyczna wskazówka przy wyborze: do prostego serwera z kilkoma narzędziami wystarczy wersja z oficjalnego zestawu. Do wszystkiego, co ma trafić na produkcję albo obsługiwać wielu klientów, sięgnij po osobny pakiet, bo brakujące funkcje i tak dopiszesz sam.

Warto też wiedzieć, że nazwa krąży w dwóch ekosystemach, a w TypeScripcie nosi ją nawet kilka rzeczy naraz. Ten sam zespół wydaje własną bibliotekę @prefecthq/fastmcp-ts, a niezależnie od niej w rejestrze npm stoi pakiet fastmcp rozwijany przez inne osoby. To nie są te same narzędzia ani zgodne interfejsy, więc szukając materiałów, sprawdzaj, o którym języku i o którym pakiecie mowa, bo przykłady kodu z jednego nie przełożą się na drugi.

Wersja stabilna z końca lipca 2026 nosi numer 3.4.5, a dzień później pojawiła się pierwsza wersja beta czwórki. Kierunek jej rozwoju jest bezpośrednią odpowiedzią na zmianę w samym protokole, o czym za chwilę.

Pierwszy serwer

Code
Bash
pip install fastmcp
Code
Python
from fastmcp import FastMCP

mcp = FastMCP("zamowienia")

@mcp.tool
def status_zamowienia(numer: str) -> dict:
    """Zwraca status zamowienia po numerze w formacie ORD-12345.

    Wywolaj, gdy uzytkownik pyta o konkretne zamowienie i podal jego numer.
    """
    return db.zamowienia.pobierz(numer)

if __name__ == "__main__":
    mcp.run()

To cały serwer. Adnotacja typu argumentu daje schemat, dokumentacja funkcji daje opis, a dekorator rejestruje narzędzie. Model widzi dokładnie to, co napisałeś w dokumentacji, więc pierwsze zdanie powinno mówić, co funkcja robi, a drugie kiedy ją wywołać.

Zasoby i szablony poleceń działają tak samo, tylko z innym dekoratorem.

Code
Python
@mcp.resource("regulamin://{sekcja}")
def regulamin(sekcja: str) -> str:
    """Tresc wskazanej sekcji regulaminu."""
    return czytaj_sekcje(sekcja)

Różnica między jednym a drugim jest istotna, nie kosmetyczna. Narzędzie ma skutek, więc klient zwykle pyta użytkownika o zgodę. Zasób jest tylko odczytem, więc klient może go pobrać sam. Ten podział opisuje szerzej artykuł o protokole MCP.

Składanie serwerów i pośredniczenie

Dwie funkcje odróżniają ten pakiet od minimalnej implementacji i obie rozwiązują problemy, które pojawiają się przy trzecim serwerze.

Składanie pozwala zmontować jeden serwer z kilku mniejszych. Zamiast trzydziestu narzędzi w jednym pliku masz trzy moduły tematyczne, każdy testowany osobno, złożone w całość przy uruchomieniu. Przy większym projekcie to różnica między kodem, który da się utrzymać, a jednym plikiem, do którego nikt nie chce zaglądać.

Pośredniczenie pozwala wystawić cudzy serwer pod własnym adresem, po drodze filtrując narzędzia albo dokładając uwierzytelnianie. To praktyczne przy udostępnianiu zespołowi serwera, który sam w sobie nie ma kontroli dostępu.

Zanim jednak owiniesz cudzy serwer, sprawdź, czy nie ma już własnych ograniczeń. Serwer GitHuba dzieli narzędzia na zestawy włączane zmienną środowiskową i ma tryb tylko do odczytu, więc pośrednik dołożyłby tam głównie kolejny element do utrzymania. Zysk pojawia się przy serwerach, które wystawiają wszystko naraz i nie pytają, kto pyta.

Code
Python
from fastmcp import FastMCP

glowny = FastMCP("firma")
glowny.mount(serwer_zamowien, namespace="zamowienia")
glowny.mount(serwer_klientow, namespace="klienci")

Przy składaniu warto ustalić zasadę nazewnictwa od początku. Przestrzeń nazw podana przy montowaniu staje się częścią nazwy narzędzia widocznej dla modelu, więc zamowienia_status czyta się lepiej niż srv1_get. Starsza nazwa tego argumentu, prefix, nadal działa, ale wypisuje ostrzeżenie o wycofaniu. Zmiana nazwy później oznacza, że wszystkie zapisane konfiguracje klientów przestają pasować.

Osobną wygodą jest generowanie serwera z istniejącego opisu OpenAPI. Jeśli masz udokumentowane API, dostajesz zestaw narzędzi bez pisania ich ręcznie, co przy pięćdziesięciu punktach końcowych oszczędza dzień pracy. Wynik warto jednak przejrzeć i ograniczyć, bo automatyczne opisy z dokumentacji API rzadko mówią modelowi, kiedy narzędzia użyć.

Bezstanowość protokołu i co z niej wynika

Specyfikacja protokołu z 28 lipca 2026 roku usunęła sesje z warstwy protokołu. To dobra wiadomość dla wdrożeń, bo serwer skaluje się jak zwykła usługa bezstanowa, ale rodzi pytanie o aplikacje, które stanu potrzebują.

Właśnie tym zajmuje się rozwijana wersja czwarta: budowaniem aplikacji ze stanem na bezsesyjnym protokole. Stan przestaje być własnością połączenia, a staje się czymś, co przechowujesz świadomie i wiążesz z identyfikatorem przekazywanym w żądaniu.

Praktycznie oznacza to jedną zmianę w sposobie myślenia. Wcześniej dało się trzymać kontekst rozmowy w pamięci procesu obsługującego połączenie. Teraz trzeba go zapisać tam, gdzie sięgnie każda instancja: w bazie, w magazynie klucz wartość albo w tokenie przekazywanym przez klienta.

Przy istniejących serwerach warto sprawdzić, czy nie polegają na trwałości połączenia. Jeśli tak, migracja jest zwykle prosta, ale wymaga świadomej decyzji, gdzie stan ma leżeć.

Uwierzytelnianie i wdrożenie

Serwer lokalny nie potrzebuje uwierzytelniania, bo klient uruchamia go jako podproces. Serwer zdalny potrzebuje go zawsze, a biblioteka daje na to gotowe mechanizmy zamiast zostawiania tego Tobie.

Konfiguracja obejmuje dostawców tożsamości i kontrolę dostępu na poziomie pojedynczych narzędzi, więc ten sam serwer może udostępniać różny zestaw funkcji różnym użytkownikom. To istotne przy narzędziach zmieniających dane, gdzie odczyt może być dostępny szeroko, a zapis wąsko.

Po stronie wdrożenia dostępne jest publikowanie z repozytorium wraz z podglądem gałęzi i szybkim cofnięciem zmiany, a także prywatny rejestr serwerów w organizacji. Ten ostatni element rozwiązuje problem, który pojawia się szybciej, niż się wydaje: po pół roku nikt nie wie, ile serwerów działa w firmie i kto za nie odpowiada.

Alternatywą jest wdrożenie własne, na dowolnej platformie obsługującej usługi HTTP, na przykład na Cloudflare albo w kontenerach. Bezstanowość protokołu sprawia, że nie potrzebujesz przypinania klienta do instancji.

Testowanie

To obszar, w którym osobny pakiet daje najwięcej i jednocześnie najrzadziej się z tego korzysta.

Klient wbudowany w bibliotekę pozwala wywołać własny serwer w teście bez uruchamiania osobnego procesu. Test wygląda jak zwykły test jednostkowy, a sprawdza całą ścieżkę: rejestrację narzędzia, walidację argumentów i kształt odpowiedzi.

Code
Python
from fastmcp import Client

async def test_status_zwraca_dane():
    async with Client(mcp) as klient:
        wynik = await klient.call_tool("status_zamowienia", {"numer": "ORD-12345"})
        assert "status" in wynik.data

Warto testować trzy rzeczy. Czy narzędzie jest widoczne na liście, bo literówka w dekoratorze nie rzuca błędem. Czy walidacja odrzuca złe argumenty, bo model będzie je przysyłał. Czy odpowiedź ma stały kształt, bo agent buduje na niej kolejne kroki.

Osobno warto uruchomić narzędzie inspekcyjne przed podłączeniem serwera do asystenta. Pokazuje ono listę narzędzi tak, jak zobaczy ją model, i pozwala wywołać każde ręcznie. Ten krok wyłapuje błędne opisy szybciej niż jakikolwiek test.

Kontekst wywołania i wywołania zwrotne do klienta

Narzędzie działające w oderwaniu od tego, kto je wywołał, wystarcza do prostych przypadków. Przy poważniejszej integracji potrzebujesz dostępu do informacji o wywołaniu i możliwości odezwania się do klienta.

Kontekst wstrzykiwany do funkcji daje dostęp do tożsamości wywołującego, do logowania zdarzeń widocznych po stronie klienta oraz do raportowania postępu przy dłuższych operacjach.

Code
Python
from fastmcp import FastMCP, Context

mcp = FastMCP("raporty")

@mcp.tool
async def zbuduj_raport(miesiac: str, ctx: Context) -> str:
    """Generuje raport sprzedazy za wskazany miesiac w formacie RRRR-MM."""
    await ctx.info(f"Zbieram dane za {miesiac}")
    dane = await pobierz_dane(miesiac)
    await ctx.report_progress(progress=50, total=100)
    return zloz_raport(dane)

Raportowanie postępu ma znaczenie praktyczne, bo bez niego operacja trwająca minutę wygląda dla użytkownika jak zawieszenie. Klient pokazuje wtedy pasek postępu zamiast ciszy.

Osobnym mechanizmem jest odpytanie użytkownika w trakcie działania. Jeśli narzędzie potrzebuje informacji, której nie dostało w argumentach, może o nią poprosić, zamiast zgadywać albo zwracać błąd. To rozwiązuje typowy problem operacji wymagających potwierdzenia albo wyboru spośród kilku pasujących rekordów.

Trzecią możliwością jest poproszenie klienta o wywołanie modelu. Serwer nie musi mieć własnego klucza do dostawcy, bo korzysta z tego, który ma aplikacja wywołująca. To upraszcza konfigurację i przenosi koszt tam, gdzie i tak jest rozliczany.

FastMCP kontra alternatywy

PodejścieZaletaWadaKiedy wybrać
FastMCP jako osobny pakietSkładanie, OpenAPI, pośredniczenie, narzędzia testoweWięcej zależności, szybkie zmiany wersjiSerwer produkcyjny, wielu klientów
Wersja w oficjalnym zestawieMniej zależności, od wersji drugiej ma klienta i uwierzytelnianieBrak składania serwerów, OpenAPI i pośredniczeniaProsty serwer lokalny
Implementacja od zeraPełna kontrola, zero zależnościSam obsługujesz protokół i jego zmianyNietypowe środowisko albo inny język
Gotowy serwer od dostawcyZero pracyZakres ustalony przez dostawcęIntegracja z popularną usługą

Przy wyborze między pakietami warto uwzględnić tempo zmian. Osobny pakiet wydaje wersje często, co daje szybki dostęp do nowych możliwości i wymaga przypinania wersji w pliku zależności, jeśli nie chcesz niespodzianek przy budowaniu.

Zanim napiszesz cokolwiek, sprawdź, czy serwer dla Twojej usługi już nie istnieje. Wiele platform udostępnia własne, a napisanie kolejnego to praca, którą ktoś już wykonał.

Od skryptu do serwera, czyli typowa droga

Większość serwerów powstaje w ten sam sposób i warto znać tę ścieżkę, bo skraca pierwsze podejście.

Zaczyna się od skryptu, który robi coś powtarzalnego: pobiera dane z wewnętrznego systemu, generuje zestawienie, sprawdza status. Uruchamiasz go ręcznie, a przy każdym uruchomieniu przypominasz sobie, jakie przyjmuje argumenty.

Pierwszy krok to opakowanie funkcji dekoratorem i napisanie dokumentacji tak, żeby model zrozumiał, kiedy jej użyć. To dosłownie kilka minut, a efekt jest natychmiastowy: przestajesz pamiętać składnię, bo opisujesz zadanie słowami.

Drugi krok pojawia się, gdy narzędzi robi się kilka. Wtedy warto rozdzielić je tematycznie i złożyć w jeden serwer, zamiast dokładać funkcje do jednego pliku. Przy okazji dodaj obsługę błędów zwracającą czytelny komunikat, bo agent poradzi sobie z informacją „brak uprawnień do tego zasobu", a nie poradzi sobie z przerwaniem działania.

Trzeci krok to udostępnienie serwera zespołowi. Tu kończy się wersja lokalna, a zaczyna wdrożenie zdalne wraz z uwierzytelnianiem i ograniczeniem uprawnień. To również moment, w którym opisy narzędzi przestają być Twoją prywatną sprawą, bo czyta je model u kilku osób.

Czwarty krok, o którym mało kto myśli na starcie, to porządkowanie. Po pół roku część narzędzi przestaje być używana, a inne robią to samo pod dwiema nazwami. Przegląd raz na kwartał utrzymuje zestaw w rozmiarze, w którym model trafnie wybiera.

Typowe błędy

Pierwszy to dokumentacja funkcji pisana dla programisty, nie dla modelu. Model czyta ten sam tekst, więc zdanie mówiące, kiedy narzędzie wywołać, jest ważniejsze niż opis implementacji.

Drugi to zwracanie surowej odpowiedzi API. Trzysta linii JSON-a zamiast pięciu pól podnosi koszt i obniża trafność kolejnych kroków agenta.

Trzeci to brak obsługi błędów. Wyjątek przerywa działanie agenta bez informacji, co poszło nie tak, podczas gdy czytelny komunikat pozwala mu spróbować inaczej.

Czwarty to wystawienie serwera zdalnego bez uwierzytelniania. To, co dałeś modelowi, dajesz każdemu, kto zna adres.

Piąty to trzymanie stanu w pamięci procesu. Przy bezsesyjnym protokole kolejne żądanie może trafić do innej instancji, więc stan musi leżeć w miejscu dostępnym dla wszystkich.

FAQ

Czy FastMCP to to samo co oficjalny zestaw deweloperski?

Częściowo. Pierwsza wersja projektu trafiła w 2024 roku do oficjalnego zestawu dla Pythona i jest tam dostępna jako moduł, choć w wersji drugiej zestawu klasa zmieniła nazwę na MCPServer. Osobny pakiet rozwija się dalej i dokłada składanie serwerów, integrację z OpenAPI i pośredniczenie, których w wersji wbudowanej nie ma. Klienta i uwierzytelnianie oficjalny zestaw dorobił sobie sam.

Której wersji użyć?

Do prostego serwera lokalnego z kilkoma narzędziami wystarczy wersja z oficjalnego zestawu. Do serwera produkcyjnego, zdalnego albo obsługującego wielu użytkowników sięgnij po osobny pakiet, bo inaczej dopiszesz te same funkcje samodzielnie.

Czy potrzebuję Pythona w konkretnej wersji?

Biblioteka wymaga Pythona w wersji 3.10 lub nowszej. Przy starszych projektach to bywa realna przeszkoda, więc sprawdź to przed planowaniem integracji.

Co zmienia bezstanowość protokołu?

Serwer zdalny nie utrzymuje sesji, więc każde żądanie może obsłużyć inna instancja. Ułatwia to wdrożenie i skalowanie, natomiast stan aplikacji trzeba przechowywać świadomie, w bazie albo w tokenie, zamiast w pamięci procesu. Rozwijana czwarta wersja biblioteki adresuje właśnie ten scenariusz.

Jak podłączyć gotowy serwer do asystenta?

Wskazujesz w konfiguracji klienta, jak go uruchomić albo pod jakim adresem szukać, po czym ten sam serwer działa w aplikacji Claude, w Cursorze i w bibliotekach agentowych, na przykład w LangChain. Na tym polega sens protokołu: integrację piszesz raz.

Dokumentacja stoi na gofastmcp.com, a kod źródłowy w repozytorium na GitHubie, które projekt prowadzi pod szyldem firmy Prefect.