Skip to content

fix: keep Codex MCP responsive during startup - #560

Merged
mohanagy merged 3 commits into
mainfrom
fix/559-codex-mcp-startup
Jul 16, 2026
Merged

mohanagy merged 3 commits into
mainfrom
fix/559-codex-mcp-startup

Conversation

@mohanagy

@mohanagy mohanagy commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary

  • keep the Codex MCP transport responsive while the initial automatic graph reconciliation runs in a worker thread
  • keep graph-backed tools, prompts, and resources fail-closed until watcher state reports a ready graph
  • surface worker startup and reconciliation failures through watcher state, stderr, and MCP freshness errors
  • set startup_timeout_sec = 180 in the managed Codex MCP block without replacing unrelated TOML
  • prepare the documented package and MCP Registry metadata for 0.31.2

Root cause

madar serve --stdio --auto-refresh performed its initial graph reconciliation on the same event-loop thread that had to answer the MCP initialization handshake. Large workspaces and synchronized folders could therefore exceed Codex's default 30-second startup timeout before the transport became responsive.

User impact

Codex can initialize and inspect the Madar MCP server while reconciliation continues. Graph-backed answers remain unavailable until the graph is safe to read, so responsiveness does not expose stale or partially written evidence. Existing installations should rerun madar codex install after upgrading to receive the 180-second managed startup window.

Validation

  • npm run release:verify
  • npm run registry:validate
  • npm run typecheck
  • npm run build
  • package dry run produced @lubab/madar@0.31.2 (396 files, 732.6 kB)
  • built CLI reports 0.31.2
  • compiled stdio smoke responded in 413 ms while initial refresh was held behind a live lock
  • Vitest aggregate: 199 files / 2,404 assertions passed, 1 skipped; the fork pool timed out starting three remaining workers under local resource pressure
  • direct reruns of those three files passed: extract (294), release hygiene (8), semantic stdio (2)

Closes #559

Summary by CodeRabbit

  • New Features

    • MCP connections are available immediately while initial graph refresh runs in the background.
    • Graph-backed requests remain safely unavailable until the watcher reports readiness.
    • Codex integrations now use a 180-second MCP startup window.
  • Bug Fixes

    • Prevented startup refresh timeouts and improved failure reporting during reconciliation.
    • MCP discovery remains responsive even when the graph is not yet available.
  • Documentation

    • Added upgrade guidance to rerun Codex installation and clarified refresh and readiness behavior.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 44 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: df67f11c-dce0-4093-a594-c0ea76be32c9

📥 Commits

Reviewing files that changed from the base of the PR and between 285fbc8 and 6b1c981.

📒 Files selected for processing (5)
  • README.md
  • docs/auto-refresh.md
  • src/infrastructure/background-auto-refresh.ts
  • src/runtime/stdio-server.ts
  • tests/unit/background-auto-refresh.test.ts
📝 Walkthrough

Walkthrough

Madar now starts stdio transport while initial graph reconciliation runs in a worker, keeps discovery responsive, rejects graph-backed calls until watcher readiness, adds a 180-second managed Codex startup timeout, and publishes corresponding tests, documentation, and 0.31.2 metadata.

Changes

MCP readiness during background reconciliation

Layer / File(s) Summary
Background reconciliation controller
src/infrastructure/background-auto-refresh.ts, src/infrastructure/watch.ts, src/runtime/stdio-server.ts
Initial reconciliation runs in a worker with controller status, failure reporting, stop handling, and readiness-based JSON-RPC gating.
Startup discovery fallbacks and validation
src/runtime/stdio/prompts.ts, src/runtime/stdio/resources.ts
Prompt and resource discovery return safe results when the workspace graph is not yet present.
Background startup and failure tests
tests/unit/background-auto-refresh.test.ts
Tests cover delayed reconciliation, responsive discovery, readiness errors, worker stopping, and surfaced failures.

Codex managed MCP startup configuration

Layer / File(s) Summary
Managed Codex timeout configuration
src/infrastructure/install.ts
Managed Codex MCP blocks now include startup_timeout_sec = 180.
Codex configuration migration tests
tests/unit/install.test.ts
Tests verify migration of older owned blocks, idempotent reinstall behavior, and preservation of unrelated TOML configuration.

0.31.2 release documentation and metadata

