Skip to content

Segate-ekb/autumn-mcpify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

autumn-mcpify

Превращает CLI-приложение на autumn-cli в MCP-сервер (Model Context Protocol, stdio) — чтобы ИИ-агенты могли вызывать команды приложения как инструменты.

Единый источник истины — обычная CLI-команда. Помечаешь подкоманду маркером &ДоступноВMCP — и она автоматически появляется как MCP-инструмент. Схема параметров генерируется рефлексией из аннотаций autumn-cli (&Опция/&Аргумент/&НаборОпций/ &Перечисление/&Т*) — дублировать ничего не нужно.

Быстрый старт

Точка входа MCP-сервера приложения (например src/mcp.os):

#Использовать autumn
#Использовать autumn-cli
#Использовать autumn-mcpify
#Использовать "."          // исходники приложения: команды, сервисы, наборы опций

Запуск = Новый MCP_Запуск();
Запуск.Старт();

Точку входа CLI приложения для фоновых задач (см. ниже) сервер находит сам — по стартовому скрипту процесса (СтартовыйСценарий()) и манифесту пакета, не завязываясь на имя main.os. Никаких аргументов передавать не нужно.

autumn-mcp подключать в точке входа не нужно — его тянет сам autumn-mcpify (внутри MCP_Запуск).

Регистрация сервера у клиента (Claude Code / Cursor / IDE), рабочий каталог — корень проекта:

// .mcp.json
{ "mcpServers": {
    "myapp": { "command": "oscript", "args": ["src/mcp.os"] }
}}

В обычной точке входа CLI (src/main.os) подключать autumn-mcpify не нужно: OneScript хранит аннотации как метаданные и спокойно игнорирует незарегистрированные маркеры (&ДоступноВMCP и др.), поэтому штатный запуск приложения работает и без загрузки библиотеки. Она нужна только в точке входа MCP-сервера.

Как пометить команду

&ПодкомандаПриложения(Имя = "compile", Родитель = "КомандаCf", Описание = "Собрать cf")
&ДоступноВMCP
Процедура ПриСозданииОбъекта()
КонецПроцедуры

Всё. Команда работает и в CLI (myapp cf compile ...), и как MCP-инструмент cf_compile. Имя инструмента = путь подкоманды через _.

Маркеры намерения

Рядом с &ДоступноВMCP:

&MCPДлительная                    // долгая команда → по умолчанию в фоне (taskId)
&MCPДлительная(Таймаут = 600)     // то же + авто-отмена фоновой задачи через 600 с
&MCPТолькоЧтение                  // readOnlyHint = true
&MCPРазрушающая                   // destructiveHint = true, readOnlyHint = false
&MCPИдемпотентная                 // idempotentHint = true
&MCPВнешнийМир                    // openWorldHint = true (иначе false)
&MCPЗаголовок("Дружелюбное имя")  // title (по умолчанию = описание команды)

&MCPДлительная управляет фоновым исполнением (см. ниже). Остальные маркеры транслируются в блок annotations ответа tools/list (хинты протокола MCP): по ним клиент решает, например, спрашивать ли подтверждение перед вызовом. Требуется сервер autumn-mcp ≥ 1.1.0 (с поддержкой АннотацииИнструмента()); со старым сервером маркеры безвредно игнорируются.

Сессионный кэш опций

Когда команда вызывается с опциями, их значения запоминаются на сессию по имени опции и автоматически подставляются в последующие команды с такой же опцией. Например, строку подключения ibconnection достаточно указать один раз — дальше она применяется ко всем командам, где есть эта опция (в т.ч. к опциям из общих наборов &НаборОпций). Явно переданное в вызове значение всегда перекрывает кэш.

Кэшируются только опции (&Опция); позиционные аргументы (&Аргумент) — нет. Это поведение описано в описании каждого инструмента, чтобы было понятно клиенту.

Управление кэшем. Для независимого/параллельного вызова передайте у самой команды nocache: true — кэш на этот вызов не читается и не пишется (вызов самодостаточен). Посмотреть, что сейчас «прилипло», — инструмент cache_show; сбросить весь кэш или одну опцию по имени — cache_clear.

Прогресс выполнения (notifications/progress)

Обычная (синхронная) команда стримит лог клиенту как notifications/message, а каждое INFO-сообщение дополнительно шлёт notifications/progress. Клиент, передавший progressToken, на каждое такое уведомление сбрасывает таймаут вызова — поэтому «болтливая» команда не обрывается, а прогресс отражает реальный ход работы (а не таймер). Требуется сервер autumn-mcp ≥ 1.1.0; со старым прогресс просто не шлётся.

Долгую и при этом «молчаливую» (без INFO-лога) операцию лучше помечать &MCPДлительная: она уходит в фон и таймаут синхронного вызова ей не грозит.

Длительные команды: фон и поллинг

Команды с &MCPДлительная по умолчанию исполняются фоном (не блокируют stdio): запускается отдельный процесс oscript <точка входа CLI> <подкоманда> <флаги>, вывод пишется в файл по ходу выполнения (живой лог — task_result показывает прогресс, пока задача ещё идёт), инструмент сразу возвращает taskId. Эффективные опции (с учётом кэша) реконструируются в CLI-флаги — дочерний процесс самодостаточен. Параметр &MCPДлительная(Таймаут = N) задаёт дедлайн: по истечении задача авто-отменяется (снимается дерево процессов), статус становится timeout.

