SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor

Jak uruchomić serwer MCP na VPS dla agentów AI

Instrukcja konfiguracji serwerów MCP na VPS z wykorzystaniem stdio oraz HTTP. Dowiedz się, jak zarządzać procesami przez systemd, zabezpieczyć TLS i uniknąć błędów JSON-RPC.

Co jest budowane

Dwie działające konfiguracje MCP na jednym VPS. Pierwsza to serwer stdio, narzędzie do obsługi systemu plików lub bazy danych, które Claude Code uruchamia jako proces potomny i z którym komunikuje się przez potok. Druga to zdalny serwer HTTP, działający jako długotrwała usługa sieciowa zarządzana przez systemd oraz odwrotny serwer proxy nginx z TLS, dostępny dla każdego klienta MCP wskazanego w konfiguracji. Instalacja obu rozwiązań jest niewielka. Większość tego przewodnika skupia się na dwóch kluczowych kwestiach: utrzymaniu czystości strumienia JSON-RPC oraz unikaniu udostępniania nieautoryzowanych punktów końcowych narzędzi w publicznym Internecie.

Czym w rzeczywistości jest MCP

Model Context Protocol to standardowy sposób, w jaki klient AI, taki jak Claude Code, Claude Desktop, Gemini CLI na VPS lub własny skrypt, wywołuje zewnętrzne narzędzia i odczytuje zasoby zewnętrzne. Sam model nie uruchamia żadnego kodu. Wysyła on zapytanie do klienta, klient komunikuje się za pomocą JSON-RPC 2.0 z serwerem MCP, a serwer wykonuje narzędzie i zwraca wynik. Klient jest tym elementem, który określa się mianem agent harness: to pętla wokół modelu, która zarządza listą narzędzi, kontrolą uprawnień oraz stanem sesji, a MCP jest po prostu sposobem na rozszerzenie części narzędziowej. Jeden protokół sprawia, że serwer napisany raz współpracuje z każdym klientem obsługującym MCP. Jeśli ten podział jest nowością, a w szczególności kwestia tego, w jaki sposób model decyduje o użyciu narzędzia, warto poświęcić godzinę na etapową ścieżkę przez podstawy działania agentów, zanim przekaże się takiemu serwerowi rzeczywiste dane uwierzytelniające.

Istnieją dwa rodzaje transportu, według których podzielona jest reszta tego przewodnika:

  • stdio. Klient uruchamia serwer jako proces potomny i wymienia komunikaty JSON-RPC rozdzielane znakami nowej linii za pośrednictwem standardowego wejścia i wyjścia. Brak sieci, brak portów, brak autoryzacji; granicą zaufania jest sam proces. Prawie każde lokalne narzędzie działa w ten sposób.
  • Streamable HTTP (oraz jego starszy odpowiednik, HTTP+SSE). Serwer jest długo działającą usługą sieciową. Klient łączy się przez HTTP, a serwer może przesyłać odpowiedzi strumieniowo za pomocą Server-Sent Events. Jest to sposób na współdzielenie jednego serwera przez wielu klientów lub uruchomienie narzędzia, które musi działać na maszynie w sposób ciągły.

Wybierz stdio, gdy narzędzie przypisane jest do jednej maszyny i jednego użytkownika. Wybierz HTTP, gdy jest to usługa współdzielona.

Wymagania wstępne i istotne uwagi

