codex-mcp
codex-mcp
Una puerta de calidad independiente y de solo lectura para los artefactos de QA.
codex-mcp es un servidor MCP independiente que ejecuta Codex como segundo revisor adversarial sobre casos de prueba candidatos y hallazgos de bugs — antes de que el agente autor escriba su informe final. Codex inspecciona el repositorio por sí mismo, forma su propia opinión sobre lo que debería cubrirse o si un defecto es real, y solo entonces lo compara con el candidato que se le ha dado.
Devuelve un delta de revisión. Nunca escribe tu artefacto.
Authoring agent (Claude, or any MCP client)
│ gathers the requirement, reads the code, drafts candidates
▼
candidate result — in memory, not yet written
│
▼ codex_qualify
codex-mcp ──► Codex (read-only sandbox, rooted at your repo)
│ ├─ reads the code, the diff, the existing tests
│ ├─ reads blast-radius / test-charter if present
│ └─ reads Jira / DB / other MCPs if configured, read-only
▼
review delta: accept · modify · remove · missing · evidence · limitations
│
▼
Authoring agent reconciles, then writes the FINAL artifactContenido · Instalación · Conectar a un proyecto · Úsalo · Configuración · Conectores de evidencia · Límite de permisos · Contrato de API · Solución de problemas · Pruebas
Por qué un segundo modelo, y por qué de solo lectura
El modo de fallo que esto aborda no es «el agente no puede escribir casos de prueba». Es que un agente que evalúa su propio trabajo está de acuerdo consigo mismo. Un revisor que comparte el contexto del autor hereda los puntos ciegos del autor.
Por lo tanto, dos propiedades son los pilares:
Independencia. Se instruye a Codex a derivar la cobertura esperada antes de examinar de cerca el candidato, y a intentar falsear cada afirmación de bug en lugar de confirmarla. Anclarlo primero al candidato produciría un revisor más complaciente y menos útil.
Solo lectura. El revisor se ejecuta en el sandbox read-only de Codex, y todo sistema posterior al que pueda llegar se filtra a través de una capa de políticas que clasifica cada herramienta y rechaza cualquier cosa que mute. Una puerta de calidad que no se puede apuntar con seguridad a un repositorio en vivo es una puerta de calidad que nadie ejecuta.
Ninguno de los dos modelos es autoritativo. La evidencia fuente es:
requirement / runtime / code / DB / external evidence > model opinionRelated MCP server: gpt-control
Instalación
Requiere Node 20+. Cuatro comandos, una vez por máquina.
# 1. The Codex CLI. codex-mcp drives it, and it owns your credentials.
npm install -g @openai/codex@latest
# 2. codex-mcp itself.
git clone <this-repo> codex-mcp && cd codex-mcp
npm install && npm run build && npm link
# 3. Sign in. A browser opens once; that is the whole flow.
codex-mcp login
# 4. Write a config, detecting any MCP servers already on this machine.
codex-mcp init --model gpt-5.6-solLuego confírmalo antes de confiar en él:
codex-mcp doctorTodas las líneas deberían decir ok. doctor es de solo lectura y seguro contra un proyecto en vivo — consulta Solución de problemas para saber qué significa cada fallo.
El nombre npm
codex-mcppertenece a un paquete no relacionado. Instala desde el código fuente como se indicó arriba, o publícalo bajo tu propio scope.
Lo que hace init
Escribe ~/.config/codex-mcp/codex-mcp.yaml, y un .env junto a él si encuentra servidores MCP posteriores en ubicaciones convencionales:
$ codex-mcp init --dry-run
Would write into /home/you/.config/codex-mcp
codex-mcp.yaml (new)
.env (new)
Detected:
jira-mcp (jira) -> /home/you/jira-mcp/src/index.js
db-mcp (database) -> /home/you/db-mcp/dist/index.jsLos servidores detectados se escriben como entradas de conector que puedes habilitar, con sus rutas mantenidas en .env para que el YAML siga siendo portátil entre máquinas. --force sobrescribe; sin él, los archivos existentes se conservan.
init es el único comando que escribe algo, y se ejecuta antes de que exista revisión alguna. Las revisiones en sí son estrictamente de solo lectura.
¿Prefieres escribir la configuración tú mismo? Copia codex-mcp.example.yaml a ~/.config/codex-mcp/codex-mcp.yaml — cada valor en él está anotado y es el valor predeterminado integrado a menos que su comentario diga lo contrario.
Autenticación
Un comando, una vez por máquina:
codex-mcp login # browser opens; sign in to ChatGPT
codex-mcp auth-status # confirmLas credenciales terminan en el almacén propio del CLI de Codex (~/.codex/auth.json, modo 0600) y son renovadas por él. Persisten entre reinicios y terminales — no vuelves a iniciar sesión por proyecto ni por sesión.
codex-mcp nunca maneja la credencial en sí. No tiene cliente OAuth, ni listener de callback, ni almacenamiento de tokens. Ejecuta externamente codex login status y lee sí/no. Nada aquí puede abrir un navegador durante una revisión: una llamada no autenticada falla rápido en su lugar.
{ "code": "CODEX_AUTH_REQUIRED", "message": "Codex is not authenticated. Run `codex-mcp login`." }Usar una clave de API en su lugar
Modo | Comando | Usos |
|
| OAuth en navegador, suscripción a ChatGPT |
|
| Una clave de API de OpenAI |
codex-mcp login --mode api # hidden prompt
printenv OPENAI_API_KEY | codex-mcp login --mode apiLa clave se lee de --api-key, luego de OPENAI_API_KEY, luego de un prompt oculto, y se canaliza a codex login --with-api-key por stdin — nunca como un elemento de argv, de modo que no queda en tu tabla de procesos ni en el historial de la shell. El CLI de Codex la almacena; codex-mcp no.
Establece auth.mode en tu configuración para que coincida. Si el CLI está autenticado en un modo diferente del que afirma la configuración, las revisiones fallan con un error claro en lugar de facturar silenciosamente a la cuenta equivocada.
Conectar a un proyecto
Elige una de estas opciones. Registrarse dos veces es el error de configuración más común — consulta la advertencia a continuación.
Opción A — un proyecto, confirmado
Crea .mcp.json en la raíz del proyecto — no en .claude/, que contiene un conjunto diferente de archivos y lo ignorará:
{
"mcpServers": {
"codex-mcp": { "command": "codex-mcp", "args": ["start"] }
}
}Hazle commit. Cada compañero que haya ejecutado Instalación ahora tiene la puerta, usando su propia elección de modelo de su propia configuración.
Opción B — todos tus proyectos, sin confirmar
claude mcp add codex-mcp -- codex-mcp startEsto escribe en ~/.claude.json y aplica dondequiera que trabajes.
Regístrate en un solo lugar.
claude mcp addescribe en el ámbito local, que prevalece sobre.mcp.json. Con ambos presentes, el archivo del proyecto — incluido cualquierenven él — se ignora silenciosamente. Ejecutaclaude mcp remove codex-mcpsi vas a cambiar a.mcp.json.
Reinicia Claude Code. /mcp debería mostrar ahora codex-mcp con tres herramientas. Si no es así, consulta Solución de problemas.
Otros clientes MCP aceptan los mismos dos campos — command: codex-mcp, args: ["start"] — en el archivo de configuración que usen.
Úsalo
Hazlo automático
Añade una regla al CLAUDE.md del proyecto. Esta es toda la superficie de integración — no hay lógica de Codex específica del proyecto en ningún otro lugar:
## Independent QA qualification
Before finalizing test cases or bug reports, send the complete candidate result,
project root, task/requirement context, and any available blast-radius or
test-charter to codex-mcp for independent qualification.
Reconciling means verifying each objection against the evidence it cites — not
accepting it. Apply what the evidence supports. Reject what it does not, and note
why. codex-mcp is a second opinion, not an approver.
One pass is normal. Run a second only if the first forced substantial high-risk
changes.Con eso en su lugar, escribes tu solicitud normal y la puerta se ejecuta por sí sola:
Crea casos de prueba para DEV-2951.
El agente recopila el requisito, lee el código, redacta candidatos, llama a codex_qualify, concilia y luego escribe el informe.
Pídelo explícitamente
Cuando no hay regla, o lo quieres sobre algo ya redactado:
Antes de que escribas el informe, envía estos casos de prueba a codex-mcp con
project.rootestablecido en/path/to/repoytask.idDEV-2951. Muéstrame a qué objeta y si estás de acuerdo, luego escribe la versión final.
Ejecuta los hallazgos de bugs que acabas de escribir a través de
codex_qualifyconreviewType: "bugs". Para cualquier cosa que llame falso positivo, verifica el código que cita antes de descartar el hallazgo.
Califica estos contra codex-mcp, pero solo reporta objeciones donde la evidencia citada realmente se sostiene. Dime cuáles rechazaste y por qué.
Variaciones útiles:
Lo que quieres | Añade a tu prompt |
Pruebas y bugs de una vez |
|
Enfocarse en un área de riesgo |
|
Omitir la base de datos |
|
Pasarle tus artefactos |
|
Leer lo que devuelve
Pide a tu agente que exponga estos en lugar de actuar sobre ellos silenciosamente:
missing— cobertura que dice que te falta. Verifica que elfile:linecitado sea real.modify— tu expectativa contradice el código. Suele ser el hallazgo más contundente.remove— redundante. Verifica que lo que dice que sustituye al tuyo realmente lo sustituya.limitations— lo que no pudo verificar. Una revisión confiada con una lista larga de limitaciones es una revisión estrecha; lee esto antes de confiar en el resto.disagreements— él y tu agente leen la misma evidencia de manera distinta. Estos te necesitan a ti, no a cualquiera de los dos modelos.
Un buen prompt de seguimiento:
Para cada objeción, dime la evidencia que citó y si tú mismo la verificaste. Enumera cualquier cosa que rechazaste y por qué.
Lo que no hará
Nunca edita archivos, hace commit, hace push, escribe en Jira o en la base de datos, ni escribe tu informe. Si tu agente afirma que codex-mcp cambió algo, no lo hizo — comprueba git status.
Conciliación — la parte que importa
codex-mcp nunca te dice que aceptes a Codex. Cada respuesta incluye:
{
"reconciliation": {
"instruction": "This is an independent second opinion, not a verdict...",
"codexIsNotAuthoritative": true
}
}Codex objection
│
▼
Author verifies the cited evidence
│
├─ evidence supports it → apply
├─ evidence does not → reject, and record why
└─ unclear → investigateLuego tú escribes el artefacto final.
Protección de bucle
review.maxPasses (por defecto 2) limita el ciclo. La pasada 1 es el caso normal; la pasada 2 existe para revisiones que obligaron a cambios sustanciales de alto riesgo. Una solicitud por encima del límite se rechaza, y meta.furtherPassesAllowed te indica cuándo se ha gastado el presupuesto. Iterar hasta que los dos modelos estén de acuerdo no es el objetivo — el acuerdo es barato, y alcanzarlo normalmente significa que uno de ellos dejó de pensar.
Configuración
Los ajustes viven en ~/.config/codex-mcp/codex-mcp.yaml. Ese es el único archivo que hay que editar. codex-mcp.example.yaml es la versión anotada, con los ids de modelo actuales de Codex.
La ausencia de un archivo de configuración es totalmente compatible — el servidor arranca con los valores predeterminados, que son los seguros. Lo que pierdes es el modelo fijado y todos los conectores, ya que los conectores solo pueden definirse en YAML.
Dónde va el modelo
review:
model: gpt-5.6-sol
requireModel: trueTres capas pueden configurarlo. Gana la más alta:
Capa | Alcance | Úsalo cuando |
| un proyecto, todos los que lo clonen | el equipo debe revisar todo con un modelo específico |
| esta máquina, todos los proyectos | configuración normal — un operador, varios proyectos |
valor predeterminado integrado | — | aceptas lo que Codex tenga como predeterminado actualmente |
Mantén el modelo en una capa. Una clave establecida en dos lugares deja la copia inferior sin efecto — editarla parece no hacer nada. doctor advierte cuando el modelo está configurado en ambas y las dos discrepan.
Para fijar un proyecto para todo un equipo, añade env al .mcp.json de la Opción A:
{
"mcpServers": {
"codex-mcp": {
"command": "codex-mcp",
"args": ["start"],
"env": { "CODEX_MODEL": "gpt-5.6-sol", "CODEX_REASONING_EFFORT": "high" }
}
}
}Eso garantiza que todos reciban el mismo revisor, lo cual vale mucho cuando los hallazgos se comparan entre un equipo. El coste: un compañero cuyo CLI de Codex es demasiado antiguo para ese modelo recibe un error CODEX_MODEL_NOT_AVAILABLE que le dice que ejecute codex update. Ese fallo es deliberado — la alternativa es que obtenga silenciosamente un revisor más débil y confíe en su veredicto.
Qué modelo. Prefiere un modelo de vanguardia. Todo el valor aquí está en detectar lo que el agente autor pasó por alto, y un revisor más barato suele estar de acuerdo con lo que se le muestre. Establece requireModel: true en una puerta compartida para que un cambio en el valor predeterminado de Codex no pueda alterar silenciosamente la calidad de la revisión. Un modelo no disponible genera CODEX_MODEL_NOT_AVAILABLE; codex-mcp no recurrirá a otro.
Cada ajuste y su variable de entorno
Precedencia: entorno > codex-mcp.yaml > valores predeterminados. Las variables existen para sobrescribir un valor de YAML sin editar el archivo — en el env de .mcp.json para fijar un proyecto, o en la shell para algo puntual.
| Variable de entorno | Valor por defecto |
|
| (ninguno: Codex decide) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| (ninguna) |
|
|
|
|
Los ajustes del conector invierten esa precedencia: gana el YAML, porque representa una intención explícita por conector, y estas variables son alternativas genéricas para cuando no hay ningún YAML que indique lo contrario.
Variable de entorno | Aplica por defecto a |
|
|
|
|
|
|
|
|
Estos conmutadores coinciden con el nombre del conector, no con su tipo:
los conectores llamados jira-mcp y db-mcp no coinciden ni con jira ni con
database, por lo que ambos caen bajo CUSTOM_MCPS_ENABLED. Establecer
enabled: en el YAML evita la cuestión por completo.
Dos variables no tienen equivalente en YAML, ya que se leen antes de localizar
cualquier archivo de configuración: CODEX_MCP_CONFIG (ruta al archivo de
configuración) y XDG_CONFIG_HOME (donde se busca ~/.config/codex-mcp/).
Dónde se encuentra el archivo de configuración
Gana la primera coincidencia:
--config <path> → $CODEX_MCP_CONFIG → ./codex-mcp.yaml → ~/.config/codex-mcp/codex-mcp.yamldoctor imprime cuál se cargó. Si existe un .env junto al archivo elegido, se
lee; no se exige ninguno. Solo merece la pena tenerlo para valores que difieren
por máquina — rutas de conectores que el YAML referencia como
${JIRA_MCP_PATH} — e incluso esos pueden llevar un valor por defecto
${VAR:-fallback}.
Nunca pongas credenciales en .env ni en el YAML. CHATGPT_TOKEN,
SESSION_TOKEN, ACCESS_TOKEN y REFRESH_TOKEN se ignoran por completo y su
presencia se notifica como advertencia de configuración. La autenticación de
Codex pertenece a la CLI de Codex y al almacén de credenciales de tu sistema
operativo.
Conectores de evidencia
Codex nunca habla directamente con Jira ni con tu base de datos. Se conecta al bróker de evidencia de codex-mcp, un proceso separado de solo lectura que descubre las herramientas de cada servidor descendente, las clasifica y reenvía solo lo que cumple la política, volviendo a comprobar en cada llamada, no solo en el descubrimiento.
# ~/.config/codex-mcp/codex-mcp.yaml
connectors:
jira-mcp:
enabled: true
kind: jira
approval: once
transport: stdio
command: node
args: ['/path/to/jira-mcp/src/index.js']
cwd: /path/to/jira-mcp
db-mcp:
enabled: true
kind: database
approval: once
transport: stdio
command: node
args: ['/path/to/db-mcp/dist/index.js']
cwd: /path/to/db-mcp
allowTools: ['execute_query']
denyTools: ['update_query']
maxRows: 500
timeoutMs: 10000kind normaliza hacia un vocabulario estable — requirement.read,
database.query_readonly, testmanagement.search, external_file.read — de
modo que el prompt del revisor pueda pedir "el requisito" sin necesidad de saber
si tu conector lo llama getJiraIssue o get_jira_ticket. Las herramientas no
mapeadas se exponen igualmente con sus propios nombres; añadir un MCP nuevo
orientado a lectura no requiere ningún cambio de código.
Un servidor descendente recibe únicamente PATH, HOME y el env que declara
su propia configuración — nunca el entorno del proceso de codex-mcp.
Un conector inalcanzable degrada la revisión a una limitación registrada en lugar de hacerla fallar. La evidencia que falta es un dato sobre la revisión, y la respuesta así lo indica.
Ejecuta codex-mcp doctor después de añadir uno. Cada línea de conector informa
de cuántas herramientas se expusieron y cuántas se retuvieron por política:
[ ok ] Connector: jira-mcp
4 read-only tool(s) exposed, 0 withheld by policy.
[ ok ] Connector: db-mcp
6 read-only tool(s) exposed, 1 withheld by policy.Pedir permiso: el campo approval
Leer el proyecto que te han entregado no requiere permiso: has proporcionado
project.root, así que leerlo es la petición. Salir fuera de él — un
gestor de incidencias, una base de datos de producción, un servidor de
archivos — es una decisión aparte, y enabled: true en un archivo de
configuración escrito hace semanas no es un consentimiento informado para la
revisión de hoy.
| Comportamiento |
| Preguntar antes de cada revisión |
| Preguntar una vez por sesión de servidor — el valor por defecto |
| No preguntar nunca |
El aviso se entrega mediante elicitación de MCP, por lo que llega al humano
en tu cliente MCP. Si tu cliente no puede mostrar avisos, el conector se
omite y se registra en limitations — no se permite en silencio. Un aviso
que nadie puede ver no es consentimiento. Usa approval: trusted en los
conectores que ya hayas verificado.
Requisitos
Cuando hay un conector de tipo jira configurado y task.id está definido,
Codex lee el ticket en sí y trata cualquier texto de requisito que hayas pasado
como la interpretación del agente autor — una afirmación que hay que
contrastar, no una fuente. Sin conector, recurre al texto que has proporcionado
y registra que no ha podido verificarlo de forma independiente.
Base de datos
Se consulta solo cuando puede cambiar un veredicto: persistencia, relaciones, propiedad del inquilino, transiciones de estado, migraciones, integridad de datos, verificación de un defecto notificado. El prompt lo dice explícitamente y la capa de políticas aplica el resto.
Usa una cuenta de base de datos de solo lectura. codex-mcp rechaza cualquier sentencia de mutación, pero una concesión de solo lectura es la frontera que no depende de que este servidor sea correcto.
La frontera de permisos
La regla central: Codex puede inspeccionar ampliamente y no mutar nada.
Interpreta "ampliamente" al pie de la letra: consulta el alcance de lectura es más amplio que el proyecto antes de apuntarlo a una máquina con secretos que te importen.
Local | |
Leer archivos, buscar, listar, inspeccionar pruebas, leer artefactos | permitir |
| permitir |
Editar, crear, eliminar archivos | denegar |
| denegar |
Wrappers de shell, metacaracteres, redirecciones, binarios desconocidos | denegar |
Jira | |
Leer incidencia, buscar, comentarios, incidencias enlazadas, criterios de aceptación | permitir |
Crear, editar, comentar, transicionar, eliminar | denegar |
Base de datos | |
Leer esquema, | permitir |
| denegar |
Cargas de varias sentencias, | denegar |
Aplicación, por capas:
El sandbox
read-onlydel propio Codex — la frontera principal.Política de comandos — basada en argv, denegación por defecto. Los binarios desconocidos se rechazan; los wrappers de shell se rechazan porque su carga no se puede clasificar.
Política SQL — los comentarios y los literales de cadena se eliminan antes del escaneo de palabras clave, de modo que una mutación no pueda ocultarse dentro de un valor entre comillas. Una sentencia por llamada, con un tope de filas inyectado cuando la consulta no lo tiene.
Política de herramientas — cada herramienta MCP descendente se clasifica como
read/write/destructive/unknown; solo se exponeread.unknownse deniega a menos que esté explícitamente en la lista blanca, y ninguna lista blanca puede rescatar una herramienta de mutación — una frontera que se puede discutir no es una frontera.
El clasificador es deliberadamente asimétrico: cualquier indicio de mutación vence a cualquier indicio de lectura, y una herramienta debe parecer claramente de solo lectura para exponerse. Una herramienta que suena insegura pero no lo es te cuesta una línea de configuración; una que suena segura pero no lo es te cuesta datos.
tests/security/ verifica todo esto, incluido que una llamada rechazada nunca
llegue al servidor descendente y que un repositorio de prueba quede
byte-idéntico después de una revisión.
El alcance de lectura es más amplio que el proyecto
El sandbox read-only de Codex limita las escrituras, no las lecturas.
Dentro de él, Codex puede leer cualquier archivo que tu cuenta de usuario pueda
leer, no solo los archivos bajo project.root. Verificado directamente:
$ codex exec --sandbox read-only -C ./proj "read ../outside.txt"
exec sed -n '1,$p' ../outside.txt in .../proj
succeeded: SECRET_OUTSIDE=canary-9f3a2bLa CLI de Codex no ofrece ninguna opción para restringir el alcance de lectura;
sandbox_permissions solo concede más acceso. Así que la afirmación honesta de
la garantía es:
No se modifica nada, en ningún sitio. Las lecturas están limitadas por los permisos de archivo de tu sistema operativo, no por
project.root.
project.root orienta hacia dónde mira el revisor — es el directorio de
trabajo y el sujeto del prompt — pero no es una celda de lectura.
Lo que esto significa en la práctica:
Un
.env, una clave privada o un archivo de credenciales en cualquier lugar legible por tu usuario es accesible para el revisor, y su contenido puede enviarse a OpenAI como parte del contexto del modelo.El confinamiento de rutas de artefactos de codex-mcp (
assertArtifactPathAllowed) impide que codex-mcp lea archivos fuera del proyecto para el prompt. No limita ni puede limitar lo que Codex lee dentro de su propio sandbox.Los hallazgos se redactan antes de registrarse, pero eso es un control de registro, no de confinamiento.
Si eso importa en tu entorno, ejecuta codex-mcp dentro de un contenedor o una máquina virtual con solo el proyecto montado. Es la única forma fiable de acotar las lecturas hoy en día.
Qué lee el revisor por diseño
Dentro de la raíz del proyecto lo lee todo, incluidos los directorios
ocultos. Ocultar .claude, .cursor, .github o el .qa de un equipo al
revisor es la forma de que acabe ignorando precisamente las reglas que el
proyecto escribió para él. Las cachés de herramientas conocidas (.venv,
.pytest_cache, .next y similares) se siguen listando, pero no se le
recomiendan como material de lectura.
Los archivos de convención — CLAUDE.md, AGENTS.md, CONTRIBUTING.md,
TESTING.md, .cursorrules, CODEOWNERS — se presentan al prompt como
"léelos primero".
El contrato
codex_qualify
Obligatorios: reviewType, project.root y un conjunto de candidatos acorde
con el tipo de revisión. Todo lo demás es opcional y nunca bloquea una
revisión.
{
"reviewType": "test-design",
"project": { "root": "/absolute/path/to/project", "branch": "feature/DEV-123" },
"task": {
"id": "DEV-123",
"source": "jira",
"title": "Archive a resource",
"description": "A user may archive a resource belonging to their own tenant.",
"acceptanceCriteria": ["Archiving an active resource sets status to archived."]
},
"artifacts": {
"blastRadiusPath": "docs/blast-radius.md",
"testCharterPath": "docs/test-charter.md"
},
"candidate": {
"testCases": [{ "id": "TC-001", "title": "Archive an active resource", "priority": "high" }],
"bugs": []
},
"options": { "useJira": true, "useDatabase": true, "useExternalMcps": true }
}Los candidatos viajan en la carga útil. Todavía no se han escrito en ningún sitio, y exigir un archivo de informe temporal iría en contra del propósito.
Las rutas de los artefactos se resuelven dentro de project.root; una ruta que
salga de él se rechaza.
Tipo | Revisiones |
| Cobertura, redundancia, aserciones débiles, escenarios de alto valor ausentes |
| Si cada hallazgo es real, un falso positivo, un duplicado o no probado |
| Ambos, como dos ejecuciones de Codex separadas — fusionar los prompts degrada ambos |
Resultado de test-design
{
"status": "CHANGES_REQUIRED",
"summary": { "accepted": 18, "modify": 2, "remove": 1, "missing": 3 },
"accepted": ["TC-001", "TC-002"],
"modify": [{
"candidateId": "TC-014",
"reason": "Expected state contradicts persistence logic.",
"evidence": [{ "source": "code", "location": "src/session/service.ts:143" }],
"recommendation": "Queue should remain persisted after this transition."
}],
"remove": [{ "candidateId": "TC-022", "reason": "Duplicates TC-018.", "supersededBy": "TC-018" }],
"missing": [{
"title": "Verify cross-tenant access is rejected",
"priority": "high",
"dimension": "authorization",
"reason": "Target lookup accepts an externally supplied identifier.",
"evidence": [{ "source": "code", "location": "src/resource/controller.ts:82" }]
}],
"disagreements": [],
"limitations": []
}Resultado de bugs
{
"status": "CHANGES_REQUIRED",
"summary": { "verified": 1, "falsePositive": 1, "needsMoreEvidence": 0, "other": 0 },
"findings": [{
"candidateId": "BUG-003",
"verdict": "FALSE_POSITIVE",
"confidence": "high",
"severityAssessment": null,
"reason": "Ownership validation occurs in router-level middleware.",
"evidence": [
{ "source": "code", "location": "src/routes/users.ts:42" },
{ "source": "code", "location": "src/middleware/access.ts:91" }
],
"recommendation": "Remove the finding unless runtime evidence contradicts the middleware."
}],
"limitations": []
}status: PASS · CHANGES_REQUIRED · INCONCLUSIVE · ERROR
verdict: VERIFIED · FALSE_POSITIVE · NEEDS_MORE_EVIDENCE ·
SEVERITY_DISAGREEMENT · DUPLICATE_OR_ALREADY_COVERED · INCONCLUSIVE
Qué garantiza el sobre
codex-mcp normaliza la salida del revisor antes de devolverla, porque un modelo
que califica una lista a veces se desvía:
los ids que el revisor inventó se descartan, con una nota — no puedes actuar sobre una referencia a un caso de prueba que no existe;
un candidato que el revisor nunca mencionó se registra como no revisado, nunca se promueve a aceptado, porque el silencio no es aprobación;
un bug sin veredicto se convierte en un
INCONCLUSIVEexplícito;los recuentos de
summaryse recalculan a partir de los arrays;statusse deriva del delta, no de la autoevaluación del revisor.
meta.evidence informa sobre qué se basó realmente la revisión — si el acceso a
git, blast-radius, test-charter y requirement estaba disponible, y qué
conectores eran alcanzables. La ruta del proyecto nunca se registra ni se
devuelve; meta.evidence.projectRootId es un hash.
codex_auth_status
Si Codex está autenticado, en qué modo, y si eso coincide con tu auth.mode
configurado. Nunca devuelve una credencial.
codex_capabilities
Diagnóstico. Qué evidencia puede alcanzar esta instancia, qué herramientas descendentes se retuvieron y por qué, y una lista explícita de lo que al revisor se le prohíbe hacer.
CLI
codex-mcp init # write ~/.config/codex-mcp/, detecting local MCP servers
codex-mcp start # run the MCP server on stdio (what a client launches)
codex-mcp login # authenticate (--mode chatgpt|api)
codex-mcp auth-status # report auth state, never credentials
codex-mcp doctor # diagnose everything; mutates nothinginit acepta --model <id>, --force y --dry-run. start y doctor
aceptan --config <path>. doctor también acepta --project <path> y --json.
codex-mcp broker es interno — el broker de evidencia que Codex lanza. No lo
ejecutas a mano.
Solución de problemas
Síntoma | Causa | Solución |
| Cliente no reiniciado, o | Reinicia; mueve el archivo a la raíz del proyecto |
| Un registro |
|
| No has iniciado sesión |
|
| CLI de Codex demasiado antiguo, o el modelo no está en tu cuenta |
|
| Falta el CLI de Codex en |
|
Error de desajuste de modo de autenticación |
| Cambia uno para que coincida; no factures silenciosamente a la cuenta equivocada |
Conector ausente en |
| Revisa el YAML; |
Conector omitido a mitad de revisión | Tu cliente no puede mostrar avisos de elicitación | Establece |
|
| Vuelve a ejecutar |
Los cambios de configuración no hacen nada | Una variable de entorno tiene prioridad sobre el archivo |
|
Todo lo que doctor informa es ok, warn (funciona, pero más laxo de lo que
debería) o FAIL (las revisiones no pueden funcionar).
Errores
Códigos estables, seguros para ramificar. Los payloads se redactan antes de salir del proceso.
CODEX_AUTH_REQUIRED CODEX_NOT_INSTALLED
CODEX_MODEL_NOT_CONFIGURED CODEX_MODEL_NOT_AVAILABLE
INVALID_PROJECT_ROOT PROJECT_ACCESS_DENIED
INVALID_REVIEW_REQUEST INVALID_REVIEW_TYPE
DOWNSTREAM_MCP_UNAVAILABLE DOWNSTREAM_MCP_PERMISSION_DENIED
DB_QUERY_DENIED DB_QUERY_TIMEOUT
CODEX_EXECUTION_FAILED CODEX_OUTPUT_INVALID
REVIEW_TIMEOUT INTERNAL_ERRORSi Codex devuelve una salida que no coincide con el esquema, codex-mcp
reintenta una vez con una corrección explícita que prohíbe el reanálisis. Si
eso también falla, devuelve CODEX_OUTPUT_INVALID. No devuelve una revisión
parcialmente analizada — actuarías sobre ella.
Observabilidad
JSON estructurado a stderr (stdout pertenece al transporte MCP). Se registran: id y tipo de revisión, id de proyecto con hash, modelo, tiempos, disponibilidad de conectores, recuentos de candidatos, estado de salida de Codex, estado de validación de esquema.
Nunca se registran: tokens, contraseñas, credenciales de BD, cookies, secretos
encontrados en el código fuente. La redacción se ejecuta en todos los niveles,
incluido debug.
Pruebas
Cinco capas, la más barata primero. Recórrelas en orden — un fallo en una capa hace que el resultado de la siguiente no tenga sentido.
1. Suite automatizada — gratuita, sin conexión, ~7s
npm install
npm run build
npm test
npm run typecheckMás de 400 pruebas contra un CLI de Codex falso y un servidor MCP falso deliberadamente hostil. Sin red, sin llamadas a modelos, determinista. Esto es lo que ejecutas en cada cambio y en CI.
tests/security/ es la parte que vale la pena leer: verifica que se rechacen
ediciones de archivos, commits, pushes, escrituras de issues y mutaciones de BD
— y que una llamada rechazada nunca llegue al servidor descendente.
2. doctor — ¿está esta instalación configurada correctamente?
codex-mcp doctor
codex-mcp doctor --project /path/to/repoSolo lectura, seguro contra un proyecto en vivo. Comprueba Node, el CLI de Codex, autenticación, acuerdo de modo de autenticación, modelo, sandbox, archivo de configuración y cada conector configurado.
3. codex_capabilities — ¿qué evidencia puede alcanzar realmente?
doctor da recuentos; esto da el desglose por herramienta, incluido por qué
se retuvo cada herramienta retenida. Llámalo desde tu cliente MCP, o:
node -e "
import('./dist/src/config/config.js').then(async ({loadConfig}) => {
const {CodexMcpServer} = await import('./dist/src/server.js');
const {Logger} = await import('./dist/src/util/logger.js');
const s = new CodexMcpServer({config: loadConfig(), logger: new Logger('error', {}, {write(){}})});
console.log(JSON.stringify(await s.callToolForTesting('codex_capabilities', {}), null, 2));
process.exit(0);
});"Comprueba que las herramientas que esperas estén en allowedTools, y que cada
entrada en deniedTools sea una que quieres denegada. Una herramienta de solo
lectura con un nombre inusual termina en deniedTools como unknown —
añádela a allowTools de ese conector.
4. npm run try — una revisión real, modelo real, coste real
Esta es la única capa que gasta presupuesto. Prueba todo el recorrido: autenticación, modelo, sandbox, recopilación de evidencia, conectores, prompt, salida estructurada.
npm run try -- --project /path/to/repo
npm run try -- --project /path/to/repo --type bugs
npm run try -- --project /path/to/repo --type combined --task DEV-123
npm run try -- --project /path/to/repo --candidates ./candidates.json --jsonSin --candidates, envía un conjunto sembrado con fallos conocidos — dos
duplicados, una aserción que el código contradice, y varias lagunas obvias. Ese
es el punto: estás probando al revisor, así que usa una entrada cuya respuesta
correcta ya conozcas.
Júzgalo según:
¿puso el duplicado en
remove?¿puso la aserción contradicha en
modify, citando el código?¿cada entrada de
missingtiene unfile:linereal, no un área vaga?¿el repositorio queda sin cambios después (
git status)?
Un PASS en el conjunto sembrado significa que algo está mal, no que tu
código esté limpio.
Proporciona --candidates con tu propio JSON para ensayar un flujo de trabajo
real:
{ "testCases": [{ "id": "TC-1", "title": "..." }], "bugs": [] }5. Fixture de extremo a extremo — opcional
CODEX_MCP_E2E=1 npm test -- tests/e2eConstruye un repositorio fixture que contiene una laguna de cobertura real (idempotencia) y un informe de bug que el middleware del router ya refuta, ejecuta una cualificación completa contra el CLI de Codex real, y verifica que el fixture sea byte-idéntico después. Tarda unos minutos.
Usándolo como servidor MCP
Una vez que las capas anteriores pasen, úsalo como lo hará un cliente:
printf '%s\n%s\n%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"1"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| codex-mcp startLuego regístralo en Claude Code y úsalo en un ticket real.
Desarrollo
src/
config/ resolution, precedence, validation
auth/ Codex CLI delegation for both auth modes
codex/ process spawning, argv construction, output parsing
review/ orchestration, per-type reviewers, output normalization
evidence/ repository, git, artifacts, requirement, database, external
mcp-broker/ downstream clients, discovery, classification, the broker server
policy/ command, SQL, MCP-tool, permission, and consent decisions
prompts/ base reviewer, test-design, bug-review
schemas/ public request and result contracts
tools/ the three MCP toolsLicencia
MIT
Available Tools
3 toolscodex_auth_statusA
Report whether Codex is authenticated and which auth mode is in use.
Call this before a review if you want to fail fast with a clear message. Credentials are owned by the Codex CLI and the operating system; this never returns a token, API key, cookie, or any other secret.
Two auth modes are supported: chatgpt (browser sign-in to a ChatGPT subscription) and api
(an OpenAI API key). The response reports the active mode, the configured mode, and whether they
agree — reviews fail while they disagree.
If it reports authenticated: false, the user must run codex-mcp login in a terminal. That
flow is interactive and cannot be triggered from here.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly states it 'never returns a token, API key, cookie, or any other secret,' indicating a read-only, safe operation. It also notes the interactive login flow cannot be triggered, and explains the two auth modes. It adds value beyond the basic purpose statement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise but includes necessary details. It front-loads the core purpose, then provides usage context, security guarantees, auth mode details, and troubleshooting steps. Each sentence adds value without redundancy, though it could be slightly trimmed without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no params, no annotations, no output schema), the description is remarkably complete. It explains what the response will report (active mode, configured mode, agreement), what to do on authentication failure, and the constraints (no secrets, interactive login unavailable). It adequately prepares the agent for safe and correct use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the input schema is an empty object. The description does not need to explain parameters, so it earns the baseline 4. It does not introduce any param-specific details, but none are required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Report whether Codex is authenticated and which auth mode is in use.' It uses a specific verb (report) and resource (authentication status), and the mention of auth modes distinguishes it from sibling tools like codex_qualify and codex_capabilities, which likely serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises when to call the tool: 'Call this before a review if you want to fail fast with a clear message.' It also explains what to do if authentication fails (run codex-mcp login). However, it does not mention alternatives or situations where the tool should not be used, so it lacks full exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
codex_capabilitiesA
Report what evidence this codex-mcp instance can actually reach, and what it is forbidden to do.
Diagnostic only — it runs no review and changes nothing. Use it to find out, before you rely on it, whether the requirement system or database is available for independent verification, and which downstream tools were withheld by policy.
Probing connectors takes a moment; pass probeConnectors: false for a configuration-only answer.
| Name | Required | Description | Default |
|---|---|---|---|
| probeConnectors | No | Connect to downstream MCP servers to list their real tools. Defaults to true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Given no annotations, the description carries full behavioral burden. It discloses that it runs no review, does not modify anything, may take a moment to probe connectors, and supports a configuration-only mode via the probeConnectors parameter.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact yet information-dense. It opens with a clear statement of purpose, then covers usage, side effects, and a practical parameter tip—all in two short paragraphs with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a diagnostic tool with no output schema, the description adequately explains what will be reported (reachable evidence, forbidden actions, withheld tools) and the optional parameter's effect. It is complete for an agent to decide when and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already describes the parameter with 100% coverage, the description adds meaningful nuance: the time trade-off of probing and the option to disable it for a faster configuration-only answer. This goes beyond the schema's static description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reports what evidence it can reach and what it is forbidden to do, using a specific verb ('Report') and resource ('this codex-mcp instance'). It distinguishes itself from sibling tools like codex_qualify and codex_auth_status by focusing on capabilities and policy restrictions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent when to use it: 'before you rely on it' to check availability of the requirement system or database and which tools were withheld. Also states it is diagnostic-only and changes nothing, setting expectations for use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
codex_qualifyA
Independently qualify candidate test cases and/or bug findings before you write your final artifact.
Send the candidate result you are holding in memory — do not write it to a file first, and do not call this after the report is published. codex-mcp runs Codex as a separate reviewer that inspects the repository itself, derives its own expected coverage or verdict, and only then compares that against your candidate. It returns a review delta.
What comes back is a second opinion, not a ruling. Verify each objection against the cited evidence: apply the ones the evidence supports, reject the ones it does not and record why, investigate the rest. You own the final artifact; codex-mcp never writes it.
The reviewer is strictly read-only: it cannot edit files, commit, push, modify issues, or write to any database or external system.
Required: reviewType, project.root, and a matching candidate set. Everything else — task context, blast-radius, test-charter, connectors — is optional and never blocks a review.
| Name | Required | Description | Default |
|---|---|---|---|
| task | No | ||
| options | No | ||
| project | Yes | ||
| artifacts | No | ||
| candidate | No | ||
| reviewType | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly states the tool is read-only ('cannot edit files, commit, push, modify issues, or write to any database or external system'), describes what it returns ('review delta'), and explains the review process (inspects repository, derives expected coverage, compares). This fully discloses behavioral traits without needing annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear paragraphs: purpose, usage instructions, process explanation, and side-effect transparency. It is informative without being verbose, each sentence adds value, and it avoids redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (multiple parameters, review types, and candidate structures), the description covers the essential aspects: what it does, how to use it, its read-only nature, and the expected outcome (review delta). It also guides post-review actions ('verify each objection'), making it complete for an agent to decide when and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description clarifies required vs optional parameters: 'Required: reviewType, project.root, and a matching candidate set' and 'Everything else is optional.' This adds meaningful context beyond the schema. However, the schema marks candidate as optional (default {}), while the description implies it is required, a minor inconsistency that slightly reduces clarity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: independently qualify candidate test cases and/or bug findings. It uses specific verbs (qualify, inspect, compare) and identifies the resource (candidate test cases/bugs) and distinguishes itself from sibling tools (auth/capabilities) by focusing on review.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage timing: 'before you write your final artifact' and 'do not call this after the report is published.' It also instructs to send the candidate in memory rather than writing to a file first, and clarifies that it is a second opinion, giving clear when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v1.0.0- First observed
codex_auth_status - First observed
codex_capabilities - First observed
codex_qualify
TDQS
Scored across 3 tools
Each tool has a clearly distinct purpose: codex_qualify runs independent reviews, codex_auth_status checks authentication, and codex_capabilities reports reachable evidence and restrictions. No overlap between these three surfaces.
All tools share the 'codex_' prefix and use lowercase underscore-separated names. The verbs are consistent (qualify, status, capabilities), though 'auth_status' and 'capabilities' are noun-like rather than pure verbs, but the overall pattern is uniform and predictable.
With three tools, the server is compact but not thin—each tool addresses a distinct concern (qualification, auth, capabilities). The scope is narrow and focused, so this count is appropriate and not bloated.
The tool surface covers the core workflow: verifying auth before reviews, checking what the server can reach, and running a qualification review. Minor gaps exist (e.g., no history or cancellation tools), but they are not essential to the server's stated purpose and agents can work around them.
Maintenance
Related MCP Connectors
Independent, cross-vendor review of a drafted recommendation, with a reviewer-attested record.
Versioned artifact review for people and AI agents, with contextual comments and human control.
Evidence-bound second-opinion audit of an agent conclusion against caller-supplied evidence.
Argues against a security finding or a draft bug bounty report before you submit it.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceProvides tools for agents to manage a local review graph, tracking acceptance behaviors, evidence, review passes, and human waivers to decouple review convergence from shipping readiness.3MIT
- AlicenseNot gradedqualityBmaintenanceEnables coding agents to request, track, and verify independent cross-model reviews with structured findings, attachment hashes, and provenance receipts via Chrome Bridge, Codex, or Responses transports.MIT
- AlicenseNot gradedqualityCmaintenanceEnables code agents to run risk-based Jev quality reviews on focused diffs through a read-only MCP tool, returning structured scores and weakness hints without modifying code.MIT
- AlicenseAqualityCmaintenanceEnables AI coding agents to submit work for external review before declaring a task done, receiving evidence-backed fix lists and verdicts based on git-measured changes and calibrated quality scoring.3MIT