MCP-сервис

Исходный файл на GitHub

AWR предоставляет свой реестр работы через MCP (Model Context Protocol) — стандартный протокол, позволяющий хосту агента, такому как ассистент программирования или настольный ИИ-клиент, обнаруживать и вызывать инструменты. MCP-сервис — это способ, которым ваш агент читает статус проекта, компилирует контекст, записывает свидетельства и продвигает работу, не обращаясь к CLI напрямую. Есть два способа его запустить:

  • stdio — локальный процесс, который ваш клиент порождает напрямую, по одному проекту за раз. Это классическая схема, и она по-прежнему доступна.
  • Общий HTTP — единая конечная точка Streamable HTTP, обслуживающая несколько проектов и несколько независимых клиентов. Пакеты npm и PyPI включают эту возможность.

Эта статья сосредоточена на общем HTTP-сервисе, который вы запускаете, когда одни и те же проекты нужны более чем одному человеку или агенту. О том, что агенты делают с этими инструментами после подключения, см. Агенты. О человекочитаемом эквиваленте тех же операций см. CLI AWR.

Как работает общий сервис

Вы инициализируете каждый проект на сервере с помощью awr init, затем регистрируете его канонический абсолютный корень вместе с project_id, возвращённым командой:

awr --json status

AWR проверяет эту идентичность при запуске и на каждый запрос. Исходные файлы и база данных .awr каждого проекта остаются раздельными — сервис не клонирует репозитории, не монтирует файловые системы клиентов и не сливает реестры проектов. Клиентам нужен сетевой доступ к сервису, а не локальный исполняемый файл AWR, и файлы проекта должны быть читаемы на сервере: путь на ноутбуке клиента не становится читаемым удалённо. Общего «текущего проекта» нет — каждый инструмент проекта принимает явный аргумент project, и инструмента для открытия произвольного пути на сервере нет.

Настройка сервиса

Создайте принадлежащий оператору TOML-файл вне публичного репозитория:

version = 1
allowed_hosts = ["awr.internal.example"]

[[projects]]
key = "billing"
root = "/srv/projects/billing"
project_id = "<actual project ID>"

[[projects]]
key = "support"
root = "/srv/projects/support"
project_id = "<actual project ID>"

[[clients]]
id = "engineering"
token_env = "AWR_ENGINEERING_TOKEN"
write = ["billing", "support"]

[[clients]]
id = "reviewer"
token_env = "AWR_REVIEWER_TOKEN"
read = ["billing"]

Каждая запись клиента называет переменную окружения, содержащую её bearer-учётные данные. Используйте разные, случайно сгенерированные учётные данные длиной не менее 32 символов. Разрешение write включает доступ на чтение; разрешение read не может изменять проекты. Держите идентификаторы клиентов стабильными при ротации учётных данных — привязки диалогов и запросов крепятся к идентификатору клиента, и его изменение создаёт отдельную область. Изменения конфигурации вступают в силу только после перезапуска сервиса.

Запуск сервиса

awr-mcp --registry /etc/awr/service.toml --listen 127.0.0.1:8080

Каждый HTTP-запрос аутентифицируется. Встроенный механизм — статическая bearer-аутентификация, а не сервер авторизации OAuth и не корпоративный провайдер идентичности. Для удалённого доступа терминируйте HTTPS на аутентифицированной границе развёртывания и ограничьте прямой доступ к бэкенду. Дополнительные средства контроля доступа:

  • Источники (origins) отклоняются, если не перечислены явно в allowed_origins; нативные клиенты обычно опускают заголовок Origin.
  • SDK проверяет allowed_hosts, по умолчанию используя loopback-хосты, когда они не настроены.
  • Сервис проверяет Origin, но не реализует браузерный CORS preflight, поэтому браузерному фронтенду нужен соответствующий шлюз.

В Unix SIGTERM и Ctrl-C корректно прекращают приём запросов и завершают активную HTTP-работу. Отключение клиента или перезапуск сервиса никогда не завершает рабочую сессию AWR — протокольные соединения и устойчивые сессии — разные сущности. AWR не устанавливает системный демон — используйте менеджер процессов вашего развёртывания для запуска и перезапуска. Для локального использования одним клиентом остаётся команда stdio:

awr-mcp --project /absolute/project

Подключение клиента

Настройте каждый MCP-клиент на Streamable HTTP с тем же URL сервиса, используя путь /mcp, плюс его собственные bearer-учётные данные в заголовке Authorization: Bearer …, доставляемом через механизм учётных данных этого клиента. После подключения вызовите awr_projects_list, чтобы обнаружить ключи проектов, для которых авторизованы ваши учётные данные. Каждый инструмент проекта затем требует project:

{"project": "billing", "work": "INVOICE-001"}

Инструменты

Общий HTTP-сервис предоставляет в сумме 21 инструмент (20 через stdio, где опущен инструмент перечисления проектов). Они делятся на три группы.

Инструменты работы и контекста

Они зеркалируют повседневные действия CLI:

