Skip to main content
Glama

forja

Una IA que programa no necesita ser más lista: necesita poder comprobar lo que hace.

forja es un servidor MCP que se conecta a cualquier IA que programe (Claude Code, opencode, Cline… o un modelo gratuito en tu propio PC) y le da lo que le falta para trabajar en proyectos reales sin perderse: saber qué hay, saber qué está roto, saber si su cambio funciona de verdad y recordar los errores que ya cometió.

Por qué existe

Las IAs que programan fallan siempre en los mismos sitios, y no por falta de inteligencia:

  • No ven el proyecto entero. Su memoria de trabajo (el contexto) es limitada, y la gastan orientándose: leen el README completo, listan carpetas, abren archivos enteros para encontrar una función.

  • Dicen "listo, funciona" sin haberlo comprobado. Es el fallo más caro: te enteras tú, después.

  • Repiten errores que ya arreglaron, porque entre una sesión y otra no recuerdan nada.

  • Se fían de tests que no prueban nada: todo verde no significa que esté bien.

  • Con modelos pequeños y gratuitos todo esto se multiplica: menos contexto y más torpeza usando herramientas.

Las herramientas para comprobar código ya existen (compiladores, linters, tests, verificadores como Dafny o Lean), pero cada una habla su propio idioma y todas están pensadas para que las lea una persona.

Related MCP server: projectmind

Para qué sirve

forja es el traductor entre esas herramientas y la IA. Le responde, en pocas palabras y siempre con el mismo formato, sea cual sea el lenguaje:

  1. ¿Qué hay en este proyecto? — un mapa de una sola llamada, en vez de leer documentación.

  2. ¿Qué está roto exactamente? — archivo, línea, el código afectado y qué hacer a continuación.

  3. ¿Mi cambio funciona de verdad? — ok solo si todo se comprobó; nunca un éxito inventado.

  4. ¿Ya me equivoqué en esto antes? — una memoria por proyecto que se llena sola.

  5. ¿Es correcto o solo lo parece? — con Dafny y Lean, demostrado matemáticamente.

Cómo funciona

  tú: "el reporte no funciona, arréglalo"
          │
          ▼
  ┌──────────────────┐   MCP   ┌──────────┐   php -l, pytest, cargo, go,
  │ tu IA            │ ──────► │  forja   │ ─► shellcheck, dafny, lean…
  │ (cualquiera)     │ ◄────── │          │
  └──────────────────┘         └────┬─────┘
          ▲   "corrige datos.php:12      │
          │    (falta ;) y vuelve        ▼
          │    a llamar a gate"     memoria del proyecto
          └─────────────────────    (errores, repetidos, lecciones)

El ciclo de trabajo de la IA con forja:

  1. overview → entiende el proyecto sin leer archivos enteros.

  2. recall → mira qué errores se repiten en este proyecto.

  3. outline → encuentra la función y lee solo esas líneas.

  4. edita y llama a gate → si algo falla, la respuesta dice exactamente qué y dónde, y su campo next dice qué hacer.

  5. repite hasta que gate diga ok. Solo entonces la tarea está terminada.

El compilador de IA: Dafny y Lean

Un compilador convierte código en un programa y se puede confiar en él porque es determinista. Una IA no lo es: la misma petición puede dar código distinto, y a veces con errores. La verificación formal resuelve eso:

  • el humano escribe qué debe cumplirse (requires/ensures en Dafny, el enunciado de un theorem en Lean) — unas pocas líneas fáciles de revisar;

  • la IA escribe el cómo;

  • el verificador demuestra que el código lo cumple. Si no, no pasa.

Así no hace falta fiarse de la IA. forja vigila además las dos trampas que lo invalidarían:

  • demostrar a medias (sorry, admit, axiom en Lean; assume, {:axiom}, {:verify false} en Dafny) → es un error, nunca un éxito;

  • debilitar la especificación para que sea fácil de cumplir → el humano la bloquea con forja-spec lock y cualquier cambio posterior es un error. El bloqueo no se puede hacer desde MCP: la IA no puede desbloquearse sola.

Principios

Funciona con cualquier cliente MCP y cualquier modelo · cada carácter que recibe la IA cuenta · nunca un falso éxito · no necesita internet ni sudo · no toca el código del proyecto salvo con fix, cuando se pide.

