Skip to main content
Glama

localagents

Delega el trabajo pesado de Claude Code en un modelo que se ejecuta en tu propio hardware.

localagents es un servidor MCP que le da a Claude Code una herramienta run_agent. Cada llamada inicia una sesión headless completa de Claude Code — las mismas herramientas, el mismo CLAUDE.md, el mismo árbol de trabajo — salvo que su tráfico de API va a un servidor llama.cpp o vLLM que tú ejecutas en lugar de a Anthropic. Claude escribe el encargo, el modelo local hace el trabajo, Claude revisa el resultado. Tu presupuesto de tokens de Anthropic se gasta en las partes que lo necesitan.

Un Qwen de 27B en una GPU es perfectamente capaz de «añade una CLI para este módulo y los tests correspondientes»; Opus está mejor empleado en la conversación de diseño que en ver correr pytest. Dos agentes locales en paralelo pueden construir las dos mitades de un paquete contra una interfaz fijada.

Estado: fase inicial. Funciona, lo uso a diario, y la interfaz cambiará. Está dirigido específicamente a llama.cpp y vLLM; Ollama no es un objetivo.

Cómo funciona

Claude Code (your session)
   │  MCP: run_agent(task, model=...)
   ▼
localagents ── spawns ──▶ headless `claude` (Agent SDK)
   │                          │  ANTHROPIC_BASE_URL
   │                          ▼
   └──── in-process shim ◀────┘   normalises requests, logs them,
              │                   translates backend errors
              ▼
   llama-server / vllm   (/v1/messages, on your machine or your LAN)

Tres cosas hacen que esto sea algo más que una variable de entorno:

  1. Un registro que se sondea en vivo. models.yaml indica dónde están los servidores y ofrece un menú de nombres de modelos. Lo que cada servidor está sirviendo realmente en ese momento, su ventana de contexto real y cuántos slots están ocupados se descubren en cada llamada. Tú levantas y detienes los modelos manualmente — el servidor nunca lanza nada — y cuando Claude necesita un modelo que no está en ejecución, te lo pide por su nombre.

  2. Un shim entre Claude Code y el backend. Claude Code envía cosas que las plantillas de chat locales rechazan, y los servidores locales fallan de maneras que Claude Code no reconoce. El shim corrige ambas direcciones (detalles más abajo) y escribe un requests.jsonl por trabajo para que puedas ver exactamente qué pasó por el cable.

  3. El mismo modelo de aislamiento que los subagentes propios de Claude. Por defecto, un trabajo opera en tu árbol, como hace la herramienta Agent. isolation: worktree le da un worktree de git nuevo en una rama local-agent/<job>, que se conserva solo si cambió algo, con un diffstat en el registro del trabajo para que Claude pueda revisarlo como un diff.

Related MCP server: Ollama MCP Server

Requisitos

  • Python 3.12+ y uv

  • Claude Code. El Agent SDK incluye su propio binario claude, así que no hay nada más que instalar.

  • Un servidor que hable el /v1/messages de Anthropic:

    • llama.cpp llama-server — arráncalo con --jinja; añade --slots --metrics para obtener ocupación y estadísticas de caché en la salida de la herramienta.

    • vLLM con --enable-auto-tool-choice --tool-call-parser <parser>.

  • Un modelo que pueda manejar realmente Claude Code: llamada a herramientas nativa sólida y una ventana de contexto de 128k o más por petición. Qwen3.8-27B funciona bien. Ventanas más pequeñas funcionan pero compactan constantemente; ver Ventanas de contexto.

Instalación

git clone https://github.com/ccebelenski/localagents.git && cd localagents
uv tool install -e .                  # `localagents` on PATH; editable, so repo edits apply
cp models.example.yaml models.yaml    # edit for your servers (gitignored)
claude mcp add --scope user local -- localagents --config "$PWD/models.yaml"

El ámbito de usuario (user scope) significa que todos los proyectos obtienen el servidor local. Este hereda el directorio de trabajo (cwd) de la sesión de Claude Code que lo lanzó, así que run_agent usa por defecto el árbol de ese proyecto. Un proyecto puede tener su propio ./models.yaml para sobrescribir el registro.

Si prefieres limitarlo a un solo proyecto, pon esto en el .mcp.json de ese proyecto:

{"mcpServers": {"local": {"command": "localagents", "args": ["--config", "/path/to/models.yaml"]}}}