ИнструментЧто он делает
awr_project_statusТекущее продолжение, доступная для захвата работа, ожидания, блокировки, сводка истории
awr_work_readyГотовые элементы с диагностикой и подсказками о захвате
awr_work_getЗадачи элемента работы, приёмка, зависимости, решения, свидетельства
awr_context_compileКомпилирует контекстный пакет для элемента работы или ветки
awr_work_transitionПродвигает, блокирует, разблокирует, отменяет, переоткрывает или завершает работу
awr_event_appendДобавляет событие в реестр
awr_evidence_recordЗаписывает свидетельство, привязанное к работе и элементам приёмки
awr_searchПоиск по реестру проекта

Инструменты сессий и продолжения

Сессии привязывают диалог к единице работы. Передавайте стабильный идентификатор conversation от вашего хоста — не идентификатор HTTP-соединения. Та же строка диалога под другим проектом или клиентом — отдельная привязка.

ИнструментЧто он делает
awr_session_startНачинает привязанную к работе сессию, опционально захватывая работу
awr_session_getИнспектирует привязку, сессию, захваты, контрольную точку, прерванные сохранения
awr_session_listЛистает историю сессий этого клиента
awr_session_checkpointСохраняет потреблённый хеш контекста, выжимку, следующее действие, открытые петли
awr_session_claimПолучает или освобождает захват сессии
awr_session_endЯвно завершает или прерывает сессию и освобождает её захваты
awr_session_resumeСоздаёт сессию-преемника с унаследованной контрольной точкой и захватами
awr_session_waitСохраняет контрольную точку и записывает устойчивый вопрос пользователю
awr_session_replyДоставляет ответ пользователя на записанное ожидание
awr_operation_getИнспектирует записанный исход записи по ID запроса
awr_operation_recoverЗаписывает зафиксированный исход для прерванной записи при наличии доказательства
awr_source_reindexОбновляет проекции проекта из его авторитетных источников

Ожидающее ожидание блокирует переходы работы и возобновление, пока хост не запишет ответ. Ответ снимает эту блокировку, но не меняет статус работы и не планирует следующий ход хоста — ваш хост инспектирует сессию, компилирует свежий контекст и решает, продолжить ли или создать преемника.

Записи, ревизии и неопределённые исходы

Каждая запись через общий HTTP требует двух вещей:

  • стабильный, сгенерированный клиентом request_id (до 256 байт),
  • последнюю наблюдавшуюся вами expected_revision.
{
  "project": "billing",
  "request_id": "host-turn-42-start",
  "expected_revision": 120,
  "work": "INVOICE-001",
  "conversation": "invoice-review",
  "agent": "billing-assistant",
  "provider": "example-provider",
  "model": "example-model",
  "claim": true
}

Повторение ровно того же ID запроса и аргументов возвращает записанный результат без повторного выполнения действия, поэтому повтор после тайм-аута безопасен. Изменённые аргументы требуют нового ID. Сохраняйте возвращённую project_revision для следующей записи и никогда не вычисляйте следующую ревизию прибавлением единицы: журнал запросов и доменная операция оба потребляют ревизии.

После тайм-аута или разрыва вызовите awr_operation_get с тем же проектом и ID запроса. Незавершённый запрос сообщает write_outcome: unknown; прерванная запись могла уже зафиксироваться, поэтому никогда не выводите неудачу из закрытого потока HTTP-ответа. awr_operation_recover может записать зафиксированный исход только когда к запросу привязано однозначное терминальное событие — он никогда не вызывает исходный инструмент повторно. Чтения могут выполняться параллельно; записи сериализуются по проектам, и разные проекты имеют независимые блокировки. Устаревшая запись возвращает конфликт — прочитайте текущее состояние и пересмотрите решение перед повтором.

Чтения рабочих потоков (в разработке)

Исходный код в разработке добавляет реестр version = 2, который даёт клиентам доступ только для чтения к явно перечисленным, неизменяемым рабочим потокам для проектов, использующих YAML-реестр рабочих потоков. Это разрешения, принадлежащие оператору: разрешения read/write на уровне проекта сами по себе не авторизуют ни один изолированный рабочий поток.

[[clients.workstreams]]
project = "billing"
workstream_id = "<actual immutable workstream ID>"
authority_version = 1

Авторизованные клиенты используют инструмент awr_workstream, доступный только в общем сервисе, начиная с action: "capabilities" и action: "list", чтобы узнать, что они могут читать. Учитывайте текущие ограничения: это расширение даёт только чтение — никаких мутаций, чтения файлов содержимого или операций Team PostgreSQL — и проекты, которые его включают, отклоняют прежние общие инструменты, включая все записи, пока не появится авторизованная реализация. Включение и переиндексация на этом этапе — локальные действия оператора.

Куда двигаться дальше

  • Агенты — как агент использует сессии, захваты и контрольные точки поверх этих инструментов.
  • CLI AWR — те же доменные операции из командной строки, для операторов и отладки.
  • Устранение неполадок — конфликты ревизий, устаревшие источники и восстановление.