mcp-delegate
mcp-delegate
MCP-сервер, который даёт Claude Code (как оркестратору) инструмент для делегирования задачи отдельному полному агентному циклу, работающему на другой модели (локально через Ollama или удалённо через OpenRouter), с собственным доступом к инструментам (файлы, bash и т.д.), возвращая только конечный результат — функционально эквивалентен нативному субагенту, но не привязан к конкретной модели.
Полный план сборки см. в mcp-subagent-delegation-plan.md, разбитый на фазы в виде отдельных коммитов/контрольных точек.
Статус
Фазы 1, 2, 3 и 4 завершены.
delegate_task— одноразовая чат-генерация против настроенной OpenAI-совместимой конечной точки (Ollama, LM Studio, vLLM, OpenRouter, ...).delegate_agentic_task— даёт делегированной модели собственный цикл использования инструментов (read_file,write_file,run_bash), ограниченный рабочей директорией, указанной вызывающей стороной; выполняется до тех пор, пока модель не перестанет вызывать инструменты, не достигнетmax_iterationsили не превыситtimeout_seconds.list_recent_delegations— просмотр того, что реально делали прошлые делегирования (любым инструментом), без копания в логах или повторного запуска.get_delegation_transcript— полный транскрипт сообщений/вызовов инструментов для одного делегирования, если оно выполнялось сcapture_transcript=True(например, для прогонов сравнения моделей/оценки).
Отклонение от исходного плана: Фаза 2 предусматривала обёртку agent-loop как подпроцесса. agent-loop поддерживает только Linux/macOS/WSL, а этот сервер должен работать нативно на Windows, поэтому мы построили внутрипроцессный цикл, описанный как альтернатива в Фазе 5 — тот же интерфейс инструментов, без сложностей подпроцессов/очистки ANSI, и это полностью обходит лицензию AGPL/запрет на коммерческое использование agent-loop. См. delegate/agentic.py.
Примечание по безопасности: working_dir задаётся вызывающей стороной, а не является фиксированной песочницей — делегированная модель получает неконтролируемый доступ к файлам/bash в любой директории, на которую её направят. Файловые инструменты (read_file/write_file) ограничены рамками working_dir; run_bash запускается с этой директорией как cwd, но shell-команды не полностью изолированы и могут выйти за её пределы (например, cd ..). Направляйте её на директорию, в которой вы готовы позволить неконтролируемой модели читать, писать и выполнять команды.
Примечание о защитных ограничениях: Фаза 4 исходного плана требовала подтвердить, что собственные защитные ограничения agent-loop (предел итераций, обнаружение повторений) активны. Поскольку мы не используем agent-loop, это напрямую не применимо — у нашего цикла есть собственные пределы max_iterations и timeout_seconds (проверено в тестировании), но нет обнаружения повторений. Модель, застрявшая в чередовании двух вызовов инструментов, будет работать до достижения max_iterations, а не будет остановлена раньше. Стоит добавить, если это начнёт происходить на практике.
Related MCP server: deepseek-subagent-mcp
Настройка
uv sync
cp .env.example .env # fill in DELEGATE_BASE_URL / DELEGATE_API_KEY / DELEGATE_MODEL
cp models.json.example models.json # optional: named backends, see belowНесколько бэкендов
Оба инструмента принимают необязательный параметр backend, который берёт base_url/model/api_key из models.json вместо переменных окружения DELEGATE_* по умолчанию — например, backend="ollama-local" для одного вызова и backend="openrouter-free" для другого в том же ходе, каждый выполняется параллельно. model, если также указан, переопределяет только строку модели внутри этого бэкенда.
Для ключа можно сослаться на переменную окружения вместо того, чтобы вписывать его прямо в models.json:
{
"openrouter-free": {
"base_url": "https://openrouter.ai/api/v1",
"model": "nvidia/nemotron-nano-9b-v2:free",
"api_key_env": "OPENROUTER_API_KEY"
}
}models.json находится в gitignore, как и .env.
Параллельность
Вызовы MCP-инструментов уже выполняются на отдельных рабочих потоках, поэтому параллельные делегирования работают одновременно без дополнительной обвязки. DELEGATE_MAX_CONCURRENCY (по умолчанию 4, см. .env.example) ограничивает, сколько делегирований — через оба инструмента, на любом бэкенде — выполняется одновременно, чтобы большой веерный запуск не перегрузил локальный сервер моделей или не упёрся в лимиты скорости платного API.
Запуск сервера напрямую (в основном полезно, чтобы проверить, что он запускается без ошибок — затем он ждёт на stdio MCP-клиента):
uv run server.pyЛогирование
Каждый вызов delegate_task/delegate_agentic_task — успешный или неудачный — логируется в локальный SQLite-файл delegations.db (в gitignore, создаётся при первом использовании): инструмент, бэкенд, модель, текст задачи, время начала/окончания, количество итераций, успех/неудача, урезанный предпросмотр результата/ошибки и использование токенов, если бэкенд его вернул. Запрос через инструмент list_recent_delegations или напрямую через sqlite3 delegations.db "select * from delegations order by id desc limit 20". Логирование — best-effort: сбой логирования не уронит в остальном успешное делегирование.
Оба инструмента также добавляют в конец собственного возвращаемого значения строку [tokens: N prompt / N completion / N total ($cost)], когда бэкенд сообщает об использовании, чтобы вызывающий агент видел это сразу без отдельного вызова list_recent_delegations.
Отслеживание стоимости
pricing.json сопоставляет строку модели → {input_per_million, output_per_million} ставки в долларах США. Когда у разрешённой модели вызова есть запись, стоимость вычисляется из фактического использования токенов, логируется в delegations.db (колонка cost_usd) и включается в суффикс [tokens: ...]. Модель без записи логирует cost_usd = NULL — неизвестно, а не считается бесплатной, — чтобы отсутствующая запись не могла молча занизить расходы. Локальные модели обычно не имеют записей по этой причине; действительно бесплатные модели (например, модели OpenRouter :free) получают явную запись {"input_per_million": 0, "output_per_million": 0} вместо того, чтобы быть опущенными.
В отличие от .env/models.json, pricing.json не является секретом и не зависит от окружения, поэтому он коммитится напрямую, а не в gitignore. Цены дрейфуют — поставляемый файл был получен из /api/v1/models OpenRouter 2026-08-21 для моделей, названных в сравнительном прогоне моделей, для которого это и было построено; перезапросите и отредактируйте его, чтобы добавить/обновить модели по мере необходимости.
Захват транскрипта (прогоны сравнения моделей / оценки)
Оба инструмента принимают capture_transcript: bool = False. При установке полный обмен сообщениями — каждое сообщение модели, вызов инструмента и результат инструмента, а не только финальный ответ — логируется, и возвращаемое значение получает суффикс [delegation_id: N]. Получить его можно через get_delegation_transcript(delegation_id).
Это существует для прогона одной и той же задачи через несколько разных моделей/бэкендов и сравнения не только финального ответа, но и того, как каждая из них к нему пришла (выбор инструментов, некорректные вызовы инструментов, повторы) — например, сравнительный прогон кандидатных моделей перед выбором одной для продакшена. По умолчанию выключено, так как это дополнительные накладные расходы на логирование, которые не нужны для рутинного делегирования.
Регистрация в Claude Code
Проектный .mcp.json уже закоммичен (uv run server.py). Перезапустите Claude Code в этой директории или выполните claude mcp list, чтобы подтвердить, что он подхватил сервер delegate, затем попросите его вызвать delegate_task с тривиальным промптом, чтобы подтвердить полный цикл.
Инструменты
delegate_task(prompt, model=None, system_prompt=None, backend=None, capture_transcript=False) -> str— однократная чат-генерация против настроенного бэкенда.delegate_agentic_task(task, working_dir, model=None, max_iterations=20, timeout_seconds=600, backend=None, capture_transcript=False) -> str— многошаговое делегирование с инструментамиread_file/write_file/run_bash, ограниченнымиworking_dir. Возвращает только финальный ответ, а не полный транскрипт, если толькоcapture_transcript=True.list_recent_delegations(limit=20) -> list[dict]— последние залогированные делегирования, новые сверху.get_delegation_transcript(delegation_id) -> list[dict]— полный транскрипт одного делегирования, залогированного сcapture_transcript=True.
delegate_task/delegate_agentic_task возвращают ошибки (неверная конфигурация, недоступная конечная точка, таймаут, предел итераций) как строки "Error: ..." вместо исключений, чтобы вызывающий агент мог видеть, что пошло не так.
Available Tools
4 toolsdelegate_agentic_taskA
Delegate a multi-step task to a model with its own tool-use loop (read_file, write_file, run_bash) scoped to working_dir. Runs until the model stops calling tools, hits max_iterations, or exceeds timeout_seconds. Returns only the final answer, not the full transcript.
The delegated model gets unattended file/bash access within working_dir for the duration of the call - point it at a directory you're comfortable it can read, write, and execute commands in.
Args:
task: The task instruction to give the delegated model.
working_dir: Directory the model's tools are scoped to.
model: Override just the model string for this call.
max_iterations: Stop after this many tool-call rounds.
timeout_seconds: Wall-clock budget for the whole task.
backend: Named backend from models.json (base_url/model/api_key) to
use instead of the default DELEGATE_* env vars. model, if also
given, overrides the model within that backend.
capture_transcript: Log every model message and tool call/result for
later retrieval via get_delegation_transcript, instead of just
the final answer. Off by default; useful when comparing models
(e.g. a bake-off) rather than for routine use.
Inputs: task (required), working_dir (required), model, backend, +3 more. Returns: result
delegate_taskA
Delegate a single-shot task to a configured OpenAI-compatible model (e.g. local Ollama or OpenRouter) and return its text response verbatim.
Args:
prompt: The task/question to send to the delegated model.
model: Override just the model string for this call.
system_prompt: Optional system prompt to steer the delegated model.
backend: Named backend from models.json (base_url/model/api_key) to
use instead of the default DELEGATE_* env vars. model, if also
given, overrides the model within that backend.
capture_transcript: Log the full message exchange for later retrieval
via get_delegation_transcript. Off by default; useful when
comparing models (e.g. a bake-off) rather than for routine use.
Inputs: prompt (required), model, backend, system_prompt, +1 more. Returns: result
get_delegation_transcriptA
Full message transcript (every model message and tool call/result) for one delegation, if it was run with capture_transcript=True. Get the id from list_recent_delegations. Returns an error string if no transcript was captured for that id.
Args:
delegation_id: The id field from a list_recent_delegations row.
Inputs: delegation_id (required). Returns: result
list_recent_delegationsA
List the most recent delegate_task / delegate_agentic_task calls (backend, model, task, duration, iterations, success, token usage, USD cost if the model has a pricing.json entry, truncated result), most recent first. Answers "what did the delegated model actually do" without re-running anything.
Args: limit: Max number of records to return (default 20).
Inputs: limit. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
Each tool has a distinct purpose: delegate_task for single-turn, delegate_agentic_task for multi-step with tool use, list_recent_delegations for querying history, and get_delegation_transcript for retrieving full logs. No overlap.
All tool names follow a consistent snake_case verb_noun pattern (delegate_task, delegate_agentic_task, list_recent_delegations, get_delegation_transcript), with clear action prefixes.
Four tools precisely cover the core delegation workflow: create a delegation (two variants), list delegations, and inspect a transcript. No unnecessary extras.
The tool set covers creating delegations, retrieving summaries, and fetching full transcripts. No update/delete is needed for delegation records, so the surface is complete for its purpose.
Maintenance
Related MCP Connectors
Agent-native task management: your AI agent is the interface. Delegate to anyone by email.
Shared task layer for AI agents: tasks, handoffs and decisions that persist across tools.
Delegate tasks between AI agents on different platforms and collect the results.
Discover available AI models and delegate analysis or code review from your existing agent.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables Claude to delegate tasks to external coding agents (Codex or Antigravity) for independent reviews, separate quota usage, and async processing.6MIT
- AlicenseAqualityCmaintenanceEnables AI coding agents like Claude Code or Codex to delegate tasks to a DeepSeek Harness subagent with its own context window, providing tools for task delegation, result waiting, continuation, and supervision with sandboxed execution.6MIT
- FlicenseAqualityCmaintenanceEnables main agents to delegate memory retrieval, web research, and multi-step tasks to internal sub-agents, returning concise conclusions while keeping detailed tool calls and raw content out of the main context.3-
- AlicenseNot gradedqualityBmaintenanceEnables MCP-capable coding assistants to delegate repository investigation, bounded implementation work, and noisy command runs (tests, builds, linters) to sandboxed OpenCode agents. Each role can use an independently selected model, and only concise results are returned to the parent agent, which keeps responsibility for architecture and high-risk operations.MIT