Skip to main content
Glama

mcp-delegate

Un servidor MCP que ofrece a Claude Code (como orquestador) una herramienta para delegar una tarea a un bucle agéntico completo y separado que se ejecuta en un modelo distinto (local vía Ollama, o remoto vía OpenRouter), con su propio acceso a herramientas (archivos, bash, etc.), y que devuelve únicamente un resultado final — funcionalmente equivalente a un subagente nativo, pero independiente del modelo.

Consulta mcp-subagent-delegation-plan.md para el plan de construcción completo, estructurado en fases como commits/checkpoints independientes.

Estado

Fases 1, 2, 3 y 4 completadas.

  • delegate_task — una sola llamada de completado de chat contra un endpoint compatible con OpenAI y configurado (Ollama, LM Studio, vLLM, OpenRouter, ...).

  • delegate_agentic_task — le da al modelo delegado su propio bucle de uso de herramientas (read_file, write_file, run_bash) en el directorio de trabajo especificado por quien llama; se ejecuta hasta que deja de llamar a herramientas, alcanza max_iterations o supera timeout_seconds.

  • list_recent_delegations — permite inspeccionar qué hicieron realmente las delegaciones anteriores (con cualquiera de las dos herramientas), sin tener que bucear en los registros ni volver a ejecutar nada.

  • get_delegation_transcript — transcripción completa del intercambio de mensajes y llamadas a herramientas de una delegación, cuando se ejecutó con capture_transcript=True (p. ej., para ejecuciones de comparación o evaluación de modelos).

Desviación del plan original: la fase 2 pedía envolver agent-loop como un subproceso. agent-loop solo admite Linux/macOS/WSL, y este servidor necesita ejecutarse de forma nativa en Windows, así que hemos construido en su lugar el bucle en el propio proceso descrito como alternativa en la fase 5: la misma interfaz de herramientas, sin la complejidad de subprocesos ni de eliminación de códigos ANSI, y evita por completo la licencia AGPL/sin uso comercial de agent-loop. Ver delegate/agentic.py.

Nota de seguridad: working_dir lo especifica el llamante; no es un sandbox fijo: el modelo delegado obtiene acceso no supervisado a archivos y bash del directorio al que se le apunte. Las herramientas de archivo (read_file/write_file) están limitadas para permanecer dentro de working_dir; run_bash se ejecuta con ese directorio como cwd, pero los comandos de shell no están supervisados del todo y podrían escapar de él (p. ej., cd ..). Apunta esto a un directorio en el que te sientas cómodo con que un modelo autónomo pueda leer, escribir y ejecutar comandos.

Nota sobre guardarraíles: el plan original, en su fase 4, pedía confirmar que las protecciones propias de agent-loop (tope de iteraciones, detección de repeticiones) estuvieran activas. Como no estamos usando agent-loop, la validación no es directamente aplicable: nuestro bucle tiene sus propios topes max_iterations y timeout_seconds (verificado en pruebas), pero no tiene detección de repeticiones. Un modelo que se quede atascado alternando entre dos llamadas a herramientas se ejecutará hasta alcanzar max_iterations en lugar de ser detectado a tiempo. Merece la pena añadirlo si eso llega a pasar en la práctica.

Related MCP server: deepseek-subagent-mcp

Configuración

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

Varios backends

Ambas herramientas aceptan un parámetro opcional backend que consulta base_url/model/api_key desde models.json en lugar de las variables de entorno DELEGATE_* por defecto — p. ej., backend="ollama-local" para una llamada y backend="openrouter-free" para otra dentro del mismo turno, cada una ejecutándose de forma concurrente. model, si se proporciona también, sobrescribe únicamente la cadena del modelo dentro de ese backend.

Para referenciar una variable de entorno para una clave en lugar de escribirla en 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 está incluido en .gitignore, igual que .env.

Concurrencia

Las llamadas a herramientas MCP ya se ejecutan en hilos de trabajo independientes, por lo que las delegaciones concurrentes se ejecutan en paralelo sin ningún tipo de cableado adicional. DELEGATE_MAX_CONCURRENCY (por defecto 4, ver .env.example) limita cuántas delegaciones — mediante ambas herramientas, para cualquier backend — se ejecutan a la vez, para evitar que una gran reventa sobrecargue un servidor de modelos local o los límites de frecuencia de una API de pago.

Ejecete el servidor directamente (sobre todo útil para comprobar que arranca sin errores; después espera en stdio a un cliente MCP):

uv run server.py

Registro (logging)

Cada llamada a delegate_task/delegate_agentic_task — tanto de éxito como fallida — se registra en un archivo SQLite local, conclusiones.db (gitignored, se crea en el primer uso): herramienta, backend, model, texto de la tarea, hora de inicio/fin, número de iteraciones, éxito/fallo, un avance truncado del resultado/error y el consumo de tokens si el backend lo proporcionó. Puedes consultarlo mediante la herramienta list_recent_delegations o directamente con sqlite3 delegations.db "select * from delegations order by id desc limit 20". El registro es con los mejores esfuerzos: en fallo del registro no dará al traste con una delegación que por lo demás haya tenido éxito.

Ambas herramientas añaden también una línea final [tokens: N prompt / N completion / N total ($cost)] a su propio valor de retorno cuando el backend informa del uso, para que el agente que llama lo vea de inmediato, sin una llamada adicional a list_recent_delegations.

Seguimiento del costo

pricing.json asigna a cada cadena de modelo una tarifa en USD {input_per_million, output_per_million}. Cuando el modelo resuelto de una llamada tiene entrada, el coste se calcula a partir del uso real de tokens, se registra en delegations.db (columna cost_usd) y se incluye en el sufijo [tokens: ...]. Un modelo sin entrada registra cost_usd = NULL: desconocido, no se asume como gratis, de modo que una entrada que falte no puede infravalorar el gasto en silencio. Los modelos locales no suelen tener entrada por esa razón; los modelos son realmente gratuitos (p. ej., :free de OpenRouter) reciben una entrada explícita {"input_per_million": 0, "output_per_million": 0} en lugar de quedar fuera.

A diferencia de .env/models.json, pricing.json no es un secreto ni específico del entorno, por lo que se incluye con seguimiento de versiones directamente, en lugar de estar republicado en .gitignore. Los precios cambiana: el archivo implementado se obtuvo de /api/v1/models de OpenRouter el 2026-08-21 para los modelos mencionados en una competición de modelos para la que se creó esto; vuelve a consultarlo y edítalo para añadir o actualizar modelos según haga falta.

Captura de transcripción (comparación/evaluación de modelos)

Ambas herramientas tienen capture_transcript: bool = False. Cuando está configurado, se registra el intercambio completo de mensajes — cada mensaje del modelo, cada llamada a herramientas y su resultado, no solo la respuesta final —, y el valor de retorno recibe un sufijo [delegation_id: N]. Puedes recuperarlo con get_delegation_transcriptn(delegation_id).

Esto existe para ejecutar la misma tarea con varios modelos/backends y comparar no solo las respuesta final sino cómo ha llegado cada uno hasta ella (la selección de herramientas, llamadas a herramientas con formato incorrecto, reintentos) — p. ej., un examen comparado entre modelos candidatos antes de elegir uno para producción. Está desactivado por defecto porque es un sobrecoste de registro que no quieres en una delegación rutinaria.

Registro con Claude Code

Un .mcp.json a nivel de proyecto ya está incluido en el repositorio (uv run server.py). Reinicia Claude Code en este directorio, o ejecuta claude mcp list para confirmar que ha cargado el servidor delegate, y luego pídele que llame a la herramienta delegate_task con un prompt trivial para confirmar el ruta de ida y vuelta.

Herramientas

  • delegate_task(prompt, model=None, system_prompt=None, backend=None, capture_transcript=False) -> str — llamada de chat de una sola pasada contra el backend configurado.

  • delegate_agentic_task(task, working_dir, model=None, max_iterations=20, timeout_seconds=600, backend=None, cache_transcript=False) -> str — delegación en varios pasos con las herramientas read_file/write_file/run_bash, limitadas a working_dir. Devuelve solo la respuesta final, no la transcripción completa, salvo que capture_transcript=True.

  • list_recent_delegations(limit=20) -> list[dict] — delegaciones registradas más recientes, primero las más nuevas.

  • get_delegation_transcript(delegation_id) -> list[dict] — transcripción completa de una delegación registrada con capture_transcript=True.

delegate_task/delegate_agentic_task devuelven los errores (configuración incorrecta, endpoint inaccesible, timeouts, límite de iteraciones) como cadenas "Error: ..." en lugar de lanzar una excepción, para que un agente que llama pueda ver qué ha pasado.

Available Tools

4 tools
delegate_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

    A4.7/5.0

    Scored across 4 tools

    Disambiguation5/5

    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.

    Naming Consistency5/5

    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.

    Tool Count5/5

    Four tools precisely cover the core delegation workflow: create a delegation (two variants), list delegations, and inspect a transcript. No unnecessary extras.

    Completeness5/5

    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

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables Claude to delegate tasks to external coding agents (Codex or Antigravity) for independent reviews, separate quota usage, and async processing.
      6
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables 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.
      6
      MIT
    • F
      license
      A
      quality
      C
      maintenance
      Enables 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
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables 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