Przejdź do głównej zawartości

Budowanie własnego MCP — kiedy MCP, kiedy skill, kiedy slash command

Q11 · Rozszerzalność Czy zbudowałeś własny serwer MCP?

Maksymalna odpowiedź: “Mam kilka i świadomie wybieram MCP vs skill vs slash command per use case.”

Zbudowanie własnego MCP to moment, w którym przestajesz być użytkownikiem narzędzi, a stajesz się ich integratorem. W 2026 Model Context Protocol osiadł jako de facto API rozszerzeń dla każdego poważnego coding agenta — Claude Code, Codex, Cursor, Windsurf, Zed, nowa fala agentic IDE — i prawie każdy SaaS, który dotyka developerów, wypuszcza oficjalnego MCP obok REST API. To zmienia asymetrię pracy: ludzie, którzy tylko instalują MCP z marketplace, potrafią zrobić wszystko, co pokrywa istniejąca integracja. Ludzie, którzy budują MCP, potrafią owinąć tę jedną dziwną wewnętrzną API, legacy bazę, narzędzie staging albo niszowy system partnera, którego nikt poza nimi nie owinął — i nagle agent może end-to-end sterować systemami ich firmy. Dźwignia jest ogromna, a przepaść między installerami a integratorami to dziś największy pojedynczy determinant tego, ile realnej pracy agent może wykonać w Twojej firmie. Druga rzecz, której 2026 zmusza Cię się nauczyć: nie każde rozszerzenie powinno być MCP. Skills, slash commands i subagenty mocno teraz zachodzą na MCP dla niektórych zadań, a wpychanie wszystkiego w serwery MCP to typowy błąd początkującego — rozdyma kontekst narzędzi, spowalnia agenta i wystawia mu prompty, których model nie powinien czytać. Q11 pyta, czy przekroczyłeś granicę konsument → producent oraz nauczyłeś się wybierać właściwą powierzchnię rozszerzenia per zadanie.

Q11 maksujesz tylko wtedy, gdy wszystkie pięć poniższych jest prawdą:

  • Wdrożyłeś co najmniej dwa serwery MCP — nie sforkowałeś, nie “raz odpaliłeś template”, tylko zaprojektowałeś, zdeployowałeś i używasz codziennie. Jeden może być lokalny stdio (wrapper na wewnętrzny CLI lub bazę sqlite); co najmniej jeden powinien być remote (zdeployowany na Cloudflare Workers, Vercelu albo własnym infra), żeby team-mate lub agent w chmurze mógł go odpalić.
  • Masz spisane drzewo decyzyjne MCP vs agent skill vs slash command vs subagent. Nie “intuicja mi powie” — dosłowna reguła w dotfiles lub team handbooku, że “fetch danych, akcja na third-party albo stateful integracja → MCP; playbook w kształcie promptu z reference docs → skill; sekwencja wywołań narzędzi triggerowana nazwą → slash command; długo działająca wyspecjalizowana pętla → subagent.”
  • Twoje MCP mają wąską, świadomą powierzchnię narzędzi. Każdy serwer wystawia maksymalnie 5–10 dobrze nazwanych narzędzi ze ścisłymi schematami inputu, a nie 40 cienkich wrapperów wokół każdego endpointu źródłowej API. Aktywnie usuwałeś narzędzia, gdy agent ciągle ich nadużywał.
  • Podpiąłeś auth, rate limiting i obserwowalność zanim wdrożyłeś. OAuth lub scoped token dla zdalnych MCP, logi requestów które możesz grepować, alert cost/rate, gdy użycie skoczy. Żaden produkcyjny MCP nie chodzi na “API key w plaintexcie, jakoś to będzie”.
  • Re-ewaluujesz co kwartał. Co kwartał patrzysz, które własne MCP były używane, które zostały porzucone i czy te, które przeżyły, byłyby teraz lepsze jako skills lub slash commands — biorąc pod uwagę, jak ewoluowały te prymitywy.

Cokolwiek mniej — “raz przeszedłem przez tutorial” albo “mam serwer, ale ma 30 narzędzi i nigdy go nie zauth’owałem” — to mid-tier.

