MCP дошёл до Go: как не утонуть в интеграциях агентов и собрать production-ready сервер без самописного glue-кода

Я — Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production-системы на Claude, Supabase, n8n, Doppler и self-hosted Postgres для B2B-клиентов в DACH. Самая неприятная точка в реальных agent workflows обычно не модель и не prompt, а слой интеграций: 6 инструментов, 3 схемы авторизации, разные форматы ошибок, и через 2 недели у команды уже больше glue-кода, чем бизнес-логики.

С появлением MCP в Go стало проще собрать сервер, который агент понимает предсказуемо: единый контракт на tools, ресурсы и вызовы, меньше самодельных адаптеров, меньше скрытого состояния между компонентами. Но сам факт поддержки Go ничего не решает, если вы сразу тащите в проект динамические tool registry, неконтролируемые права на SQL и дебаг через print. Ниже — как я смотрю на MCP-сервер для production: не как на витрину для демо, а как на контролируемую точку доступа между моделью и вашей инфраструктурой.

Почему интеграции агентов ломаются быстрее, чем сами модели

Когда команда впервые собирает multi-agent систему, она обычно оптимизирует выбор модели и orchestration. На практике сбои приходят из другого места: tool contracts расползаются, retries дублируют побочные эффекты, а логирование не позволяет восстановить цепочку решений. Если agent может вызвать SQL, HTTP и внутренний workflow, то у вас уже не “чат с функциями”, а распределённая система с требованиями к идентичности, наблюдаемости и контролю прав.

Типичный анти-паттерн

Я регулярно вижу один и тот же сценарий: сначала делают 2–3 helper-функции “на скорую руку”, потом оборачивают их в кастомный JSON-формат, потом добавляют ручную валидацию параметров, а потом пишут ещё один слой, чтобы один и тот же tool понимали Claude и внутренний runner. Формально всё работает. Фактически команда сама построила нестабильный протокол, который теперь обязана поддерживать.

MCP здесь полезен не потому, что это модная аббревиатура, а потому что он задаёт границу. Агент видит описанные capabilities, сервер отвечает в ожидаемом формате, а вы можете централизованно решать, что именно разрешено в production. Для regulated environments это важнее, чем “гибкость любой ценой”.

Что именно я считаю production-ready MCP-сервером

Production-ready MCP-сервер — это не “сервер, который отвечает на list_tools”. Это сервис, который можно обновлять, логировать, ограничивать и проверять до релиза. Минимальный набор у меня такой:

СлойЧто должно бытьЗачем
КонтрактСтрогие схемы входа и выходаИсключить неявные поля и разъезд типов
АвторизацияРазделение прав по tool и средеНе давать agent лишний доступ
НаблюдаемостьRequest ID, audit log, trace связи tool вызововРазбор инцидентов и воспроизводимость
БезопасностьSecret isolation, SQL allowlist, статический анализСнизить риск утечек и опасных вызовов
ЭксплуатацияHealth checks, timeouts, retries с идемпотентностьюПереживать сетевые сбои без побочного хаоса

Если хотя бы 2 строки из этой таблицы у вас пока нет, не надо называть это agent platform. Это ранний integration layer, и к нему нужно относиться честно.

Go здесь удобен по практическим причинам

Для MCP-сервера Go хорош тем, что позволяет держать небольшой бинарник, предсказуемые зависимости и понятную модель конкурентности. В среде, где есть n8n, Postgres, внутренние API и очереди задач, это часто выгоднее, чем плодить ещё один тяжёлый runtime ради 5–7 tools. Особенно если сервер нужно self-hosted разворачивать у клиента.

Минимальный каркас без лишней магии

Ниже не “фреймворк ради фреймворка”, а обычный принцип: один tool — одна явная функция, валидируемый вход, ограниченный side effect. Даже если дальше вы подключите Anthropic SDK или Claude Code в контур разработки, граница сервера должна остаться скучной и предсказуемой.

export DATABASE_URL="postgres://app:***@db.internal:5432/app"
export MCP_ALLOWED_TABLES="customers,orders"
export TOOL_TIMEOUT_SECONDS="8"

gitleaks detect --source . --no-banner
semgrep --config p/owasp-top-ten .
bandit -r scripts/

go test ./...
go build -o mcp-server ./cmd/server
./mcp-server

Даже в Go-проекте я часто гоняю semgrep и gitleaks вокруг обвязки, инфраструктурных скриптов и CI-конфигов. OWASP ASVS и OWASP Top 10 остаются полезной рамкой для проверки того, как ваш сервер работает с секретами, вводом и авторизацией. Если в проекте есть Python-утилиты для миграций или data tasks, bandit тоже уместен.

version: "3.9"
services:
  mcp-server:
    image: ghcr.io/example/mcp-server:latest
    environment:
      DATABASE_URL: ${DATABASE_URL}
      MCP_ALLOWED_TABLES: customers,orders
      TOOL_TIMEOUT_SECONDS: "8"
    read_only: true
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "/app/mcp-server", "healthcheck"]
      interval: 30s
      timeout: 3s
      retries: 3

