ContextForge Server
БесплатноНе проверенEnables AI agents to efficiently retrieve relevant code context via PageRank-optimized subgraphs and automate spec generation, implementation planning, and pre-
Описание
Enables AI agents to efficiently retrieve relevant code context via PageRank-optimized subgraphs and automate spec generation, implementation planning, and pre-commit validation.
README
Pipeline determinista que convierte cualquier repo en un índice consultable por agentes IA. 94.4 % menos tokens por sesión, 17.9× compresión, ÷28× costo SDD con prompt caching — sin LLM en el pipeline, sin lock-in de agente.
214 600 tokens (todo el repo) → 11 988 tokens (lo que importa a la tarea)
El problema que resuelve
Cada vez que un agente IA (Claude Code, Cursor, OpenCode) abría el repo tenía que:
- Leer TODO para entender qué existe
- Recordar correr
pnpm forge contextmanualmente antes de cada tarea - Adivinar qué archivos tocar sin contexto del grafo
- No había gate pre-commit — specs y guardrails se saltaban fácil
Ahora todo eso es automático vía MCP + hooks.
Cómo encaja cada pieza
Dev / Agente (Claude Code · Cursor · OpenCode) escribe tarea
│
▼
[Hook UserPromptSubmit] ← automático, sin hacer nada
→ MCP: select_agent_context(task)
→ Agente recibe: skills relevantes + domains tocados
│
▼
Agente llama forge_context(task) ← MCP tool, sin pnpm, sin disco
→ ~20 archivos rankeados por PageRank + BFS
→ sabe exactamente qué leer, no el repo entero
│
▼
Agente llama forge_spec("mi-feature") ← MCP tool
→ escribe openspec/changes/mi-feature/
├── proposal.md ← motivación y alcance
├── design.md ← decisiones técnicas
├── tasks.md ← lista de tareas
├── specs/ ← Requirements + Scenarios (Given/When/Then)
├── graph.subset.json ← subgrafo FROZEN de los archivos relevantes
├── context.md ← mapa de lectura para el agente
└── agent-manifest.json ← skills filtradas SOLO para este change
│
▼
Agente/Dev llena proposal.md + specs/*.md
openspec validate mi-feature ← verifica formato Requirement + Scenario
│
▼
Agente llama forge_implement("mi-feature") ← MCP tool
→ .contextforge/implement-plan.json
allowedFiles: [solo los del context-pack]
maxLocDelta: estimado del pack
│
▼
Agente implementa código
│
▼
Agente intenta git commit
│
▼
[Hook PreToolUse] ← automático, bloquea si hay violaciones
→ node .claude/hooks/forge-pre-commit.mjs
→ forge implement --check valida git diff vs guardrails
→ archivo fuera de allowedFiles → exit 2 → COMMIT BLOQUEADO
→ Agente recibe lista de violaciones y corrige antes de reintentar
│
▼
Commit pasa → merge
│
▼
Agente corre openspec archive mi-feature
│
▼
[Hook PostToolUse(openspec)] ← automático, en background
→ forge_rebuild_graph async
→ grafo fresco para la próxima tarea
ContextForge no reemplaza OpenSpec — lo alimenta
OpenSpec es el framework de specs. Claude Code / Cursor / OpenCode son los agentes IA que lo usan. ContextForge le da a los agentes el contexto correcto para que OpenSpec reciba datos reales del código, no inventados.
| OpenSpec hace | ContextForge aporta |
|---|---|
Valida formato Requirement: + Scenario: |
El contexto correcto para escribir la spec |
Archiva y mueve specs a openspec/specs/ |
El subgrafo frozen que dice qué archivos aplican |
openspec validate chequea Given/When/Then |
forge_check chequea que el código respete los guardrails |
| Historial de specs por feature | forge_status muestra qué changes tienen subgrafo activo |
Antes vs ahora
Sin hooks ni MCP — el dev recordaba (o no) cada paso:
pnpm forge scan
pnpm forge graph
pnpm forge context "mi tarea"
pnpm forge spec mi-feature
# llenar docs...
pnpm forge implement mi-feature
# codear...
pnpm forge implement --check # se olvidaba frecuentemente
git commit
openspec archive mi-feature
pnpm forge scan && pnpm forge graph # se olvidaba siempre
Ahora — los hooks y MCP tools hacen el trabajo:
# Agente recibe contexto automático al escribir el prompt (hook)
# Llama forge_context → forge_spec → forge_implement via MCP (sin pnpm)
# Dev/agente llena las specs → openspec validate confirma formato
# Agente codea
git commit # → hook bloquea si hay violaciones, las explica
openspec archive mi-feature # → hook reconstruye grafo en background
pnpm forge manual solo para bootstrap (forge init) o forzar reconstrucción (forge graph --force).
Instalación
npm — público, sin token:
# CLI (uso diario)
pnpm add -g @anai-raia-alex/contextforge-cli # global
# o
pnpm add -D @anai-raia-alex/contextforge-cli # por proyecto
# MCP server (para agentes vía Node)
pnpm add -D @anai-raia-alex/contextforge-mcp
# OpenSpec CLI (recomendado, activa el modo handoff)
npm i -g @fission-ai/openspec
Docker — sin instalar Node, multi-arch (amd64+arm64):
docker pull ghcr.io/alejandro-cedeno-10/contextforge-mcp:latest
Desde fuente (desarrollo):
git clone https://github.com/alejandro-cedeno-10/contextforge-cli.git
cd contextforge-cli
pnpm install && pnpm build
Quick start (5 comandos para empezar)
# 1. Inicializar (corre 'openspec init' si está en PATH; instala instrucciones del agente)
pnpm forge init
# 2. Indexar el repo (incremental; cache por hash)
pnpm forge scan
pnpm forge graph
# 3. Por cada tarea
pnpm forge context "fix race en tokenLedger writer"
# 4. SDD opcional (con OpenSpec)
pnpm forge spec mi-feature-id # spec-input + handoff/fallback
openspec validate mi-feature-id
# 5. Implementar con guardrails
pnpm forge implement mi-feature-id
# (trabajas con el agente)
pnpm forge implement --check # gate pre-commit
Las tres capas
Capa 1 — Grafos para ahorrar tokens
En lugar de "leer todo el repo", rankeamos los archivos por relevancia a tu tarea con el grafo de dependencias real del código + Personalized PageRank.
Pipeline:
pnpm forge scan # Indexa con BLAKE3 (incremental)
pnpm forge graph # Grafo file + symbol con tree-sitter
pnpm forge context "<tarea>" # PageRank + BFS + budget
Algoritmo:
1. resolve_seeds(task) → archivos semilla por keywords
2. personalized_pagerank() → ranking de relevancia (alpha=0.85, 50 iter)
3. bfs_expand(depth=2) → captura deps directas + transitivas
4. score_nodes() → pagerank × (1/bfs_dist) × edge_multiplier
5. greedy_pack(budget=12000) → llena hasta 12k tokens (full → excerpt → summary)
Edge multipliers: tests=1.2 · defines=1.0 · calls=1.0 · imports=0.8 · references=0.6
Ahorro medido en este repo:
| Sin ContextForge | Con context-pack |
|---|---|
| 214 600 tokens | 11 988 tokens |
| ~$0.64 / sesión (Claude Sonnet 4.6) | ~$0.036 / sesión |
| 128 archivos enviados | 50 archivos seleccionados |
Compresión: 17.9× · Ahorro: 94.4 %
Capa 2 — SDD apoyando a OpenSpec (no compitiendo con él)
v0.3.0+ —
forge specya no genera el spec final. Genera la entrada (spec-input.json+spec-prompt.md) para que OpenSpec o un agente IA lo escriban con todo el contexto correcto.
Tres roles separados, cada uno hace lo suyo:
┌─────────────────────┐ ┌─────────────────────┐ ┌────────────────┐
│ ContextForge │ │ OpenSpec │ │ Agente IA │
├─────────────────────┤ ├─────────────────────┤ ├────────────────┤
ROL │ Selección de │ │ Estructura + │ │ Redacción │
│ contexto │ │ validación │ │ │
├─────────────────────┤ ├─────────────────────┤ ├────────────────┤
TÉC. │ PageRank + BFS + │ │ Schemas RFC 2119 │ │ LLM │
│ budget tokens │ │ Given/When/Then │ │ │
├─────────────────────┤ ├─────────────────────┤ ├────────────────┤
INPUT │ scan + graph + │ │ spec-input.json │ │ spec-prompt.md│
│ task │ │ │ │ + context-pack│
├─────────────────────┤ ├─────────────────────┤ ├────────────────┤
OUTPUT │ context-pack + │ │ proposal/design/ │ │ .md llenos │
│ spec-input + prompt│ │ tasks/spec.md │ │ + commits │
└─────────────────────┘ └─────────────────────┘ └────────────────┘
Pipeline SDD completo:
pnpm forge context "<tarea>" # context-pack + agent-manifest
pnpm forge spec mi-feature-id # spec-input + handoff/fallback
openspec list # ver changes activos
openspec validate mi-feature-id # validación oficial
pnpm forge implement mi-feature-id # plan con guardrails
# (trabajas con el agente)
pnpm forge implement --check # gate pre-commit
openspec archive mi-feature-id -y # al mergear: mueve a specs/
Modo handoff vs modo fallback:
| Modo | Cuándo | Qué pasa |
|---|---|---|
| Handoff (default si OpenSpec CLI está) | openspec --version resuelve |
forge spec ejecuta openspec new change + emite .contextforge/spec-prompt.md con instrucciones canónicas + contexto del grafo. El dev pega ese prompt en su agente |
Fallback (sin OpenSpec CLI o --no-openspec) |
CLI ausente, CI sin instalación | ContextForge emite el scaffold con formato moderno (### Requirement: + #### Scenario:). Cuando se instale el CLI después, openspec validate pasa sin retoque |
Mismo contrato (spec-input.json), dos formas de consumirlo. Portable Mac/Linux/Windows.
Forma de cada Requirement (RFC 2119 + Given/When/Then):
### Requirement: System produces fix-token-race within budget
The system MUST implement the change `fix-token-race` while respecting
`guardrails.allowedFiles` and not exceeding `guardrails.maxLocDelta`.
#### Scenario: change is implemented within scope
- **Given** a valid `.contextforge/context-pack.json` for the task
- **When** the developer runs `pnpm forge implement fix-token-race`
- **Then** `pnpm forge implement --check` exits with code 0
Guardrails de implementación (derivados del grafo):
forge implement produce implement-plan.json cuyos campos vienen del context-pack:
allowedFiles[]← exactamente los archivos del packforbiddenPaths[]— nunca tocarmaxLocDelta— derivado del tamaño del packmaxFilesChanged—allowedFiles.length + 2
forge implement --check valida tu git diff antes del commit. Si te saliste del scope, te lo dice exactamente y el commit no pasa.
Capa 3 — Solo cargar las skills/rules que aplican a la tarea
forge context ya emite 5 artefactos sin paso extra:
.contextforge/context-pack.json ← archivos relevantes
.contextforge/token-ledger.json ← métricas
.contextforge/agent-manifest.json ← NEUTRAL (validado por schema)
.claude/agent-manifest.md ← renderer Claude Code
.cursor/rules/contextforge-active.mdc ← renderer Cursor (Auto-Attached)
.contextforge/manifests/opencode-readme.md ← renderer OpenCode
Reglas de matching (priorizadas):
alwaysApply: true→ siempre incluida.- frontmatter
domains: [..]∩ dominios tocados → match domain. - nombre
contextforge-domain-<slug>del dominio tocado → match explicit (legacyctx-<slug>aún soportado). - nada matchea → skipped (con razón).
Frontmatter mal formado nunca crashea: cae en skipped con frontmatter parse error.
Activación por agente (sin pasos manuales después de setup):
| Agente | Cómo se carga | Setup |
|---|---|---|
| Claude Code | Hook UserPromptSubmit regenera el manifest en cada prompt |
Pegar snippet en .claude/settings.json (ver docs/integrations/claude-code-hook.md) |
| OpenCode | El agente llama tool MCP select_agent_context({task}) al inicio. Live, sin disco |
opencode.json ya configurado |
| Cursor | Rule Auto-Attached con globs: por dominio. Se activa al abrir un archivo del dominio |
Sin setup; forge context regenera la rule |
El grafo en detalle
Esta sección explica qué genera forge graph, cómo lo genera, cómo lo visualiza, y cómo el agente lo consume. Si vienes de Understand-Anything, vas a reconocer la idea: convertir un repo en un mapa navegable. La diferencia es que aquí el pipeline es 100 % determinista (sin LLM en el loop, sin coste por correrlo), cacheable por archivo, y los outputs son JSON portables que cualquier agente puede consumir sin la app.
Pipeline de generación (qué pasa cuando corres forge graph)
┌──────────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ scan.json │ → │ per-file │ → │ graph passes│ → │ graph.json │
│ (BLAKE3) │ │ cache hit? │ │ (4 etapas) │ │ + cache.json│
└──────────────┘ └─────────────┘ └──────────────┘ └──────────────┘
│ │ │
│ │ ├─ Pass 0: file nodes
│ │ ├─ Pass 1: parse code/test (paralelo, n=cpus)
│ │ ├─ Pass 2: defines + imports + tests
│ │ ├─ Pass 3: extends / implements
│ │ ├─ Pass 3.5 (--with-calls): calls
│ │ └─ Pass 4: folder + contains
│ │
│ └─ Si `file.hash` coincide con cache, reusa el fragment parseado
│ y solo recomputa las aristas cross-file (imports/extends/calls).
│
└─ Hash global del scan: si no cambió, `forge graph` ni siquiera arranca (skip).
Output canónico — .contextforge/graph.json cumple docs/schemas/graph.schema.json:
{
"schemaVersion": "0.2.0",
"project": { "name": "contextforge-cli", "root": "." },
"generatedAt": "2026-05-08T...Z",
"scanRef": { "path": ".contextforge/scan.json", "scanHash": "..." },
"parser": { "engine": "heuristic" },
"stats": {
"nodesByType": { "file": 287, "folder": 117, "symbol": 3104 },
"edgesByType": { "imports": 71, "defines": 2256, "contains": 376 }
},
"nodes": [
/* ordenados por id, JSON byte-estable */
],
"edges": [
/* ordenadas por (from,to,type) */
]
}
Tipos de nodo y arista que produce
| Nodo | Cuándo aparece |
|---|---|
file |
Uno por cada archivo del scan (code/test/doc/config/asset) |
symbol |
Por cada función/clase/interface/type/var/enum exportada o interna |
folder |
Sintético, derivado de los paths (anidación completa) |
package |
Por cada import externo único (react, node:path, @anthropic-ai/sdk, …) |
| Arista | De qué | Cuándo se emite |
|---|---|---|
defines |
file → symbol |
Siempre que el archivo contiene un símbolo |
imports |
file → file o file → package |
Relativos · alias workspace (pnpm) · alias tsconfig.paths · externos |
tests |
file:test → file:impl |
Convención *.test.ts ↔ *.ts |
extends |
symbol → symbol |
Clase/interface extiende un símbolo del mismo file o de un import |
implements |
symbol → symbol |
class A implements B resuelto |
contains |
folder → folder y folder → file |
Estructura de carpetas |
calls |
file → symbol |
Solo con --with-calls (heurística regex, ruido aceptado) |
references |
file → symbol |
Solo con --with-refs (PascalCase, fuera de imports/defines) |
Lenguajes parseables hoy (heurística regex, no tree-sitter WASM): TypeScript, TSX, JavaScript, JSX, Python, Go, Rust, Java. El resto se incluye como file pero sin símbolos.
Incrementalidad y reproducibilidad
pnpm forge graph # 1ª vez en este repo: 112 archivos parseados
# editas un archivo
pnpm forge scan # actualiza hashes
pnpm forge graph # → "cache: 111 reutilizados, 1 reparseados"
pnpm forge graph --force # ignora ambos caches; reconstruye todo
pnpm forge graph --with-calls # añade aristas calls (heurística, opt-in)
pnpm forge graph --with-refs # añade aristas references PascalCase (opt-in)
# resolución de imports
# 1. workspace pnpm (packages/<name>)
# 2. tsconfig.paths (compilerOptions.paths con baseUrl)
# 3. relativos (./foo, ../bar)
# 4. externos → nodo type=package (react, node:fs, @scope/lib)
# export a otros formatos
pnpm forge graph --export=dot > graph.dot
pnpm forge graph --export=graphml > graph.graphml
# Render con Graphviz: dot -Tsvg graph.dot -o graph.svg
# O abrir graph.graphml directamente en Gephi.
# enriquecimiento opcional con LLM (Anthropic)
ANTHROPIC_API_KEY=sk-... pnpm forge graph --enrich
# Agrega summary / tags / complexity a los símbolos exportados.
# El default sigue siendo determinista; --enrich es la única excepción opt-in.
- Cache global por hash del scan: si
scan.jsonno cambió,forge graphno arranca. - Cache por archivo (
.contextforge/graph.cache.json): solo se reparsean los archivos cuyo hash BLAKE3 cambió. - Output byte-idéntico entre dos corridas (excluyendo
generatedAt): los nodos y aristas se ordenan al final porid/(from,to,type), así quegit diffdel JSON es revisable y el prompt cache de Claude no se invalida innecesariamente.
Visualización: forge viz
pnpm forge graph
pnpm forge viz # genera .contextforge/graph.html
# abre el archivo en cualquier navegador, no necesita servidor ni Node
El HTML viewer es standalone (un solo archivo, Cytoscape vía CDN) y trae:
┌──────────────────────────────────────────────────────────────────────┐
│ ContextForge [Grafo] [Dominios] 287 nodos · 2703 edges · 50 pack│
├──────────────┬───────────────────────────────────────────────────────┤
│ Estadísticas │ │
│ 287 archivos │ ●─────● │
│ 3104 símbolos│ ╱ ╲ ● ← archivo en pack │
│ 2703 edges │ ●─────●───● ◇ ← símbolo exportado │
│ 50 en pack │ ╲ ╱ ◇ ← dashed = interno │
│ │ ●─● ▢ ← carpeta │
│ Tour ◀ ▶ ✕ │ │
│ 3 / 50 │ │
│ │ │
│ Leyenda nodos │ ┌──────────────┐ │
│ ● Código 128 │ │ src/ │ ← agrupación por dominio │
│ ● Test 24 │ │ ┌────┐ ┌──┐ │ (toggle "Agrupar") │
│ ● Doc 17 │ │ │a.ts│ │b │ │ │
│ ▢ Carpeta 117│ │ └────┘ └──┘ │ │
│ ◇ Interno 218│ └──────────────┘ │
│ ● En pack 50 │ │
│ │ │
│ Leyenda edges │ │
│ ─ imports │ │
│ ─ defines │ │
│ ─ tests │ │
│ ─ extends │ │
│ ─ contains │ │
│ │ │
│ Filtros │ │
│ [Solo pack] [+Sím] [+Carpetas] [Agrupar] │
│ [⊕ Centrar] [⟳ Layout] │
│ │ │
│ 🔍 Buscar... │ │
│ │ │
│ Nodo selec. │ │
│ src/main.ts │ │
│ [code][ts] │ │
│ Define 4 sím │ │
│ → importa: 3 │ │
│ ← usado por:5│ │
└───────────────┴────────────────────────────────────────────────────────┘
Capacidades del viewer:
- Dos vistas: grafo file/symbol/folder + vista de dominios (agregación por carpeta top-level, edges = imports cruzados entre dominios).
- Tour por context-pack:
▶recorre uno por uno los archivos seleccionados por PageRank para tu tarea, centrándose y mostrando vecinos. - Filtros incrementales: solo pack (default), añadir símbolos, añadir carpetas, agrupar por dominio.
- Estilos diferenciados para
exported:false(símbolos internos en dashed) y nodosfolder. - Búsqueda por nombre o ruta con resaltado.
- Panel de nodo: kind, lang, contadores de edges entrantes/salientes, lista navegable de vecinos.
Cómo lo usa el agente
El agente nunca lee el repo a ciegas. Lee artefactos derivados, en este orden:
1. .contextforge/agent-context.md ← qué hay disponible y en qué orden leerlo
2. .contextforge/context-pack.json ← solo los archivos relevantes a la tarea
3. .contextforge/agent-manifest.json ← qué skills/rules aplican (con razón)
4. .contextforge/graph.json ← solo si necesita ver vecinos / cross-deps
El grafo no se inyecta entero al prompt. El agente lo consulta puntualmente:
| Pregunta del agente | Cómo responde el grafo |
|---|---|
"¿Qué archivos tocan a Foo?" |
Edges defines/imports entrantes del símbolo |
| "¿Quién testea esto?" | Edges tests entrantes del file |
"¿De qué hereda Bar?" |
Edge extends saliente del símbolo |
| "¿En qué carpeta vive este archivo?" | Edge contains entrante del file |
| "Dame el subgrafo de mi tarea" | Lo entrega forge context ya filtrado (PageRank + BFS + budget) |
| "Que nada se salga del scope" | implement-plan.json::allowedFiles[] derivado del pack |
Vía MCP — los agentes que hablen MCP pueden llamar tools sin tocar disco:
{ "tool": "forge_neighbors", "arguments": { "path": "src/foo.ts" } }
// → { incoming: [...], outgoing: [...], symbols: [...] }
{ "tool": "forge_context", "arguments": { "task": "fix race in writer" } }
// → { files: [...], packTokens: 11988, tokenLedger: {...} }
Vs. Understand-Anything (qué tomamos, qué no)
| Aspecto | Understand-Anything | ContextForge |
|---|---|---|
| Pipeline | Tree-sitter + LLM agents (híbrido) | Regex/tree-sitter, 0 LLM en el pipeline |
| Lenguajes soportados | 10+ con WASM | 8 con heurística (TS/JS/Py/Go/Rust/Java/TSX/JSX) |
| Schema de nodo | 21 tipos (con dominio + knowledge) | 4 tipos canónicos (file/symbol/folder/package) |
| Schema de arista | 35 tipos | 8 tipos (los que un agente usa de verdad) |
| Enriquecimiento (summary) | LLM agents enriquecen cada nodo | Determinista: contadores derivados del grafo |
| Coste de regenerar | API key + tiempo + ruido | CPU-only · cache por archivo · idempotente |
| Visualización | Dashboard rico, tours guiados | HTML standalone con tour + dominios + filtros |
| Persistencia | knowledge-graph.json + embeddings | graph.json + graph.cache.json (BLAKE3) |
| Roadmap LLM enrich | Es la base | Opt-in futuro (--enrich), nunca el default |
La filosofía: el grafo de ContextForge no intenta entender el código, intenta darte un índice rápido y barato. La inteligencia semántica vive en el agente, no en el pipeline. Por eso es reproducible y por eso el output sirve de input al prompt cache de Claude (descuento del 90 % en iteraciones 2+ del SDD).
Cómo el grafo le da superpoderes a OpenSpec
El bloque clave de v0.3.0+. Sin grafo, OpenSpec hace su trabajo bien pero el agente trabaja a ciegas. Con grafo, el spec se vuelve trazable, validable y barato.
1. El spec-input.json deriva del grafo, no del repo.
| Campo | Lo aporta el grafo |
|---|---|
affectedFiles |
El context-pack ya filtró por PageRank → spec apunta a archivos reales |
crossDomainDeps |
El grafo de imports → design.md menciona dependencias correctas |
domain |
Inferencia por mayoría de paths del pack |
evidence |
Referencias trazables a los artefactos JSON validados |
purpose |
Inferencia determinista del nombre del archivo |
2. El agente recibe el spec-prompt, NO el repo.
forge spec genera .contextforge/spec-prompt.md con 4 secciones:
1. Contexto del repo (de ContextForge)
- Tarea, dominio inferido, archivos afectados, cross-domain deps, evidencia
2. Instrucciones canónicas de OpenSpec
- Lo que devuelve `openspec instructions proposal --change <id> --json`
3. Restricciones para tu salida
- Token budget, allowed files, formato moderno
4. Output esperado
- Editar openspec/changes/<id>/{proposal,design,tasks,specs}.md
El agente no abre el repo. Solo lee este prompt + el context-pack si necesita más detalle.
3. El multiplicador escondido — prompt caching.
Claude descuenta 90 % del precio de tokens cacheados. ContextForge mete un boost porque su output es determinista:
- Mismo
forge context→ mismocontext-pack.jsonbyte-a-byte. - Mismo
forge spec→ mismospec-prompt.mdbyte-a-byte.
Entre las iteraciones 2, 3, N del SDD, el agente cachea todo el prompt. Solo paga full por el delta.
4. Ahorro doble medido.
Por iteración SDD:
Sin ContextForge 217 600 tokens $0.65
Con ContextForge 18 988 tokens $0.057 (-91%)
3 iteraciones de un feature normal:
Sin caching 3 × $0.65 = $1.96
Con caching activo $0.07 (÷28×)
5. Trazabilidad auditable.
Cada path en design.md apunta a un archivo del context-pack.json. Cada commit puede verificarse con forge implement --check contra allowedFiles[] derivado del pack.
6. Subgrafo congelado dentro del change (v0.3.7+).
forge spec <id> ahora también escribe openspec/changes/<id>/graph.subset.json — un subgrafo limitado al context-pack del change + 1 hop por aristas. Eso significa:
- Las skills/prompts del agente que leen
openspec/changes/<id>/tienen el grafo del momento exacto en que se autorizó el spec, sin necesidad de reabrir.contextforge/graph.json(que pudo haber mutado). design.mdincluye una sección "Context graph (subset)" con stats y la referencia al adjunto.- Vía MCP:
forge_change_subgraph({ change_id: "mi-feature" })lo devuelve directo, ideal para que un agente lo cargue al inicio de una sesión de implementación.
openspec/changes/mi-feature/
├── proposal.md
├── design.md ← incluye tabla con stats del subset
├── tasks.md
├── specs/<domain>/spec.md
├── graph.subset.json ← subgrafo self-contained · validado por JSON Schema
└── graph.subset.html ← viewer interactivo standalone (Cytoscape, sin servidor)
Trazabilidad real: el subgrafo es byte-stable (orden determinista), validado por JSON Schema (docs/schemas/graph-subset.schema.json), y queda commiteado con el resto del change. Si seis meses después el grafo global cambió, puedes comparar este subset con el subgrafo equivalente de hoy y ver el drift.
Tabla — qué aporta cada herramienta:
| Aporte | ContextForge | OpenSpec | Agente IA |
|---|---|---|---|
| Ranking de archivos por relevancia | ✓ | ||
| Grafo de dependencias | ✓ | ||
| Token budget + selección por presupuesto | ✓ | ||
| Trazabilidad (cada archivo viene del pack) | ✓ | ||
| Schemas estables (Requirement+Scenario) | ✓ | ||
Validación estructural (openspec validate) |
✓ | ||
| Templates canónicos por artefacto | ✓ | ||
Instalación de instrucciones por agente (openspec init) |
✓ | ||
| Redacción de prosa | ✓ | ||
| Decisiones de diseño contextual | ✓ | ||
| Determinismo + cacheabilidad | ✓ | ✓ |
Documentación generada para agentes (forge init)
forge init genera .contextforge/agent-context.md — un archivo derivado que cualquier agente puede leer al iniciar sesión y entender:
- Qué artefactos hay disponibles y en qué orden leerlos.
- Cómo consumirlos (no leer el repo a ciegas).
- La receta SDD completa (ContextForge ⊕ OpenSpec).
- Política para agentes (no specs a mano, no bullets, gate pre-commit).
- Tabla de comandos clave por intención.
Adicionalmente, forge init detecta si openspec CLI está en PATH y, si el directorio openspec/ no existe, ejecuta:
openspec init . --tools=claude,cursor,opencode --force
Eso instala las instrucciones canónicas de OpenSpec para los 3 agentes (las que aparecen en .claude/, .cursor/rules/, opencode.json). Idempotente: si el directorio openspec/ ya existe, salta.
Comandos completos
| Comando | Qué hace | LLM |
|---|---|---|
forge init |
.contextforge/ + agent-context.md + openspec init (si está) |
No |
forge scan |
Indexa con BLAKE3 (incremental) | No |
forge graph [--force] [--with-calls] [--with-refs] [--enrich] [--export=<dot|graphml>] |
Grafo file/symbol/folder/package con cache por archivo (BLAKE3) | No (¹) |
forge context "<tarea>" [--no-manifest] [--force] |
PageRank + BFS + budget · auto-emite manifest | No |
forge spec <id> [--no-openspec] |
spec-input.json + handoff/fallback OpenSpec | No |
forge implement <id> |
Plan con guardrails derivados del pack | No |
forge implement --check |
Valida diff vs guardrails | No |
forge skills [--force] |
Auto-genera skills por dominio (contextforge-domain-<slug>.md) |
No |
forge manifest [--agents=...] [--force] |
Re-genera manifest sin re-rankear | No |
forge sync [--since X] [--rebuild] |
Reporta delta desde un ref de git | No |
forge impact |
Health check de artefactos + cobertura | No |
forge viz |
Visualización HTML interactiva del grafo | No |
forge docs [--force] |
Scaffold Diátaxis (tutorials/how-to/reference/explanation/adr/architecture) | No |
Política: ningún comando llama a un LLM por defecto. Todo es derivable, reproducible, auditable.
(¹) forge graph --enrich es la única excepción opt-in — agrega summary/tags/complexity a símbolos exportados vía Anthropic API. Requiere ANTHROPIC_API_KEY. Sin la flag, el pipeline sigue 100 % determinista.
Servidor MCP
packages/mcp expone 10 tools consumibles por cualquier cliente MCP (Claude Code, OpenCode, etc.).
| Tool | Propósito |
|---|---|
forge_status |
Estado de los artefactos (frescura, conteos, savings) |
forge_domain_map |
Mapa de dominios + dependencias cruzadas |
forge_neighbors |
Vecinos directos de un archivo en el grafo |
forge_context |
Selección PageRank para una tarea (con o sin contenido) |
forge_check |
Valida git diff contra guardrails del implement-plan |
forge_change_subgraph |
Subgrafo congelado de un OpenSpec change (openspec/changes/<id>/graph.subset.json) |
forge_change_context |
Mapa de lectura del change (openspec/changes/<id>/context.md) |
forge_archive_change |
Cierra un change: openspec archive + rebuild graph padre + refresh subgrafos |
select_agent_context |
Runtime: computa agent-manifest en memoria para una tarea (cache mtime) |
get_agent_manifest |
Offline: lee .contextforge/agent-manifest.json precomputado |
Wiring (Docker, recomendado):
{
"mcpServers": {
"contextforge": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-v",
"${PWD}:/project",
"-e",
"PROJECT_ROOT=/project",
"ghcr.io/alejandro-cedeno-10/contextforge-mcp:latest"
]
}
}
}
Wiring (npm):
{
"mcpServers": {
"contextforge": {
"command": "node",
"args": ["./node_modules/@anai-raia-alex/contextforge-mcp/dist/index.js"],
"env": { "PROJECT_ROOT": "." }
}
}
}
Artefactos generados
Todos los JSON validados con JSON Schema 2020-12 antes de escribirse.
.contextforge/
scan.json # archivos con hashes BLAKE3
graph.json # 368 nodos, 267 edges
context-pack.json # archivos seleccionados dentro del presupuesto
token-ledger.json # métricas auditables del ahorro
agent-manifest.json # skills/rules relevantes a la tarea (neutral)
spec-input.json # entrada determinista para OpenSpec / agente
spec-prompt.md # prompt copy-paste (modo handoff)
implement-plan.json # guardrails: allowedFiles, maxLocDelta, etc.
agent-context.md # documentación del repo para agentes IA
graph.html # visualización interactiva (Cytoscape.js)
manifests/opencode-readme.md # instrucciones MCP para OpenCode
.claude/agent-manifest.md # manifest renderer Claude Code
.cursor/rules/contextforge-active.mdc # rule auto-attached por dominios tocados
openspec/changes/<id>/
proposal.md # intent, scope, why, alternatives
design.md # decisiones técnicas con archivos del grafo
tasks.md # T1, T1.1, T2... checklist
specs/<dominio>/spec.md # ## ADDED Requirements + ### Requirement: + #### Scenario:
Schemas
| Artefacto | Schema |
|---|---|
scan.json |
docs/schemas/scan.schema.json |
graph.json |
docs/schemas/graph.schema.json |
context-pack.json |
docs/schemas/context-pack.schema.json |
implement-plan.json |
docs/schemas/implement-plan.schema.json |
token-ledger.json |
docs/schemas/token-ledger.schema.json |
agent-manifest.json |
docs/schemas/agent-manifest.schema.json |
spec-input.json |
docs/schemas/spec-input.schema.json |
Métricas reales (este repo, hoy)
| Métrica | Valor |
|---|---|
| Tests | 270 / 270 verde (26 archivos) |
| Coverage | ≥ 80 % global · módulos manifest/ y spec/ ≥ 95 % |
| Token savings | 94.4 % vs baseline |
| Compresión | 17.9× por sesión · ÷28× SDD con caching |
| Archivos del repo | 128 |
| Archivos en context-pack | 50 |
| Tokens del context-pack | 11 988 |
| Tokens baseline | 214 606 |
| Grafo | 368 nodos, 267 edges |
Comandos forge |
13 |
| Tools MCP | 7 |
Distribución
| Canal | Identificador |
|---|---|
| npmjs.com (público, sin token) | @anai-raia-alex/contextforge-{core,cli,mcp} |
| GitHub Container Registry | ghcr.io/alejandro-cedeno-10/contextforge-mcp:latest (multi-arch amd64+arm64) |
| Repo público | https://github.com/alejandro-cedeno-10/contextforge-cli |
Integración con agentes — matriz
| Agente | Configuración | Selección por tarea | Estado |
|---|---|---|---|
| Claude Code | .claude/skills/ (3 task-oriented + N auto-generadas) · hook UserPromptSubmit |
Hook inyecta manifest live + JSON precomputado | Listo |
| Cursor | .cursor/rules/contextforge.mdc (alwaysApply) + contextforge-active.mdc (Auto-Attached) |
Rule por glob regenerada por forge context (Cursor no tiene hooks reactivos) |
Listo |
| OpenCode | opencode.json con MCP server registrado |
Tool MCP select_agent_context({task}) live |
Listo |
| Codex / otros | Leen .contextforge/*.json directamente |
Lectura directa de agent-manifest.json |
Compatible |
Los .contextforge/*.json son portables. Cualquier agente futuro los puede consumir sin modificación.
Principios
- Determinismo primero: ningún comando llama a un LLM. Reproducible, auditable, cacheable.
- OpenSpec por defecto:
forge specdelega a OpenSpec CLI cuando está, fallback determinista cuando no. - Cache por hash: si
scan.jsonno cambió,forge graphsalta el rebuild. - Presupuesto explícito: cada context-pack tiene
maxInputTokenstrazable entoken-ledger.json. - JSON validado: ningún artefacto se escribe sin pasar JSON Schema.
- Portable: cualquier agente puede consumir
.contextforge/*.jsonsin modificación. - Sin lock-in: si mañana sale otra herramienta SDD, lee los mismos JSON.
Para la exposición — los 5 puntos memorables
- 94 % menos tokens por sesión — verificado con
token-ledger.json, no estimado. - ÷28× costo SDD con prompt caching — porque el output es determinista byte-a-byte.
- No competimos con OpenSpec, lo apoyamos. Tres roles separados (CF / OpenSpec / agente). Si OpenSpec evoluciona, no nos pisamos.
- El agente solo carga lo de tu tarea actual — context-pack + manifest. Las 100 skills viejas no entran al contexto.
- Sin lock-in. Los
.contextforge/*.jsonson neutrales. Si mañana sale otra herramienta, los puede consumir igual.
Estructura del monorepo
packages/
core/ → scanner, parser tree-sitter, graph builder, selector PageRank,
packer, schema validator, skill builder, agent-manifest, spec-input,
spec promptRenderer
cli/ → comandos forge (init, scan, graph, context, spec, implement, manifest,
skills, sync, impact, viz, docs)
mcp/ → servidor MCP con 7 tools
.claude/skills/ → 3 skills task-oriented (contextforge-*) +
N auto-generadas (contextforge-domain-*) +
agent-manifest.md (per-task)
.cursor/rules/ → contextforge.mdc (alwaysApply) +
contextforge-active.mdc (Auto-Attached, regenerada por tarea)
opencode.json → configuración MCP para OpenCode
docs/integrations/ → guías de wiring por agente
docs/explanation/ → contextforge-and-openspec.md (lectura clave)
Tests
pnpm test # todos los tests
pnpm test:coverage # con cobertura
pnpm typecheck # tsc -b --force (project references)
Suite actual: 270/270 tests pasando (26 archivos), coverage global ≥ 80 % · módulos manifest/ y spec/ ≥ 95 %.
Documentación
| Documento | Descripción |
|---|---|
docs/explanation/contextforge-and-openspec.md |
Lectura clave: 3 roles (CF / OpenSpec / agente), ahorro medido, prompt caching ÷28× |
docs/how-to/use-contextforge.md |
Guía paso a paso: instalación, pipeline, integración por agente |
docs/integrations/claude-code-hook.md |
Snippet copy-paste para activar manifest en runtime en Claude Code |
docs/integrations/cursor-rules.md |
Los 3 modos de rules en Cursor + estrategia recomendada |
docs/integrations/opencode-mcp.md |
Ejemplo de select_agent_context desde OpenCode |
docs/token-savings-architecture.md |
Análisis de ahorro de tokens por capas con tabla de costos |
docs/EXAMPLES/end-to-end-flow.md |
Walkthrough completo del pipeline con outputs reales |
docs/IMPLEMENTATION_TASKS.md |
Backlog de sprints con criterios verificables |
docs/CHANGELOG-schemas.md |
Historial de cambios de schemas |
openspec/changes/forge-spec-as-prepare-step/ |
OpenSpec change del re-arquitectura v0.3.0 |
openspec/changes/agent-manifest/ |
OpenSpec change del manifest por tarea |
openspec/changes/auto-domain-skills/ |
OpenSpec change de las skills auto-generadas |
CONTEXTFORGE_SOURCE_OF_TRUTH.md |
Decisiones de diseño, arquitectura, roadmap |
Licencia
MIT
Установка ContextForge Server
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/alejandro-cedeno-10/contextforge-cliFAQ
ContextForge Server MCP бесплатный?
Да, ContextForge Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для ContextForge Server?
Нет, ContextForge Server работает без API-ключей и переменных окружения.
ContextForge Server — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить ContextForge Server в Claude Desktop, Claude Code или Cursor?
Открой ContextForge Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare ContextForge Server with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