Przyjęto założenie korzystania z czystej instancji Ubuntu 24.04 na VPS typu KVM z dostępem root lub sudo. Ponadto:

  • Środowisko uruchomieniowe dla serwera. Większość serwerów referencyjnych jest napisana w Node lub Python. Ubuntu 24.04 dostarcza Node 18, jednak wiele aktualnych pakietów MCP wymaga wersji Node 20 lub nowszej. Należy zainstalować bieżące wydanie LTS z NodeSource lub nvm, zamiast polegać na apt. Python 3.12 jest dostępny domyślnie.
  • Domena i rekord DNS A, ale tylko w przypadku zdalnego serwera HTTP; TLS wymaga nazwy, która wskazuje na ten VPS. Przykład stdio nie wymaga żadnej konfiguracji DNS.
  • 512 MB pamięci RAM jest wystarczające. Serwery MCP to lekkie procesy JSON-RPC; zużycie pamięci zależy od wykorzystywanych narzędzi (sterownik bazy danych, pamięć podręczna plików), a nie od samego protokołu.
  • Specyfikacja jest młoda i dynamiczna. Wersja z 2025-03-26 zastąpiła HTTP+SSE protokołem Streamable HTTP i oznaczyła SSE jako przestarzałe. SSE nadal działa i wiele serwerów wciąż go obsługuje, dlatego wszelkie ograniczenia dotyczące transportu należy weryfikować w informacjach o wydaniu serwera, zamiast traktować je jako ostateczne.

Krok 1: podłączenie serwera stdio do Claude Code

Należy rozpocząć od serwera systemu plików; jest on oficjalny, aktywnie utrzymywany i wymaga jedynie środowiska Node. Poniższe polecenie rejestruje go w Claude Code i ogranicza jego zasięg do bieżącego projektu, dzięki czemu zapisuje się on w pliku podlegającym kontroli wersji:

cd /home/matt/projects/api
claude mcp add --scope project --transport stdio filesystem \
  -- npx -y @modelcontextprotocol/server-filesystem /home/matt/projects/api

Separator -- jest istotny: wszystko, co znajduje się po nim, jest poleceniem wykonywanym przez Claude Code, a nie flagą dla samego Claude Code. Powoduje to zapisanie pliku .mcp.json w katalogu głównym projektu:

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/home/matt/projects/api"
      ]
    }
  }
}

W tym momencie nic jeszcze nie działa. Przy kolejnym uruchomieniu Claude Code w tym katalogu, agent odczyta .mcp.json, uruchomi npx -y @modelcontextprotocol/server-filesystem ... jako proces potomny i przeprowadzi uzgadnianie MCP za pośrednictwem standardowego wejścia/wyjścia (stdin/stdout) tego procesu. Należy potwierdzić poprawność konfiguracji:

claude mcp list

Poprawnie działający serwer wyświetla swoje polecenie oraz zielony znacznik filesystem: npx -y @modelcontextprotocol/server-filesystem ... - ✔ Connected. Wewnątrz sesji polecenie ukośnikowe /mcp wyświetla listę narzędzi udostępnianych przez serwer (read_text_file, write_file, list_directory), a agent może teraz wywoływać je w ramach dozwolonych ścieżek. Narzędzie bazodanowe działa w ten sam sposób; należy zamienić pakiet i przekazać ciąg połączeniowy jako ostatni argument. Warto jednak sprawdzić repozytorium danego serwera w celu uzyskania aktualnej nazwy pakietu, ponieważ referencyjny serwer Postgres zmieniał już właściciela.

Na tym polega istota uruchamiania agenta na serwerze: sesja Claude Code działa na VPS wewnątrz tmux, a serwery stdio pracują bezpośrednio obok niej, mając dostęp do plików projektu i usług lokalnych bez opóźnień sieciowych. Gdy agent posiada zarówno write_file, jak i read_text_file, warto połączyć ten zasięg z umiejętnością dążenia do najmniejszej działającej zmiany, ponieważ narzędzie systemu plików sprawia, że rozległe przepisanie kodu jest równie łatwe, co poprawka dwuliniowa. To samo połączenie wykracza poza pliki lokalne: jeśli na VPS działa już wyszukiwarka, można przekazać agentowi własną instancję SearXNG jako narzędzie wyszukiwania. Dzięki temu zapytania pozostają na serwerze, a tekst z niezaufanych stron jest pobierany bezpośrednio do kontekstu, na którym operuje agent.

Krok 2: budowa zdalnego serwera HTTP