Ключевой момент: MCP-сервер не должен получать unrestricted database credentials. Если tool нужен только для чтения заказов и клиентов, дайте ему read-only роль и ограничьте SQL на уровне приложения. На 3 моих последних проектах с агентами именно чрезмерные права на DB были самым частым техническим риском, который всплывал ещё до выхода в production.

Где чаще всего ошибаются при сборке tool layer

1. Пытаются сделать универсальный tool executor

Идея “один executor на всё” почти всегда заканчивается размытым контрактом. Агенту лучше отдать 6 узких tools с ясными схемами, чем 1 мегатул с 14 режимами работы.

2. Смешивают orchestration и policy

n8n подходит для orchestration и интеграционных маршрутов, но policy-решения вроде “какие таблицы можно читать” или “какие домены можно вызывать” лучше фиксировать в сервере и конфиге. Иначе вы теряете одну точку контроля.

3. Не хранят достаточно аудита

Для production мало знать, что tool был вызван. Нужно видеть входные параметры, caller identity, результат, длительность, код ошибки и связанный trace ID. Иначе разбор инцидента превращается в реконструкцию по косвенным признакам.

4. Проверяют только happy path

Я бы отдельно тестировал timeout, отмену запроса, битые аргументы, пустые выборки и повторный вызов после частичного сбоя. Именно эти сценарии бьют по SLA, а не успешный демо-запрос из IDE.

Что говорят внешние источники и почему это важно

Anthropic в документации по Model Context Protocol описывает MCP как стандартный способ давать моделям доступ к tools и данным через единый интерфейс: docs.anthropic.com. Практический смысл для архитектуры простой: чем меньше у вас кастомных протоколов между агентом и инфраструктурой, тем проще обеспечивать тестируемость и заменяемость компонентов.

OWASP Top 10 2021 отдельно подчёркивает риски, связанные с broken access control и insecure design: owasp.org/www-project-top-ten. MCP-сервер как раз становится местом, где эти риски либо локализуются, либо разрастаются. Если вы строите agent layer поверх Postgres, Supabase и внутренних API, вопрос не в том, “умеет ли агент вызывать tool”, а в том, при каких условиях этот вызов безопасен и воспроизводим.

FAQ

MCP подходит только для Claude?

Нет, ценность MCP в самом контракте между моделью и инструментами. Даже если у вас несколько моделей или свой orchestration layer, единый протокол снижает количество переходников.

Нужно ли сразу поднимать много tools?

Нет. Я бы начинал с 3–5 критичных tools с узкими правами и хорошим audit trail. Широкий каталог инструментов без дисциплины обычно только увеличивает площадь ошибок.

Можно ли использовать Supabase за MCP-сервером?

Да, если вы чётко разделяете service-role доступ, read-only сценарии и то, что вообще разрешено агенту. MCP не заменяет политику доступа к данным, он делает точку вызова более управляемой.

Где лучше держать секреты?

Не в prompt и не в коде tool-обвязки. Я обычно выношу их в Doppler или другой менеджер секретов, а в сам сервер подаю только то, что нужно конкретной среде.

Когда не стоит использовать MCP?

Если у вас 1 локальный скрипт и 1 внешний API, отдельный MCP-сервер может быть лишним. Но как только появляется несколько tools, разные роли доступа и требования к аудиту, стандартизованная граница быстро окупается.

На каком этапе у вас сейчас теряется больше всего времени: описание tool contracts, контроль прав, аудит вызовов или разбор сбоев после релиза? Мне правда интересно, потому что именно эта точка обычно и определяет, станет ли agent system продуктом, а не затянувшимся прототипом.

I run a free 30-min stack audit for DACH founders building AI in regulated markets. DM me on LinkedIn or write to @ger_dennis_ai.

Read more

Computer-Use-Agenten scheitern an Pixeln: wie Sie auf stabile UI-Referenzen über Accessibility Trees umstellen und fehleranfällige Desktop-Automatisierung nicht mehr ständig reparieren

von Denis Shokhirev, Enterprise AI Architect aus Freiburg im Breisgau Ich bin Denis Shokhirev, Agentic AI Systems Architect in Freiburg im Breisgau, Germany, und bei DennisCraft AI Studio setze ich produktive KI-Systeme für DACH-B2B-Kunden auf Basis von Claude, Supabase, n8n, Doppler und selbst betriebenem Postgres um. Die teuersten Fehler in

By Denis Shokhirev

Компьютерные агенты ломаются на пикселях: как перейти на stable UI refs через accessibility tree и перестать чинить flaky desktop automation

Я Denis Shokhirev, Agentic AI Systems Architect из Freiburg im Breisgau, Germany, и в DennisCraft AI Studio я собираю production AI-системы для DACH B2B на Claude, Supabase, n8n, Doppler и self-hosted Postgres. Самая дорогая поломка в desktop automation, которую я вижу у клиентов, почти никогда не связана с моделью: агент

By Denis Shokhirev