Точка входа CLI — это CLI-диспетчер приложения (обычно src/main.os), а НЕ сам mcp-скрипт: фон перезапускает именно его. Сервер определяет её автоматически (путь mcp-скрипта берётся из СтартовыйСценарий()), по приоритету:

  1. явно заданная Конфигурация().УстановитьТочкаВходаCLI(...);
  2. opm-metadata.xml собранного пакета — единственный <executable>, не равный mcp-скрипту (несколько имён на один файл — норма);
  3. packagedef (запуск из исходников) — единственный .ИсполняемыйФайл(...), не равный mcp-скрипту;
  4. main.os рядом с mcp-скриптом.

Имя main.os нигде не предполагается — оно лишь крайний фолбэк. Если автоопределение неоднозначно (несколько разных executable), задайте точку входа явно.

Инструмент Назначение
task_status состояние по taskId: running / completed / failed / cancelled / timeout
task_result результат и лог (живой — доступен и пока задача выполняется)
task_cancel отменить (завершает дерево процессов)

Опция background: false у длительной команды — выполнить синхронно с потоковым логом и прогрессом (см. выше).

Отладочный лог: опция debug

У каждой команды есть debug. При debug: true команда выполняется синхронно, уровень логгеров поднимается до Отладки, собранный лог возвращается в результате (в т.ч. при исключении). Длительную команду debug переводит в синхронный режим.

Конфигурация (zero-config)

По умолчанию параметры выводятся из соглашений (запуск oscript <entry> из корня проекта):

Параметр Умолчание
Рабочий каталог ТекущийКаталог()
Точка входа CLI из манифеста пакета (opm-metadata.xml/packagedef), исключая mcp-скрипт; иначе main.os рядом с ним
Путь oscript автоопределение в PATH
Каталог фоновых задач <временный каталог ОС>/autumn-mcpify-tasks (не в проекте)
Префикс логгера (debug) "" (все логгеры)

Нестандартное приложение переопределяет нужное до Старт():

Запуск = Новый MCP_Запуск();
Запуск.Конфигурация()
    .УстановитьТочкаВходаCLI("app/cli.os")
    .УстановитьПрефиксЛоггера("myapp");
Запуск.Старт();

Архитектура

Сервер — отдельная точка входа (не подкоманда myapp mcp): так рогатки autumn-cli и autumn-mcp не конфликтуют (обе вешают ПриЗапускеПриложения). MCP_Запуск строит autumn-контекст с ЗапускатьРогатки = Ложь и запускает сервер (MCP_Сервер из autumn-mcp) вручную. Команды исполняются in-process: бин команды резолвится из контейнера, сервисы &Пластилин автовайрятся, поля заполняются Рефлектором. Лог стримится клиенту как notifications/message.

autumn-mcp подключается только в MCP_Запуск (#Использовать autumn-mcp), ради бина MCP_Сервер. Штатная точка входа CLI библиотеку вообще не грузит, поэтому рогатка autumn-mcp не может перехватить обычные команды. Даже если приложение зачем-то подключит autumn-mcpify в CLI-точке, это безопасно: OneScript компилирует классы лениво, и #Использовать autumn-mcp внутри MCP_Запуск срабатывает лишь при Новый MCP_Запуск() (в точке входа MCP), а не при штатном запуске, где MCP_Запуск не инстанцируется.

Публичный API (src/Классы)

Это всё, чем пользуется потребитель:

Класс Роль
MCP_Запуск точка входа: Новый MCP_Запуск(); Старт(); Конфигурация() для override
MCP_АннотацияДоступноВMCP маркер &ДоступноВMCP (opt-in команды в MCP)
MCP_Аннотация* маркеры намерения (&MCPДлительная, &MCPРазрушающая и пр.)

Внутренняя реализация (src/internal/Классы)

Не часть публичного API; подключается относительным #Использовать "../internal" из MCP_Запуск и не сканируется загрузчиком пакета напрямую:

Класс Роль
MCP_Конфигурация параметры запуска (zero-config соглашения + сеттеры)
MCP_РеестрИнструментов рефлексия команд autumn-cli → MCP-инструменты + JSON Schema
MCP_ИнструментКоманды исполнение команды in-process: синхронно / фоном / debug
MCP_КэшОпций сессионный кэш значений опций по имени
MCP_ИнструментКэша инструменты cache_show / cache_clear
MCP_РеестрЗадач реестр фоновых задач: запуск, статус, живой лог, отмена/таймаут
MCP_ИсполнительЗадачи тело фоновой задачи: внешний процесс, живой лог в файл, таймаут
MCP_ИнструментЗадачи инструменты task_status / task_result / task_cancel
MCP_АппендерУведомлений аппендер logos → notifications/message (стриминг лога)
MCP_АппендерПрогресса аппендер logos → notifications/progress (прогресс по INFO-логу)
MCP_БуферАппендер буфер-аппендер logos для захвата debug-лога
MCP_Платформа кроссплатформенные операции над процессами (убийство дерева по PID)

OneScript не поддерживает модификаторы доступа у классов — формально внутренние классы остаются Новый-абельными после загрузки библиотеки. Каталог src/internal — организационная граница (та же идиома, что в async): он обозначает приватный контракт и держит публичную папку src/Классы чистой.

Проверка вручную

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | oscript src/mcp.os

About

Превращает CLI-приложение на autumn-cli в MCP-сервер

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors