MCP без хаосу: як спроєктувати безпечний контур інструментів для AI

ai · 2026-10-03

MCP варто сприймати не як каталог «ще десяти інструментів для агента», а як межу можливостей. Сервер додає моделі нові дані або дії, але водночас збільшує контекст, поверхню атаки й кількість способів помилитися. Практичне питання тому звучить так: який мінімальний контур інструментів потрібен саме цьому агенту для цієї операції?

Що саме додає MCP

В архітектурі MCP є host, client і server. AI-застосунок є host і створює окреме з’єднання client для кожного server. Server може надавати tools для дій, resources для даних і prompts для шаблонів. Локальний server зазвичай працює через stdio, віддалений — через Streamable HTTP.

Це корисна модель для проєктування: MCP server — не «плагін із довірою за замовчуванням», а окрема зона повноважень. Якщо один server має доступ до GitHub, пошти й бази даних, то помилка агента вже не локальна для однієї задачі.

Як відрізняються Claude, Codex і OpenCode

  • Claude Code. Документація Claude Code про MCP прямо попереджає перевіряти довіру до server: зовнішній контент може містити prompt injection. Для віддалених сервісів рекомендовано HTTP; server можна додати командою, а доступ до нього зберігається в конфігурації клієнта. Отже, для Claude важливо перевірити походження server до першого підключення, а не після першого небезпечного результату.
  • Codex. Документація Codex про MCP описує спільну конфігурацію для CLI, desktop-застосунку та IDE. Вона має окремі allowlist/denylist для tools, режими підтвердження auto, prompt, writes, approve, тайм-ліміти та ознаку required. Це зручна основа для політики «читання автоматично, запис — із підтвердженням». Важливо також, що Codex використовує інструкції server як загальні вказівки; це ще одна причина не підключати невідомі server без рев’ю.
  • OpenCode. Документація OpenCode про MCP servers окремо застерігає: кожен server додає інструменти до контексту, а великі інтеграції можуть швидко з’їсти його бюджет. OpenCode дозволяє вимикати server глобально й вмикати його лише для конкретного агента. Це сильний шаблон: не кожен агент повинен бачити весь каталог можливостей.

Спільний висновок: протокол стандартизує з’єднання, але не визначає, кому й коли дозволено виконувати дію. Це має визначати ваша топологія агентів і політика підтверджень.

Мінімальна схема для OpenClaw

Розкладіть систему на чотири шари:

  1. Vault з рішеннями, правилами та журналом — джерело довгоживучого контексту.
  2. Skills — повторювані процедури: пошук у vault, перевірка дублювання, підготовка публікації.
  3. Agents — ролі з різним набором tools: triage, research, execution.
  4. MCP servers — вузькі capability-порти до зовнішніх систем.

Skill не має бути заміною server: skill пояснює послідовність і критерії успіху, server надає конкретний доступ. Агент не має бути «суперагентом», який бачить усе: він має отримувати лише те, що відповідає його ролі.

Практичний опис дозволів можна тримати поруч із кожним агентом:

agent: research
purpose: зібрати факти й підготувати чернетку
servers:
  vault:
    mode: read
  web:
    mode: read
tools:
  - search
  - fetch
  - write_draft
approval:
  external_write: always
  publish: never

Це не універсальний синтаксис конфігурації OpenClaw, а короткий контракт, який варто відтворити у ваших профілях агентів. Його цінність у явній відповіді на питання «що станеться, якщо модель помилиться?». Для execution-агента додайте окремий write-capability, але не успадковуйте весь набір research-інструментів автоматично.

Чотири робочі патерни

1. Vault як read-only MCP-порт

Не давайте кожному агенту довільний доступ до всього сховища Markdown. Зробіть вузький read-only server із трьома операціями: search_notes, get_note, get_index. Агент спочатку отримує індекс, потім запитує конкретні сторінки й лише після цього пише відповідь.

Плюси — менше контексту, простіший аудит і менша ймовірність випадкової зміни нотаток. Мінус — потрібен невеликий адаптер і дисципліна індексів. Для OpenClaw це особливо корисно для рішень, runbook-ів та історії сесій: Telegram-агент може читати потрібне, але не перетворює всю приватну базу на безмежний prompt.

2. Два Telegram-боти замість одного всесильного

Публічний або командний бот маршрутизує повідомлення до triage-агента без write-tools. Приватний операторський бот доступний лише власнику й передає затверджені задачі execution-агенту. Результат записується в журнал разом із request_id, назвою агента та списком викликаних tools.

Потік може виглядати так:

Telegram inbound
  -> triage (read-only)
  -> plan + risk label
  -> private approval
  -> execution agent (narrow write tools)
  -> result + audit event

Це збільшує кількість кроків і трохи затримує прості задачі, зате зменшує blast radius: повідомлення з групи не може одразу опублікувати пост, змінити інфраструктуру або відправити листа.

3. Capability-профілі для «режимів дня»

Створіть профілі research, maintenance і publish, а не перемикайте десятки server вручну. У ранковому режимі підключені vault і web-read. У maintenance додається аудит репозиторіїв, але немає публікації. У publish доступний лише валідатор і вузький запис до чернетки; commit залишається окремим кроком із перевіркою.

Почніть із allowlist, а не denylist:

[profile.research]
enabled_servers = ["vault-read", "web-read"]
write_tools = []

[profile.publish]
enabled_servers = ["vault-read", "blog-validator"]
write_tools = ["create-draft"]
approval = "required"

Назви полів тут є прикладом політики, не готовим конфігом конкретного клієнта. Сенс — у версіонованому наборі можливостей, який можна перевірити під час code review.

4. Незвичний патерн: «тіньовий» MCP server для vault

Замість filesystem-server зробіть server, який повертає лише денормалізовану «тінь»: назви актуальних проєктів, останні рішення, відкриті блокери й посилання на першоджерела. Він не приймає довільний шлях і не має операції запису. Окремий job оновлює тінь після змін у vault.

Це нетипово, бо ви додаєте проміжний шар і ризикуєте отримати застарілий індекс. Натомість агент не бачить зайвих сторінок, не може прочитати випадковий секретний файл, а формат відповіді стабільний для різних моделей. Компроміс прийнятний для Telegram-бота або нічного дайджесту, де краще отримати трохи неповний список із позначкою updated_at, ніж відкрити весь vault кожній інтеграції.

Runbook підключення нового server

  1. Запишіть одну задачу, для якої server потрібен, і одного власника.
  2. Перегляньте список tools та розділіть їх на read, write і destructive. Якщо server не дозволяє таке розділення, це вже ризик.
  3. Почніть із read-only профілю та вимкненого server за замовчуванням.
  4. Перевірте транспорт: локальний stdio для довіреного процесу, віддалений HTTP — лише з TLS та чіткою автентифікацією.
  5. Виконайте canary-запит на тестових даних і перевірте журнал: який агент, який tool, які аргументи, який результат.
  6. Для запису додайте явне підтвердження, ідемпотентний request_id та спосіб вимкнути server без видалення конфігурації.
  7. Якщо tool повертає несподівані інструкції або server часто падає, вимкніть його й продовжіть роботу в read-only режимі. Не просіть модель «ігнорувати дивний результат» і не розширюйте дозволи навмання.

Коротке правило для щоденної роботи: контекст можна розширювати поступово, повноваження — тільки явно. MCP робить інтеграції переносимими між Claude, Codex, OpenCode та OpenClaw; без профілів, allowlist і перевірки результатів він так само переносить і помилки.

Джерела