Al terminar, Codex CLI podrá responder "¿qué cambió en el proyecto Launch plan desde ayer?" sin volver a leer cada nota y cada canal del proyecto. Le pregunta a osFoundry qué recursos concedió el propietario (list_granted_resources), averigua qué hay en el proyecto (list_project_resources) y luego pide a cada recurso solo los eventos posteriores al último número de secuencia que vio (poll_resource_events). Esos números viven en un archivo pequeño de tu repo, así que la siguiente sesión de Codex continúa donde se quedó la anterior. Cada llamada aparece en Recent activity de la conexión en osFoundry.
Quién hace qué
| Codex CLI | osFoundry | |
|---|---|---|
| Login | Guarda el token OAuth de osFoundry; con osfoundry:read basta | El propietario aprueba la conexión una sola vez en la pestaña Connected |
| Qué puede ver | Lo que devuelva list_granted_resources, nada más | Lo decide el propietario: proyectos añadidos a la conexión y Message channels a los que se la invitó |
| Dónde vive el estado de "visto por última vez" | Un entero por recurso, que guarda Codex (aquí en .osfoundry/cursors.json) | Un log de eventos ordenado por recurso, que se lee a partir de un número de secuencia |
| Qué se ejecuta cuando hay un cambio | Lo decide Codex: releer esa nota, leer el canal o solo informar | Nada. El polling nunca cambia nada en el servidor |
| Quién puede pararlo | Tú, dejando de preguntar | El propietario quita el proyecto, desmarca una herramienta o revoca la conexión |
Configuración
1. Busca la conexión de Codex
En osFoundry, el icono de la llave en la cabecera abre la pestaña Connected. Si Codex aún no está conectado, elige Other MCP client en Assistant, ponle un nombre visible como Codex CLI y haz clic en Add assistant. El panel muestra la dirección del servidor que tienes que darle a Codex.
Ejemplo: la pestaña Connected agents con una conexión activa de Codex CLI
En el lado de Codex:
codex mcp add osfoundry --url https://api.osfoundry.io/api/v1/external-mcp codex mcp login osfoundry 2. Decide qué puede vigilar Codex
Esta parte le toca al propietario, y es la respuesta completa a "¿qué va a ver Codex?". Selecciona la conexión y abre Projects. Elige un proyecto en "Choose a project" y haz clic en Add to project. La línea de ayuda explica qué concede eso: "Adding this agent to a project gives it access to supported synced content in that project and its discussion channel. Other Message channels require a separate invitation."
Es decir, un proyecto le da a Codex sus notas, knowledge bases, record channels, Rooms, repositorios de GitNest y sesiones, además del canal de discusión del proyecto. Cualquier otro Message channel es un segundo paso explícito: más abajo, en Message channels, elígelo en "Choose a Message channel" y haz clic en Invite.
Ejemplo: la conexión Codex CLI con el proyecto Launch plan añadido y un Message channel invitado
Los permisos guardados antes de que existiera el acceso por proyecto aparecen en "Older individual access". list_granted_resources también los devuelve, como recursos concedidos de forma individual, así que revisa esa sección antes de dar por hecho que un proyecto es la única vía de entrada.
3. Deja marcadas las tres herramientas
Abre Tools en la misma conexión. "All supported tools are on by default." Deja marcadas list granted resources, list project resources y poll resource events, junto con los lectores que Codex necesite cuando sepa que algo cambió (read note tab, read channel messages, etc.). Desmarcar una herramienta aquí la quita en el lado de osFoundry, diga lo que diga la configuración de Codex.
4. Limita Codex al bucle de vigilancia
# ~/.codex/config.toml [mcp_servers.osfoundry] url = "https://api.osfoundry.io/api/v1/external-mcp" scopes = ["osfoundry:read"] enabled_tools = [ "list_granted_resources", "list_project_resources", "poll_resource_events", "list_note_tabs", "read_note_tab", "read_channel_messages", ] Las seis están marcadas como de solo lectura en el servidor, así que Codex las ejecuta sin preguntar.
5. Dile a Codex dónde guardar los cursores
Codex empieza cada sesión de cero, así que la última secuencia de cada recurso tiene que vivir en algún sitio que pueda leer. Un AGENTS.md en el repo se encarga de eso:
## osFoundry changes - Cursors are in .osfoundry/cursors.json: {"<resource_type>:<resource_id>": <last sequence>}. - Start with list_granted_resources. Drop cursors for resources it no longer returns. - For each watched resource call poll_resource_events with after_sequence from the file and limit 100. If a page comes back full, call again from its last sequence. - Only after reporting the changes, write the new sequence back to the file. - A resource with no cursor yet: poll from after_sequence 0 once to get its current sequence. Escribir el cursor después del informe, y no antes, hace que una sesión que se cae a mitad de camino muestre los mismos eventos la próxima vez en lugar de perderlos.
Una ejecución real
Codex no está instalado en la máquina donde se escribió esto, así que la sesión de abajo es un ejemplo simulado. Los nombres de las herramientas y de los argumentos son los del servidor en vivo, con el prefijo mcp__osfoundry__ que añade Codex. El proyecto, los recursos, los números de secuencia y los resultados son contenido de demostración.
Example (simulated) > What changed in the Launch plan project since my last check? • mcp__osfoundry__list_granted_resources {} ← project "Launch plan"; message_channel "launch-updates" (invited) • mcp__osfoundry__list_project_resources {"project_id": "…", "resource_type": "note"} ← 3 notes: "Launch checklist", "Pricing page copy", "Press list" • mcp__osfoundry__poll_resource_events {"resource_type": "note", "resource_id": "…", "after_sequence": 118, "limit": 100} (Launch checklist) ← 2 events, last sequence 120 • mcp__osfoundry__poll_resource_events {… "Pricing page copy", "after_sequence": 64 …} ← no events • mcp__osfoundry__poll_resource_events {… "Press list", "after_sequence": 9 …} ← no events • mcp__osfoundry__poll_resource_events {"resource_type": "message_channel", "resource_id": "…", "after_sequence": 311, "limit": 100} ← 5 events, last sequence 316 • mcp__osfoundry__read_note_tab {"note_id": "…", "tab_id": "…"} (Launch checklist) • mcp__osfoundry__read_channel_messages {"channel_id": "…", "limit": 5} (Codex writes 120 and 316 back to .osfoundry/cursors.json) Two things moved since yesterday. In "Launch checklist", the press embargo line now says Thursday 09:00 instead of Wednesday. In launch-updates, five messages: the pricing page is approved, and the App Store build is still in review. "Pricing page copy" and "Press list" haven't changed. Cuatro polls y dos lecturas. Sin los cursores, la misma respuesta obliga a leer enteras las tres notas y el canal y compararlas con lo que Codex recuerde, que es nada.
En el lado del propietario, cada llamada es una línea en Recent activity de la conexión: el nombre de la herramienta, la decisión y la hora.
Ejemplo: Tools y Recent activity de la conexión Codex CLI después de una revisión
Dónde está el límite
Codex solo ve lo que lista list_granted_resources. La propia respuesta de initialize del servidor dice "Use list_granted_resources first", y esa llamada no admite argumentos: Codex no puede pedir un proyecto por su nombre y entrar. Un Message channel que no sea el canal de discusión del proyecto sigue invisible hasta que el propietario invite a la conexión. La descripción de list_project_resources lo repite: "Ordinary Message channels require a separate invitation."
El polling lee, no se suscribe. El servidor anuncia herramientas y nada más, así que osFoundry nunca despierta a Codex. De todos modos, eso encaja con cómo funciona Codex: mira cuando lo ejecutas, y los cursores hacen que "desde la última vez" salga barato.
poll_resource_events trabaja con un recurso por llamada. No existe un cursor de "todo el proyecto". Así cada log se mantiene pequeño y cada permiso queda separado. Cuando el propietario quita el proyecto, los polls de sus recursos dejan de funcionar y el siguiente list_granted_resources ya no los incluye. En ese momento Codex debe descartar esos cursores, no reintentarlos.
Las sesiones de Graph son un caso aparte. poll_resource_events acepta graph_session, pero los Graphs viven en el escritorio del propietario. Solo llegan a la conexión cuando el propietario los marca en "Share desktop Graph sessions" y la app de escritorio está abierta y con la sesión iniciada. Todo lo demás que solo existe en el dispositivo se queda ahí. La respuesta de initialize lo dice: "Local-only data is unavailable to cloud clients."
Como siguiente paso, mételo en tu rutina de la mañana: codex exec "What changed in the Launch plan project since my last check?" desde el repo con el AGENTS.md, antes de abrir nada más. Qué herramientas recibe cada conexión, y por qué el acceso se sigue decidiendo por proyecto, está en la página de tool scope. El protocolo que hay debajo está en la entrada de MCP del glosario.




