Claude Code: trzy nieoczywiste usprawnienia (gość: Jakub Mrugalski)

2026-05-31 • Mikołaj Abramczuk • AI po polsku •wywiad •waga 4/5 •34 min czytania

Trzy techniki dla użytkowników Claude Code: własny serwer MCP w n8n, skille Superpowers z brainstormingiem i TDD oraz bezpieczny tryb YOLO w piaskownicy Bubblewrap. Praktyczny poradnik kontroli nad agentem.

Robocza publikacja redakcyjna na podstawie publicznego transkryptu YouTube. Źródło: YouTube.

O czym jest ten film

  1. Rozmowa Mikołaja Abramczuka z Jakubem Mrugalskim — specjalistą od cyberbezpieczeństwa, współtwórcą szkolenia AI Devs i autorem newslettera Unknown News — o trzech sposobach przeniesienia pracy z Claude Code na wyższy poziom.
  2. Technika pierwsza: n8n jako kreator własnych serwerów MCP — zwykły workflow złożony z klocków staje się zestawem narzędzi, po które agent sięga podczas rozmowy.
  3. Własny serwer zamiast oficjalnych konektorów daje kontrolę: agent może np. tylko odczytywać zadania z jednego projektu Todoista, a klucze API nigdy nie opuszczają naszego serwera.
  4. Skuteczność doboru narzędzi sterują opisy w węzłach — ręcznie dopisane „używaj, gdy pytam o…” oszczędza tokeny i zapobiega błędnym wyborom (przykład: trzy kalendarze rodzinne zamiast jednego).
  5. Narzędzia można parametryzować — agent sam poda adres kanału RSS albo wybierze właściwy kalendarz; jednym narzędziem można też uruchamiać całe, rozbudowane automatyzacje.
  6. Publicznie wystawiony serwer MCP trzeba zabezpieczyć tokenem — nietypowy adres to nie ochrona, a udane polecenie dodania konektora nie dowodzi, że połączenie działa.
  7. Ten sam serwer można podpiąć jako konektor w przeglądarkowym Claude i dzięki temu realizować pojedyncze czynności modelami innych dostawców, np. GPT-5 od OpenAI.
  8. Technika druga: Superpowers — oficjalny pakiet skili Antropica z brainstormingiem, planowaniem, wykonywaniem planów i tworzeniem skilli metodą TDD.
  9. Brainstorm zamienia bardzo lakoniczny prompt w pełną specyfikację, dopytując o wszystko, czego nie doprecyzowaliśmy; wygenerowane skille da się przenieść do Claude web, ChatGPT czy n8n.
  10. Technika trzecia: tryb YOLO (pomijanie pytań o zgodę) bezpieczniejszy dzięki Bubblewrap — własnej piaskownicy systemowej z precyzyjnie podmontowanymi katalogami; przykład: system publikowania notatek wprost do przeglądarki przez nginxa.

10 najważniejszych takeaways — z kontekstem zastosowania

1.Buduj własne serwery MCP w n8n, zamiast podpinać cudze

Na czym polega: Gotowe serwery MCP — choćby oficjalny od Todoista — dają agentowi pełen wachlarz możliwości: przeglądanie wszystkich notatek, tworzenie zadań i projektów, wyszukiwanie. Własny serwer w n8n wystawia dokładnie te operacje, na których nam zależy, i nic więcej.

Jak stosować: W nowym workflow wybierz węzeł „MCP Server Trigger”, dorzuć klok usługi (np. Todoist z akcją odczytu), kliknij „Publish” i podepnij serwer w Claude Code poleceniem claude mcp add --transport http <nazwa> <adres>. Cała konfiguracja trwa dosłownie chwilę.

Na co uważać: Kopiuj produkcyjny adres URL z n8n, nie testowy — w domyślnie podświetlonym linku jest słowo „test”. Po każdej zmianie workflow trzeba ją opublikować i w Claude wykonać „reconnect”, inaczej asystent nie zobaczy nowych narzędzi.

2.Ogranicz uprawnienia agenta do rzeczywistego minimum

Na czym polega: Zamiast dostępu do całego konta wystaw jedną operację (np. sam odczyt) i jeden projekt czy kalendarz. Klucze API zostają po stronie n8n na naszym serwerze — w przeciwieństwie do nieoficjalnych serwerów MCP obcych osób, w których nie wiadomo, co dzieje się z poświadczeniami i cudzym kodem.

Jak stosować: W konfiguracji węzła ustaw filtr na konkretny identyfikator projektu i zablokuj akcje zapisu, dopóki realnie ich nie potrzebujesz. Tak zbudowany „mózg” można bezpiecznie odpytywać nawet w trybie pełnej automatyzacji.

Na co uważać: Operacja „tylko do odczytu” wciąż udostępnia dane — nie podpinaj projektów z informacjami poufnymi tylko dlatego, że łatwo je zaznaczyć na liście.

3.Ręczny opis narzędzia steruje wyborem agenta

Na czym polega: Model dobiera narzędzie po jego nazwie i opisie. Domyślne opisy bywają tak ogólne, że asystent odpytuje wszystko po kolei — na przykład scala trzy kalendarze rodzinne zamiast zajrzeć do jednego — i przepala tokeny. Dopisane ręcznie „używaj tego, gdy pytam o rzeczy do zrobienia” radykalnie podnosi trafność.

Jak stosować: We właściwościach węzła wypełnij pole opisu warunkiem użycia w języku naturalnym, łącznie z mapowaniem potocznych sformułowań na konkretne źródło danych. Dla wywołań automatycznych, zawsze identycznych, można wręcz zapisać, że dane narzędzie służy wyłącznie do tej jednej czynności.

Na co uważać: Opis narzędzia ma limit długości i sam zużywa tokeny — szerszą wiedzę (np. listę dostępnych kalendarzy) lepiej trzymać w CLAUDE.md albo w prompcie, a nie w opisie węzła.

4.Parametryzuj narzędzia i łańcuchuj automatyzacje

Na czym polega: Pole, w które zwykle wpisuje się adres kanału RSS czy nazwę kalendarza, można oznaczyć jako wypełniane przez model — wtedy agent w trakcie rozmowy sam poda właściwą wartość. Z kolei węzeł „Call n8n workflow” pozwala wystawić jedno narzędzie, które pod spodem uruchamia całą rozbudowaną pajęczynę automatyzacji z własnymi zmiennymi wejściowymi.

Jak stosować: Parametru używaj tam, gdzie zakres danych zależy od pytania — przeszukiwany okres, wybór kalendarza, adres kanału. Dostępne opcje opisz w prompcie, a decyzję zostaw modelowi.

Na co uważać: Swoboda wyboru wymaga jasnych opisów; inaczej asystent podstawia parametr „z grubsza pasujący” do niewłaściwego zasobu. W API bywają też pułapki semantyczne — np. w Todoiście priorytety w API są odwrócone względem interfejsu, więc w opisie warto dopisać instrukcję zamiany kolejności.

5.Publiczny punkt MCP zawsze chroń tokenem