Serwer stdio kończy działanie wraz z procesem nadrzędnym i jest uruchamiany osobno dla każdego klienta. Jeśli uruchomisz dwie sesje Claude Code na maszynie, które przekazują sobie zadania, każda z nich otrzyma własną, prywatną kopię narzędzia. Jeśli potrzebujesz narzędzia, które działa stale dla wszystkich klientów, współdzielonego narzędzia operacyjnego, bramy bazodanowej lub usługi wywoływanej zarówno z laptopa, jak i z CI, wymagany jest transport HTTP oraz rzeczywista usługa. Poniżej znajduje się minimalny serwer w języku Python korzystający z oficjalnego SDK, udostępniający jedno narzędzie:

# /opt/mcp-ops/server.py
from mcp.server.mcpserver import MCPServer
import subprocess

mcp = MCPServer("ops-tools")

@mcp.tool()
def disk_free() -> str:
    """Return `df -h` for the server."""
    out = subprocess.run(["df", "-h"], capture_output=True, text=True)
    return out.stdout

if __name__ == "__main__":
    # Serves Streamable HTTP at /mcp on 127.0.0.1:8000
    mcp.run(transport="streamable-http", host="127.0.0.1", port=8000)

Zwróć uwagę na host="127.0.0.1". Serwer wiąże się wyłącznie z localhost, więc żaden zewnętrzny host nie uzyska do niego bezpośredniego dostępu, co jest pożądanym stanem przed wdrożeniem autoryzacji. Jest to SDK w wersji 2.x, które pip install "mcp[cli]" pobiera obecnie (wersja 2.3.0 na dzień 2026-10-20). Zmieniono w nim nazwę FastMCP na MCPServer, przeniesiono host oraz port z konstruktora do run(), a stary import mcp.server.fastmcp kończy się obecnie błędem ModuleNotFoundError. Zainstaluj go w oddzielnym środowisku virtualenv, aby systemd posiadał stabilną ścieżkę do interpretera:

sudo useradd --system --home /opt/mcp-ops --shell /usr/sbin/nologin mcp
sudo install -d -o mcp -g mcp /opt/mcp-ops
sudo -H -u mcp python3 -m venv /opt/mcp-ops/.venv
sudo -H -u mcp /opt/mcp-ops/.venv/bin/pip install "mcp[cli]"

Krok 3: utrzymanie ciągłości działania za pomocą systemd

Narzędzie, które jest niedostępne w momencie, gdy agent próbuje z niego skorzystać, jest bezużyteczne. Ma to kluczowe znaczenie, gdy klientem jest proces długotrwały: zawsze aktywny agent, który zachowuje stan pamięci i harmonogramy po restartach, będzie wywoływał te narzędzia zgodnie z harmonogramem bez nadzoru, dlatego serwer musi automatycznie powracać do pracy. Utwórz plik /etc/systemd/system/mcp-ops.service:

[Unit]
Description=MCP ops-tools server
After=network.target

[Service]
Type=simple
User=mcp
WorkingDirectory=/opt/mcp-ops
ExecStart=/opt/mcp-ops/.venv/bin/python /opt/mcp-ops/server.py
Restart=on-failure
RestartSec=2
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true

[Install]
WantedBy=multi-user.target

Bezwzględna ścieżka do interpretera Python wewnątrz venv w ExecStart nie jest opcjonalna; należy wskazać /usr/bin/python3, aby proces uruchamiał się z ModuleNotFoundError: No module named 'mcp', ponieważ systemowy interpreter nie posiada dostępu do Twojego pip install. Włącz usługę i sprawdź jej stan:

sudo systemctl daemon-reload
sudo systemctl enable --now mcp-ops
sudo systemctl status mcp-ops
curl -si -H 'Accept: application/json, text/event-stream' \
  -H 'Content-Type: application/json' \
  -X POST http://127.0.0.1:8000/mcp

status powinno zwrócić active (running). curl powróci z HTTP/1.1 400 Bad Request zawierającym błąd JSON-RPC w treści, ponieważ żądanie nie zawierało sesji ani poprawnego ładunku JSON, co jest pożądanym zachowaniem: potwierdza to, że port odpowiada i obsługuje protokół. Connection refused lub pusta odpowiedź oznaczają, że proces nie jest powiązany z portem w oczekiwanym miejscu; sprawdź journalctl -u mcp-ops -n 50.