Reinicia Claude Code (o /mcp → reconnect) después de añadirlo; los servidores MCP se cargan al inicio.

Uso

Claude lo usa como cualquier otra herramienta. Pídeselo por su nombre y hará lo correcto:

Usa el agente local para añadir una opción --json a la CLI y cúbrela en los tests.

Lo que Claude hace detrás de eso: list_models para ver qué hay disponible, run_agent(task=…) que devuelve un id de trabajo, luego wait_job / job_status / job_log hasta que termina, después lee files_touched (o el diff del worktree) y comprueba el trabajo. Los trabajos que superan el tiempo de espera de 2 minutos de las herramientas de Claude Code pasan a segundo plano y se retoman más tarde; no tienes que hacer nada.

Si no hay nada adecuado en ejecución, se te pedirá que lo levantes:

qwen3.8-27b no se está ejecutando en ningún sitio. Pide al usuario que lo levante. Notas: codificador mediano por defecto en llama.cpp; ejecutar con --reasoning on

Levántalo como lo hagas normalmente, di «ya está», y Claude lo reintentará.

Herramientas

herramienta

qué hace

list_models

endpoints con estado de salud en vivo, ids servidos, ventana de contexto, ocupación de slots; el pool con available

run_agent

iniciar un trabajo: task, model, cwd, isolation (none/worktree), wait_s, max_turns, permission_mode, resume_job, …

wait_job / job_status / job_log / list_jobs / cancel_job

seguir y controlar trabajos

request_model

qué decirle al usuario para que levante un modelo del pool

register_model / register_endpoint

añadir al pool desde dentro de una sesión (escrito en models.local.yaml)

local_complete

generación one-shot sin herramientas — resúmenes, borradores, clasificación

Los registros de los trabajos viven en ~/.local/state/localagents/jobs/<job>/: transcript.txt (lo que el agente dijo e hizo), events.jsonl (cada mensaje del SDK), requests.jsonl (cada petición al backend con tiempos, tamaño y uso), y requests_full.jsonl si activas el volcado de peticiones.

Configuración: models.yaml

Parte de models.example.yaml. Se relee en cada llamada, así que los cambios tienen efecto inmediato, y el servidor nunca lo reescribe — register_* escribe en un sidecar models.local.yaml que se fusiona por encima.

endpoints:
  llamacpp:
    base_url: http://127.0.0.1:8080
    backend: llama.cpp
  gpu-server:
    base_url: http://gpu-server.lan:8000
    backend: vllm
    host: gpu-server

models:
  qwen3.8-27b:
    notes: default mid-size coder on llama.cpp; run with --reasoning on
  deepseek-v4-flash:
    host: gpu-server
    notes: vllm needs --enable-auto-tool-choice --tool-call-parser deepseek_v3
  • endpoints son lugares que sirven /v1/messages. Lo que sirven se sondea.

  • models son solo nombres. Un nombre se compara de forma difusa contra los ids servidos (qwen3.8-27b encuentra unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL), así que una entrada solo necesita notes y quizá un host para transmitir cuando se te pida que lo levantes. served_name (id exacto o glob), endpoint, context (ventana de respaldo) y bring_up (un comando de arranque) existen como sobrescrituras si las quieres. Los comandos de arranque se quedan obsoletos rápidamente; un nombre y una nota suelen envejecer mejor.

  • defaults cubren el modelo por defecto, permission_mode (acceptEdits), herramientas permitidas y no permitidas (los subagentes no pueden crear subagentes), qué ajustes de Claude cargar, max_turns, timeout_s, y un sufijo de prompt de sistema que le dice al agente que es un delegado y cómo informar.

Qué hace el shim

Tanto llama.cpp como vLLM hablan /v1/messages de forma nativa, así que apuntar ANTHROPIC_BASE_URL a ellos casi funciona. El shim cierra las brechas:

Mensajes de sistema en mitad de la conversación. Claude Code pone entradas role: system dentro de messages — la lista de habilidades, un marcador de presupuesto de tokens, y una más por turno. La plantilla de chat de Qwen lo rechaza: "System message must be at the beginning". El shim pliega cada una dentro del mensaje de usuario adyacente como un bloque de texto <system>…</system>, en su lugar. Elevarlas al campo system de nivel superior en su lugar cambia el inicio del prompt cada turno, lo que invalida el prefijo de la caché KV del servidor y re-evalúa todo el prompt de ~35k tokens cada vez (21–47 s por turno en un 27B). Plegar en su lugar mantiene el prompt de solo añadidura: f_sim_best 0.88–0.99 en el log de llama-server, 2.5–14 s por turno.