Na czym polega: Otwarty serwer MCP na publicznym adresie może odpytywać każdy, kto go namierzy. Poleganie na tym, że „nikt nie zna adresu”, to nie zabezpieczenie — wystarczy nagrany ekran albo trafione zgadnięcie. n8n pozwala dodać prostą autoryzację tokenem, a Claude Code przekazuje go nagłówkiem Authorization: Bearer.

Jak stosować: W ustawieniach serwera MCP w n8n włącz token, a w Claude usuń dotychczasowe wpisanie (claude mcp remove) i dodaj je na nowo z przełącznikiem --header przenoszącym token.

Na co uważać: Komunikat o zapisaniu konfiguracji do pliku oznacza tylko tyle, że plik się edytował. O tym, że połączenie faktycznie działa, świadczy wyłącznie zielony status serwera na liście MCP w Claude — to trzeba sprawdzić osobno.

6.Ten sam serwer działa w Claude web i z innymi modelami

Na czym polega: Serwer MCP można dodać jako konektor także w przeglądarkowym Claude (Settings → Connectors). Dzięki temu pojedyncza czynność — na przykład „przeredaguj ten tekst” — bywa realizowana przez innego dostawcę, np. GPT-5, choć cała sesja biegnie w Claude. Działa to i w odwrotną stronę: w ChatGPT fragment zadania może wykonywać Opus.

Jak stosować: Zbuduj w n8n akcję, która pod spodem woła API wybranego dostawcy (własny klucz, ewentualnie przez OpenRouter), opublikuj ją i podepnij jako konektor. Nazwa i opis akcji powinny jednoznacznie mówić, do czego służy.

Na co uważać: Klucze dostępowe trzymaj w konfiguracji n8n, po stronie serwera — nie w kliencie. Mieszanie dostawców opłaca się przy konkretnych, powtarzalnych zadaniach, a nie jako globalna podmiana modelu.

7.Superpowers — jeden pakiet, cała metodyka pracy

Na czym polega: Instalowana jednym poleceniem wtyczka dodaje zestaw oficjalnych, zoptymalizowanych pod Claude skili Antropica: „Brainstorm” (doprecyzowanie celu), „Writing Plans” (plany), „Writing Skills” (tworzenie skilli metodą TDD), „Executing Plans” (wykonanie), code review, TDD jako podmoduł i podagentów rozbijających plan na mniejsze zadania.

Jak stosować: Sięgaj po niego przy zadaniach, których nie umiesz doprecyzować od razu: najpierw brainstorm, potem plan, na końcu wykonanie. Każdy z etapów można przerwać i skorygować — „miałem na myśli inaczej” jest obsługiwane.

Na co uważać: Skile bardzo intensywnie dopytują o szczegóły. Przy ograniczonym budżecie tokenów koszt sesji wyraźnie rośnie — warto używać tego pakietu tam, gdzie liczy się jakość rezultatu, a nie oszczędność każdego przebiegu.

8.Brainstorm zamienia słaby prompt w pełną specyfikację

Na czym polega: Bardzo lakoniczny opis — „chcę load balancer, żeby ruch skakał między kontenerami” — wtyczka rozbudowuje serią pytań o wszystko, czego zabrakło: algorytm rozdziału ruchu, porty, źródło plików, strukturę sieci. Efektem jest projekt z diagramem, plikiem Docker Compose i konfiguracją, uwzględniający też pułapki, na które sami byśmy nie wpadli (jak problemy skalowania klastra pocztowego).

Jak stosować: Korzystaj wtedy, gdy wiesz, co chcesz osiągnąć, ale nie znasz zagrożeń. Końcowy krok — pisanie skryptów i konfiguracji — można zatrzymać słowem „stop”, a gotowy projekt wyeksportować jako notatkę (np. do Obsidiana) i zlecić komuś innemu.

Na co uważać: Model bazuje głównie na własnej wiedzy, nie zawsze na świeżej dokumentacji. Na tanim modelu jakość pytań bywa różna — przy wymagającym temacie lepiej pracować na mocniejszym i samodzielnie podać źródła.

9.Skille tworzone metodą TDD są przenośne poza Claude

Na czym polega: „Writing Skills” prowadzi przez pełny cykl: najpierw dopytuje o oczekiwany wynik (werdykt binarny? z uzasadnieniem? z miarą pewności?), potem destilluje zasady z przygotowanej próbki danych, dodaje kilkanaście reprezentatywnych przykładów i obraca to testami — czerwoną i zieloną fazą — dopóki skuteczność nie będzie zadowalająca.

Jak stosować: Przygotuj próbkę danych (np. sto tytułów z archiwum), opisz, co ma być wynikiem, i pozwól narzędziu dopytać o resztę. Gotowy skill skopiuj do Claude web w niezmienionej formie, a w narzędziach bez skilli — jak ChatGPT czy automatyzacje n8n — odetnij nagłówek i użyj samych reguł jako długiego prompta albo reguł klasyfikatora.

Na co uważać: Same reguły bez przykładów bywają za słabe, a wklejanie całego zbioru treningowego do definicji skilla przepala tokeny. Złoty środek z filmu: destylacja zasad plus dziesięć–dwadzieścia przykładów.

10.Tryb YOLO tylko w piaskownicy — Bubblewrap

Na czym polega: Uruchomienie Claude’a tak, by o nic nie pytał, jest sensowne co najwyżej na jednorazowej, dedykowanej maszynie — tym bardziej że asystent domyślnie odmawia pracy na koncie root. Bubblewrap tworzy mikrokontener, w którym agent jest „prawie rootem”: widzi wyłącznie jawnie podmontowane katalogi, w zadanym trybie odczytu lub zapisu, z osobnym katalogiem tymczasowym. Wbudowany sandbox Claude’a zamyka go w jednym katalogu projektu; własny wrapper pozwala montować ich wiele, także zasoby NFS.

Jak stosować: Przygotuj skrypt uruchamiający Claude przez Bubblewrap z listą montowań; współdziel katalog domowy z konfiguracją, by rozszerzenia i pamięć były wspólne dla wersji opakowanej i zwykłej. Efekt pokazany w filmie: katalog „dane” podmontowany jednocześnie do piaskownicy i do nginxa w Dockerze zamienia Claude’a w system publikowania notatek dostępnych od razu w przeglądarce.

Na co uważać: Piaskownica ogranicza agenta, ale nie chroni danych, do których dostęp świadomie nadałeś — listę montowań projektuj tak, żeby ewentualna szkoda nie sięgała poza wyznaczone katalogi. Obejście blokady roota (deklaracja „to sandbox, zaufaj mi”) łamie zabezpieczenie i zostaw tylko na maszynach, które można wyrzucić.

Redakcyjne tłumaczenie

(Informacja dodatkowa: MCP, czyli Model Context Protocol, to otwarty standard łączenia modeli AI z zewnętrznymi narzędziami i danymi. n8n to popularne narzędzie typu no-code do budowy automatyzacji, które można uruchomić na własnym serwerze.)

Wstęp

Mikołaj Abramczuk: Cześć, moi drodzy. Dzisiaj zapraszam na rozmowę z Jakubem Mrugalskim — specjalistą od cyberbezpieczeństwa, współtwórcą szkolenia AI Devs i autorem kultowego newslettera Unknown News. Omówiliśmy trzy sposoby — mniej i bardziej zaawansowane — na przeniesienie współpracy z Claude Code na wyższy poziom. Rozdziały znajdziecie w opisie filmu, a ja już nie przedłużam. Kuba, co pokazałbyś jako pierwsze?

