Створення локального агента для досліджень у LM Studio з використанням чотирьох серверів MCP.
Місцевий агент досліджень у LM Studio із чотирма серверами MCP: filesystem, GitHub, SearXNG та Camofox, спрощеною схемою інструментів, запитом до плану та демонстрацією функції grounding.
Джерела: How to Turn LM Studio Into a Local Research Agent With MCP Servers
Локальна модель, яка може шукати, читати файл чи створювати pull request, є корисною. Локальна модель, яка може поєднати всі ці дії в одному ланцюжку міркувань для відповіді на одне запитання, є дослідницьким асистентом. Щоб у LM Studio досягти другого рівня від першого, потрібні чотири сервери MCP, які працюють паралельно, план щодо запобігання тому, щоб об’єднані схеми інструментів поглинали вікно контексту, а також механізм, який змушує модель класу 9B виконувати багатокрокове завдання, замість того щоб використати один інструмент та зупинитися.
Чотири сервери – це сервер файлової системи, сервер GitHub, самостійно розгорнута інстанція SearXNG для пошуку та браузер на основі Camoufox (Camofox) для перегляду сторінок, які знаходяться під час пошуку. Сервер файлової системи має назву @modelcontextprotocol/server-filesystem та працює лише у дозволеній директорії. До GitHub підключаються через OAuth за адресою api.githubcopilot.com/mcp/. SearXNG та Camofox запускаються в Docker та підключаються через mcp-searxng та camofox-mcp. Кожен з них працює окремо. Цікаво те, що відбувається, коли в одному чаті об’єднуються всі ці компоненти.
Одна застереження щодо налаштування перед підключенням обладнання: усе це призначене для звичайних онлайн-досліджень, таких як конкурентний аналіз, перевірка постачальника чи перевірка тверджень зі статті. Агент не має уявлення про те, що досліджується, і йому це не важливо. Він шукає, отримує та читає все, на що його спрямовують.
Налаштування складається з чотирьох етапів: об’єднання серверів, скорочення списку інструментів, надання моделі плану та запуск демонстрації функцій.
Етап 1: усі чотири сервери в одному чаті
LM Studio не обмежує кількістю серверів MCP, які може використовувати чат. Він завантажує їх усі та передає моделі схеми кожного інструменту з кожного з них. У цьому й полягає перевага такого підходу, але, як покаже наступний етап, саме це стає першою проблемою.
Файлова система та записи у GitHub налаштовані так, як це робиться у самостійній конфігурації, так само як і записи SearXNG та Camofox. Основні контейнери вже мають бути запущені, з наявністю файлів docker-compose.yml та searxng/settings.yml, оскільки ці файли не повторюються тут. Зміна полягає у тому, що всі чотири записи тепер знаходяться в одному файлі 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"
}
}
}
}
Три деталі заслуговують уваги.
- Елемент
githubініціює власний крок OAuth. LM Studio запитує його вперше, коли сервер намагається завантажитися. Оскільки кінцева точка GitHub не підтримує динамічну реєстрацію клієнтів, процес використовує додаток GitHub OAuth, який необхідно зареєструвати вручну заздалегідь. Обійти це неможливо. - Дозволений каталог для сервера файлової системи обирається довільно. Спеціальна папка
research-workspaceпрацює краще, ніж домашня директорія, головним чином тому, що це чітко показує, до чого може отримати доступ модель. CAMOFOX_URLтаSEARXNG_URLмають вказувати на контейнери Docker. Якщо вони не працюють, сервери все одно завантажуються в LM Studio, але кожен виклик інструментів до них зазнає невдачі, що спричиняє плутанину протягом двадцяти хвилин під час першої спроби.
Коли увімкнені всі чотири елементи, а маленькі зелені крапки поруч із назвою кожного сервера у панелі MCP стають суцільними, чат містить чотири інструменти файлової системи, десятки інструментів GitHub, чотири інструменти SearXNG та приблизно сорок п’ять інструментів Camofox. Це велика кількість інформації, над якою має працювати одна модель об’ємом 9 мільярдів параметрів, і саме ця проблема вирішується на наступному етапі.
Етап 2: підтримка обсягу контексту
Вже сама кількість інструментів GitHub є ризиком, як і кількість інструментів Camofox. Разом із інструментами SearXNG та файловою системою навантаження стає значним.
Назва кожного інструменту, його опис та схема параметрів токенізуються у контексті моделі ще до того, як вона прочитає хоча б одне слово з фактичного запиту. У невеликій моделі з обмеженим обсягом контексту цей додатковий навантаження може зайняти значну частину всіх доступних ресурсів.
Найпряміший спосіб вирішення проблеми — це просто не увімкнути кожен інструмент з кожного сервера. Для GitHub існує кращий спосіб, ніж вручну перемикати інструменти в панелі MCP. Віддалений сервер приймає заголовок X-MCP-Readonly, який обмежує всю з’єднання лише інструментами для читання, перш ніж LM Studio побачить решту схеми. Завдяки цьому запис github з попереднього етапу стає наступним:
{
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"auth": {
"CLIENT_ID": "<your Client ID>",
"CLIENT_SECRET": "<your client secret>"
},
"headers": {
"X-MCP-Readonly": "true"
}
}
}
Коли ввімкнено заголовок, сервер пропонує лише інструменти для читання: pull_request_read, issue_read, list_commits, get_file_contents, search_repositories та search_code. Усі інструменти, які дозволяють видаляти, об’єднувати, додавати чи створювати щось, просто відсутні. Це обмеження запроваджується з боку GitHub, а не через приховування кнопки у LM Studio, тому це справжня межа. Це також означає, що схеми для недоступних інструментів запису ніколи не токенізуються в контексті, що є основною метою цього етапу.
Ті, хто хоче ще більше обмежень, можуть використовувати X-MCP-Tools, який приймає явний список дозволених функцій, розділених комами, наприклад search_code,search_repositories,get_file_contents,list_commits. Це підходить у випадках, коли інструменти для проблем та запитів на зміни явно ніколи не знадобляться.
Скріншот GitHub MCP у цьому стані показуватиме лише інструменти get, read, list, scan та search, оскільки прапорець read-only було встановлено як true, з можливістю вимкнути додаткові інструменти, які не потрібні та що підвищують витрати на токени.
У Camofox немає еквівалентного прапорця з боку сервера, тому його інструменти вимикаються по одному у панелі MCP. Для чату, призначеного лише для досліджень, до інструментів, які можна вимкнути, належать delete_download, import_cookies та все, що пов’язано з керуванням профілями, зокрема save_profile та load_profile, адже сеанс досліджень не має причин користуватися збереженими профілями браузера.
Принцип полягає у тому, щоб залишити лише те, що потрібно для конкретного випадку використання, та вимкнути решту. Для більшості серверів це рішення, пов’язане з обмеженнями контексту, а не з питаннями безпеки. GitHub є винятком, оскільки його власний сервер забезпечує дотримання цього правила.
Демо на етапі 4 ніколи не потребує прав на запис у GitHub, оскільки єдина дія GitHub — це читання одного маніфесту, що дозволяє залишити обмеження лише на читання. Якщо пізніше завдання справді потребуватиме запису, наприклад для створення запиту з описом того, що знайшов агент, слід видалити заголовок для цього чату. Поєднання коннекторів GitHub з обмеженнями лише на читання та з можливістю запису в одній сесії — це неправильний підхід до вирішення проблеми.
Саме вікно контексту також потребує уваги. Мінімум у 4096 токенів був розумною межею, коли схема походила з одного сервера. З чотирма серверами та скороченим, але все ще значним списком інструментів 4096 є занадто малою кількістю. Потрібно значно підняти показник, можливо, навіть понад 32 к, залежно від того, скільки може вмістити модель та апаратне забезпечення, та як довго очікується тривати взаємодія. Жодне конкретне число не є ідеальним. Це компроміс між простором для міркувань та вільною VRAM, тому стежте за відсотком заповнення контексту, який відображає LM Studio під полем введення чату, та коригуйте значення відповідно.
Етап 3: план, якого може дотримуватися модель
Агент, написаний вручну, має одну перевагу, якої інтерфейс чату LM Studio не надає автоматично. У скрипті системний запит є рядком мови Python під повним контролем, і можна чітко описати логіку циклу: пошук, вибір джерела, отримання інформації, а потім вирішення, чи це відповідає на запитання, чи потрібен ще один пошук.
Краще чітко пояснити, що насправді пропонує LM Studio, ніж натякати на наявність прихованої опції планування. Її немає — окремих налаштувань планування не існує.
Є лише поле System Prompt у бічній панелі чату, під розділом Model Parameters. Цей запит можна зберегти разом із налаштуваннями температури та контексту як названу налаштування заздалегідь, тож його не потрібно переписувати щоразу під час сеансу. Це та сама функція, яку використовує агент, написаний вручну, тільки у вигляді текстового поля, а не рядка в коді.
Системний запит у такому форматі підходить для дослідницького чату:
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.
Деякі примітки щодо його поведінки:
- Це звичайний прозовий текст, без машини станів, яка б його контролювала. Інструкції — це те, що бачить модель, і вона зазвичай дотримується їхньої структури, хоча це не гарантовано, так само, як і у випадку з системним запитом усередині скрипту.
- Крок 5 має більше значення, ніж здається. Без нього модель схильна відповідати лише на основі уривка з пошуку, пропускаючи крок отримання даних, що суперечить меті використання Camofox у цьому процесі.
- Збереження результату як налаштування дозволяє передавати його між розмовами без необхідності повторного вставлення.
На скріншоті запит розташований під розділом „Параметри моделі“, а налаштування збережене як „Research Chat“. Запит та скорочений список інструментів на своїх місцях дають моделі можливість та своєрідний план щодо їх використання. Залишається питання, чи вона справді це робить.
Етап 4: демонстрація, яка доводить використання інструментів
Хороший тест на знання реальності має змушувати використовувати справжні інструменти. Впевнене згадування з пам’яті не може дати правильну відповідь, тому модель або знаходить справжнє джерело, або вгадує. Завдання має бути таким, яке вона не могла запам’ятати, підлягати незалежній перевірці та бути достатньо універсальним, щоб не стосуватися конкретної особи.
Приклад підходящого завдання: спрямувати агента до репозиторію, який підтримується чи від якого залежать інші системи, та змусити його простежити за фіксованою версією одного з компонентів до всіх сповіщень про безпеку, пов’язаних саме з цією версією. Наведений нижче запит можна вставити в чат після заповнення трьох місць для заміни:
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.
Місця заміни працюють так:
<owner>/<repo>— це будь-який репозиторій із правами на читання. Особистий проект підходить так само добре, як і публічний, який випадково є залежністю.<manifest-file>— це назва файлу залежності, від якого залежить проект, наприкладgo.mod,pyproject.toml,requirements.txtабоpackage.json.<dependency-name>— це окрема залежність з цього маніфесту, бажано така, яка справді є важливою.
Якщо немає підходящого репозиторію, juice-shop/juice-shop — навмисно небезпечний додаток для навчання від OWASP — може слугувати заміною. У його файлі package.json є достатньо раніше виявлених залежностей, тож крок пошуку зазвичай знаходить щось корисне, а express-jwt та sanitize-html є розумним вибором для початку. Повна версія виглядає так:
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.
Надсилання цього запиту має змусити агента виконати п’ять кроків по черзі: читання з GitHub, зовнішній пошук, отримання даних ззовні та нарешті запис файлу, з урахуванням швидкості, яку дозволяє обладнання.
Повне виконання цього запиту використало всі чотири сервери MCP та спожило загалом 37803 токенів.
Цей запит був обраний навмисно. Відповідь залежить від репозиторію та від того, що в ньому закріплено, а бази даних CVE, які використовуються для пошуку, постійно оновлюються, тому не можна заздалегідь навести фіксований результат.
Перевірка роботи моделі вимагає двох кроків. Відкрийте маніфест та особисто прочитайте фіксовану версію, щоб підтвердити, що повернуло запит до GitHub. Після цього перевірте інформацію з попередження за допомогою пошуку власних попереджень про безпеку GitHub або у NVD. Якщо обидва джерела збігаються з звітом агента, це вважається справжнім доказом: модель дійсно прочитала маніфест та дійсно завантажила сторінку з попередженням, а не відповіла на основі розмитої пам’яті про те, що якась бібліотека колись мала CVE.
Демонстрація також показує, що достатньо лише заголовка режиму читання у рівні 2. Усі операції полягають у читанні даних з GitHub, поза межами пошуку та завантаження, а також у записі у локальний файл, тому GitHub не потребує прав на запис, і заголовок може залишатися активним. Одне запитання активує всі чотири сервери за один прохід: GitHub читає маніфест, SearXNG шукає інформацію про попередження, Camofox завантажує сторінки з цими попередженнями, а файлова система зберігає отриману інформацію. Це швидкий спосіб перевірити, чи все налаштовано правильно, перш ніж починати справжні дослідження.
Де виникають проблеми
Краще назвати слабкі місця, ніж удавати, що вся ланцюгова структура є надійною від початку до кінця.
Іноді модель відповідає на основі уривка з пошуку та пропускає завантаження сторінки, навіть якщо системний запит просить її робити інакше. Це трапляється частіше з короткими, простими запитаннями, коли модель, здається, вважає уривок достатньо гідним. Додаткове повідомлення з проханням завантажити сторінку зазвичай вирішує проблему. Справа не в тому, що модель не може цього зробити, а лише в тому, що 9B-модель іноді помиляється у таких оцінках.
Іноді, стикаючись із десятками інструментів GitHub, які вона ніколи раніше не використовувала, модель обирає щось правдоподібне, але неправильне, наприклад list_pull_requests замість list_issues. Оптимізація, яка виконується на другому етапі, є найкращим захистом. Коротший список схожих варіантів зменшує кількість можливостей обрати неправильний інструмент.
Жоден з цих елементів не робить цей агент детерміністичною системою. Там, де потрібен детермінізм, правильним інструментом є скрипт, а вручну написаний цикл ще більше наближений до цього. Перевагою використання LM Studio полягає у тому, що модель адаптується до будь-якого поставленого запитання, але ціною є те, що іноді вона адаптується погано. Спостереження за її роботою над кількома дослідницькими запитаннями — це найшвидший спосіб зрозуміти, де їй можна довіряти, а де їй потрібна допомога.
Готова конфігурація
Чотири етапи забезпечують один чат у LM Studio, який керує чотирма серверами MCP. Список інструментів було скорочено, щоб у контексті все ще залишалося місце для обробки інформації. Системний запит надає 9B-моделі структуру для дії там, де раніше була порожня сторінка, а демонстрація функції отримання даних показує, що завантажуються справжні сторінки, а не відповіді, запам’ятовані в пам’яті. Конкретно кажучи:
- Файлова система, GitHub, SearXNG та Camofox — усе це доступно в одному чаті.
- Відібраний набір інструментів та вікно контексту достатнього розміру для об’єднаної схеми, замість обмежень одного сервера.
- Системний запит, збережений як налаштування, змушує модель самостійно планувати цикл пошуку, отримання та збереження даних, використовуючи те, що фактично надає інтерфейс LM Studio, а не відсутній параметр конфігурації.
- Демонстрація повторюваного процесу обробки даних, кожна частина якої може перевірятися окремо, і яка охоплює всі чотири сервери за один запит.
Є можливість його розширити. Другий сервер пошуку поруч із SearXNG дозволив би порівнювати результати між собою. Після кожного отримання даних виконання операції підсумовування запобігло б тому, щоб довгі сторінки займали занадто багато контексту під час завантаження. Для тих, хто регулярно цим займається, створення налаштованих шаблонів за допомогою скриптів дозволить починати кожен новий дослідницький сеанс із правильними налаштуваннями без необхідності ручної настройки.
Постійно повертається один висновок. Після того, як вручну об’єднано всі складові — файлову систему, механізм пошуку, функції перегляду та сервер коду, — та визначено, де саме виникають проблеми, стає зрозуміло, що більш складна фреймворк-структура — це просто ті самі елементи, приховані за додатковою абстракцією. Прийняття такої компромісної схеми має сенс лише для тих, хто вже розуміє, що знаходиться під спудом.
Пов’язана література
- Практичні нотатки: створення AI-фінансового агента за допомогою сервера MCP від EODHD — Детальний посібник з практичних нотаток: створення AI-фінансового агента за допомогою сервера MCP від EODHD: контракти, перевірки та готові фрагменти коду для команд, які розробляють системи MCP без цього інструменту.
- Playwright чи браузерні агенти? Де скриптована автоматизація все ще має перевагу — Порівняння скриптів Playwright та браузерних агентів, керованих MCP: крихкість, детермінізм, витрати, приклад виконання завдання з рахунком-фактурою, інструменти для спостереження, ризики для безпеки та система прийняття рішень.