pypi local-delegate-mcpstdioMITupdated 8d ago
Delega tareas mecánicas texto→texto a un LLM local para conservar la cuota de tu suscripción de Claude. Un servidor MCP (stdio o daemon HTTP compartido) que es cliente genérico de cualquier endpoint OpenAI-compatible — llama-swap, Ollama, LM Studio, vLLM.
local delegate 能做什么?
local-delegate
Delega tareas mecánicas texto→texto a un LLM local para conservar la cuota de tu suscripción de Claude.
Un servidor MCP (stdio o daemon HTTP compartido) que es cliente genérico de cualquier
endpoint OpenAI-compatible — llama-swap, Ollama, LM Studio, vLLM.
zahirinatzuke.github.io/local-delegate — qué
hace y por qué, en una página (es/en). Su fuente está en site/.
Demo

Dashboard embebido (datos de ejemplo): estado del backend local (modelos montados, delegación en curso con su progreso por trozos, tools MCP), RAM/VRAM del sistema con consumo por proceso, tokens de contexto conservados, ahorro por herramienta y modelo, dónde corrió el cómputo —esta máquina o un backend remoto— y actividad reciente paginada en tu hora local. Se sirve en http://127.0.0.1:9393.
¿Por qué?
Cuando Claude tiene que resumir un log enorme, clasificar, extraer campos o generar boilerplate,
gasta cuota de tu suscripción en trabajo mecánico. local-delegate expone esas tareas como
tools MCP que corren en un LLM local: pasas path en vez de text y el archivo se lee
del lado del servidor, así el contenido grande nunca entra al contexto de Claude. Solo
vuelve el resultado corto — cuota que no gastaste.
Instalación rápida
Con uv no hay nada que instalar: uvx baja y ejecuta el paquete aislado.
Añádelo a tu config de MCP (Claude Desktop / Claude Code) en modo compatible stdio:
{
"mcpServers": {
"local-delegate": {
"command": "uvx",
"args": ["local-delegate-mcp"]
}
}
}
Ver plantillas completas en examples/.
O deja que el paquete lo configure todo por ti —entrada MCP, hooks, skill y la regla de
delegación en tu CLAUDE.md/AGENTS.md global— con un solo comando:
uv tool install local-delegate-mcp # deja `local-delegate` en el PATH
local-delegate install --dry-run # muestra exactamente qué tocaría
local-delegate install # aplica
También sirve uvx local-delegate-mcp install para probarlo sin instalar nada, pero ten en cuenta
que uvx no deja el comando disponible: monta un entorno efímero y lo borra al terminar, así
que después local-delegate doctor responderá «command not found». El propio install te lo avisa
si detecta ese caso.
Es idempotente, deja .bak de lo que edita, no toca configuración ajena y se revierte con
local-delegate uninstall. Detalle y opciones en Instalación de la integración.
Si usas varias sesiones o varios clientes en la misma máquina, se recomienda un solo daemon:
uvx local-delegate-mcp serve
El daemon sirve MCP en http://127.0.0.1:9393/mcp y el dashboard en
http://127.0.0.1:9393/. Codex, Claude Code, opencode y cualquier cliente compatible con Streamable HTTP
pueden compartir esa URL sin levantar procesos MCP duplicados. Guía completa:
Daemon compartido.
Para usar la GPU de otra máquina manteniendo los paths locales del cliente, usa un MCP local que apunte al backend remoto: guía Mac → PC y recipe técnica completa.
No fijes una versión vieja «por estabilidad». Un pin (
==X.Y.Z) congela también los rangos de dependencias que declaraba aquel wheel, y eso envejece mal: las versiones anteriores a la 0.12.2 pedíanmcpsin techo, así que hoy resuelven al SDK 2.x y mueren en el import. Si necesitas fijar, fija la actual, y súbela cuando salga una nueva.
En Windows, si lo registras como tarea al iniciar sesión, ejecuta el pythonw.exe del entorno
donde instalaste el paquete con -m local_delegate serve --log-level warning. pythonw no crea
consola ni botón en la barra de tareas. La tarea pertenece al usuario de Windows, no a Codex
ni a Claude: cualquier cliente local comparte el mismo daemon. El dashboard identifica ese único
proceso con la insignia DAEMON MCP; las sesiones conectadas son clientes HTTP, no procesos MCP
adicionales.
Requisitos
Python 3.11+ — con uvx no tienes que instalarlo tú, lo resuelve él; solo importa si instalas
con pip en un entorno propio.
Y un endpoint OpenAI-compatible ya corriendo, accesible en LOCAL_DELEGATE_BASE_URL
(default http://127.0.0.1:9292/v1). Cualquiera sirve:
- llama-swap — ver recipe con GPU Blackwell.
- Ollama —
http://127.0.0.1:11434/v1. - LM Studio, vLLM, o cualquier servidor que hable la API de OpenAI.
El paquete no arranca ningún backend por defecto (LOCAL_DELEGATE_AUTOSTART=0). El
auto-arranque de llama-swap es opt-in (ver tabla de configuración).
¿Qué versiones de llama-server/llama-swap usar y cómo disponer el workspace? Ver
Versiones del backend y workspace de referencia (sugerencia
probada, no requisito). local-delegate doctor compara tu instalación contra esas versiones y, de
paso, comprueba el resto del andamiaje —hooks, skill, memoria, entradas MCP y el daemon— sin
escribir nada (qué mira cada check).
Tools
Pasar path (en vez de text) hace que el MCP lea el archivo server-side → ahorro real de cuota.
| Tool | Qué hace | Rol de modelo (default) |
|---|---|---|
local_summarize |
Resume texto o archivo | mecánico / largo (auto) |
local_classify |
Devuelve UNA etiqueta de una lista | mecánico |
local_extract |
Extrae campos → objeto validado, no una cadena que haya que parsear | mecánico / largo (auto) |
local_boilerplate |
Genera código desde una spec | código |
local_delegate |
Escape genérico texto→texto | mecánico (o el que pases) |
local_lint_summary |
Resume logs de lint/tests/CI | mecánico / largo (auto) |
local_commit_msg |
Mensaje de commit desde un diff | código |
local_translate |
Traduce texto o archivo | mecánico / largo (auto) |
local_explain_code |
Explica código en prosa | código |
local_describe_image |
Describe una imagen o responde una pregunta sobre ella (imagen→texto) | visión |
local_status |
Diagnóstico de solo lectura: backend, catálogo, log, VRAM, RAM de sistema | — (no llama al backend de chat) |
Los modelos locales no usan tool-calling: el server arma el prompt + guardrails, hace POST al endpoint y devuelve solo texto.
Documentos largos. local_translate (y local_delegate con entradas largas) parten el texto
por límites naturales —headers Markdown, párrafos, líneas— y procesan un trozo por llamada
respetando el techo de max_tokens, concatenando las salidas en orden y conservando el formato en
las costuras. Un documento de 20 000+ caracteres vuelve completo en vez de cortado a mitad. El log
registra chunks: N y el dashboard muestra el progreso (trozo 3/7) mientras corre.
Resúmenes de documentos enormes. local_summarize y local_lint_summary hacen map-reduce
cuando la entrada no cabe en el modelo: resumen cada parte y luego resumen los resúmenes, por
niveles si hace falta. Antes truncaban —de un log de CI enorme se resumía el principio y el resto
se descartaba en silencio, que es justo donde suelen estar los errores— y ahora se lee entero.
local_extract sigue truncando a propósito: fusionar el JSON de varios trozos no tiene una
respuesta única y adivinarla sería peor que avisar.
Configuración
Todo por variables de entorno; nada hardcodeado. Los ids de modelo default son solo eso — cámbialos por los de tu backend.
| Variable | Default | Descripción |
|---|---|---|
LOCAL_DELEGATE_BASE_URL |
http://127.0.0.1:9292/v1 |
Endpoint OpenAI-compatible |
LOCAL_DELEGATE_API_KEY |
(vacío) | Bearer token, si tu endpoint lo exige |
LOCAL_DELEGATE_BACKEND_ORIGIN |
auto |
local/remote fuerzan el origen del cómputo; auto lo deduce del host. Ponlo si llegas al backend por un túnel (ssh -L, port-forward): en loopback se vería como local |
LOCAL_DELEGATE_TIMEOUT |
180 |
Timeout HTTP (segundos) |
LOCAL_DELEGATE_MAX_CONCURRENT_REQUESTS |
2 |
Backpressure máximo por proceso; compartido por todos los clientes del daemon |
LOCAL_DELEGATE_ASK |
1 |
Preguntar al usuario (vía elicitation) en vez de fallar seco: backend caído, modelo fuera del catálogo, output_format vacío. 0 lo desactiva |
LOCAL_DELEGATE_ASK_TIMEOUT |
30 |
Segundos de espera por una respuesta; agotados, la tool sigue como si no hubiera preguntado |
LOCAL_DELEGATE_LOG_DIR |
(dir de datos de usuario) | Directorio de los usage-YYYYMM.jsonl rotados por mes y del clients.jsonl |
LOCAL_DELEGATE_LOG |
(vacío = rotación activa) | Si se fija, ruta de un usage.jsonl explícito sin rotar (compatibilidad) |
LOCAL_DELEGATE_MODEL_MECHANICAL |
gemma3-4b |
Modelo para clasificar/extraer/resumen corto |
LOCAL_DELEGATE_MODEL_LONG |
llama31-8b |
Modelo para documentos largos |
LOCAL_DELEGATE_MODEL_CODE |
qwen25-coder-14b |
Modelo para código |
LOCAL_DELEGATE_MODEL_FAST |
qwen35-2b |
Modelo ultrarrápido / trivial |
LOCAL_DELEGATE_MODEL_VISION |
qwen3-vl-8b |
Modelo de visión para local_describe_image |
LOCAL_DELEGATE_MAX_IMAGE_MB |
8 |
Tope de tamaño de imagen para local_describe_image |
LOCAL_DELEGATE_LONG_INPUT_CHARS |
6000 |
Umbral mecánico↔largo |
LOCAL_DELEGATE_CHUNK_CHARS |
3500 |
Tamaño de trozo al partir documentos largos (local_translate, local_delegate) |
LOCAL_DELEGATE_CHUNK_MAX_TOKENS |
2048 |
Techo de max_tokens por trozo |
LOCAL_DELEGATE_CHUNK_MIN_CHARS |
400 |
Trozo mínimo: por debajo ya no se vuelve a partir |
LOCAL_DELEGATE_JSON_SCHEMA |
auto |
response_format con schema en local_extract: auto/on/off |
LOCAL_DELEGATE_FEEDBACK |
1 |
Línea de ahorro anexada al resultado cuando source=path (0 la apaga). En local_extract no se anexa al texto —rompería el JSON—: va dentro de _local_delegate |
LOCAL_DELEGATE_ALLOWED_DIRS |
(vacío = sin restricción) | Raíces permitidas para path, separadas por ; |
LOCAL_DELEGATE_WEB |
1 |
Web embebida del modo stdio (0 para desactivarla) |
LOCAL_DELEGATE_WEB_HOST / _PORT |
127.0.0.1 / 9393 |
Host/puerto de la web o del daemon |
LOCAL_DELEGATE_WEB_FONTS |
1 |
Tipografía de marca desde Google Fonts (0 = cero peticiones a terceros) |
LOCAL_DELEGATE_AUTOSTART |
0 |
Auto-arranque de llama-swap (opt-in) |
LLAMASWAP_EXE / LLAMASWAP_CONFIG / LLAMASWAP_LISTEN |
— | Solo si AUTOSTART=1 |
LLAMASWAP_WATCH_CONFIG |
0 |
1 añade -watch-config al backend autoarrancado |
La métrica de ahorro
El MCP registra cada llamada en un log rotado por mes y sirve un dashboard en
http://127.0.0.1:9393, con selector de rango y visibilidad de delegaciones en curso.
El ahorro de contexto = la entrada leída server-side (llamadas con source=path) ≈ tokens que
nunca entraron al contexto de Claude, contados una vez por delegación aunque el MCP la trocee.
Enfrente, el coste local = los tokens que consumió de verdad tu GPU sumando todas las
llamadas: una delegación troceada repite el prompt de sistema en cada trozo, y esa diferencia es
lo que costó trocear. Se usa siempre el token real que reporta el backend; chars ÷ 4 es solo el
respaldo cuando no lo da. Detalle en la wiki.
Los rangos, los días del gráfico y las horas de la tabla usan tu zona horaria (el log se
escribe en UTC, que es un instante sin ambigüedad; la conversión es de presentación). El
dashboard también separa dónde corrió el cómputo: local si el backend escucha en loopback,
remote si la inferencia se fue a otra máquina —por ejemplo esta Mac usando la GPU de la PC—.
Los eventos anteriores a la v0.11.0 no traen el campo y aparecen como n/d.
Alcance / no-objetivos
local-delegate es deliberadamente texto/imagen→texto: arma el prompt (o el payload
multimodal), hace POST a /chat/completions y devuelve solo texto. Cosas que no hace
a propósito:
- Tool-calling local. Los modelos locales no invocan herramientas ni ejecutan código; eso lo sigue haciendo Claude. Añadirlo convertiría este paquete en un orquestador paralelo, que no es el objetivo.
- Generación o edición de imágenes.
local_describe_imagees solo imagen→texto (describir, leer texto visible, responder una pregunta puntual); nada de generar ni editar imágenes. - Audio. Para transcripción usa el companion
whisper-transcribe-mcpen vez de intentar meter audio aquí. - Sustituir la suscripción. El objetivo es conservar cuota delegando pasos mecánicos acotados, no enrutar todo el trabajo a modelos locales.
Integración con el cliente: hooks, skill y memoria
local-delegate install deja lista la integración completa en tu HOME:
| Componente | Dónde | Qué hace |
|---|---|---|
| Entrada MCP | config de Claude Code / ~/.codex/config.toml / ~/.config/opencode/opencode.json[c] |
registra el servidor (stdio con uvx o HTTP contra el daemon) |
| Hooks | ~/.claude/hooks/local-delegate/ + settings.json |
sugieren delegar sin bloquear nunca la tool original |
| Skill | ~/.claude/skills/delegacion-local/ y ~/.config/opencode/skill/delegacion-local/ |
regla de oro y catálogo de tools |
| Memoria | bloque gestionado en ~/.claude/CLAUDE.md, ~/.codex/AGENTS.md y ~/.config/opencode/AGENTS.md |
la regla en una nota corta siempre cargada |
Por defecto se configuran solo los clientes que tengas instalados; se elige a mano con
--clients claude|codex|opencode. Los hooks son solo de Claude Code: opencode extiende con
plugins en TypeScript, que es otra superficie. Cada pieza se puede excluir (--no-hooks, --no-skill,
--no-memory, --no-mcp). Los hooks recomendados tras el piloto A/B son
UserPromptSubmit (intenciones mecánicas) y PreToolUse/Bash (salidas largas de lint/tests);
el experimento PreToolUse/Read queda apagado salvo --enable-read-hook, que lo registra y lo
enciende (uninstall lo apaga).
Ver Instalación de la integración y
docs/recipes/claude-code-hooks.md.
Groups de llama-swap (opcional)
Con pip install "local-delegate-mcp[llamaswap]" quedan disponibles dos CLIs para gestionar
groups de llama-swap (un modelo residente siempre cargado + un pool que se turna) con
guardrail de VRAM y RAM de sistema incorporado (--ram-gb es opcional: llama-server
mapea el GGUF también en RAM aunque el cómputo sea 100% GPU, así que un catálogo que cabe en
VRAM puede igual agotar la RAM en máquinas con menos de 32 GB):
local-delegate check-llamaswap --config config.yaml --vram-gb 16 --ram-gb 32
local-delegate init-llamaswap --config config.yaml --resident gemma3-4b --swap llama31-8b,qwen25-coder-14b --vram-gb 16 --ram-gb 32
El paquete nunca toca tu config.yaml por su cuenta — estos comandos solo corren si vos
los invocás. init-llamaswap corre el/los guardrail(es) antes de escribir (no escribe nada si
no cabe en VRAM o, si pasaste --ram-gb, en RAM) y nunca sobreescribe sin --force (dejando
.bak). Detalle completo, semántica de groups verificada contra el código de llama-swap, y
ritual de aplicación en docs/recipes/llama-swap-groups.md.
Enlaces
安装
把 local delegate 添加到你的客户端。选择你正在使用的那个。
claude mcp add local-delegate-mcp -- uvx local-delegate-mcpcodex mcp add local-delegate-mcp -- uvx local-delegate-mcpamp mcp add local-delegate-mcp -- uvx local-delegate-mcp{
"mcpServers": {
"local-delegate-mcp": {
"command": "uvx",
"args": [
"local-delegate-mcp"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"local-delegate-mcp": {
"command": "uvx",
"args": [
"local-delegate-mcp"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"local-delegate-mcp","command":"uvx","args":["local-delegate-mcp"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"local-delegate-mcp": {
"command": "uvx",
"args": [
"local-delegate-mcp"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"local-delegate-mcp": {
"command": "uvx",
"args": [
"local-delegate-mcp"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"local-delegate-mcp": {
"command": "uvx",
"args": [
"local-delegate-mcp"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"local-delegate-mcp": {
"type": "local",
"command": "uvx",
"args": [
"local-delegate-mcp"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"local-delegate-mcp": {
"command": {
"path": "uvx",
"args": [
"local-delegate-mcp"
]
}
}
}
}Add to your Zed `settings.json`.
uvx local-delegate-mcpRun `goose configure`, choose **Add Extension → Command-line Extension**, and paste this command.
11 个工具
local delegate 向已连接的智能体提供 11 个工具。
- local_summarize
- Resume texto o archivo
- local_classify
- Devuelve UNA etiqueta de una lista
- local_extract
- Extrae campos → **objeto validado**, no una cadena que haya que parsear
- local_boilerplate
- Genera código desde una spec
- local_delegate
- Escape genérico texto→texto
- local_lint_summary
- Resume logs de lint/tests/CI
- local_commit_msg
- Mensaje de commit desde un diff
- local_translate
- Traduce texto o archivo
- local_explain_code
- Explica código en prosa
- local_describe_image
- Describe una imagen o responde una pregunta sobre ella (imagen→texto)
- local_status
- Diagnóstico de solo lectura: backend, catálogo, log, VRAM, RAM de sistema
评分
83 / 100
优秀
- 文档25/25
- 维护25/25
- 可信度13/20
- 能力8/15
- 安装体验12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 1 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 11 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint — no local install
版本历史
| 版本 | 发布于 |
|---|---|
| 0.26.0最新 | 2026年8月18日 |
| 0.25.0 | 2026年8月18日 |
| 0.24.0 | 2026年8月4日 |
| 0.23.0 | 2026年8月3日 |
| 0.22.1 | 2026年8月3日 |
| 0.22.0 | 2026年8月3日 |
| 0.21.0 | 2026年8月1日 |
| 0.20.0 | 2026年7月31日 |
| 0.19.0 | 2026年7月31日 |
| 0.18.1 | 2026年7月31日 |
| 0.18.0 | 2026年7月31日 |
| 0.17.0 | 2026年7月30日 |
| 0.16.0 | 2026年7月30日 |
| 0.15.0 | 2026年7月30日 |
| 0.14.0 | 2026年7月30日 |
| 0.13.1 | 2026年7月29日 |
| 0.13.0 | 2026年7月29日 |
| 0.12.4 | 2026年7月29日 |
| 0.12.3 | 2026年7月29日 |
| 0.12.2 | 2026年7月28日 |
| 0.12.1 | 2026年7月28日 |
| 0.12.0 | 2026年7月28日 |
| 0.11.0 | 2026年7月28日 |
| 0.10.0 | 2026年7月24日 |
| 0.9.0 | 2026年7月23日 |
| 0.8.1 | 2026年7月12日 |
| 0.1.1 | 2026年7月8日 |