No es un linter, ni una IA, ni un IDE: no sustituye a ninguna herramienta, las traduce.

Herramientas

Herramienta

Para qué

overview(path)

Mapa del proyecto en una llamada: lenguajes, carpetas, cómo se comprueba, puntos de entrada, índice de la documentación (solo títulos) y git. En vez de leer README y listar carpetas

outline(path)

Funciones y clases de un archivo o carpeta con su rango de líneas, para leer solo ese trozo

check(path)

Sintaxis, tipos y lint de todos los lenguajes del proyecto, sin ejecutarlo

fix(path)

Aplica las correcciones seguras y dice qué tocó

test(path)

Ejecuta los tests de todos los lenguajes y localiza cada fallo

gate(path)

check + test: la puerta final, ok solo si todo pasa

mutate(path)

¿Los tests sirven? Mete bugs pequeños en copias y mira si los detectan (Python)

recall(path)

Memoria del proyecto: errores que se repiten, abiertos, patrones, recientes, lecciones

learn(path, lesson)

Guarda una lección; aparecerá sola junto a ese error si vuelve

Cada respuesta trae next: el siguiente paso en una frase, para que un modelo pequeño no tenga que deducirlo.

Lenguajes

Lenguaje

check

test

Python

ruff + mypy

pytest (+ coverage, mutate)

JavaScript / TypeScript

node --check, tsc y eslint si el proyecto los trae

vitest, node --test

Rust

cargo clippy / check

cargo test

Go

go vet

go test

PHP

php -l

phpunit si está en vendor/bin

Shell (sh/bash)

shellcheck (incluido en forja)

—

fish

fish --no-execute

—

Lua

luac -p

—

JSON / YAML / TOML

interno

—

Dafny

dafny verify + trampas + especificación bloqueada

— (verificar es más fuerte que probar)

Lean 4

lake build / lean + trampas + especificación bloqueada

—

Cualquier otro

.forja.toml

.forja.toml

Un proyecto con varios lenguajes se revisa entero. Para una herramienta que forja no conoce:

# .forja.toml
[[check]]
name = "phpstan"
cmd = ["vendor/bin/phpstan", "analyse", "--error-format=raw", "--no-progress"]  # salida archivo:línea: mensaje

[[test]]
name = "phpunit"
cmd = ["vendor/bin/phpunit", "--log-junit", "{junit}"]   # {junit}: forja lee ese XML

[forja]
disable = ["data"]   # opcional

Memoria por proyecto

Cada check, test, gate y edición vista por el hook se guarda sola en una base SQLite por proyecto (~/.local/share/forja/), fuera de la carpeta del proyecto. forja anota qué errores aparecen, cuáles se arreglan y cuáles vuelven después de arreglados. recall devuelve un resumen corto y ordenado por importancia (repetidos → críticos → patrones → recientes → lecciones), y un error que la IA repite llega con memory: "repetido: ya lo arreglaste…". Si una herramienta no llegó a ejecutarse, nada se da por resuelto.

Cómo ahorra contexto

  • overview / outline: medido en proyectos reales, −84 % a −92 % frente a leer los .md y listar archivos, y −98 % frente a leer un script entero para encontrar una función.

  • Forma compacta: sin campos vacíos; un check limpio es {"ok": true, "next": ...}.

  • source: cada error trae su línea de código.

  • Duplicados agrupados (ruff + mypy, tests con la misma causa) y trazas limpias.

  • Historial: en llamadas repetidas lo ya visto llega resumido (full=true para todo).

Reglas que nunca se rompen

  • Una herramienta que no pudo ejecutarse aparece con ran: false y el resultado nunca es ok: true: un paso sin comprobar no cuenta como éxito.

  • Un proyecto sin tests no pasa test: "no hay tests" no es "los tests pasan".

  • forja no escribe en el proyecto (cachés en ~/.cache/forja-mcp, memoria en ~/.local/share/forja), salvo fix, que lo pide explícitamente.

  • mutate trabaja en copias temporales y se niega a empezar si los tests no pasan sin mutar.

Instalación

Con Docker (recomendado: no instala nada en tu máquina)

La imagen trae todas las herramientas: Python, PHP, Lua, fish, Node, Go, Rust, Dafny y Lean.

git clone https://github.com/Asced1807/forja-mcp && cd forja-mcp
docker build -t forja-mcp .

