Tworzenie lokalnego agenta badawczego w LM Studio z wykorzystaniem czterech serwerów MCP
Lokalny agent badawczy w LM Studio z czterema serwerami MCP: filesystem, GitHub, SearXNG i Camofox, skróconym schematem narzędzia, promptem planistycznym oraz demonstracją ugruntowania.
Źródła: How to Turn LM Studio Into a Local Research Agent With MCP Servers
Przydatny jest lokalny model, który potrafi wyszukiwać, czytać plik lub otwierać prośbę o integrację. Model lokalny, który może połączyć wszystkie te funkcje w jednej sekwencji rozumowania, aby odpowiedzieć na jedno pytanie, pełni rolę asystenta badawczego. Aby osiągnąć taki poziom w LM Studio, potrzebne są cztery serwery MCP działające równolegle, plan zapobiegający temu, by łączne schematy narzędzi pochłaniały okno kontekstowe, oraz mechanizm zachęcający model klasy 9B do wykonywania zadań wieloetapowych zamiast użycia jednego narzędzia i zatrzymania się w tym momencie.
Cztery serwery to serwer systemu plików, serwer GitHub, samodzielnie hostowana instancja SearXNG do wyszukiwania oraz przeglądarka oparta na Camoufox (Camofox) do przeglądania stron znalezionych podczas wyszukiwania. Serwer systemu plików to @modelcontextprotocol/server-filesystem, ograniczony do określonego katalogu. Do GitHuba uzyskuje się dostęp przez OAuth pod adresem api.githubcopilot.com/mcp/. SearXNG i Camofox działają w środowisku Docker i łączą się za pośrednictwem mcp-searxng oraz camofox-mcp. Każdy z nich funkcjonuje niezależnie. Najciekawsze jest to, co dzieje się, gdy w jednej rozmowie są używane wszystkie te narzędzia.
Jedna uwaga dotycząca konfiguracji przed podłączeniem przewodów: wszystko to jest przeznaczone do zwykłych badań online, takich jak analiza konkurencji, weryfikacja dostawcy lub sprawdzenie informacji z artykułu. Agent nie ma pojęcia, co jest badane, i go to nie obchodzi. Szuka, pobiera i czyta to, na co jest skierowany.
Konfiguracja składa się z czterech etapów: łączenia serwerów, redukcji listy narzędzi, dostarczania modelowi planu oraz przeprowadzenia demonstracji.
Etap 1: wszystkie cztery serwery w jednej rozmowie
LM Studio nie ogranicza liczby serwerów MCP, których może używać jedna rozmowa. Ładuje je wszystkie i przekazuje modelowi schemat każdego narzędzia z każdego z nich. To jest zaleta tej konfiguracji, a jak pokazuje następny etap, także pierwsza trudność, z którą się spotyka.
System plików oraz wpisy w GitHub są skonfigurowane tak, jak w przypadku samodzielnej instalacji, podobnie jak wpisy dla SearXNG i Camofox. Kontenery tła muszą już być uruchomione, z plikami docker-compose.yml oraz searxng/settings.yml w odpowiednich miejscach, ponieważ te pliki nie są tutaj powtarzane. Jedyną zmianą jest to, że wszystkie cztery wpisy znajdują się teraz w jednym pliku mcp.json:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/jes/research-workspace"
]
},
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"auth": {
"CLIENT_ID": "<your Client ID>",
"CLIENT_SECRET": "<your client secret>"
}
},
"searxng": {
"command": "npx",
"args": ["-y", "mcp-searxng"],
"env": {
"SEARXNG_URL": "http://localhost:8080"
}
},
"camofox": {
"command": "npx",
"args": ["-y", "camofox-mcp"],
"env": {
"CAMOFOX_URL": "http://localhost:8765",
"CAMOFOX_API_KEY": "your-camofox-api-key",
"CAMOFOX_AUTH_MODE": "api_key"
}
}
}
}
Trzy szczegóły zasługują na uwagę.
- Wpis
githuburuchamia własny krok OAuth. LM Studio żąda go po raz pierwszy, gdy serwer próbuje się załadować. Ponieważ endpoint GitHub nie obsługuje dynamicznego rejestracji klienta, w tym procesie używana jest aplikacja GitHub OAuth, którą trzeba wcześniej ręcznie zarejestrować. Nie ma na to żadnego skrótu. - Dozwolony katalog dla serwera systemu plików jest wyborem dowolnym. Specjalna folder
research-workspacedziała lepiej niż katalog domowy, głównie dlatego, że jasno pokazuje, do czego dokładnie może mieć dostęp model. CAMOFOX_URLiSEARXNG_URLmuszą wskazywać na kontenery Docker. Jeśli te nie działają, serwery nadal się ładują w LM Studio, ale każda próba połączenia z nimi kończy się niepowodzeniem, co powoduje dezorientację przez około dwadzieścia minut przy pierwszym wystąpieniu tego problemu.
Gdy wszystkie cztery funkcje są włączone, a małe zielone kropki obok nazw każdego serwera w panelu MCP stają się pełnymi kropkami, czat zawiera cztery narzędzia do zarządzania systemem plików, dziesiątki narzędzi GitHuba, cztery narzędzia SearXNG oraz około czterdziestu pięciu narzędzi Camofox. To dużo informacji, nad którymi musi rozważyć decyzję jeden model o pojemności 9 miliardów parametrów, i to właśnie jest problem, który ma rozwiązać następny etap.
Etap 2: utrzymanie dostępnej ilości kontekstu
Sama liczba narzędzi GitHuba stanowi zagrożenie, podobnie jak sama liczba narzędzi Camofox. W połączeniu z narzędziami SearXNG i narzędziami do zarządzania systemem plików obciążenie staje się znaczne.
Nazwa każdego narzędzia, jego opis oraz schemat parametrów są tokenizowane i dodawane do kontekstu modelu, zanim ten przeczyta choćby jedno słowo z rzeczywistego pytania. W przypadku małego modelu o ograniczonej pojemności kontekstowej ten dodatkowy obciążenie może pochłonąć znaczną część dostępnych zasobów.
Najprostszym rozwiązaniem jest po prostu nie włączanie każdego narzędzia z każdego serwera. Dla GitHub istnieje lepsze rozwiązanie niż ręczne włączanie narzędzi w panelu MCP. Serwer zdalny przyjmuje nagłówek X-MCP-Readonly, który ogranicza całe połączenie do narzędzi tylko do odczytu, zanim LM Studio zobaczy resztę schematu. Dzięki temu wpis github z poprzedniego etapu staje się następujący:
{
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"auth": {
"CLIENT_ID": "<your Client ID>",
"CLIENT_SECRET": "<your client secret>"
},
"headers": {
"X-MCP-Readonly": "true"
}
}
}
Gdy nagłówek jest włączony, serwer oferuje jedynie narzędzia do czytania: pull_request_read, issue_read, list_commits, get_file_contents, search_repositories oraz search_code. Wszystko, co umożliwia usuwanie, łączenie, wysyłanie lub tworzenie, po prostu nie istnieje. Ograniczenie to jest wprowadzane przez samą platformę GitHub, a nie przez LM Studio poprzez ukrycie przycisku, więc stanowi rzeczywisty limit. Oznacza to również, że schematy dla wyłączonych narzędzi do zapisu w ogóle nie są tokenizowane i nie trafiają do kontekstu, co jest właśnie celem tej fazy.
Każdy, kto potrzebuje bardziej wąskich uprawnień, może użyć pola X-MCP-Tools, które przyjmuje wyraźną listę dozwolonych funkcji oddzieloną przecinkami, na przykład search_code,search_repositories,get_file_contents,list_commits. Jest to rozwiązanie odpowiednie w przypadkach, gdy narzędzia do obsługi problemów i wniosków o integrację zdecydowanie nie będą potrzebne.
Zdjęcie ekranu GitHub MCP w tym stanie pokazałoby tylko narzędzia get, read, list, scan i search, ponieważ flaga read-only została ustawiona na true, z opcją wyłączania dodatkowych narzędzi, których nie jest potrzeba i które zwiększają koszt tokena.
Camofox nie ma odpowiedniej flagi po stronie serwera, więc jego narzędzia są wyłączane po jednym w panelu MCP. W przypadku czatu przeznaczonego wyłącznie do badań, narzędziami, które można wyłączyć, są delete_download, import_cookies oraz wszystko, co zarządza profilami, w tym save_profile i load_profile, ponieważ sesja badawcza nie ma powodu, by edytować zapisane profile przeglądarki.
Zasada polega na zachowaniu tego, czego wymaga konkretny scenariusz użycia, oraz wyłączeniu reszty. W przypadku większości serwerów jest to decyzja dotycząca ograniczeń kontekstowych, a nie kwestia bezpieczeństwa. Wyjątkiem jest header GitHub, ponieważ jego własny serwer to egzekwuje.
Demo w etapie 4 nigdy nie wymaga uprawnień do zapisu na GitHubie, ponieważ jedyne działanie GitHuba polega na odczytywaniu jednego pliku manifestu, co oznacza, że ograniczenie tylko do odczytu może pozostać w mocy. Jeśli późniejsze zadanie faktycznie wymaga zapisu, na przykład w celu utworzenia zgłoszenia z zapisem tego, co odkrył agent, należy usunąć odpowiedni nagłówek dla tej rozmowy. Mieszanie połączeń GitHuba z ograniczeniami tylko do odczytu i z możliwością zapisu w jednej sesji nie jest właściwym sposobem radzenia sobie z tym problemem.
Sama okno kontekstowe również wymaga uwagi. Minimalna liczba 4096 tokenów była rozsądnym minimum, gdy schemat pochodził z jednego serwera. Przy czterech serwerach oraz skróconej, ale wciąż znacznej liście narzędzi, 4096 to za mało. Należy przesunąć suwak do góry, być może powyżej 32k, w zależności od tego, ile może pomieścić model i sprzęt oraz jak długo przewiduje się trwanie wymiany informacji. Nie ma jednej poprawnej liczby – chodzi o kompromis pomiędzy przestrzenią na rozumowanie a dostępną ilością VRAM, więc obserwuj procent wypełnienia kontekstem wyświetlany w LM Studio pod polem do wpisywania wiadomości i dostosowuj odpowiednio.
Etap 3: plan, który może realizować model
Agent napisany ręcznie ma jedną przewagę, której interfejs czatu w LM Studio nie zapewnia automatycznie. W skrypcie komenda systemowa to ciąg znaków w Pythonie, który znajduje się pod pełną kontrolą, i można w nim wyraźnie opisać proces: wyszukiwanie, wybór źródła, pobranie go, a następnie decyzja o tym, czy to odpowiada na pytanie, czy potrzebne jest kolejne wyszukiwanie.
Lepiej jest jasno określić, co faktycznie oferuje LM Studio, zamiast sugerować, że istnieje ukryta opcja planowania. Takiej opcji nie ma – nie ma oddzielnego ustawienia do planowania.
Istnieje natomiast pole „Komenda systemowa” w bocznym pasku czatu, pod zakładką „Parametry modelu”. Tę komendę można zapisać razem z ustawieniami temperatury i kontekstu jako nazwany preset, dzięki czemu nie trzeba jej wpisywać na nowo przy każdej sesji. To jest ta sama funkcja, której używa agent napisany ręcznie, tylko w formie pola tekstowego, a nie ciągu znaków w kodzie.
Komenda systemowa o takim charakterze sprawdza się w czacie badawczym:
You are a research assistant with tools for web search, page fetching,
file storage, and GitHub. When asked a factual question you cannot
answer with confidence from memory, follow this plan:
1. Search for the topic using searxng_web_search. Look at more than one
result before deciding a source is good.
2. Fetch the most promising source with camofox's navigate and
snapshot or extract_structured tools, not just the search snippet.
When using camofox always open a new tab before trying to navigate
to a page.
3. If the question needs more than one source to answer confidently,
search again and fetch again before answering.
4. If asked to save findings, write them to a markdown file in the
workspace using the filesystem tools, don't just describe them in chat.
5. State which sources you actually fetched, not just which ones you
found in search results.
Kilka uwag na temat jego zachowania:
- Jest to zwykła proza, bez żadnej maszyny stanowej, która by ją kontrolowała. Instrukcje to to, co widzi model, i zazwyczaj trzyma się ich zarysu, choć bez żadnych gwarancji, tak jak w przypadku promptu systemowego w skrypcie.
- Krok 5 jest ważniejszy, niż się wydaje. Bez niego model ma tendencję do odpowiadania wyłącznie na podstawie fragmentu z wyszukiwarki, pomijając krok pobierania danych, co unieważnia cel umieszczenia Camofox w tym procesie.
- Zapisanie wyniku jako ustawienia domyślne umożliwia przenoszenie go pomiędzy rozmowami bez konieczności ponownego wklejania.
Na zrzutce ekranu prompt znajduje się pod „Parametry modelu”, a ustawienia domyślne są zapisane jako „Research Chat”. Gdy prompt oraz skrócona lista narzędzi są już dostępne, model ma możliwości oraz coś w rodzaju planu ich użycia. Pozostaje pytanie, czy faktycznie je wykorzystuje.
Etap 4: demonstracja potwierdzająca użycie narzędzi
Dobry test sprawdzający podstawową wiedzę musi wymagać rzeczywistego użycia narzędzi. Pewne przywoływanie informacji z pamięci nie może dać prawidłowej odpowiedzi, więc model albo pobiera rzeczywisty źródło, albo zgaduje. Zadanie powinno być takie, którego nie można zapamiętać, które można niezależnie sprawdzić oraz wystarczająco ogólne, by nie dotyczyć konkretnej osoby.
Przykład odpowiedniego zadania: wskazać agentowi repozytorium, które jest utrzymywane lub od którego zależy działanie systemu, i kazać mu śledzić wersję ustaloną jako standardową w ramach danej zależności aż do wszystkich zaleceń bezpieczeństwa dotyczących dokładnie tej wersji. Poniższy prompt można wkleić do czatu po uzupełnieniu trzech miejsc zastępczych:
I want you to check one dependency in a GitHub repository for known
security advisories. Do this:
1. In the repository <owner>/<repo>, read <manifest-file> using
get_file_contents.
2. From that file, find the exact pinned version of the dependency
"<dependency-name>".
3. Search the web for known security advisories filed against that
specific version of "<dependency-name>".
4. Fetch the actual advisory page(s) you find rather than relying on
the search snippet alone.
5. Write a short summary to dependency-risk.md in the workspace: the
dependency name, the pinned version, any advisories found (with
severity and a link), and a one-line recommendation.
Miejsca zastępcze działają w następujący sposób:
<owner>/<repo>to dowolny repozytorium z uprawnieniami do odczytu. Projekt osobisty jest równie dobry jak publiczny, który przypadkowo jest zależnością.<manifest-file>określa nazwę pliku zależności, od którego zależy projekt, na przykładgo.mod,pyproject.toml,requirements.txtlubpackage.json.<dependency-name>to pojedyncza zależność z tego manifestu, najlepiej taka, która rzeczywiście jest interesująca.
Jeśli nie mamy pod ręką odpowiedniego repozytorium, takiego jak juice-shop/juice-shop – celowo niesecure aplikacja do szkolenia od OWASP – może pełnić tę rolę. Jej plik package.json zawiera wystarczającą liczbę wcześniej zidentyfikowanych zależności, dzięki czemu krok wyszukiwania zazwyczaj przynosi coś rzeczywistego, a express-jwt oraz sanitize-html to oba rozsądne wybory na początek. Wypełniona wersja wygląda tak:
I want you to check one dependency in a GitHub repository for known
security advisories. Do this:
1. In the repository juice-shop/juice-shop, read package.json using
get_file_contents.
2. From that file, find the exact pinned version of the dependency
"express-jwt".
3. Search the web for known security advisories filed against that
specific version of "express-jwt".
4. Fetch the actual advisory page(s) you find rather than relying
on the search snippet alone.
5. Write a short summary to dependency-risk.md in the workspace:
the dependency name, the pinned version,
any advisories found (with severity and a link),
and a one-line recommendation.
Wysłanie tego powinno sprawić, że agent przejdzie przez pięć kroków w kolejności: odczyt z GitHuba, wyszukiwanie w zewnętrznych źródłach, pobranie danych z zewnętrznych źródeł oraz w końcu zapis pliku, z prędkością określoną przez sprzęt.
Pełne wykonanie tego polecenia wykorzystało wszystkie cztery serwery MCP i zużyło łącznie 37803 tokenów.
To polecenie zostało wybrane celowo. Odpowiedź zależy od repozytorium oraz od tego, co w nim jest zaznaczone, a bazy danych CVE, które są wyszukiwane, są stale aktualizowane, więc nie można z góry podać żadnego ustalonego wyniku.
Sprawdzenie poprawności działania modelu polega na dwóch krokach. Należy otworzyć plik manifestu i osobiście przeczytać wersję zaznaczoną, aby potwierdzić, jakie dane zwrócił GitHub. Następnie należy sprawdzić informacje zawarte w ostrzeżeniu w oparciu o własną wyszukiwarkę ostrzeżeń bezpieczeństwa GitHuba lub w bazie NVD. Jeśli oba źródła pokrywają się z raportem agenta, stanowi to rzeczywisty dowód na poprawność działania modelu: model rzeczywiście przeczytał plik manifestu i pobrał odpowiednią stronę z ostrzeżeniem, a nie odpowiadał na podstawie mglistych wspomnień o tym, że jakaś biblioteka kiedyś miała CVE.
Demo pokazuje również, że nagłówek odczytu wyłącznie z poziomu etapu 2 jest wystarczający. Cały proces polega na odczytywaniu z GitHuba, wyszukiwaniu poza serwisem, pobieraniu danych poza serwisem oraz zapisie pliku lokalnego, więc nie ma potrzeby dostępu do zapisu na GitHubie, a nagłówek może pozostać w takiej formie. Jedno polecenie uruchamia wszystkie cztery serwery za jednym razem: GitHub odczytuje manifest, SearXNG wyszukuje ostrzeżenia, Camofox pobiera strony z informacjami o ostrzeżeniach, a system plików zapisuje ich treść. Dzięki temu można szybko sprawdzić, czy cała konfiguracja jest poprawnie skonfigurowana, zanim zacznie się prawdziwe badanie.
Gdzie występują problemy
Lepiej określić słabe punkty, niż udawać, że cały łańcuch jest niezawodny od początku do końca.
Czasami model odpowiada na podstawie fragmentu z wyników wyszukiwania i pomija pobieranie pełnej strony, mimo że instrukcje systemowe mówią mu inaczej. Problem ten występował częściej przy krótkich, prostych pytaniach, w których model wydawał się uważać ten fragment za wystarczająco dobry. Wiadomość z prośbą o pobranie pełnej strony zazwyczaj rozwiązuje ten problem. Nie chodzi o to, że model nie może tego zrobić, lecz o to, że model o mocy 9B czasami popełnia błędy w takich ocenach.
Czasami, stając przed dziesiątkami narzędzi z GitHuba, których nigdy wcześniej nie używał, model wybiera takie, które wydają się prawdopodobne, ale są błędne – na przykład list_pull_requests zamiast list_issues. Optymalizacja przeprowadzana na etapie 2 jest najlepszą obroną; krótszy wybór podobnych opcji zmniejsza szanse na wybór niewłaściwego narzędzia.
Żadne z tych elementów nie czyni tego agenta deterministycznym procesem. Tam, gdzie wymagany jest determinizm, odpowiednim narzędziem jest skrypt, a pętla napisana ręcznie jest bliższa temu celowi. Zaletą łączenia wszystkiego w LM Studio jest to, że model dostosowuje się do każdego postawionego pytania, natomiast wadą jest to, że czasami dostosowuje się źle. Obserwowanie, jak radzi sobie z kilkoma pytaniami badawczymi, to najszybszy sposób, aby dowiedzieć się, w których przypadkach można mu ufać, a w których potrzebuje dodatkowego wsparcia.
Gotowa konfiguracja
Cztery etapy prowadzą do uruchomienia w LM Studio pojedynczej rozmowy z czterema serwerami MCP. Lista narzędzi została skrócona, aby kontekst nadal miał miejsce na przetwarzanie informacji. Systemowy prompt dostarcza modelowi 9B struktury do postępowania tam, gdzie wcześniej była pusta strona, a demonstracja pokazuje, że pobierane są rzeczywiste strony, a nie odpowiedzi wywoływane z pamięci. Mówiąc konkretnie:
- System plików, GitHub, SearXNG i Camofox – wszystko dostępne w jednej rozmowie.
- Wyselekcjonowana lista narzędzi oraz okno kontekstowe wystarczająco duże na całą strukturę danych, zamiast ograniczeń typowych dla jednego serwera.
- Wskazówka systemowa zapisana jako ustawienie domyślne, która sprawia, że model sam planuje cykl wyszukiwania, pobierania i zapisywania, korzystając z tego, co faktycznie udostępnia interfejs LM Studio, a nie z nieistniejącej opcji konfiguracyjnej.
- Demo pokazujące możliwość powtarzalnego działania, w którym każda część może być sprawdzona niezależnie, przy jednoczesnym wykorzystaniu wszystkich czterech serwerów w jednej instrukcji.
Można to rozszerzyć. Drugi backend wyszukiwania obok SearXNG umożliwiłby wzajemną weryfikację wyników. Przeprowadzanie procesu streszczania po każdym pobraniu zapobiegłoby temu, by długie strony pochłaniały zbyt dużo kontekstu podczas ładowania. Dla tych, którzy robią to regularnie, skryptowanie procesu tworzenia ustawień domyślnych pozwoliłoby na poprawne konfigurowanie każdego nowego czatu badawczego bez konieczności ręcznego dostosowywania.
Wciąż powraca ta sama konkluzja. Po ręcznym połączeniu wszystkich elementów – systemu plików, narzędzi wyszukiwania, przeglądania oraz hosta kodu – oraz po zidentyfikowaniu miejsc, w których coś naprawdę zawodzi, okazuje się, że bardziej zaawansowane frameworki to po prostu te same komponenty ukryte za dodatkową abstrakcją. Akceptacja takiego kompromisu ma sens tylko dla osób, które już rozumieją, co kryje się pod spodem.
Literatura pokrewna
- Praktyczne notatki: Stwórz agenta finansowego z AI za pomocą serwera MCP firmy EODHD — Szczegółowy przewodnik po praktycznych notatkach: Stwórz agenta finansowego z AI za pomocą serwera MCP firmy EODHD: umowy, sprawdzenia oraz miejsca na kod do wklejenia dla zespołów tworzących systemy MCP bez niego.
- Playwright czy agenty przeglądarkowe? Gdzie skryptowana automatyzacja wciąż ma przewagę — Porównanie skryptów Playwright z agentami przeglądarkowymi napędzanymi MCP: kruchość, determinizm, koszt, przykładowe zadanie z fakturą, narzędzia do obserwacji, zagrożenia bezpieczeństwa oraz ramy decyzyjne.