Layer / File(s) Summary
Version and release metadata
package.json, package-lock.json, docs/mcp-registry/server.json, sbom.cdx.json, CHANGELOG.md
Package, registry, SBOM, and changelog records are updated for 0.31.2.
Operational documentation
README.md, docs/auto-refresh.md, docs/reference/cli-and-mcp.md, docs/release.md, docs/tutorials/agent-quickstarts.md
Documentation covers install migration, background readiness, graph freshness, Codex timeout troubleshooting, and release verification.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Codex
  participant StdioServer
  participant BackgroundWorker
  participant Watcher
  Codex->>StdioServer: Start MCP stdio transport
  StdioServer->>BackgroundWorker: Start initial reconciliation
  BackgroundWorker->>Watcher: Run graph auto-refresh
  StdioServer-->>Codex: Respond to initialize and discovery
  Codex->>StdioServer: Request graph-backed operation
  StdioServer-->>Codex: Return readiness error until watcher is idle
  Watcher-->>BackgroundWorker: Report reconciliation completion or failure
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main startup-responsiveness fix in the Codex MCP flow.
Description check ✅ Passed The description covers the summary, root cause, impact, validation, and closes the linked issue.
Linked Issues check ✅ Passed The changes satisfy #559 by adding the startup timeout, keeping MCP responsive during reconciliation, failing graph-backed requests closed, and adding tests/docs.
Out of Scope Changes check ✅ Passed The changes stay focused on Codex MCP startup behavior, related docs, tests, and release metadata.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/559-codex-mcp-startup

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
tests/unit/background-auto-refresh.test.ts (1)

92-160: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Cover the transition from blocked to ready.

This test stops without publishing a usable graph and matching watcher state. Extend it to complete reconciliation, then assert that a graph-backed request succeeds; otherwise a permanently gated server regression passes unnoticed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/background-auto-refresh.test.ts` around lines 92 - 160, The test
should complete the slow auto-refresh reconciliation before finishing, then
issue a graph-backed request through serveGraphStdio and assert it succeeds once
the watcher and graph are ready. Extend the existing “completes MCP discovery…”
scenario using its graphPath, completionMarker, and output assertions, while
preserving the current startup-time failure checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/auto-refresh.md`:
- Line 3: Update the watcher-health guidance’s refusal-state list to include the
starting state, matching the documented fail-closed behavior for graph-backed
requests before the refresh worker begins. Keep the existing refusal states and
surrounding readiness guidance unchanged.

In `@README.md`:
- Around line 74-76: Update the README readiness guidance near the Madar upgrade
instructions to document the complete graph-readiness contract: require startup
completion, a non-blocking watcher state, and matching published policy in
addition to an idle watcher. Align the wording with the readiness conditions in
docs/reference/cli-and-mcp.md, and avoid implying that madar status reporting
idle alone guarantees graph-backed calls succeed.

In `@src/infrastructure/background-auto-refresh.ts`:
- Around line 95-108: Update markFailed to make all watcher-state read and write
operations best-effort: catch persistence errors, report them through the
existing stderr/controller failure-reporting path, and prevent any exception
from escaping worker failure handling. Preserve the existing PID guard and
failed-state contents when persistence succeeds.

In `@src/runtime/stdio-server.ts`:
- Around line 196-225: Update the readiness calculation in the surrounding
startup-status function to require that controller.failureReason() is absent, so
a terminal failure from completedFailureController prevents ready from becoming
true even when stale watcher state is idle and policy-matching. If runtime
failures are recoverable, clear the controller failure signal after successful
reconciliation while preserving the existing watcher-state readiness checks.

---

Nitpick comments:
In `@tests/unit/background-auto-refresh.test.ts`:
- Around line 92-160: The test should complete the slow auto-refresh
reconciliation before finishing, then issue a graph-backed request through
serveGraphStdio and assert it succeeds once the watcher and graph are ready.
Extend the existing “completes MCP discovery…” scenario using its graphPath,
completionMarker, and output assertions, while preserving the current
startup-time failure checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a55247c2-db06-4719-933e-3d411ab47f03

📥 Commits

Reviewing files that changed from the base of the PR and between 594642e and 285fbc8.

📒 Files selected for processing (18)
  • CHANGELOG.md
  • README.md
  • docs/auto-refresh.md
  • docs/mcp-registry/server.json
  • docs/reference/cli-and-mcp.md
  • docs/release.md
  • docs/tutorials/agent-quickstarts.md
  • package-lock.json
  • package.json
  • sbom.cdx.json
  • src/infrastructure/background-auto-refresh.ts
  • src/infrastructure/install.ts
  • src/infrastructure/watch.ts
  • src/runtime/stdio-server.ts
  • src/runtime/stdio/prompts.ts
  • src/runtime/stdio/resources.ts
  • tests/unit/background-auto-refresh.test.ts
  • tests/unit/install.test.ts

Comment thread docs/auto-refresh.md
Comment thread README.md Outdated
Comment thread src/infrastructure/background-auto-refresh.ts
Comment thread src/runtime/stdio-server.ts
@mohanagy
mohanagy merged commit 0dde85b into main Jul 16, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Codex MCP startup times out during initial auto-refresh reconciliation

1 participant