Como servidor MCP, el proyecto se monta en la misma ruta para que las rutas coincidan, y la memoria en una carpeta tuya para que no se pierda entre sesiones:

docker run -i --rm --user "$(id -u):$(id -g)" -v "$PWD:$PWD" -w "$PWD" \
  -v "$HOME/.local/share/forja:/data" forja-mcp

Para desarrollar forja sin instalar nada (los tests de Dafny y Lean incluidos):

docker run --rm --user "$(id -u):$(id -g)" -v "$PWD:/work" -w /work -e PYTHONPATH=/work/src \
  -e PYTHONDONTWRITEBYTECODE=1 --entrypoint python forja-mcp -m pytest

Sin Docker

Requisitos: Python 3.12+ y uv. Las herramientas de cada lenguaje (php, cargo, go, node…) se usan si están instaladas; shellcheck, ruff y mypy vienen incluidas.

git clone <este repo> forja-mcp && cd forja-mcp
uv sync
uv run pytest            # comprueba que todo funciona en tu máquina

El servidor es <ruta>/forja-mcp/.venv/bin/forja-mcp (MCP por stdio).

Claude Code

claude mcp add --scope user forja -- <ruta>/forja-mcp/.venv/bin/forja-mcp

Hook opcional que revisa cada archivo editado (en .claude/settings.json del proyecto):

{"hooks": {"PostToolUse": [{"matcher": "Edit|Write|MultiEdit",
  "hooks": [{"type": "command", "command": "<ruta>/forja-mcp/.venv/bin/forja-hook", "timeout": 90}]}]}}

opencode

En ~/.config/opencode/opencode.jsonc:

"mcp": {
  "forja": { "type": "local", "command": ["<ruta>/forja-mcp/.venv/bin/forja-mcp"], "enabled": true }
}

Estructura

src/forja_mcp/
  server.py           servidor MCP y campo `next`
  model.py            formato único, forma compacta y combinación de lenguajes
  memoria.py          memoria SQLite por proyecto
  mapa.py             overview y outline
  files.py            archivos del proyecto (respeta .gitignore)
  parsers.py          lectores compartidos (formato gcc)
  junit.py            lector de JUnit XML
  history.py          comparación con la llamada anterior
  runner.py           ejecución de comandos con tiempo límite
  hook.py             hook PostToolUse
  adapters/
    base.py           clase base y revisión archivo por archivo
    python.py, python_mutation.py
    scripting.py      PHP, Lua, JavaScript/TypeScript
    compiled.py       Rust, Go
    shell.py          sh/bash, fish
    data.py           JSON, YAML, TOML
    custom.py         .forja.toml

Añadir un lenguaje

Una clase que herede de BaseAdapter con name, extensions y check; test, fix y mutate son opcionales (por defecto "no aplica"). Regístrala en ADAPTERS (adapters/__init__.py). per_file y parse_gcc resuelven la mayoría de los casos en pocas líneas, y junit_run cualquier runner de tests que escriba JUnit XML.

Licencia

Copyright (C) 2026 Asced1807

forja-mcp es software libre bajo la licencia BSD de 3 cláusulas (BSD-3-Clause).

En resumen: cualquiera puede usarlo, modificarlo y redistribuirlo, también dentro de proyectos cerrados o comerciales, siempre que mantenga este aviso de copyright y el texto de la licencia. Lo que no puede es usar el nombre del autor para promocionar sus derivados sin permiso. Las contribuciones son bienvenidas.

Available Tools

9 tools
checkA

Comprueba el proyecto sin ejecutarlo: sintaxis, tipos y lint de TODOS sus lenguajes.

Args:
    path: ruta absoluta al proyecto o a cualquier archivo dentro de él.
    timeout: segundos máximos por herramienta.
    full: true para recibir todos los campos, incluido el detalle de lo ya visto.

Inputs: path (required), full, timeout. Returns: object

fixC

Aplica las correcciones automáticas SEGURAS y vuelve a comprobar.

Modifica archivos: `fixed` dice qué se corrigió y dónde.

Inputs: path (required), timeout. Returns: object

gateA

check + test en una llamada: la puerta final. ok solo si TODO pasa.

Args:
    path: ruta absoluta al proyecto o a cualquier archivo dentro de él.
    coverage: true para incluir las líneas sin cubrir por los tests.
    timeout: segundos máximos por fase.