Część 1. Własny serwer MCP zbudowany w n8n

Jakub Mrugalski: Chciałbym pokazać, jak zintegrować Claude Code — albo dowolnego innego agenta AI — z n8n. Od razu nasuwa się pytanie: po co to robić, skoro większość rzeczy da się załatwić kodem albo poprosić agenta, żeby ten kod napisał? Konkretnie chciałbym pokazać, jak w n8n błyskawicznie tworzyć serwery MCP.

Mikołaj: Bardzo chętnie posłucham, patrząc na otwarty ekran.

Jakub: To świeża instalacja n8n — wykonałem w niej kilka drobnych operacji, żeby wszystko szybciej skonfigurować — i tworzę nowy workflow. Klockiem startowym musi być serwer MCP, więc wpisuję „MCP” i dostaję do wyboru klienta albo serwer z regułą wyzwalającą. Wybieram serwer i w zasadzie na tym kończy się cała konfiguracja. Mamy gotowy serwer MCP. Trudne nie było — do zobaczenia w następnym odcinku. A tak poważnie: serwer coś przecież musi robić, więc dodajmy narzędzie. Ja często korzystam z Todoista, więc dodaję Todoista.

Mikołaj: Ja również, ja również.

Jakub: Można zapytać: po co komu MCP dla Todoista, skoro Todoist wystawia własny, oficjalny serwer, podpinany jednym poleceniem? I właśnie o to chodzi — pytanie brzmi, jak chcemy z tego korzystać i jak bardzo ufamy agentom. Podłączając oficjalne MCP, dajemy agentowi możliwość przeglądania wszystkich notatek, tworzenia zadań i projektów, wyszukiwania — wszystko. Takim agentem można przypadkiem rozjechać całe repozytorium zadań. A jeśli do tego włączymy tryb YOLO, czyli „rób co chcesz, niczego nie będę akceptować”, robi się po prostu niebezpiecznie.

Zróbmy wersję ograniczoną. Nie chcę, żeby agent cokolwiek tworzył — chcę, żeby zadania tylko wyciągał. Dodaję więc akcję pobierania wielu rekordów, ustawiam zwrot wszystkich, ale z jednego projektu. Nie chcę, żeby łaził po wszystkich moich projektach — mam tam rzeczy prywatne, może biznesowe, może firmową tajemnicę. Wybieram konkretny projekt — przy okazji zobaczycie, jakie mam projekty — i wykonuję krok. Rekordy się pobierają; w tym projekcie są między innymi filmy do nagrania na YouTube, czym dawno się nie zajmowałem.

Mikołaj: …i od razu możemy zaprosić cię na twój kanał.

Jakub: Jak najbardziej. Teraz chcę to podpiąć pod Claude Code. Jestem połączony z jednym z moich Mikrusów — prostym serwerkiem z dwoma gigabajtami RAM-u, na którym stoi Claude. Nie będę przechodził przez samą instalację, bo większość sobie z nią poradzi. Uruchamiam Claude’a i podpinam serwer MCP: najpierw publikuję to, co mam w n8n. Uwaga — n8n domyślnie podaje link testowy, a ja biorę produkcyjny. Następnie w Claude dodaję serwer, podaję transport HTTP, nazwę — mogła być „todoist”, ale nazwałem to „brain”, bo zamierzam dorzucić więcej funkcji — i skopiowany adres. Upewniam się, że w adresie nie ma słowa „test”. Jeśli nie zrobiłem literówki, dostanę komunikat, że konfiguracja została zapisana do pliku.

Mikołaj: A dla tych, którzy panicznie boją się terminala — przecież można po prostu włączyć Claude’a i powiedzieć: „dodaj to MCP”…

Jakub: Jak najbardziej. Podajesz link, akceptujesz — zrobi dokładnie to samo.

Mamy podpięte MCP. Widzę mojego „brain” na liście z zieloną plakietką „connected”, czyli wszystko gra. Mogę więc pytać: „podaj mi trzy najnowsze zadania z Todoista”. Claude nie ma pojęcia, czym jest Todoist, ale ma podpięte zewnętrzne narzędzie, więc wydedukuje, że serwer MCP pewnie coś takiego zawiera. Znajduje w „brainie” funkcję o mówiącej samej za siebie nazwie i po niej ją kojarzy. Pyta, czy zgadzam się na jej użycie — zresztą przy oryginalnym MCP od Todoista też za każdym razem potwierdalibyśmy każde zaglądnięcie czy utworzenie zadania. Akceptuję i czekam.

Mikołaj: Rodzi mi się pytanie: czy budowanie takiego MCP to głównie narzucanie ograniczeń, czy nadaje się do czegoś jeszcze?

Jakub: Do czegoś jeszcze. Po pierwsze — tak, ograniczenia. Po drugie — możemy w ten sposób pracować nad konektorami do różnych rzeczy: firmowego Slacka, Google Drive, Dropboxa. Można oczywiście kazać Claude’owi napisać konektor albo poszukać nieoficjalnych serwerów, ale wtedy korzystamy z cudzego kodu, nie wiedząc, co siedzi w środku, i z cudzego serwisu, nie wiedząc, co dzieje się z naszymi kluczami. A tu robimy sobie taki mały „brain” i dokładnie wiemy, jakie są bariery i czego nie da się przekroczyć. Wiemy też, że klucze dostępowe nigdzie nie zostały wysłane — siedzą na jednym z Mikrusów.

Działa: pobrały się trzy filmy do nagrania, z datami dodania, terminami, etykietami i opisami. Nasz serwer niewiele jeszcze potrafi, więc dodajmy coś więcej — na przykład Wikipedię. Moglibyśmy napisać parser, który skrapuje stronę i zamienia tekst na Markdown, ale po co wymyślać koło na nowo, skoro jest gotowy klocek? Po dodaniu narzędzia trzeba zrobić dwie rzeczy: opublikować serwer i — skoro Claude nie ma pojęcia, że Wikipedia się pojawiła — wejść w listę MCP, wybrać „brain” i kliknąć „reconnect”. Wtedy Claude pobiera nowe definicje. I już mogę pytać: „sprawdź w Wikipedii, kim jest Lech Wałęsa, maksymalnie cztery zdania”. Nie chodzi o jakość odpowiedzi, tylko o to, żeby nowe narzędzie zostało użyte. Claude dopytuje, czy w „brainie” wolno mu skorzystać z Wikipedii — pozwalam. I proszę: odpowiedź przyszła na żywo z Wikipedii, a nie z pamięci modelu. Skąd to wiem? W n8n, w historii wykonań, widać, co zostało uruchomione ostatnio: Wikipedia, a wcześniej pobranie danych z Todoista.

Mikołaj: Zauważyłem, że w ogóle nie konfigurowałeś tego węzła — po prostu podpiąłeś gotowiec.