Desbordamiento de contexto. Claude Code asume una ventana de 200k para cualquier modelo que no reconoce; con un slot más pequeño se topa con exceed_context_size_error de llama.cpp, que no entiende, y el trabajo muere. Ver la siguiente sección.

Todo lo que hace el shim es un no-op cuando no se necesita, y cada petición se registra con su tiempo, número de mensajes, tamaño en bytes y uso notificado.

Ventanas de contexto

Dos capas mantienen una sesión dentro de la ventana real:

  1. La sonda la lee — llama.cpp /props n_ctx (por slot: -c dividido por --parallel cuando la KV unificada está desactivada), vLLM max_model_len — y la sesión recibe CLAUDE_CODE_MAX_CONTEXT_TOKENS. El auto-compactado propio de Claude Code se dispara entonces en el punto correcto. Por debajo de 128k, el presupuesto de salida también se reduce a n_ctx/8, porque el umbral de compactación es window − max_output y de otro modo se quedaría en cero.

  2. Si una petición aún se desborda, el shim reescribe el error del backend en el prompt is too long: N tokens > M maximum de Anthropic, al que Claude Code responde compactando y reintentando.

Con 64k esto funciona pero sufre thrashing: los ~20k de prompt fijo y esquemas de herramientas de Claude Code, más un resumen de compactación de ~7k tokens (~55 s en un 27B) y los archivos que vuelve a adjuntar, rellenan la ventana en pocos turnos y su guardia anti-thrash termina el trabajo. Dale a cada slot 128k o más.

Notas del backend

  • llama.cpp: llama-server -hf <gguf> --jinja -fa on --slots --metrics, más --reasoning on para modelos de razonamiento y --parallel N para trabajos concurrentes. Con /slots activado, list_models muestra {total, busy, free} para que Claude sepa si un segundo agente se ejecutará ahora o hará cola. Con /metrics activado, cada trabajo registra tokens de prompt procesados frente a cacheados, ratio de aciertos de caché, tok/s de prompt y de generación, y aceptación de decodificación especulativa — los contadores son de todo el servidor, así que los trabajos superpuestos comparten el delta.

  • vLLM: vllm serve <model> --served-model-name <alias> --enable-auto-tool-choice --tool-call-parser <parser>. La ventana de contexto viene de max_model_len en /v1/models; la ocupación (requests_running/waiting, kv_cache_usage) y las estadísticas de caché por trabajo vienen de su /metrics, siempre activo. vLLM notifica el desbordamiento de contexto en el endpoint de Anthropic como HTTP 500 internal_error; el shim también lo traduce. La sesión se inicia con CLAUDE_CODE_ATTRIBUTION_HEADER=0 porque el hash de atribución por petición impide el cacheo de prefijos. Verificado con DeepSeek-V4-Flash: los bloques de razonamiento se reproducen con sus firmas, aciertos de caché de prefijo en cada turno después del primero.

  • El primer turno de un trabajo cuesta unos 20k tokens de prompt en un slot frío (prompt de sistema más esquemas de herramientas), ~10 s en un 27B. Todo lo demás es un acierto de caché más el delta.

Desarrollo

uv sync --dev
uv run pytest -q

Consulta CONTRIBUTING.md para la estructura y cómo probar cambios contra un servidor real.

Licencia

MIT. Consulta LICENSE.

Copyright © 2026 Chris Cebelenski

A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    C
    quality
    D
    maintenance
    Bridges Claude Desktop with local LLM instances running via llama-server, enabling full conversation support with complete parameter control and health monitoring. Allows users to chat with their local models directly through Claude Desktop with configurable sampling parameters.
    3
    9
    9
    Creative Commons Zero v1.0 Universal
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude to delegate coding tasks to local Ollama models, reducing API token usage by up to 98.75% while leveraging local compute resources. Supports code generation, review, refactoring, and file analysis with Claude providing oversight and quality assurance.
    488
    24
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes local Ollama instances as tools for Claude Code, allowing users to offload code generation, text drafting, and embedding tasks to local GPUs. It supports multi-turn conversations and model management through the Model Context Protocol.
    MIT

View all related MCP servers

Related MCP Connectors

  • Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.

  • Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer

  • Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ccebelenski/localagents'

If you have feedback or need assistance with the MCP directory API, please join our Discord server