Inputs: path (required), timeout, coverage. Returns: object

learnA

Guarda una lección del proyecto para no repetir un error (p. ej. "usar Decimal, nunca float, para dinero"). Aparecerá sola junto a ese error si vuelve a ocurrir.

Args:
    path: ruta absoluta al proyecto.
    lesson: la lección, en una frase.
    about: opcional, a qué se aplica: código de error (F821), archivo o nombre de test.

Inputs: path (required), lesson (required), about. Returns: object

mutateA

¿Los tests son buenos? Mete bugs pequeños en COPIAS del código y mira si los tests los detectan. Cada superviviente es algo que ningún test comprueba (algunos son equivalentes: júzgalos). Hoy solo para Python.

Args:
    path: ruta absoluta al proyecto.
    file: opcional, solo muta este archivo (ruta relativa al proyecto).
    max_mutants: máximo de mutaciones a probar.
    timeout: segundos máximos en total.

Inputs: path (required), file, timeout, max_mutants. Returns: object

outlineB

Funciones y clases de un archivo, o de todos los de una carpeta, con su rango de líneas (p. ej. "L12-40 def calcular(x) -> int"). Lee después solo ese rango, no el archivo entero.

Args:
    path: ruta absoluta a un archivo o carpeta del proyecto.

Inputs: path (required). Returns: object

overviewA

Mapa del proyecto en una llamada: lenguajes, carpetas, cómo se comprueba, puntos de entrada, índice de la documentación (solo títulos con su línea) y estado de git. Úsalo al empezar en vez de leer README o listar carpetas.

Args:
    path: ruta absoluta al proyecto o a cualquier archivo dentro de él.

Inputs: path (required). Returns: object

recallA

Memoria del proyecto, ordenada por importancia: errores que se repiten, errores abiertos, patrones (el mismo tipo de error en varios sitios), lo resuelto hace poco y las lecciones guardadas. Se llena sola con cada check/test. Úsalo antes de cambiar código en un proyecto en el que ya trabajaste.

Args:
    path: ruta absoluta al proyecto.
    topic: opcional, filtra por archivo, código de error o texto (p. ej. "cli.py").

Inputs: path (required), topic. Returns: object

testB

Ejecuta los tests de todos los lenguajes del proyecto y localiza cada fallo.

Args:
    path: ruta absoluta al proyecto o a cualquier archivo dentro de él.
    selector: opcional, limita a un archivo o test concreto.
    coverage: true para ver qué líneas no ejecuta ningún test (Python).
    timeout: segundos máximos.
    full: true para recibir todos los campos, incluido el detalle de lo ya visto.

Inputs: path (required), full, timeout, coverage, +1 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 9 tools

    Disambiguation4/5

    Each tool has a fairly distinct role: learn/recall handle memory (write vs read), check/test/gate handle verification, and fix/mutate/overview/outline are clearly separate operations. The main risk is check vs gate (gate is explicitly 'check + test in one call') and overview vs outline, but the descriptions clarify the boundaries well.

    Naming Consistency4/5

    All nine tools use a single lowercase word with no style mixing, which is highly consistent. It is not a verb_noun pattern and mixes verbs (learn, fix, test, mutate, recall, check) with nouns (overview, outline, gate), but the stylistic convention is uniform and readable.

    Tool Count5/5

    Nine tools is well-scoped for a code QA/testing server, with each tool covering a distinct aspect (memory, static check, tests, combined gate, mutation testing, safe fixes, project mapping, file outline). No obvious redundancy or padding.

    Completeness4/5

    The surface covers a solid lifecycle: explore (overview/outline), verify (check/test/gate), improve (fix), assess test quality (mutate), and accumulate knowledge (learn/recall). Minor gaps exist, such as no way to remove/update a stored lesson, but core workflows are covered.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Persistent, compact project memory for AI coding agents, enabling them to read a small digest instead of re-scanning the codebase every session, saving tokens and costs.
      49 npm
      2
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to carry durable project memory across windows, agents, and days, injecting a compressed context of architecture, progress, decisions, and critical files so a new session can resume without re-reading the whole repository. It also classifies files as current/legacy/intermediate and suggests cleanup so stale or draft artifacts don't mislead the agent.
      8 npm
      MIT