agent-godmode
Un paquete MCP en Python que otorga a tus agentes LLM capacidades completas de sistema de archivos y shell — listo para producción, en entorno aislado y conectable a cualquier LLM en minutos.
Documentación
agent-godmode
Herramientas MCP con ámbito de espacio de trabajo para construir agentes estilo Cursor: read_file, write_file, edit_file, run_command, list_files. Incluye prompts de sistema estrictos y versionados (SYSTEM_PROMPT_V1) y definiciones de herramientas estilo OpenAI para que tu aplicación pueda conectar cualquier LLM con una sola importación.
El LLM y las claves API permanecen en tu aplicación. Este paquete proporciona ejecución de herramientas, sandboxing y prompts, no un modelo alojado.
OpenAI + herramientas en proceso: la sección Tier B a continuación es autocontenida: copia el código Python en un script, módulo o REPL; no se requiere un artefacto separado.
Instalación
pip install agent-godmode
Editable / desarrollo:
pip install -e ".[dev]"
Migración desde mcp-agent-tools: desinstala el paquete antiguo, instala agent-godmode, cambia las importaciones de Python de mcp_agent_tools a agent_godmode, la CLI de mcp-agent-tools a agent-godmode, y las variables de entorno de MCP_AGENT_TOOLS_* a AGENT_GODMODE_* (por ejemplo AGENT_GODMODE_ROOT).
Herramientas
Todas las herramientas están limitadas a una única raíz de espacio de trabajo. Las rutas son relativas a esa raíz (o absolutas solo si se resuelven dentro de ella). Las mismas operaciones están disponibles a través de MCP (el servidor agent-godmode) y en proceso mediante AgentWorkspace / WorkspaceTools.
| Herramienta | Propósito |
|---|---|
read_file | Lee un archivo de texto UTF-8; rango de líneas y límite de bytes opcionales. |
write_file | Crea o sobrescribe/añade texto UTF-8; crea directorios padre. |
edit_file | Buscar y reemplazar en un archivo UTF-8 existente: old_string no vacío, replace_all opcional. Con replace_all=false, old_string debe coincidir exactamente una vez (usa contexto circundante de read_file para unicidad). UTF-8 inválido devuelve un error en lugar de corromper datos binarios. |
list_files | Lista entradas de directorio con recursión, glob, límite de profundidad y control de archivos ocultos opcionales. |
run_command | Ejecuta un subproceso desde una lista argv únicamente (sin shell); cwd opcional bajo la raíz. |
Para integraciones con LLM, las formas y descripciones de las herramientas están centralizadas en OPENAI_TOOL_DEFINITIONS y TOOL_DESCRIPTIONS; el comportamiento del agente se guía por SYSTEM_PROMPT_V1.
Tier A — Cursor (o cualquier cliente MCP)
1. Elige un directorio de espacio de trabajo (solo se permiten rutas bajo esta raíz).
2. Añade una entrada de servidor (stdio). Ejemplo para una configuración MCP global (las rutas usan barras diagonales en Windows):
{
"mcpServers": {
"agent-godmode": {
"command": "agent-godmode",
"args": [],
"env": {
"AGENT_GODMODE_ROOT": "D:/your/project"
}
}
}
}
O con una raíz CLI explícita (anula el entorno para ese proceso):
{
"mcpServers": {
"agent-godmode": {
"command": "agent-godmode",
"args": ["--root", "D:/your/project"]
}
}
}
3. Pega SYSTEM_PROMPT_V1 (de agent_godmode.prompts o abajo) en el prompt de sistema de tu host si el cliente no carga los instructions del servidor automáticamente.
Variables de entorno
| Variable | Significado |
|---|---|
AGENT_GODMODE_ROOT | Requerida a menos que se pase --root. Raíz absoluta del espacio de trabajo. |
AGENT_GODMODE_MAX_READ_BYTES | Máximo de bytes por lectura (predeterminado 512000). |
AGENT_GODMODE_COMMAND_TIMEOUT | Tiempo de espera del subproceso en segundos (predeterminado 120). |
AGENT_GODMODE_MAX_COMMAND_OUTPUT_BYTES | Trunca stdout/stderr combinados (predeterminado 256000). |
AGENT_GODMODE_LIST_MAX_ENTRIES | Límite para list_files (predeterminado 2000). |
AGENT_GODMODE_ALLOWED_COMMANDS | Nombres base separados por comas permitidos como argv[0] (p. ej. python,uv,node). Si no se establece, todos los comandos están permitidos bajo el sandbox. |
Tier B — Aplicación Python (en proceso + OpenAI)
Notas de diseño
- Raíz del espacio de trabajo — Los ejemplos usan
D:\Avi-assigncomo marcador de posición; apuntaWORK_DIRa cualquier directorio que controles. - Política de claves API —
OPENAI_API_KEYes requerida solo para Chat Completions. Las importaciones establecenclient = OpenAI() if HAS_OPENAI_KEY else None; la configuración del espacio de trabajo yedit_filedirecto se ejecutan sin clave. - E/S autorada por el modelo — Para
write_file, persiste solo el texto devuelto por el modelo. Paraedit_file, el modelo debe copiarold_stringexactamente desderead_file(verSYSTEM_PROMPT_V1).
1. Instalar dependencias
En un shell o cualquier sesión interactiva de Python:
pip install -q openai
pip install -q -e "D:/MCP" # editable checkout; or: pip install agent-godmode
Si tu entorno admite magias de línea (por ejemplo %pip en IPython), puedes ejecutar las mismas instalaciones allí; no coloques comentarios de shell en la misma línea que %pip.
2. Importaciones y manejo de claves API
import os
from pathlib import Path
# OPENAI_API_KEY is required only for steps that call Chat Completions (LLM + agent loops).
# Workspace + direct edit_file work without a key.
# Set via OS env or e.g. %env OPENAI_API_KEY sk-... in IPython
# Local-only optional override — never commit a real key:
# os.environ["OPENAI_API_KEY"] = "sk-..."
from openai import OpenAI
from agent_godmode import (
AgentWorkspace,
OPENAI_TOOL_DEFINITIONS,
SYSTEM_PROMPT_V1,
run_agent_loop,
)
HAS_OPENAI_KEY = bool(os.environ.get("OPENAI_API_KEY"))
client = OpenAI() if HAS_OPENAI_KEY else None
MODEL = "gpt-4o-mini"
if not HAS_OPENAI_KEY:
print(
"Note: OPENAI_API_KEY not set — Chat Completions examples will raise until you set it. "
"Workspace + direct edit_file still work."
)
3. Bootstrap del espacio de trabajo y archivo semilla
# Fixed workspace — all reads/writes/commands stay under this folder
WORK_DIR = Path(r"D:\Avi-assign")
WORK_DIR.mkdir(parents=True, exist_ok=True)
print("Workspace:", WORK_DIR.resolve())
hello = WORK_DIR / "hello.txt"
if not hello.exists():
hello.write_text("Hello from Avi-assign workspace.\n", encoding="utf-8")
ws = AgentWorkspace(WORK_DIR)
print(ws.read_file("hello.txt"))
print("--- list_files ---")
print(ws.list_files(".", recursive=False))
4. Cuerpo de archivo autorado por LLM (sin llamadas a herramientas)
Requiere OPENAI_API_KEY. Omite esto si solo estás ejercitando herramientas sin la API.
if client is None:
raise ValueError(
"Set OPENAI_API_KEY to run this block (e.g. export OPENAI_API_KEY=... or %env in IPython). "
"Skip if you only want workspace / edit_file demos."
)
# 1) Context from disk (read-only)
context = ws.read_file("hello.txt")
# 2) Ask the model to author the entire new file; no static template for the body
user_prompt = (
"Here is the current contents of hello.txt in my workspace:\n\n"
f"---\n{context}\n---\n\n"
"Write ONLY the body of a new Markdown file (no preamble, no code fences) "
"with a title line and two bullet points explaining what this greeting is for."
)
resp = client.chat.completions.create(
model=MODEL,
messages=[
{
"role": "system",
"content": "You output only the file body the user asked for. No extra commentary.",
},
{"role": "user", "content": user_prompt},
],
)
generated = (resp.choices[0].message.content or "").strip()
if not generated:
raise RuntimeError("LLM returned empty content; nothing to write.")
# 3) Persist exactly what the LLM produced
out_rel = "llm_generated_notes.md"
ws.write_file(out_rel, generated, mode="overwrite")
print(f"Wrote {out_rel!r} ({len(generated)} chars from model)\n")
print(ws.read_file(out_rel))
5. edit_file directo (sin Chat Completions)
No se requiere clave API. Las siguientes líneas crean ws si aún no has ejecutado la sección del espacio de trabajo (misma raíz).
# Direct edit_file (no Chat Completions call).
# If `ws` is not defined yet (e.g. you skipped §3), the next few lines create it (same WORK_DIR).
from pathlib import Path
from agent_godmode import AgentWorkspace
if "ws" not in globals():
WORK_DIR = Path(r"D:\Avi-assign")
WORK_DIR.mkdir(parents=True, exist_ok=True)
ws = AgentWorkspace(WORK_DIR)
demo_edit = "edit_demo.txt"
ws.write_file(
demo_edit,
"version: 1\nstatus: draft\nfooter: end\n",
mode="overwrite",
)
print("--- before ---")
print(ws.read_file(demo_edit), end="")
print(ws.edit_file(demo_edit, old_string="status: draft", new_string="status: ready"))
print("--- after ---")
print(ws.read_file(demo_edit), end="")
6. Bucle de agente: el modelo llama a write_file
Requiere OPENAI_API_KEY.
if client is None:
raise ValueError(
"Set OPENAI_API_KEY to run this block. "
"Skip if you only need workspace or direct edit_file."
)
def complete(messages, tools):
"""One Chat Completions turn; return OpenAI-shaped dict for run_agent_loop."""
resp = client.chat.completions.create(
model=MODEL,
messages=messages,
tools=tools,
tool_choice="auto",
)
return resp.model_dump()
answer = run_agent_loop(
complete,
"Use tools only. List the workspace root, read hello.txt, then call write_file on "
"agent_notes.txt. The `content` argument must be your own freshly written summary "
"(several sentences) based only on what you read—do not paste boilerplate.",
ws,
system_prompt=SYSTEM_PROMPT_V1,
max_turns=12,
)
print("--- final answer ---")
print(answer)
print("--- agent_notes.txt (if created by tool write_file) ---")
p = WORK_DIR / "agent_notes.txt"
print(p.read_text(encoding="utf-8") if p.exists() else "(missing)")
7. Bucle de agente: el modelo llama a edit_file
Requiere OPENAI_API_KEY y la función complete de la §6.
from pathlib import Path
from agent_godmode import AgentWorkspace
if "ws" not in globals():
WORK_DIR = Path(r"D:\Avi-assign")
WORK_DIR.mkdir(parents=True, exist_ok=True)
ws = AgentWorkspace(WORK_DIR)
if "complete" not in globals():
raise NameError("Define `complete` in §6 (after imports) before running this block.")
if client is None:
raise ValueError(
"Set OPENAI_API_KEY to run this block. "
"The direct edit_file example in §5 works without a key."
)
target = "edit_agent_target.txt"
ws.write_file(
target,
"# Demo\nThere are three erorrs in this sentance.\n",
mode="overwrite",
)
edit_answer = run_agent_loop(
complete,
(
f"Use tools only. Read `{target}`. Then use edit_file (not write_file) to fix typos: "
"change erorrs to errors and sentance to sentence. "
"Copy old_string exactly from read_file; use two edit_file calls or replace_all where appropriate."
),
ws,
system_prompt=SYSTEM_PROMPT_V1,
max_turns=14,
)
print("--- agent (edit_file) answer ---")
print(edit_answer)
print("--- file after agent ---")
print(ws.read_file(target), end="")
8. Opcional: bucle de herramientas personalizado sin run_agent_loop
Usa OPENAI_TOOL_DEFINITIONS, llama a la API de Chat Completions con tools=..., analiza tool_calls y enruta cada llamada a través de ws.dispatch(name, json.loads(arguments)) (requiere import json). Para write_file, el campo content debe ser lo que el modelo haya creado; para edit_file, pasa old_string, new_string y replace_all exactamente como los devolvió el modelo.
Límites opcionales en AgentWorkspace
ws = AgentWorkspace(
r"D:\Avi-assign",
allowed_commands=frozenset({"python", "uv"}),
command_timeout_sec=60.0,
)
Nivel inferior (WorkspaceTools + OPENAI_TOOL_DEFINITIONS)
Mismo sandbox sin AgentWorkspace: usa config_from_root(...) y WorkspaceTools. Pasa OPENAI_TOOL_DEFINITIONS a tu proveedor como tools= cuando implementes tu propio bucle en lugar de run_agent_loop.
from agent_godmode import WorkspaceTools, OPENAI_TOOL_DEFINITIONS, SYSTEM_PROMPT_V1
from agent_godmode.config import config_from_root
tools = WorkspaceTools(config_from_root(r"D:\Avi-assign"))
print(tools.read_file("hello.txt"))
Compón el mensaje de sistema:
final_system = SYSTEM_PROMPT_V1 + "\n\n" + "Your org rules here."
Referencia de importaciones
AgentWorkspace— pasa una ruta de directorio; usaread_file/write_file/edit_file/list_files/run_commandsolo en ese árbolSYSTEM_PROMPT_V1,SYSTEM_PROMPT_CHANGELOG,TOOL_DESCRIPTIONSOPENAI_TOOL_DEFINITIONS— mismas formas que las herramientas MCP (paratools=en chat completions)build_server(config)— construye una aplicaciónFastMCP(stdio mediantebuild_server(cfg).run())run_agent_loop— ejecutor multiturno mínimo con tu callablecomplete(aceptaWorkspaceConfigoAgentWorkspace)
Modelo de seguridad
- Python: todas las rutas se resuelven bajo el directorio que pasaste a
AgentWorkspace(...)oconfig_from_root(...). - MCP / CLI: misma regla mediante
AGENT_GODMODE_ROOTo--root(sin escape de..). read_file,write_fileyedit_filesolo tocan rutas de texto UTF-8 bajo esa raíz;edit_filerequiere UTF-8 válido (decodificación estricta).run_commandusaargvúnicamente (sin shell). Lista de permitidos opcional medianteAGENT_GODMODE_ALLOWED_COMMANDS.- El subproceso hereda el entorno actual; evita pasar secretos que no quieras que los procesos hijos vean.
CLI
agent-godmode --root D:/your/project
Ejecuta el servidor MCP en stdio (predeterminado para Cursor).
Bucle de agente (conceptual)
- Sistema =
SYSTEM_PROMPT_V1(+ sufijo opcional). - Mensaje de usuario +
OPENAI_TOOL_DEFINITIONS→ tu LLM. - Para cada
tool_call, ejecutaWorkspaceTools.dispatch(o MCPcall_tool) — incluyendoread_file,write_file,edit_file,list_filesyrun_commandsegún lo definido por el servidor. - Añade los resultados de las herramientas; repite hasta que el modelo devuelva texto sin herramientas.
run_agent_loop implementa los pasos 2–4 dada tu función complete().
Licencia
MIT