Jakub: Dokładnie. Jeszcze jedna rzecz: skąd Claude wie, które narzędzie kiedy wybrać? Po nazwach węzłów — „Wikipedia”, „Todoist”. Ale można wejść w ustawienia węzła i wypełnić pole opisu. Ktoś, kto pracował niskopoziomowo z API modeli, wie, że da się zdefiniować, kiedy danego narzędzia należy użyć. Ja najczęściej nie piszę, tylko dyktuję, więc mówię na przykład: „używaj tego, gdy pytam o zadania z Todoista albo o rzeczy do zrobienia”. Zapisuję, publikuję, w Claude znowu reconnect — i teraz pytanie o „trzy rzeczy do zrobienia o najwyższym priorytecie” trafia prosto do Todoista, bo to sformułowanie zdefiniowałem w opisie klocka.

Mikołaj: A z twojego doświadczenia: kiedy opisywać ręcznie, kiedy zostawiać automatyczne?

Jakub: Zawsze warto opisać ręcznie, bo zależy nam na wysokiej skuteczności doboru narzędzi. Przy dwóch — liście zadań i Wikipedii — kolizji raczej nie będzie. Ale mam „brain” z dostępem do kalendarzy Google: szkolny kalendarz dzieci, mój i mojej żony. Ja wiem, o który pytam, ale agent nie ma pojęcia — najczęściej przeszukuje wszystkie i scala wyniki. Krótko mówiąc, przepala tokeny. Jeśli opiszę konkretnie — o sprawy szkolne pytaj tego kalendarza, o wyjazdy i konkretne projekty — żony, wszystko pozostałe domyślnie — mój — opisy stają się bardzo skuteczne. Weźmy też pod uwagę, że z serwerem MCP nie zawsze rozmawia człowiek. Czasem odpytuje go automat, wysyłając w kółko te same polecenia. Po co agent ma wtedy zastanawiać się nad wyborem narzędzia? Można mu po prostu wskazać: do tej czynności zawsze używaj tego.

Mikołaj: Jeśli się nie mylę, da się jeszcze podpiąć wywołanie innej, wcześniej zbudowanej automatyzacji?

Jakub: Tak, jest węzeł do wywoływania całych workflow. Ktoś powie: tu mogę podpiąć tylko jedno narzędzie — a my możemy zbudować wielką pajęczynę automatyzacji i ją wywoływać. Workflow zwykle ma zmienne wejściowe i można je wykorzystywać dalej, więc całkiem fajnie się to układa.

Z rzeczy, z których często korzystam: RSS. Dodaję klocek do czytania kanałów i podaję ten, który mnie interesuje — na przykład newsy z Unknown News. Wklejam adres, wykonuję krok testowy. Narzędzie ostrzega: „ponad megabajt danych, nie wyświetlę ci tego w przeglądarce, bo ci ją rozbije”. Nie szkodzi — przeglądarka może, agent sobie poradzi. Klocek dostał automatyczny opis, czyli — szału nie ma. Gdybym zapytał „co nowego na Unknown News?”, agent najpierw sięgnąłby po Wikipedię, potem po zadania z Todoista — wszędzie nie tam. Dopisuję więc: „używaj tego narzędzia, gdy pytam o nowości z Unknown News albo o wieści ze świata IT”. Opis przegadany, ale chodzi o ideę. Publikuję, wracam do Claude’a, reconnect — i to jest częste zaniedbanie: bez odświeżenia brain nie działa, a agent odpowiada z własnej, wewnętrznej wiedzy.

Pytam: „podaj trzy pierwsze linki z najnowszego wydania Unknown News”. Claude łączy się z brainem, ten pobiera dane, potwierdzam użycie czytnika RSS — i czekamy.

Mikołaj: Bardzo fajnie to wygląda. Zaczynamy wizualnie rozumieć, jak agent działa, i czujemy, że nie jest do końca samodzielny — że jednak mamy nad nim pieczę.

Jakub: Zgadza się. Zwróćmy uwagę, że Claude użył do tego narzędzia jq do parsowania danych — plik jest spory, więc go porządkuje i tnie, żeby nie przepalać tokenów. Trochę to trwa… no i mamy linki z ostatniego wydania — rozwiązanie działa. A teraz pytanie do ciebie, Mikołaju: co jest nie tak z tym całym serwerem MCP?

Mikołaj: Ojejku, się zestresowałem… Z bezpieczeństwa?

Jakub: Zdecydowanie. To serwer otwarty — coś, co ludzie najczęściej stawiają. Wystarczy, że ktoś znajdzie, gdzie stoi, a nie jest trudno: mam publiczny adres, a całe zabezpieczenie opiera się na tym, że „tego adresu nikt nie zna”. Uznajmy, że nikt go na filmie nie widział. Ale dopóki nie zmienię adresu, każdy może grzebać w moim Todoiście. Kiepsko. Trzeba dodać uwierzytelnianie — na przykład zwykły token. Wymyślamy sobie nowy, nazwijmy go „token Jakuba”, z super tajnym hasłem „trololo”. Zapisuję i mam logowanie — serwer przestaje być otwarty na świat. Teraz rekonfiguruję Claude’a: usuwam brain, dodaję go ponownie, tym razem z nagłówkiem autoryzacji „Bearer” i tokenem. Bez tego tokenu nikt nam w niczym nie pogrzebie — nawet z Wikipedii nie skorzysta.

I ważna rzecz: to, że wpis trafił do pliku konfiguracyjnego, nie znaczy, że działa. To znaczy tylko, że plik się edytował — nic więcej. Trzeba wejść do Claude’a i sprawdzić zieloną strzałkę przy serwerze. Jest — więc jesteśmy podłączeni bezpiecznie, o to chodziło. Nie wystawiamy swoich wewnętrznych narzędzi otwartych na świat i nie opieramy się na tym, że w adresie siedzi jakiś identyfikator, którego nikt nie trafi — to prawie jak trafienie szóstki w totka. A przecież wystarczy, że ktoś akurat nagrywa ekran — i właśnie wyciekł.

Mikołaj: Poza tym człowiek nie zawsze trafia — czasem po prostu zgaduje.

Jakub: Oczywiście. Do czego takie MCP jeszcze? Można podłączyć odpytywanie AI. Ktoś powie: „moment, jestem w środku agenta AI i podłączam kolejne AI? Incepcja!”. Trzeba sobie zadać pytanie, jak chcemy tego używać. Pracuję w Claude Code na modelach Antropica, ale chciałbym, żeby generowanie tekstu robił zupełnie inny dostawca — OpenAI, GPT-5. Da się? Są konektory, jest OpenRouter, można poszaleć. Tylko że ja nie chcę globalnie zmieniać dostawcy — chcę, żeby jedno zadanie wykonywał ktoś inny. Nie będę tego teraz konfigurował, bo trochę by to zajęło. Opublikuję zmiany, skopiuję link produkcyjny i pokażę coś ciekawego.

