TÁNDEM MCP Server
Enables cross-refinement between two LLMs with automated critique, revision, and convergence, providing tools for managing tandem sessions.
README
TÁNDEM
Refinamiento cruzado entre dos LLM — Claude Code CLI × Codex CLI — que trabajan en paralelo sobre copias aisladas del mismo material, se critican mutuamente con evidencia re-ejecutada, absorben cada uno lo mejor del otro y solo convergen cuando se cumple un predicado de excelencia computable (gates verdes + doble APPROVE + puntuación mínima).
Este repositorio implementa la arquitectura descrita en tandemarquitectura.md (proyecto LLM COLLAB). Las referencias §N de los comentarios del código apuntan a las secciones de ese documento.
1. Estado actual: esqueleto + base técnica
| Módulo | Fichero(s) | Estado |
|---|---|---|
| Protocolo de mensajes (§5) | src/protocol/schemas.ts |
✅ Completo: schemas zod de Finding, Critique, WorkResult, TaskSpec, EvidenceReport, TandemConfig, WorkPackage, ReviseInput, Rebuttal + parseAgentJson (extracción y auto-reparación de JSON) |
| Plantillas de prompt (§10) | src/protocol/prompts/*.md + prompts.ts |
✅ Las 6 plantillas (spec-sync, produce, critique, revise, merge, audit) + motor de renderizado con bloques condicionales |
| Máquina de estados (§3) | src/orchestrator/state-machine.ts |
✅ Fases, transiciones legales validadas, estado del run, helpers de ronda |
| Controlador de convergencia (§6) | src/orchestrator/convergence.ts |
✅ checkConvergence + isStagnant con lógica real y tests (incluye anti-adulación) |
| Ejecución de ronda (§3–§4) | src/orchestrator/round.ts |
✅ Generalizada PRODUCE|REVISE ∥ → snapshots git → gates → crítica cruzada ∥ → adjudicación; cancelación del hermano si un agente cae; test de integración sobre repo git real |
| Bucle completo (Fase 2) | src/orchestrator/loop.ts |
✅ SPEC_SYNC negociado (proponer→fusionar→votar, 2 intentos→ESCALATE) · bucle multironda con CHECK · REBUTTAL con contra-evidencia re-ejecutada · MERGE con integrador rotatorio · FINAL_AUDIT por el que NO integró · una corrección acotada · DELIVER copy-out · kill-switch cooperativo |
| Adaptadores (§7) | src/adapters/ |
✅ produce()/critique()/revise() + ask() genérico validado en ambos. Claude: stdin + auto-reparación con --resume + sesión encadenada entre rondas. Codex: exec - + --output-schema. Modelos configurables por agente |
| Workspace Manager (§9) | src/workspace/ |
✅ copy-in + repo interno + worktrees (A/B/merge) + install por worktree + deliver copy-out (sin .git ni node_modules) |
| Evidence Runner (§8) | src/evidence/ |
✅ runGates + adjudicación de findings + adjudicación de contra-evidencia (REBUTTAL, semántica inversa); rúbrica/links (modo docs) — Fase 3 |
| Informes | src/orchestrator/report.ts |
✅ Por ronda (comparativo) + final multironda: tabla de rondas, fusión y auditoría, backlog no bloqueante de minors, mapa de discrepancias si ESCALATE |
| Persistencia (§9) | src/store/ |
✅ SQLite (runs/rounds/messages + history para resume) + transcript JSONL append-only, alimentados en vivo |
| CLI (§12) | src/index.ts |
✅ COMPLETO: run (bucle entero) · status · report · stop (sentinela) · resume (frontera de ronda o directo a MERGE) · doctor |
| Cabina MCP — Variante B (§14) | src/mcp/server.ts + mcp/server.ts |
✅ Servidor MCP stdio para Claude Desktop: 7 tools (tandem_start/status/report/stop/resume/list/doctor), runs en segundo plano, testeado con cliente MCP real. Setup: mcp/README.md |
| Modo docs funcional | src/evidence/validators/docs-structure.ts |
✅ Gate mecánico de memorias vía tandem.docs.json: cobertura LITERAL del baremo, secciones en espejo, anticontaminación (términos vetados), límites de extensión, cero «rojos», ficheros exigidos; + links locales |
| Eje de entornos | src/workspace/agent-env.ts |
✅ agentEnv: personal (cada cuenta con su arsenal — duelo de EQUIPOS; cada modelo interpreta sus skills a su manera, declarándolo en NOTES) | clean (solo auth — duelo de MODELOS); manifiesto arsenal.json por run; sharedTools MCP idénticas a ambos CLIs (metro común) |
| Verticales | src/verticals.ts + verticals/ |
✅ Arquitecturas especializadas como DATOS (config + normas + plantillas), kernel ciego al dominio. Primero: licitaciones (método NextHorizont: espejo del baremo, anclaje literal, anticontaminación) — --vertical licitaciones |
| Ejecución compartida | src/execute.ts |
✅ executeLoop + buildResumeState comunes a CLI y MCP (logger inyectable; store SIEMPRE por import dinámico) |
| Dashboard / MCP (§12, §14) | dashboard/, mcp/ |
🔲 Placeholders con diseño — Fase 3 |
Leyenda: ✅ implementado y testeado · 🟡 parcial (lo indicado pendiente) · 🔲 diseñado, sin código.
2. Requisitos
- Node ≥ 20 (probado con Node 22).
- pnpm (
corepack enableo https://pnpm.io/installation). - git en el PATH (los worktrees son el mecanismo de aislamiento).
- Claude Code CLI con login de tu suscripción (
claudeen el PATH). - Codex CLI con
codex loginde tu suscripción ChatGPT.
Los CLIs solo hacen falta para ejecutar runs reales; para desarrollar y testear el orquestador no se necesitan.
3. Puesta en marcha, paso a paso
# 1) Entra en la carpeta del proyecto
cd tandem
# 2) Instala dependencias (siempre pnpm, nunca npm)
pnpm install
# 3) Comprueba que el esqueleto compila con TypeScript estricto
pnpm typecheck
# 4) Ejecuta la batería de tests (convergencia, máquina de estados, protocolo)
pnpm test
# 5) Diagnóstico del entorno: qué CLIs tienes y cuáles faltan
pnpm dev doctor
# 6) DUELO COMPLETO (Fase 2): bucle entero hasta la entrega auditada
pnpm dev run --dir ..\mi-carpeta --task "Tarea concreta y verificable"
#
# Fases (cada ronda tarda MINUTOS — §16.1):
# SPEC_SYNC (pactan la spec) → PRODUCE ∥ → gates → crítica cruzada
# → adjudicación → REBUTTAL (contra-evidencia) → CHECK
# → [REVISE con polinización cruzada → …]* hasta MERGE o ESCALATE
# → fusión dirigida (integrador rotatorio) → FINAL_AUDIT (el otro)
# → entrega en runs/<id>/final (o --out <carpeta>)
#
# Flags útiles:
# --blind crítica sin autoría (Solución 1/2)
# --no-spec-sync usar la tarea literal como spec
# --no-rebuttal sin fase de contra-evidencia
# --integrator claude|codex|auto
# --model-claude X · --model-codex Y
# --max-rounds 4 · --threshold 90 · --out D:\resultado
# 7) Control del run en vuelo (desde otra terminal)
pnpm dev status <run-id> # rondas, gates, scores, decisiones
pnpm dev stop <run-id> # kill-switch: para en la próxima frontera de fase
pnpm dev resume <run-id> # reanuda desde la última ronda persistida
pnpm dev report <run-id> # imprime el informe final
Notas: ambos CLIs deben tener login hecho (claude y codex login); tu carpeta original nunca se toca (copy-in → todo pasa en runs/<id>/, y la entrega es copy-out); resume re-produce la ronda que estaba en vuelo sobre los worktrees existentes.
4. Estructura del repositorio (§11)
tandem/
├── package.json # pnpm · Node ≥ 20 · ESM · TypeScript estricto (sin `any`)
├── tsconfig.json
├── src/
│ ├── index.ts # CLI (commander): run · status · report · resume · doctor · stop
│ ├── orchestrator/
│ │ ├── state-machine.ts # fases y transiciones (§3)
│ │ ├── round.ts # ejecución de una ronda (§3–§4) [Fase 1]
│ │ └── convergence.ts # checkConvergence + isStagnant (§6)
│ ├── adapters/
│ │ ├── agent-adapter.ts # interfaz común + AgentContext (§7)
│ │ ├── claude-code.ts # claude -p / --resume (headless)
│ │ └── codex.ts # codex exec / resume / --output-schema (headless)
│ ├── protocol/
│ │ ├── schemas.ts # zod: TODOS los mensajes agente↔orquestador (§5)
│ │ ├── prompts.ts # carga y renderizado de plantillas
│ │ └── prompts/ # spec-sync · produce · critique · revise · merge · audit (§10)
│ ├── workspace/
│ │ ├── git.ts # helpers git (repo interno del run)
│ │ ├── worktrees.ts # ws-A / ws-B / ws-merge (§9)
│ │ ├── diff.ts # snapshots etiquetados r<N>-A/B y diffs
│ │ └── merge.ts # entrega fast-forward / copy-out [Fase 2]
│ ├── evidence/
│ │ ├── runner.ts # runGates + replayEvidence (el árbitro no-LLM, §8)
│ │ └── validators/ # typecheck · lint · tests · build · rubric · links
│ └── store/
│ ├── db.ts # SQLite: runs · rounds · messages (coste/latencia)
│ └── transcript.ts # JSONL append-only auditable
├── test/ # vitest: convergencia · máquina de estados · protocolo
├── dashboard/ # Fase 3 (Next.js, Server Components sobre la SQLite)
└── mcp/ # Fase 3 (variante B: cabina de mando en Claude Desktop)
5. Decisiones técnicas ya cerradas en el esqueleto
- ESM + NodeNext: imports con extensión
.jsobligatoria. TypeScript en modo máxima estrictez (strict,noUncheckedIndexedAccess,exactOptionalPropertyTypes); el tipoanyestá prohibido. - El APPROVE nunca contradice la evidencia: implementado en
convergence.ts(no confiado al modelo) y testeado entest/convergence.test.ts(caso "ANTI-ADULACIÓN"). - Sin checks aplicables no hay pase gratis:
runGatesdevuelvepass=falsesi ningún validador aplica — obliga a configurar gates o rúbrica antes de que nada pueda aprobarse. - Un finding sin evidencia no existe:
FindingSchemaexigeevidenceno vacía; la re-ejecución (replayEvidence) la adjudica en Fase 1. - Codex valida en origen, Claude en destino: Codex usa
--output-schema(JSON conforme garantizado); para Claude,parseAgentJson+ bucle de auto-reparación sobre la misma sesión (máx. 2 intentos). - Identidad git local por run: el repo interno usa
tandem-orchestrator <tandem@localhost>— no toca tu configuración global. - Línea de comandos fija + datos por stdin (
src/util/exec.ts): los CLIs se invocan conshell: true(imprescindible para los shims.cmdde Windows) pero el prompt NUNCA se interpola en la línea de comandos — viaja por stdin (claude -pycodex exec -). Cero problemas de escapado en cmd.exe y sh. - Heurística de adjudicación documentada (
src/evidence/runner.ts): buscadores (grep/rg) reproducen con exit 0; comandos normales con exit ≠ 0 o si la salida contiene la expectativa declarada tras→; citas si el fichero:línea existe. Losdisputedno cuentan (§5) pero quedan en el informe y el transcript. - La identidad de las críticas la normaliza el orquestador: author/target/round se sobreescriben tras el parseo — un agente no puede atribuirse la autoría que quiera (testeado).
- REBUTTAL con semántica inversa: la contra-evidencia del autor gana si su comando TIENE ÉXITO (exit 0 o expectativa presente) — al revés que un finding, donde el fallo demuestra el defecto. Contra-evidencia no ejecutable = finding mantenido (se exige comando, no prosa).
- SPEC_SYNC en tres pasos deterministas: proponer ∥ → fusiona uno → vota el otro; si rechaza, fusiona el que rechazó (con sus objeciones sobre la mesa) y vota el primero; segundo rechazo → ESCALATE
spec_conflict. Barato de escalar en ronda 0, caro en ronda 4 (§3). - Kill-switch cooperativo:
tandem stopcrea el sentinelaSTOP; el bucle lo consulta entre fases (los CLIs en vuelo no se matan a mitad).resumeretoma en frontera de ronda re-produciendo la ronda en vuelo sobre los worktrees existentes. - Cancelación del hermano: si un agente cae en una fase paralela, el otro se aborta vía AbortSignal → no quedan procesos huérfanos consumiendo cuota.
- Normas del duelo (Karpathy Guidelines adaptadas): los cuatro principios de multica-ai/andrej-karpathy-skills (MIT) — pensar antes de programar, simplicidad primero, cambios quirúrgicos, ejecución guiada por objetivos — se inyectan automáticamente en los prompts en DOS caras:
norms-build.mdpara quien produce/revisa/fusiona ynorms-review.mdpara quien critica/audita (los incumplimientos objetivos son material legítimo de finding, sin relajar la evidencia obligatoria ni habilitar bloqueos por estilo). Adaptación clave: el "pregunta si dudas" headless se canaliza a supuestos declarados enNOTES.mdy ambigüedades resueltas en SPEC_SYNC. Se desactivan pasandoNORMS: nullabuildPrompt(o editando los .md).
6. Roadmap — qué implementar y en qué orden
Fase 1 — MVP (una ronda demostrable) — ✅ COMPLETADA (y validada con un duelo real en producción).
Fase 2 — Bucle completo — ✅ COMPLETADA (validada en producción: run cfa59ae1, fusión de codex auditada por claude y entregada).
Variante B — Cabina en Claude Desktop — ✅ COMPLETADA: servidor MCP local con runs en segundo plano (ver mcp/README.md).
Fase 3 — Confort (pendiente): dashboard Next.js, modo docs (rúbricas + links), contenedores, deliver fast-forward en modo-rama, sesión persistente de Codex (exec resume + eventos --json), tabla de rondas del informe reconstruida desde la BD en runs reanudados.
Fase 3 — Confort: dashboard Next.js, servidor MCP (variante B), modo docs (rúbricas + links), --blind operativo, presupuestos finos, contenedores.
7. Solución de problemas (Windows)
better-sqlite3 falla al instalar con «"node-gyp" no se reconoce…».
El proyecto fija better-sqlite3@^12 a propósito: la v12 instala con prebuild-install || node-gyp rebuild, es decir, descarga un binario ya compilado para tu plataforma (hay binarios win32-x64 para Node 22 — ABI 127 — y Node 24 — ABI 137) y solo compila como último recurso. La v13 eliminó los binarios precompilados y SIEMPRE compila desde código, lo que en Windows exige Python + Visual Studio Build Tools. Si con la v12 sigue intentando compilar, tu versión de Node no tiene binario publicado: comprueba node -v y usa Node 22 o 24 LTS.
doctor decía que un CLI no estaba, pero sí está. En Windows, pnpm/claude/codex son shims .cmd, y Node (tras el parche de seguridad CVE-2024-27980) se niega a spawnearlos sin shell (error EINVAL). El doctor ya los invoca con shell: true. Verifica en una terminal nueva que claude --version y codex --version responden.
codex aborta con «Not inside a trusted directory». Es su puerta de confianza: en modo interactivo pregunta si confías en la carpeta; en headless no puede y aborta. TANDEM ya invoca codex exec con --skip-git-repo-check (seguro: el cwd es siempre el worktree git del run). Si lo ves, tu copia del adaptador es antigua.
codex escupe errores «failed to load skill … missing YAML frontmatter». Son NO fatales: codex rechaza skills personales de ~/.agents/skills/ cuyo SKILL.md no empieza por ---, y continúa. Puedes ignorarlos o poner esas skills en cuarentena para limpiar el ruido (muévelas a otra carpeta y reviértelo cuando quieras).
Runs reales en Windows. Los CLIs se lanzan con línea de comandos fija + prompt por stdin (ver decisión 7), que funciona en Windows nativo. Si tu instalación de codex no soportara --sandbox workspace-write en Windows, la alternativa es ejecutar los runs bajo WSL2.
8. Seguridad (§13) — ya reflejada en el esqueleto
- Claude:
--permission-mode acceptEdits+ lista blancaCLAUDE_ALLOWED_TOOLS(nuncabypassPermissionsfuera de contenedor). - Codex:
--sandbox workspace-write(escritura limitada al worktree). runs/está en.gitignore(contiene worktrees y transcripts);.envfuera del árbol que ven los agentes.- Timeouts por fase (
phaseTimeoutMs) y presupuesto por run (budgetMs) en la config.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。