Krok 4: wdrożenie TLS i reverse proxy

Serwer nasłuchuje na localhost. Aby uzyskać dostęp z zewnątrz, należy zakończyć połączenie TLS na nginx i przekierować ruch do wewnątrz. Zainstaluj nginx, uzyskaj certyfikat zgodnie z Certbot i Let's Encrypt na nginx, a następnie utwórz blok location. Kluczowe jest wyłączenie buforowania, ponieważ domyślne zachowanie nginx polega na wstrzymaniu odpowiedzi do momentu jej pełnego odebrania, co powoduje trwałe zablokowanie strumienia SSE:

server {
    listen 443 ssl;
    server_name mcp.example.com;

    # ssl_certificate lines managed by Certbot

    location /mcp {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;

        # The four lines that make SSE work through nginx:
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 3600s;
        chunked_transfer_encoding off;
    }
}

Przeładuj konfigurację za pomocą sudo nginx -t && sudo systemctl reload nginx. Jeśli zarządzasz już zestawem kontenerów, to samo zadanie wykona za Ciebie Traefik reverse proxy z automatycznym TLS, który wystawi certyfikat i skieruje ruch na podstawie nazwy hosta; wystarczy dodać odpowiednie etykiety do kontenera MCP. Niezależnie od wybranej metody, reverse proxy jest teraz jedynym elementem dostępnym na publicznym porcie i wskazuje na usługę, która nie została jeszcze zabezpieczona. Należy to naprawić przed zarejestrowaniem adresu URL w jakimkolwiek publicznym miejscu.

Krok 5: zasada bezpieczeństwa kluczowa dla tego zagadnienia

Nigdy nie udostępniaj nieuwierzytelnionego punktu końcowego MCP. Serwer MCP nie jest interfejsem API typu read-only. Zapewnia on dostęp do narzędzi, plików, bazy danych, a niekiedy nawet do powłoki systemowej. Otwarty /mcp w publicznym Internecie to nieznajomy z takimi samymi uprawnieniami jak Twój agent AI: może on wyświetlić listę narzędzi, a następnie je wywołać. Traktuj to dokładnie tak samo, jak nieuwierzytelnione gniazdo administracyjne, ponieważ w istocie tym właśnie jest. Zakres szkód wynikających z kradzieży tokena zależy również od serwera, który za nim stoi: serwer MCP typu read-only dostarczany z trackerem treningów openGym może jedynie zwrócić dane treningowe, podczas gdy narzędzie typu filesystem lub shell daje pełny dostęp do maszyny.

Trzy metody ochrony, w kolejności od najbardziej zalecanej:

  1. Nie publikuj go. Utrzymuj serwer na 127.0.0.1 i łącz się z nim z laptopa za pomocą tunelu SSH: ssh -L 8000:127.0.0.1:8000 matt@vps, a następnie skieruj klienta na http://127.0.0.1:8000/mcp. Nic nie jest wystawione na zewnątrz.
  2. Umieść go w sieci prywatnej. Powiąż adres tunelu z samodzielnie hostowanym VPN WireGuard i zezwól na dostęp tylko uczestnikom sieci VPN. Publiczny Internet widzi zamknięty port.
  3. Jeśli musi być publiczny, wymagaj tokena. Właściwym rozwiązaniem jest przepływ MCP OAuth, który jest natywnie wspierany przez transport HTTP. Pragmatycznym minimum jest współdzielony token bearer weryfikowany na poziomie proxy; jest to rozwiązanie tanie, które całkowicie eliminuje ataki typu drive-by:
location /mcp {
    if ($http_authorization != "Bearer REPLACE_WITH_LONG_RANDOM") {
        return 401;
    }
    proxy_pass http://127.0.0.1:8000;
    # ...buffering-off block from above...
}