Wchodzę do Claude’a w wersji przeglądarkowej, w ustawieniach znajdę konektory. Dodaję nowy, nazywam go znowu „brain”, wklejam adres, dodaję. Jeśli nazwa świeci na czarno, a nie jest przekreślona — konfiguracja się udała. Zakładam nowy czat, podpinam konektor i pytam: „sprawdź w mojej aplikacji Todoist rzeczy do zrobienia, wyświetl tylko trzy pierwsze wyniki”. Claude połączy się z brainem stojącym na Mikrusie i odpyta serwer MCP — ale najpierw zapyta o pozwolenie, żeby czegoś nie nabroić. Wybieram „zawsze ufam” — w końcu to moje dzieło — i agent zaczyna grzebać.

A konektor wcale nie musi prowadzić do Todoista czy RSS-ów. Może prowadzić do innych dostawców. Możemy mieć akcję „przeredaguj mi ten tekst”, która pod spodem używa zupełnie innego modelu. Mówiąc prościej: jak ktoś kocha ChatGPT, nie ma problemu, żeby fragment zadania w ChatGPT realizował Opus. Da się. I w drugą stronę — uwielbiasz Opusa, a streszczenia wolisz w jakimś małym, tanim modelu. Też się da.

Mikołaj: Powiedziałeś „pierwszych”, a on zrozumiał „najstarszych” i pobrał je po dacie — stąd ta kolejność.

Jakub: Właśnie. I tu kolejna pułapka: w API Todoista priorytety są odwrócone — jedynka to najmniej ważne, a najwyższa liczba najważniejsze — a w interfejsie użytkownika jest odwrotnie. Trzeba to wytłumaczyć w opisie narzędzia: „gdy pobierasz dane, odwracaj kolejność priorytetów”. Podobnie z RSS: a gdybym chciał czytać dowolny kanał na świecie? Zmieniam opis: „używaj tego narzędzia, gdy próbuję odczytać dowolny kanał RSS”, a w polu, w którym stał konkretny adres, klikam magiczną ikonkę — wartość będzie wypełniana przez model. Publikuję. Jeśli model zechce skorzystać, serwer dopyta: „a który kanał?”, model poda adres i zostanie on podstawiony jako parametr. W ten sposób parametryzujemy różne rzeczy. Nie będę podłączał kalendarza, ale wyobraźcie sobie narzędzie pobierające wydarzenia: z którego kalendarza? Możemy pozwolić, by model sam wybrał — powiedzmy mu w prompcie, jakie kalendarze mamy do wyboru, a on zdecyduje.

Mikołaj: A to opisywałoby się w prompcie czy w opisie narzędzia?

Jakub: Nie pakowałbym wszystkiego do opisu narzędzia. Można to dać do CLAUDE.md, do skilla, do czegokolwiek — bo opis ma ograniczenie rozmiaru, a do tego przepala tokeny. Po co? Chodzi też o zakresy danych: zamiast sztywnego „od dziś do tygodnia w przód” można pozwolić modelowi decydować samemu. Zapytam, gdzie byłem na wakacjach w zeszłym roku — niech wybierze tamten rok, pobierze zadania i poszuka w nich czegoś pasującego do wakacji. Da się to w pełni sparametryzować.

Tak w skrócie wygląda używanie MCP. Nie musimy z tego korzystać, ale jest naprawdę wygodne — zwłaszcza gdy nie chcemy wymyślać koła na nowo. Widzieliście przecież, ile minut zajęło podłączenie czterech serwisów.

Mikołaj: I to, co mówiłeś o innych modelach do konkretnych zadań, to kwestia podpięcia własnego klucza API i odpowiedniego modułu — albo OpenRoutera. Bez problemu. Dobra, przechodzimy do drugiego zastosowania.

Część 2. Superpowers — pakiet skili dla Claude Code

Jakub: Jest taki plugin o nazwie Superpowers. Mam go zainstalowanego, a instalacja to jedno polecenie — podrzucimy je w notatkach. Dodaje on do Claude’a kilka nowych skili. Chciałbym wywołać moduł, który bardzo lubię — nazywa się „Brainstorm”. Mogę go po prostu uruchomić, a on od razu zapyta, co chcę uzyskać. Wiem, że takich modułów jest sporo, nawet jakiś natywny podpowiada w samym Claude Code, ale ważne jest, jak to konkretnie działa.

Zróbmy proste, trochę improwizowane zadanie: load balancer. Dla niewtajemniczonych — mamy serwer, za którym stoją kolejne serwery, i ruch jest między nie rozrzucany: ktoś łączy się z domeną, a jego żądanie trafia na maszynę pierwszą, drugą albo trzecią. Admini często coś takiego budują. Zakładam, że nie mam pojęcia, jak to zrobić, więc opisuję: „Chciałbym zbudować środowisko dockerowe z trzech kontenerów. Pierwszy niech nazywa się master, z zainstalowanym nginxem, i działa jako serwer rozrzucający ruch. Dwa kolejne — kontener 1 i kontener 2 — też z nginxem: pierwszy wyświetla napis «jestem jedynką», drugi «jestem dwójką». Chcę, żeby ruch po prostu skakał między kontenerami.”

I zwróć uwagę: to ekstremalnie niedokładny prompt. Co znaczy „skakał”? Round robin? Najmniejsze obciążenie? Jaki algorytm? Per użytkownik? Nic tu nie ma. To opis typu „jestem laik” — daję enter.

Mikołaj: Aż wstyd się przyznać, że moje prompty czasami tak wyglądają.

Jakub: Ale wiesz co — przy dobrze skonfigurowanym środowisku słabe prompty potrafią dawać niezłe rezultaty. Wszystko zależy od budowy środowiska. On pyta, gdzie utworzyć projekt — nieważne, maszyna jest dedykowana tylko na ten pokaz. Ale zaraz powinna zapalić się lampka: „moment, co ty właściwie chcesz tworzyć?”. On automatycznie sprawdza, czy mamy Dockera, Docker Compose’a i pozostałe elementy. Zgadzam się na kolejne kroki — on bada wersje; Docker Compose jako osobne narzędzie nie występuje, bo w nowym Dockerze jest wbudowany, stąd te komunikaty. Potem przechodzi do pytań doprecyzowującego: jak kontenery mają serwować swój tekst? Czy podawać plik index z wolumenu? Może przez dyrektywę nginixa? A może zbudować stronę własnym Dockerfilem? Wybieram index — „index HTML” brzmi jakoś znajomo. I teraz pyta krok po kroku o wszystko, czego nie uszczegółowiłem. Load balancer na jakim porcie? Na osiemdziesiątym? Podobno to popularny port, niech będzie.

Na tym polega brainstorming: możemy pisać bardzo słabe prompty, a one zostaną rozbudowane do poziomu, przy którym da się osiągnąć cel — a wszystko, o czym zapomnieliśmy, zostanie dopytane. On nas prowadzi za rękę: jak ta architektura powinna według niego wyglądać. Nawet ładny diagram narysował — master na osiemdziesiątym porcie, kontenery, osobna sieć. Sieć nam stworzy, powie, jak to będzie działać, mamy Docker Compose, konfigurację. Zatwierdzamy; chodzi o to, że znajdą się tu rzeczy, na które sami nigdy byśmy nie wpadli.