Dwa referencyjne SDK utrzymywane przez Model Context Protocol working group nadal są środkiem ciężkości i oba mocno się ustabilizowały przez 2025–2026.

  • Python SDK (modelcontextprotocol/python-sdk) — minimalna wspierana wersja to 1.2.0; większość produkcyjnych serwerów chodzi na 1.5+. Instalacja: uv add "mcp[cli]" httpx. Builder FastMCP (teraz w oficjalnym SDK po zmergowaniu z community projektu o tej samej nazwie) to ścieżka najmniejszego oporu — narzędzia to dekorowane funkcje Pythona, schematy są wnioskowane z type hints, a ten sam serwer chodzi po stdio albo Streamable HTTP z jednolinijkową zmianą transportu.
  • TypeScript SDK (modelcontextprotocol/typescript-sdk) — pakiet npm to @modelcontextprotocol/sdk (uwaga: nie @anthropic/* — Anthropic nie publikuje serwerów MCP na npm pod własnym scope). Instalacja: npm install @modelcontextprotocol/sdk zod. Tak jak Python SDK, pokrywa pełną specyfikację MCP — narzędzia, resources, prompty, sampling — i ma transporty stdio, SSE oraz Streamable HTTP.
  • Społecznościowe SDK istnieją dla Go, Rust, Java (Quarkus), C# i Kotlin. Użyj ich, jeśli Twój istniejący serwis jest w tym języku; w innym wypadku domyślnie wybierz Python lub TypeScript, gdzie dokumentacja, przykłady i tooling są najgłębsze.

Wyższego poziomu frameworki (FastMCP dla TS, MCP-Framework, EasyMCP, Higress) dokładają wzorce typu middleware, auth i observability na bazie tego SDK. Dla pierwszego MCP wybierz oficjalny SDK bezpośrednio — gdy będziesz mieć dwa-trzy serwery i poczujesz tarcie, dopiero wtedy sięgnij po framework.

Sposób deploymentu zależy od tego, kto musi wywoływać serwer.

  • Lokalny stdio. Oryginalny transport MCP. Serwer to binarka lub skrypt na Twoim hoście, klient (Claude Code, Cursor, Codex) odpala go jako child process i gada przez stdin/stdout. Dobry do osobistych narzędzi, rzeczy dotykających lokalnego filesystemu albo wrapperów wokół wewnętrznych CLI. Prawie zero ops; prawie zero shareability poza npx/uvx.
  • Zdalny HTTP (Streamable HTTP). Obecny standard dla współdzielonych i cloud-hosted serwerów MCP — zastępuje starszy transport oparty na SSE, który jest deprecated. Jeden endpoint HTTP, wsparcie streamingu, łatwo schować za OAuth. Każdy poważny publiczny serwer MCP w 2026 używa Streamable HTTP.
  • Cloudflare Workers. Najpopularniejszy hosting remote-MCP w 2026, bo praktycznie darmowy przy niskim wolumenie, globalnie rozproszony, a Cloudflare publikuje utrzymywany template plus integrację z Durable Objects do stanu sesji. Wzorzec endpointu to https://your-mcp-server.<account>.workers.dev/mcp, a własne MCP Cloudflare’a trzymają kanonical kształt {name}.mcp.cloudflare.com/mcp.
  • Vercel / Fly / Railway / własne infra. Wszystkie viable; wybierz to, co Twój team i tak już ogarnia. Specyfikacja MCP jest transport-agnostyczna, więc ten sam kod serwera chodzi na dowolnym hoście HTTP wspierającym streaming response.

Dla pierwszego zdalnego MCP komenda npm create cloudflare@latest -- my-mcp-server --template=cloudflare/ai/demos/remote-mcp-authless doprowadzi Cię z zera do wdrożenia w mniej niż dziesięć minut. Dopinaj OAuth, zanim wystawisz cokolwiek wrażliwego.

Te trzy prymitywy rozszerzeń zachodzą na siebie, ale każdy ma jasny sweet spot.

  • MCP wygrywa, gdy agent musi coś zrobić poza swoim kontekstem — fetchnąć live data, wywołać API, zapisać do bazy, sterować third-party SaaS-em. Narzędzia MCP są typowane, walidowane schemą, wywoływalne w środku pętli i reużywalne między wszystkimi MCP-aware klientami. Jeśli odpowiedź na “gdzie żyją dane?” to “wszędzie poza oknem kontekstu agenta”, to terytorium MCP.
  • Agent skill wygrywa, gdy masz playbook — kawałek wiedzy w kształcie promptu plus opcjonalne pliki referencyjne — który agent powinien załadować on-demand. Skills (konwencja SKILL.md+resources rozpowszechniona przez Anthropic agent-skills i marketplace skills w Claude Code) żyją jako tekst. Są właściwym kształtem dla “jak zrobić review PR w tym repo”, “jak napisać migrację”, “jak złożyć postmortem”. Bez zewnętrznego systemu, bez wywołań narzędzi — po prostu skompresowana ekspertyza, którą model wciąga, gdy jest relewantna.
  • Slash command wygrywa, gdy chcesz nazwany entry point, który triggeruje deterministyczną sekwencję wywołań narzędzi albo zafiksowany prompt. Slash commandy to keyboard shortcuts workflow agentów: /review-pr, /ship, /refactor-this-component. Często wołają narzędzia MCP i ładują skille, ale sam slash command to tylko trigger.
  • Subagent wygrywa, gdy masz długo działającą wyspecjalizowaną pętlę — code review, code exploration, doc writing — którą chcesz delegować, żeby orchestrator nie tonął w outpucie narzędzi. Subagenty zazwyczaj używają MCP i skills, ale mają własne okno kontekstu i własny wybór modelu (Haiku 4.5 do fan-out, Sonnet 4.6 do poważnego rozumowania).

Drzewo decyzyjne, skondensowane:

  1. Czy to zewnętrzny system, którym agent ma sterować?MCP.
  2. Czy to prompt + reference docs, który agent ma wciągnąć on-demand?skill.
  3. Czy to nazwany trigger dla istniejącej sekwencji?slash command.
  4. Czy to długa równoległa pętla z własnym kontekstem?subagent.

Gdy nie jesteś pewny, domyślnie wybieraj skill — najtaniej wysłać, najłatwiej skasować. MCP są najdroższym rozszerzeniem do utrzymania, więc próg powinien być najwyższy.

Minimalny serwer MCP w Pythonie z dwoma narzędziami, używający oficjalnego SDK:

server.py
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("releases")
@mcp.tool()
def list_recent_releases(repo: str, limit: int = 5) -> list[dict]:
"""Zwraca ostatnie release'y dla wewnętrznego repo."""
# tu wywołaj swoje wewnętrzne API
return [{"tag": "v1.2.3", "date": "2026-05-01"}]
@mcp.tool()
def promote_release(repo: str, tag: str, env: str) -> str:
"""Promuje release na staging lub prod."""
assert env in {"staging", "prod"}
# tu wywołaj swoje wewnętrzne narzędzie release
return f"promoted {repo}@{tag} to {env}"
if __name__ == "__main__":
mcp.run() # stdio domyślnie; przekaż transport="streamable-http" dla remote

Dwa narzędzia, wąska powierzchnia, typowane inputy, docstringi jako opisy. To jest kształt, do którego mierzysz w pierwszym MCP — a nie 30-narzędziowy wrapper.

  1. Wybierz jedno irytujące, powtarzalne zadanie, które dotyka zewnętrznego systemu. Nie wybieraj “owinę GitHub” — github MCP istnieje. Wybierz wewnętrzne admin tool, partner API, legacy bazę, jedyne staging CLI, którego wszyscy używają. Coś z wyraźnym inputem i wyraźnym outputem, co robisz co najmniej raz w tygodniu.

  2. Naszkicuj powierzchnię narzędzi najpierw na papierze. Spisz te 3–7 narzędzi, które agent ma wywołać: ich nazwy, inputy, outputy. Jeśli przekroczysz 10 — stop, podziel na dwa MCP albo zepchnij ogon do skills. Wąska powierzchnia to sposób, w jaki agent zostaje dobry w wywoływaniu Twojego serwera.

  3. Wystartuj z oficjalnego templatu. Lokalny stdio: uv init my-mcp && uv add "mcp[cli]" dla Pythona albo wzorce npm init mcp-server@latest dla TypeScripta. Remote: npm create cloudflare@latest -- my-mcp-server --template=cloudflare/ai/demos/remote-mcp-authless to ścieżka najmniejszego oporu.

  4. Zaimplementuj narzędzia ze ścisłymi schematami inputu. Użyj type hints (Python) lub Zod schemas (TS). Odrzucaj złe inputy wcześnie — agent uczy się z Twoich error messages, więc rób je ostre (“tag musi pasować do ^v\\d+\\.\\d+\\.\\d+$”, a nie “invalid input”).

  5. Najpierw przetestuj w MCP Inspector, potem w realnym kliencie. npx @modelcontextprotocol/inspector daje Ci UI, które listuje narzędzia, pozwala je wywołać z sample inputami i pokazuje raw protocol traffic. Wyczyść wywołania w Inspectorze, zanim wskażesz Claude Code lub Cursor na ten serwer.

  6. Podepnij auth, zanim podepniesz produkcyjne dane. Dla lokalnych stdio MCP przekazuj sekrety przez env vary z konfigu klienta — nigdy nie hardcoduj. Dla zdalnych MCP postaw OAuth z przodu (template Cloudflare zawiera przykład OAuth na GitHubie) albo co najmniej scoped, rotowalny bearer token w headerze Authorization.

  7. Dodaj rate limiting i logging. Nawet osobisty MCP powinien logować każde wywołanie narzędzia z timestampem, nazwą narzędzia, hashem inputu i wynikiem. Cloudflare Workers daje Ci rate limiting per-IP/token w kilku linijkach configu; lokalnie soft cap 100 wywołań/minutę wystarczy, żeby złapać pętle agentów, zanim wywalą Ci quota API.

  8. Zarejestruj MCP w daily-driver klientach. Claude Code: dodaj do .mcp.json dla projektu albo ~/.claude.json globalnie, używając udokumentowanej składni claude mcp add z --transport http dla zdalnych serwerów. Cursor i Codex mają ekwiwalenty UI. Użyj serwera do realnego zadania w ciągu 48 godzin — jeśli nie użyjesz, ubij go teraz i przemyśl.

  9. Napisz README i linijkę “kiedy tego używać”. Jeden akapit w dotfiles albo team docs: co MCP robi, kiedy po niego sięgnąć, kiedy nie. To jest to, co stop future-you (albo team-mate’a) od odbudowania tego samego za sześć miesięcy.

  10. Iteruj powierzchnię narzędzi. Po tygodniu używania spójrz w log wywołań. Narzędzia, których nigdy nie wywołano: skasuj je. Narzędzia, które agent nadużył: zmień nazwę albo zaostrz schemat inputu. Narzędzia, które są wołane ciągle z tymi samymi argumentami: rozważ promocję do slash commanda.

  • Za szeroka powierzchnia narzędzi. 40-narzędziowy MCP prawie zawsze jest gorszy niż 6-narzędziowy. Każde dodatkowe narzędzie to więcej kontekstu, który model musi przeczytać w każdej turze, więcej szans na wybór złego narzędzia i więcej kodu do utrzymania. Jeśli owijana API ma 200 endpointów, Twój MCP wystawia tych 6, które faktycznie liczą się w Twoim workflow. Dokładaj kolejne tylko, gdy poczujesz konkretny ból.
  • Brak auth na zdalnym MCP. “To tylko osobisty serwer” — tak właśnie wyciekają wewnętrzne credentiale. Każdy zdalny endpoint potrzebuje OAuth albo przynajmniej scoped, rotowalnego bearer tokenu, plus IP allowlistingu, jeśli grupa odbiorców jest mała. Traktuj endpointy MCP dokładnie tak, jak traktujesz wewnętrzne admin API.
  • Brak rate limitingu. Agenty się zapętlają. Bug w prompcie może wywołać list_releases 400 razy na minutę. Jeśli to wjedzie w Twoją wewnętrzną API bez capa, sam sobie zDOSowałeś infra. Cap na warstwie MCP, oddzielnie od limitów upstream.
  • Wpychanie promptów i playbooków do MCP zamiast skills. Jeśli Twoje “narzędzie” to tak naprawdę “wyrenderuj ten prompt, przeczytaj te docsy, wyrzuć ten format”, to powinien być skill, nie MCP. Skille są tańsze do napisania, łatwiejsze do update, wersjonowane razem z projektem i nie palą tokenów tool-context.
  • Owijanie rzeczy, które już mają dobre MCP. GitHub, Linear, Sentry, Cloudflare, Context7, Stripe, Notion, Slack, Figma — wszystkie mają first-party lub kanoniczne community MCP. Budowanie własnego duplikatu to zmarnowana robota plus tracisz każdy upstreamowy update specyfikacji/auth. Rezerwuj własne MCP dla systemów, których nikt inny nie owinął.
  • Wdroż raz, nigdy nie sprawdzaj. Własne MCP rdzewieją — API się zmieniają, tokeny auth wygasają, oryginalny use case się rozwadnia. Bez kwartalnego review zbierasz cmentarzysko półdziałających serwerów, które dezorientują agenta i zaśmiecają listę narzędzi.
  • Potrafisz z głowy wymienić co najmniej dwa serwery MCP, które osobiście napisałeś i zdeployowałeś.
  • Co najmniej jeden z nich jest remote (Cloudflare Workers, Vercel albo własne infra) i team-mate lub agent w chmurze go używał.
  • Każdy z Twoich MCP wystawia ≤10 narzędzi, z typowanymi schematami inputu i krótkimi opisami.
  • Masz spisaną regułę (w CLAUDE.md, dotfiles albo team handbooku) dla MCP vs skill vs slash command vs subagent.
  • Każdy zdalny MCP ma auth (OAuth lub scoped token) i log requestów, który możesz grepować.
  • Użyłeś MCP Inspector do walidacji serwera, zanim wskazałeś na niego coding agenta.
  • Usunąłeś co najmniej jedno narzędzie z jednego z MCP, bo agent ciągle je nadużywał.
  • Potrafisz wskazać jedno rozszerzenie, które świadomie wdrożyłeś jako skill albo slash command, a nie MCP, bo drzewo decyzyjne wskazało tam.
  • Re-audytujesz listę własnych MCP co kwartał i ubiłeś co najmniej jeden, który przestał się zwracać.