Wygeneruj token za pomocą openssl rand -hex 32 i nigdy nie wiąż samego serwera z 0.0.0.0 bez zastosowania jednego z powyższych zabezpieczeń. Klient przesyła następnie token w nagłówku. W Claude Code:

claude mcp add --scope project --transport http ops-tools https://mcp.example.com/mcp \
  --header 'Authorization: Bearer ${MCP_TOKEN}'

Ustaw MCP_TOKEN w swojej powłoce, aby sekret nigdy nie trafił do .mcp.json w postaci jawnej; Claude Code rozwija ${MCP_TOKEN} ze środowiska w momencie odczytu. Jeśli zmienna nie jest ustawiona, Claude Code nie podstawia pustego ciągu znaków: zgłasza brakującą zmienną w claude mcp list i używa dosłownego tekstu ${MCP_TOKEN}. Wybierz własną nazwę, ponieważ w nagłówkach zdalnego serwera Claude Code celowo odczytuje własne zmienne oraz zmienne poświadczeń dostawcy chmury, takie jak ANTHROPIC_API_KEY, jako puste, podobnie jak inne poświadczenia obecne w środowisku, takie jak NPM_TOKEN.

Każda z powyższych metod ochrony zabezpiecza punkt końcowy, a nie agenta, który już posiada token, co stanowi drugą część problemu: jeśli Twoim klientem jest DeepSeek Harness, wtyczki ograniczające dostęp agenta do narzędzi oraz skanujące dane wyjściowe narzędzi pod kątem wstrzykniętych instrukcji zabezpieczają ten aspekt.

Krok 6: debugowanie za pomocą MCP Inspector

Gdy serwer działa nieprawidłowo, nie należy zgadywać przyczyn z poziomu agenta; należy sterować nim bezpośrednio za pomocą Inspector, oficjalnego testowego klienta przeglądarkowego. W przypadku serwera stdio należy przekazać mu to samo polecenie, które uruchamia agent:

npx @modelcontextprotocol/inspector \
  npx -y @modelcontextprotocol/server-filesystem /tmp

Narzędzie udostępnia interfejs użytkownika przez serwer WWW na http://localhost:6274 i wyświetla adres URL zawierający ciąg zapytania MCP_INSPECTOR_API_TOKEN; należy otworzyć ten link zamiast wpisywać adres z pamięci. Od wersji v2 (2.11.0 jest aktualna na dzień 2026-10-20) backend wstrzykuje token do strony przy każdym ładowaniu, dzięki czemu odświeżenie strony nie przerywa pracy, a token zabezpiecza trasy /api/*, które mogą uruchamiać procesy. Osobny proxy v1 na porcie 6277 został usunięty, ale serwer WWW nie jest jedynym nasłuchującym komponentem: v2 uruchamia również piaskownicę dla MCP Apps na MCP_SANDBOX_PORT (domyślnie 6275) oraz dedykowany serwer app-origin na MCP_APP_ORIGIN_PORT (domyślnie 6278), który obsługuje każdą aplikację MCP, której zasób UI deklaruje _meta.ui.domain. Jeśli Inspector jest dostępny przez tunel SSH lub działa w kontenerze i wymagana jest karta Apps, należy przekierować porty 6275 i 6278 wraz z 6274. Po połączeniu należy otworzyć kartę Tools, wybrać narzędzie, wypełnić rzeczywiste argumenty i wywołać je. Jeśli narzędzie działa w Inspector, a zawodzi w agencie, błąd leży w konfiguracji klienta, a nie serwera. W przypadku zdalnego serwera HTTP należy uruchomić Inspector bez polecenia, dodać serwer z transportem Streamable HTTP i https://mcp.example.com/mcp, umieścić nagłówek Authorization w jego ustawieniach i połączyć się; jest to najszybszy sposób na weryfikację poprawności autoryzacji i proxy przed zaangażowaniem agenta. Inspector zapisuje nagłówki w katalogu serwera w niezmienionej formie, więc token ten znajduje się teraz również w ~/.mcp-inspector/mcp.json.

Utrzymywanie serwerów w aktualnym stanie