Do czego to realnie użyć? Bywają problemy, których nie umiemy dobrze rozwiązać — nie w sensie „na skróty”, po prostu nie znamy pułapek. Ostatnio chciałem zbudować klaster do wysyłania maili: jeden serwer, z którym łączę się przez SMTP, i rzesza małych serwerów rozsyłających wiadomości w świat. Wiem, jak to zbudować, ale nie wiem, co może pójść nie tak. Mówię mu: zrób brainstorm na ten temat. I on pyta: ilu będzie użytkowników? — to się źwo skaluje. Jakie będą połączenia? — kiepsko. Wszystko u jednego dostawcy? — słabo. Wysyłka z jednej domeny czy z tysiąca? I tak dalej. W efekcie pełna konfiguracja, wszystko wypisane. Za każdym razem możemy powiedzieć, że coś mieliśmy na myśli inaczej albo czegoś nie uwzględnił — i to zostanie obsłużone.

Mikołaj: Czyli nie musimy zakładać, że model wie wszystko w danej dziedzinie? Przy tym klastrze mailowym — czy powinniśmy mu dać dokumentację, z której ma czerpać?

Jakub: To od nas zależy. Najczęściej działa tak: jeśli chodzi o dokumentację, coś jest wyszukiwane w sieci, ale w większości przypadków to wiedza wewnętrzna modelu. Jeśli bazujemy na Opusie — całkiem nieźle radzi sobie z serwerami. Jeśli na czymś ekstremalnie tanim, jak Haiku — bywa różnie.

A co mi się w tym prowadzeniu nie podoba: najpierw robi projekt, potem specyfikację techniczną, opracowuje przypadki skrajne, dopytuje — super — a na końcu przechodzi do implementacji. Nie wdraża na serwer, ale pisze skrypty i konfiguracje. Tego ostatniego kroku najczęściej nie chcę, więc mówię „stop”. I sztuczka, którą często stosuję — może kogoś zainspiruje: warto podłączyć do Claude’a własnego Obsidiana i udostępnić dosłownie jeden katalog. Nie całość, ale ten jeden. Obsidian ma teraz synchronizator działający z wiersza poleceń — dawniej tego nie było — który można wrzucić do crona. Stworzyłem sobie skilla wrzucającego wszystko, co zostało opracowane, prosto do Obsidiana: „zrób mi z tego notatkę” — koniec. I ląduje tam opis krok po kroku: ile serwerów, jaka konfiguracja, jak to wszystko działa. Ja tego nie wdrażam, tylko zlecam adminowi — a to już pełny szkic, oczywiście po moich poprawkach. On nawet zakłada repozytorium Gita.

Mikołaj: Kilka pytań rodzi mi się odnośnie Superpowers. Jaka jest fundamentalna różnica między Superpowers a skille?

Jakub: Superpowers to po prostu plugin, który zawiera skille. To nie jest jakaś osobna kategoria — to implementacja skilli, które w pewien ustrukturyzowany sposób realizują cele. Równie dobrze moglibyśmy pobrać innego skilla do brainstormingu czy do projektowania infrastruktury — wszystko jest dostępne. Superpowers to paczka skili instalowanych jednocześnie, aktywująca różne ciekawe rzeczy.

Mikołaj: To natywne od Antropica?

Jakub: Oficjalne od Antropica, zoptymalizowane pod ich modele. Tak to działa.

Mikołaj: Pokażesz na szybko listę skili z tego pakietu?

Jakub: „Brainstorming” — z niego korzystaliśmy przed chwilą. „Writing plans” — pisanie planów tego, co chcemy zrealizować: powiemy, że chcemy wyjechać na wakacje, a on przeprowadzi nas przez zbudowanie planu krok po kroku. „Writing skills” — fajna rzecz, zaraz pokażę — do tworzenia skilli, ale z użyciem metodyki TDD.

Mikołaj: Lepszy niż zwykły kreator skilli, się domyślam?

Jakub: Zdecydowanie. Stosuje podejście sterowane testami: pisze testy i przechodzimy przez wszystkie fazy — czerwoną, zieloną i tak dalej. Całkiem fajnie się to układa. „Executing plans” — wykonanie wcześniejszego planu: jeśli dotyczy serwera albo kodu, zostanie zrealizowany. Jest code review, jest TDD używany jako podmoduł w pozostałych, jest sub-agent, który wykonując plan rozbija się na przykład na dziesięciu podagentów i robi wszystko równolegle.

Tworzenie własnego skilla metodą TDD

Jakub: A z rzeczy, z których często korzystam… Mam tu pusty katalog i wspomnę: gdybyśmy sami chcieli stworzyć własnego „superpowera”, to de facto tworzymy własnego skilla. Prowadzę newsletter — jakby ktoś nie wiedział — Unknown News. Ma taki mały ficzer: jeśli w adresie wpiszemy „archiwum”, dostajemy pełne archiwum wydań od wielkiego wybuchu do dziś. Możemy dopisać jeszcze „archiwum.json” — wersję bardziej dla agentów. JSON się ładuje, bo jest spory — okej. Kopiuję sobie adres i pobieram plik. Ile zajmuje? Sześć megabajtów newsów za Unknown News. Chciałbym użyć tego do czegoś pożytecznego: niech na podstawie samego tytułu znaleziska będzie wiadomo, czy pasuje do mojego newslettera, czy nie. Takiego skilla-klasyfikatora chcę mieć.

Więc w Claude sięgamy po „writing skills”… ale może najpierw odchudzmy dane. Mówię: „z tego pliku JSON wybierz sto pierwszych rekordów i zapisz w pliku mini.json, bo sześć megabajtów danych treningowych trochę by nam zabrało”. On używa jq do obcięcia — i na małej wersji będziemy pracować, trochę oszczędzając czas słuchaczom. Zapisał: osiemdziesiąt trzy kilobajty — niech będzie.

Mikołaj: Skoro już przy robótce jesteśmy — dla tych, którzy panicznie boją się terminala: co byś im poradził, żeby sprawniej się po nim poruszać?

Jakub: Wejść na YouTube, wpisać „Mrugalski” i „Linux podstawy”. Jest tam film, chyba dwadzieścia minut, z absolutnymi podstawami terminala linuksowego — według mnie wiedza, którą ludzie powinni dziś znać. To nie jest wiedza dla adminów, to wiedza dla totalnych laików: jak założyć katalog, jak przejść do innego folderu, jak otworzyć plik, jak choćby wyczyścić ekran. Film ma pewnie sześć, siedem lat, ale wszystko jest nadal aktualne — środowiska aż tak bardzo się nie zmieniają. Dawniej, jak korzystałem głównie z wiersza poleceń, byłem hipsterem. Teraz jestem mainstreamem — niestety wszyscy to robią.

Mikołaj: A tak z ciekawości — dyktujesz do jakiejś lokalnej instancji Whispera?

Jakub: To MacWhisper na Macu, z licencją dożywotnią: kupujesz raz i korzystasz. Można podpiąć lokalne modele. Dawniej używałem Parakeet od Nvidii — naprawdę świetnie działało, bardzo polecam. Ma jeden problem: przy bardzo technicznym języku, nazwach produktów, przekręca. Normalny człowiek na Parakeecie będzie działał świetnie. Więc podpiąłem do MacWhispera ElevenLabs — płacę pięć dolarów i używam modelu Scribe w wersji drugiej, na bieżąco aktualizowanego pod techniczne słownictwo. Jak tworzę opisy do newslettera, dyktuję je i mogę swobodnie wymieniać wszystkie produkty i technologie — nie myli się. Zresztą widzicie jakość tego dyktowania na żywo.