MCP rozwija się dynamicznie, dlatego należy stosować harmonogram aktualizacji. Serwery Node uruchamiane z nieprzypiętym npx -y korzystają z wersji, którą rozstrzygnie npx: tej zainstalowanej w lokalnym projekcie (jeśli istnieje) lub kopii pobranej do pamięci podręcznej npm. Flaga -y jedynie pomija monit instalacji, nie wymusza aktualizacji, więc nie śledzisz najnowszego wydania ani nie masz pewności, która wersja jest uruchomiona. Przypnij dokładną wersję, którą przetestowałeś, odczytaj ją z npm view @modelcontextprotocol/server-filesystem version i dopisz do nazwy pakietu w .mcp.json (@modelcontextprotocol/server-filesystem@<version>), gdy serwer staje się produkcyjny, a następnie zwiększaj ją w sposób kontrolowany. Serwery Python działające pod systemd aktualizuje się za pomocą sudo -H -u mcp /opt/mcp-ops/.venv/bin/pip install -U "mcp[cli]", a następnie sudo systemctl restart mcp-ops. Przed dużą aktualizacją zapoznaj się z informacjami o wydaniu: przejście z Python SDK 1.x na 2.x powoduje błędy importu w kodzie 1.x, a przewodnik migracji SDK zaleca stosowanie górnego ograniczenia <2, na przykład "mcp[cli]<2", do czasu zakończenia migracji. Podczas aktualizacji sprawdzaj wersję specyfikacji, do której odwołuje się SDK; przeskok przez granicę SSE-to-Streamable-HTTP może zmienić protokół transportowy, którego muszą używać klienci.

Tryby awarii i towarzyszące im komunikaty

Agent zgłasza awarię serwera. claude mcp list wyświetla ✘ Failed to connect, a bieżące wersje dołączają szczegóły błędu do tej linii. Uruchom claude --debug, aby zazwyczaj zobaczyć Error: spawn npx ENOENT; oznacza to, że polecenie nie znajduje się w zmiennej PATH agenta. Środowisko uruchomieniowe jest nieobecne lub znajduje się w innej lokalizacji, niż oczekuje agent: brak zainstalowanego Node, brak npx lub odwołanie do środowiska virtualenv Python za pomocą samej nazwy. Należy poprawić polecenie na ścieżkę bezwzględną lub zainstalować środowisko, a następnie ponownie nawiązać połączenie.

Serwer stdio łączy się i natychmiast rozłącza. Klient rejestruje błąd parsowania JSON, na przykład Unexpected token 'S', "Server sta"... is not valid JSON lub Failed to parse message. Przyczyna jest zawsze taka sama: serwer zapisał linię dziennika do stdout. W przypadku stdio, stdout jest kanałem JSON-RPC, więc każdy przypadkowy tekst uszkadza strumień i przerywa proces uzgadniania. W Node console.log wysyła dane do stdout; należy użyć console.error. W Pythonie samo print() wysyła dane do stdout; należy zapisywać dzienniki za pomocą logging skonfigurowanego na sys.stderr lub przekazać file=sys.stderr. Zasada jest bezwzględna: w stdio na stdout może znajdować się tylko JSON-RPC, a wszystkie komunikaty dla użytkownika muszą trafiać na stderr.

Zdalny serwer przekracza limit czasu lub zamyka połączenie w trakcie uzgadniania. Klient zgłasza błąd MCP error -32000: Connection closed lub Inspektor zawiesza się na etapie Connect i nie wyświetla narzędzi. W przypadku użycia nginx przyczyną jest buforowanie: proxy wstrzymuje strumień SSE zamiast go przesyłać na bieżąco, więc klient oczekuje na odpowiedź, która nigdy nie dociera. Należy dodać proxy_buffering off; (oraz resztę bloku z kroku 4) do location. Należy zweryfikować działanie za pomocą curl -N względem publicznego adresu URL; dane zdarzeń powinny pojawiać się przyrostowo, a nie wszystkie naraz po zakończeniu transmisji.