Ale wracajmy. Mamy plik mini, piszemy skilla. Uruchamiam „writing skills” i opisuję: „W pliku JSON, który za chwilę podam, jest archiwum mojego newslettera. Znajdują się tam tytuły znalezisk, opisy i linki. Interesują nas tylko tytuły. Chcę skilla, który będzie klasyfikował dostarczane przez użytkownika tytuły: czy pasują do mojego newslettera, czy nie. Użytkownik podaje tytuł, ty mówisz mi, czy pasuje”. Mało to składne, ale da sobie radę. Podaję plik, na którym ma się szkolić — mini.

I teraz ważna rzecz: gdy użyłem tego skilla, pod spodem uruchomił się brainstorming. Mimo że powiedziałem „zaczynamy pisać skilla”, on na to: „momencik, najpierw rozumiem, co ty w ogóle chcesz uzyskać”. I pyta: chcesz werdykt z uzasadnieniem? A może binarny — pasuje albo nie pasuje? A może werdykt z miarą pewności? Niech będzie werdykt z krótkim uzasadnieniem. Znowu nie powiedziałem, czego oczekuję — co znaczy „zaklasyfikuj”? Ma zwracać jedynkę? Zero? „Nadaje się”, „nie nadaje się”, „tak sobie”? Może skalę od jeden do dziesięciu? Tego nie ma, więc on buduje plan, sprawdza dane i zadaje kolejne pytania.

Mikołaj: To dopytywanie wynika z brainstormingu z Superpowers?

Jakub: Tak, po prostu go używa. Pyta: „które dane pobrać?”. Przecież mówiłem „mini”, a on: „może jednak archiwum? Tam jest więcej danych”. Nie — na mini się szkolisz.

Mikołaj: Nie wie, że nagrywamy odcinek na YouTube?

Jakub: Powiem, o co tu dokładnie chodzi, bo ktoś może rzec: po co plugin, skoro można puścić zwykłego Claude’a bez wtyczek i kazać mu pracować na danych? Chodzi o metodykę TDD — ona jest tu najważniejsza. I teraz zasadnicze pytanie: jak skill ma korzystać ze stu jeden tytułów podczas klasyfikacji? Ma wszystkie wbudować w definicję? Będzie mocno przepalał tokeny. Ma destylować same zasady, bez konkretnych tytułów? Ja wybrałem drugą drogę z destylacją — on ma wyciągnąć wnioski, jak działa mój system, co jest dobre, a co złe — plus dziesięć, dwadzieścia reprezentatywnych przykładów, bo przykłady zwiększają skuteczność. Gdybym kazał zrobić samą destylację, powstałoby pytanie, czy będzie dobra. Ale mamy testy — tyle razy je przechodzimy, aż będzie dobrze. I zauważcie: sam na to wpada. „No to dodamy przykłady”. Nie nadałem mu nawet nazwy; pewnie zapyta, gdzie skill ma być zainstalowany — dla wszystkich czy lokalnie, osobisty. Wszystko jest dopytywane.

Mikołaj: Fajnie to wygląda. Zwykle Claude, jak ma dobre samopoczucie, dopyta o dwie, trzy rzeczy…

Jakub: Są plusy i minusy. Ktoś, kto cierpi na chroniczny niedobór tokenów, przy Superpowers poczuje to mocniej — będzie jeszcze gorzej. Pytań jest gigantyczna ilość, do doprecyzowania naprawdę dużo. Jak mam podawać te tytuły? Po jednym — okej. Ale w zamian dostajemy pięknie wypielęgnowanego skilla. I jeszcze jedna ważna rzecz: jeśli ktoś pracuje z Claude Code od święta, a woli wersję przeglądarkową — skilla można przenieść metodą kopiuj-wklej, format jest identyczny. A jak ktoś korzysta z ChatGPT, gdzie oficjalnie skilli nie ma? Odcinamy nagłówek „używaj tego skilla, kiedy…” i kopiujemy same zasady, które wygenerował. Powstaje taki wielki prompt z paroma kilobajtami tekstu, do wklejenia w dowolne narzędzie. Nie przyzwyczajajmy się więc, że to wtyczka dla Claude’a i efekty pracy muszą zostać w Claude’u — to narzędzie, które w Claude działa, a efekty generuje przenośne.

Mikołaj: Ja zrobiłem to tak, że korzystam z automatyzacji w n8n i mam tam bloczek klasyfikujący treści — ten klasyfikator został wygenerowany właśnie w Superpowers, przez „writing skills”.

Jakub: Widzisz — narzędzia są trochę wtórne. Najważniejsza jest metodyka: zrozumienie reguł, które działają pod spodem, i świadomość, że można je zaimplementować choćby w ChatGPT.

Mikołaj: Nie będziemy trzymać was do końca tego procesu — może potrwać od kilkunastu do kilkudziesięciu minut, zależnie od liczby przebiegów. Przechodzimy dalej, a wy możecie zrobić to samo zadanie u siebie: pobierzcie archiwum — nie wiem, jakiegoś kanału RSS albo z Unknown News — i powiedzcie, co chcecie z niego wydestylować. Ja przerywam.

Część 3. Tryb YOLO i piaskownica Bubblewrap

(Informacja dodatkowa: Mikr.us to polska usługa tanich, niewielkich serwerów wirtualnych; Bubblewrap, zwany też bwrap, to lekki uniksowy mechanizm piaskownic ograniczający, do czego proces ma dostęp w systemie plików.)

Jakub: Trzecie, ostatnie zastosowanie. Istnieje coś takiego zwanego trybem YOLO: uruchomienie Claude’a tak, żeby o nic nie pytał — enter, enter, enter i wszystko działa. Jakie są z tym problemy? Domyślnie oznacza to pomijanie wszystkich uprawnień — i tu tkwi niebezpieczeństwo. Na dedykowanym serwerze, postawionym tylko pod Claude’a, problemu nie ma; ja często tak pracuję. Ale na domowym komputerze to problem, a na produkcji — duży problem.

Pierwsza rzecz: jestem zalogowany na roota. Pewnie w komentarzach zostanę za to zjechany, ale uruchamiam… i to się nie uruchomi. Nie wolno tak pracować na koncie roota. A jeśli ktoś bardzo chce mieć „podwójne YOLO”, da się obejść — deklaruje się, że to piaskownica; „zaufaj mi”. I działa. Można zapytać: po co komu podwójne YOLO, przecież to rozwali serwer? Zależy, co robimy — czasem przydaje się do diagnozowania problemów. Albo narobimy sobie nowych kłopotów, albo rozwiążemy problem na serwerze — ale warto wiedzieć, że taka opcja istnieje.

Czasem potrzebny jest tryb pośredni — coś między „akceptuję wszystko po kolei” a „pełne YOLO”. Antropic stworzył jakiś adaptacyjny tryb, ale programistów nie zadowala. Ja używam więc czegoś, co nazywa się Bubblewrap. To nie dodatek do Claude’a — to narzędzie systemowe, powinno być w repozytorium dystrybucji, często jest już domyślnie zainstalowane. To narzędzie do konteneryzacji — może nie tak pełnokrwistej jak Docker czy Podman, ale tworzy mikrokontener, w którym teoretycznie jesteś rootem, z bardzo sztywno określonymi zasadami: co ci wolno, a czego nie.

Opisywałem to kiedyś w mediach społecznościowych i spotkałem się z komentarzami: „widać, że nie czytałeś dokumentacji Claude’a — Claude Code przecież sam używa Bubblewrapa, ma go wbudowanego, niczego nie musisz instalować”. A ja jednak instaluję i używam świadomie. Czym to się różni? Claude potrafi zamknąć się piaskownicy w obrębie jednego katalogu: zamykasz się w katalogu projektu i masz gwarancję, że stamtąd nie ucieknie. A co, jeśli tych katalogów miałoby być dziesięć i nie są one sobie podległe? Da się tak? Nie da się. A gdyby z tej dziesiątki połowa była tylko do odczytu, połowa do zapisu, a jeszcze inna połowa to zasoby NFS z innego serwera? To już czysta magia — wbudowanym mechanizmem tego nie osiągniesz.

Co więc robimy? Własnego wrappera na Bubblewrap. Mam go zainstalowanego, a konfigurację skopiowałem żywcem z dokumentacji — nazwijmy ten skrypt po prostu „cl”. Co robi? Tworzy za pomocą Bubblewrapa środowisko, w którym podmontowane są dokładnie te rzeczy, których potrzebujemy, w trybie, w jakim potrzebujemy. Podmontowujemy urządzenia; systemowego katalogu tymczasowego nie rzucamy, tylko własny, ulotny, wyłącznie dla tego środowiska; do tego biblioteki i pozostałe elementy, bez których Claude nie wstanie. Ktoś powie: jest przecież zdockeryzowana wersja Claude Code, czemu nie użyć tej? Właśnie dlatego, że my chcemy pracować na prawdziwym systemie — nie odgórnym, wirtualnym — tylko prawdziwym, lecz obciętym.

I obcinam: podmontowałem na przykład cały katalog domowy razem z konfiguracją Claude’a. Czyli jeśli w normalnym Claude zainstaluję rozszerzenie — choćby Superpowers — to w wersji opakowanej Bubblewrapem też będzie dostępne. I odwrotnie: coś zainstalowanego w wersji opakowanej zobaczy wersja normalna, bo nieustannie współdzielimy ten sam katalog. Plik skryptu musi być wykonywalny. Chcę teraz udostępnić katalog „dane” — dopisuję montowanie na końcu i uruchamiam swojego „cl”. Jeśli nie ma literówek, wstanie.

Dla niewtajemniczonych: w Claude wykrzyknik przed poleceniem uruchamia komendę systemową bez ingerencji AI. Pytam o plik z hasłami systemowymi — nie ma takiego pliku. A jednak jestem rootem? Zadaję filozoficzne pytanie „kim jestem” — no, rootem jesteś. Rootem, ale bez dostępu do plików systemowych. Jak to w końcu jest? Jesteś „prawie rootem” — rootem skonteneryzowanym. Za to po wydaniu listy plików widzę katalog „dane”. Zapisuję do niego plik testowy — jest. A gdy wyjdę z wersji opakowanej i zajrzę tam normalnie — też jest, oczywiście. W ten sposób mam wersję obciętą: mogę udostępnić tylko te konfiguracje i zasoby, które mnie interesują.

Często realizuję coś takiego: chcę udostępniać notatki z Claude’a ludziom ze świata. Najprościej — stawiam szybko nginxa w Dockerze, w tle, z wystawionym portem. Dla tych, którzy nie rozumieją numeracji: działamy na Mikrusie, tam porty są niestandardowe — mój serwer to „1.01”, więc mam porty w stylu 10101, 30101 i tak dalej. Wystawiam osiemdziesiątkę kontenera na jeden z takich portów i podmontowuję katalog „dane” jako katalog html nginixa — obraz dockera podaje się na końcu polecenia. Chodzi o to, że zawartość „danych” będzie odsyłana przez serwer webowy. Testuję narzędziem curl: dostaję błąd „brak dostępu”, bo w katalogu nie ma jeszcze pliku indeksu. Ale wystarczy, że utworzę w nim plik — i już działa.

Wchodzę teraz do Claude’a i mówię: „Za każdym razem, gdy będę prosił cię o zrobienie notatki, założysz plik HTML, ładnie sformatowany, z użyciem Tailwind CSS — jasne tło, ciemne literki — w katalogu dane, a nazwę pliku wymyślisz sam, w zależności od kontekstu”. On zapisze moją wolę do pamięci — a pamięć jest współdzielona między wersją opakowaną i globalną, więc zapis zostanie na stałe. W międzyczasie piszę: „napisz mi w czterech zdaniach, kim jest Lech Wałęsa, i zrób z tego notatkę”. Teraz powinien użyć nowej reguły i zbudować w miarę ładnie sformatowaną notatkę — byłem bardzo nieprecyzyjny, co to znaczy „ładnie”, więc możemy być zaskoczeni — i rzucić ją do katalogu „dane”. A „dane” obsługuje nginx, czyli to katalog webowy. Co się stanie? Notatka jest od razu dostępna pod adresem.

Mikołaj: Co za klamra tematyczna — znowu Lech Wałęsa.

Jakub: Wchodzimy na adres i mamy naszą notatkę. Zbudowaliśmy webowy system publikowania notatek za pomocą jednego kontenera Dockera i podmontowanego katalogu. Możemy teraz kazać agentowi analizować, co dzieje się w systemie, i wszystko notować — niech stworzy podlinkowaną wiki — całkiem nieźle to działa.

I jeszcze jedno o Bubblewrapie: jeśli ktoś z was bardzo chce działać w tym trybie YOLO, to przynajmniej samodzielnie zdecydujcie, co w jego ramach można zepsuć. Szkody będą mniejsze, a system łatwiej odratować.

Zakończenie

Mikołaj: Kuba, poruszyłeś tyle kwestii, że ludzie na pewno zechcą dowiedzieć się więcej wprost od ciebie. Gdzie można cię znaleźć? LinkedIn, YouTube, może newsletter?

Jakub: Tak naprawdę jestem wszędzie, ale ostatnio najczęściej publikuję na LinkedInie i Instagramie — te dwa miejsca warto odwiedzić. A najprościej wejść na mrugalski.pl, gdzie są linki do wszystkiego: Instagram, Twitter, LinkedIn, Facebook, Mastodon. I przede wszystkim zapraszam na Unknown News — newsletter wydawany regularnie od dziewięciu lat, w każdy piątek, z materiałami z branży IT. To nie są ciekawostki dla zabicia czasu, ale rzeczy, które mogą posłużyć do rozbudowania wiedzy — dla programistów, adminów i wszystkich ludzi z IT.

Mikołaj: Świetnie. Dziękuję ci bardzo za dzisiejszą rozmowę.

Jakub: Dzięki za zaproszenie.