Uwierzytelnianie zostało odrzucone. Klient zgłasza Error POSTing to endpoint (HTTP 401) lub po prostu 401 Unauthorized. Oznacza to brak nagłówka, błędny token lub brak rozwinięcia zmiennej, co jest częstym błędem. Jeśli MCP_TOKEN nie jest ustawione w momencie odczytu konfiguracji przez klienta, Claude Code ostrzega o brakującej zmiennej w claude mcp list i wysyła dosłowny tekst, przez co nginx otrzymuje Bearer ${MCP_TOKEN}. Zmienna nazwana tak samo jak jedna ze zmiennych Claude Code, dostawcy chmury lub innych poświadczeń środowiskowych jest odczytywana jako pusta, a nginx otrzymuje Bearer bez wartości. Należy wyświetlić zmienną za pomocą echo, ponownie dodać nagłówek i zweryfikować, czy bajty dokładnie odpowiadają tokenowi w if serwera nginx.

Usługa nie uruchamia się w systemd. journalctl -u mcp-ops pokazuje ModuleNotFoundError: No module named 'mcp', a ExecStart wskazuje na systemowy interpreter Python zamiast na interpreter z venv. Alternatywnie Address already in use oznacza, że inny proces zajmuje port 8000; należy go zlokalizować za pomocą sudo ss -ltnp | grep 8000.

FAQ

Czym dokładnie jest serwer MCP?

Jest to program udostępniający narzędzia i zasoby klientowi AI za pośrednictwem protokołu Model Context Protocol, przy użyciu JSON-RPC 2.0. Model AI nigdy nie uruchamia narzędzia samodzielnie; wysyła zapytanie do klienta, klient wywołuje serwer MCP, a serwer wykonuje zadanie i zwraca wynik. Ponieważ protokół jest standardowy, jeden serwer współpracuje z każdym zgodnym klientem, niezależnie od tego, czy jest to Claude Code, Claude Desktop czy Gemini CLI.

Jaka jest różnica między transportem stdio a HTTP?

Serwer stdio jest uruchamiany przez klienta jako proces potomny i komunikuje się przez stdin/stdout, więc działa i kończy pracę wraz z jednym klientem na jednej maszynie i nie wymaga sieci ani autoryzacji. Serwer HTTP to długo działająca usługa sieciowa, z której może korzystać wielu klientów jednocześnie, dlatego wymaga TLS i uwierzytelniania. Używaj stdio dla lokalnych narzędzi dla jednego użytkownika; używaj HTTP (w obecnych serwerach Streamable HTTP) dla wszystkiego, co jest współdzielone lub trwałe.

Jak zabezpieczyć zdalny serwer MCP?

Należy założyć, że serwer zapewnia dostęp do plików, bazy danych lub powłoki, dlatego nigdy nie należy wystawiać go bez uwierzytelniania. Najlepiej jest powiązać go z localhost i uzyskiwać do niego dostęp przez tunel SSH lub prywatną sieć VPN; jeśli musi być publiczny, należy umieścić go za reverse proxy, które wymusza token bearer lub przepływ MCP OAuth. Wygeneruj token za pomocą openssl rand -hex 32 i nigdy nie wiąż serwera z 0.0.0.0 bez jednego z tych zabezpieczeń przed nim.

Jak debugować serwer, który nie chce się uruchomić?

Najpierw sprawdź claude mcp list, ✘ Failed to connect; jeśli występuje spawn ... ENOENT, oznacza to, że polecenie lub środowisko uruchomieniowe jest niedostępne, więc popraw ścieżkę lub zainstaluj brakujący komponent. Jeśli połączenie zostaje nawiązane, a następnie przerwane z błędem parsowania JSON, oznacza to, że serwer zapisuje logi do stdout, co powoduje uszkodzenie strumienia JSON-RPC; przenieś wszystkie logi do stderr. W każdym innym przypadku uruchom dokładnie to samo polecenie w MCP Inspector, który uruchamia serwer w izolacji, co pozwala odróżnić błąd serwera od błędu konfiguracji klienta.