-
Notifications
You must be signed in to change notification settings - Fork 0
Finish runtime-aware container MCP launcher #227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Getting started | ||
|
|
||
| This guide connects Codex to the read-only `codex-memoryd` MCP server. The | ||
| recommended release-shaped path uses the native binary: | ||
|
|
||
| ```zsh | ||
| # Future release command: the formula and release artifacts are not published yet. | ||
| brew install joshyorko/tools/codex-memoryd | ||
| codex-memoryd mcp codex apply | ||
| codex-memoryd mcp codex status | ||
| ``` | ||
|
|
||
| Restart Codex after applying the configuration, then call `memory_status` to | ||
| verify that the server starts and responds. `preview` and `status` inspect the | ||
| owned Codex MCP block; `apply` updates only that block and backs up the existing | ||
| Codex configuration before changing it. | ||
|
|
||
| ## Opt in to the container launcher | ||
|
|
||
| Use the container runtime when Docker or Podman should launch the MCP image: | ||
|
|
||
| ```zsh | ||
| codex-memoryd mcp codex preview --runtime container | ||
| codex-memoryd mcp codex apply --runtime container | ||
| codex-memoryd mcp codex status --runtime container | ||
| ``` | ||
|
|
||
| The CLI performs setup and does not pull an image or start a container during | ||
| `apply`. When Codex later starts the MCP server, the generated stdio command | ||
| launches the configured Docker or Podman image on demand. The default image is | ||
| `ghcr.io/joshyorko/codex-memoryd:latest`; `CODEX_MEMORYD_IMAGE` can override it. | ||
| The container mounts the parent directory of the persistent SQLite database at | ||
| `/data`, using the corresponding database filename inside the container. This | ||
| directory mount preserves SQLite sidecar files such as WAL and shared-memory | ||
| files. The database remains persistent host data; its exact path is determined | ||
| by the resolved configuration. | ||
| The selected database parent must already exist; run codex-memoryd init or | ||
| create the configured directory before previewing the container launcher. | ||
|
|
||
| Restart Codex after applying the container configuration and call | ||
| `memory_status` again. Docker or Podman must be installed and available to the | ||
| CLI and to Codex when the MCP server starts. | ||
|
|
||
| ## Switch runtimes or remove the integration | ||
|
|
||
| Switch back to the native binary with: | ||
|
|
||
| ```zsh | ||
| codex-memoryd mcp codex preview --runtime native | ||
| codex-memoryd mcp codex apply --runtime native | ||
| codex-memoryd mcp codex status --runtime native | ||
| ``` | ||
|
|
||
| Restart Codex and verify with `memory_status`. To remove only the owned | ||
| `codex-memoryd` MCP block: | ||
|
|
||
| ```zsh | ||
| codex-memoryd mcp codex remove | ||
| codex-memoryd mcp codex status | ||
| ``` | ||
|
|
||
| Removing the MCP block, uninstalling the Homebrew formula, or removing the | ||
| container image does not delete the persistent memory database. Delete that | ||
| database separately only if you intentionally want to discard stored memory. | ||
| To uninstall the future-release Homebrew installation after removing the MCP | ||
| block, run `brew uninstall codex-memoryd`. | ||
|
|
||
| ## Source-build fallback | ||
|
|
||
| If the future-release Homebrew command is unavailable, build the binary from a | ||
| checkout and use `target/release/codex-memoryd` in the commands above: | ||
|
|
||
| ```zsh | ||
| cargo build --release | ||
| target/release/codex-memoryd mcp codex apply | ||
| target/release/codex-memoryd mcp codex status | ||
| ``` | ||
|
|
||
| Homebrew, release, image, tag, and tap artifacts are not published in this | ||
| feature slice. The Homebrew command above becomes usable only after a later | ||
| release and tap publication completes. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| # Container MCP Launcher and Homebrew Onboarding | ||
|
|
||
| ## Context | ||
|
|
||
| `codex-memoryd mcp codex preview|apply|status|remove` manages the owned Codex | ||
| MCP block. The global `--runtime native|container` option already parses for | ||
| these commands, but MCP config rendering always emits the native binary path. | ||
| Josh's current Codex config therefore points at a native binary that no longer | ||
| exists. | ||
|
|
||
| The repository also lacks a short release-user guide. The README contains | ||
| source-build, dogfood, daemon, and operator detail, but there is no minimal | ||
| Homebrew install-to-first-recall path. There are currently no repository tags, | ||
| GitHub releases, release workflow, or `homebrew-tools` formula for this binary, | ||
| so Homebrew instructions must be clearly described as the intended release | ||
| contract until those artifacts land. | ||
|
|
||
| ## Decision | ||
|
|
||
| Make the existing global runtime selector authoritative for Codex MCP config | ||
| generation: | ||
|
|
||
| - `--runtime native` preserves the current direct-binary stdio entry. | ||
| - `--runtime container` emits a Docker or Podman stdio entry that starts the | ||
| published image on demand and exits when Codex closes stdin. | ||
| - Omitting `--runtime` preserves the resolved/default native behavior. | ||
|
Comment on lines
+23
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The repository's global Useful? React with 👍 / 👎. |
||
|
|
||
| Do not add another runtime option under `mcp codex`. Because the root option is | ||
| global, both placements remain valid: | ||
|
|
||
| ```zsh | ||
| codex-memoryd --runtime container mcp codex apply | ||
| codex-memoryd mcp codex apply --runtime container | ||
| ``` | ||
|
|
||
| The documentation will use the second form because it reads naturally at the | ||
| point where the choice matters. | ||
|
|
||
| ## Generated Container Contract | ||
|
|
||
| The container MCP block uses the runtime already resolved by | ||
| `codex-memoryd`: | ||
|
|
||
| - command: resolved `docker` or `podman` executable | ||
| - transport: interactive stdio (`run -i`) | ||
| - lifecycle: ephemeral container (`--rm`) | ||
| - image acquisition: pull when missing (`--pull=missing`) | ||
| - image: resolved `CODEX_MEMORYD_IMAGE`, defaulting to | ||
| `ghcr.io/joshyorko/codex-memoryd:latest` | ||
|
Comment on lines
+47
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When the default Useful? React with 👍 / 👎. |
||
| - identity: resolved host UID/GID so SQLite files remain host-owned | ||
| - storage: mount only the database's parent directory read-write at `/data` | ||
| - database argument: the corresponding `/data/<filename>` path | ||
| - MCP tier: explicit `mcp stdio --read-only` | ||
|
Comment on lines
+50
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Mounting only the database directory and passing only Useful? React with 👍 / 👎. |
||
|
|
||
| The existing Codex allowlist, approval mode, startup timeout, and tool timeout | ||
| remain unchanged. The database directory mount, rather than a single-file | ||
|
Comment on lines
+55
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The container path pulls a missing image synchronously during MCP startup but explicitly preserves the existing 30-second startup timeout. On a first launch, downloading and unpacking the image can readily exceed that limit, causing Codex to abort the MCP server before onboarding completes even though the runtime is functioning normally. Give container entries a longer startup timeout or pull the image during an explicit setup step before Codex starts it. Useful? React with 👍 / 👎. |
||
| mount, is required because SQLite may create WAL and shared-memory sidecars. | ||
|
|
||
| `preview` and `status` are read-only. `apply` mutates only the owned MCP table, | ||
| backs up an existing Codex config before changing it, and remains idempotent. | ||
| It does not pull the image or start a container; Codex does that when it starts | ||
| the MCP server. | ||
|
|
||
| ## First-Time User Guide | ||
|
|
||
| Add a short `docs/getting-started.md` and link it near the top of the README. | ||
| The release-shaped native path is: | ||
|
|
||
| ```zsh | ||
| brew install joshyorko/tools/codex-memoryd | ||
| codex-memoryd mcp codex apply | ||
| codex-memoryd mcp codex status | ||
| ``` | ||
|
|
||
| The guide then tells the user to restart Codex and call `memory_status`. | ||
| Homebrew-native is the recommendation because the installed artifact is | ||
| already available and requires no container runtime. | ||
|
|
||
| The opt-in container path is: | ||
|
|
||
| ```zsh | ||
| codex-memoryd mcp codex preview --runtime container | ||
| codex-memoryd mcp codex apply --runtime container | ||
| codex-memoryd mcp codex status --runtime container | ||
|
Comment on lines
+82
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For a first-time container user, the default database parent ( Useful? React with 👍 / 👎. |
||
| ``` | ||
|
|
||
| It explains that the Homebrew CLI performs setup while Codex subsequently | ||
| launches the MCP image on demand. The guide includes switching back to native, | ||
| uninstalling the MCP block, the persistent database location, and a concise | ||
| note that removing the MCP block or formula does not delete memory data. | ||
|
|
||
| The tap command is marked as a future release command until the formula and | ||
| release artifacts exist. Source-build instructions remain available from the | ||
| README but are not part of the primary user journey. | ||
|
|
||
| ## Errors | ||
|
|
||
| Container rendering fails before config mutation when: | ||
|
|
||
| - neither Docker nor Podman can be resolved; | ||
| - the database has no usable file name or parent directory; | ||
| - UID/GID or mount values cannot be represented safely. | ||
|
Comment on lines
+98
to
+102
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If Docker or Podman has been uninstalled or is temporarily unavailable while the resolved runtime remains Useful? React with 👍 / 👎. |
||
|
|
||
| Errors name the failed requirement and give the next command or configuration | ||
| override. Runtime image-pull, permission, and container-start failures remain | ||
| visible as MCP startup failures from Docker or Podman; the generated arguments | ||
| must not suppress their stderr. | ||
|
|
||
| ## Tests | ||
|
|
||
| Focused CLI tests prove: | ||
|
|
||
| - native output remains byte-for-byte compatible; | ||
| - container preview contains the resolved engine, image, identity, mount, and | ||
| in-container database path; | ||
| - Docker and Podman selections render deterministically; | ||
| - spaces and TOML-sensitive characters in host paths are escaped correctly; | ||
| - preview and status do not write; | ||
| - apply backs up and replaces a drifted block; | ||
| - repeated apply is idempotent; | ||
| - remove deletes only the owned block; | ||
| - missing container runtime and invalid database paths fail before mutation; | ||
| - CLI help continues to expose one global `--runtime` option. | ||
|
|
||
| Documentation checks assert that the short guide contains native install, | ||
| container opt-in, verification, switching, and uninstall/data-retention paths. | ||
|
|
||
| ## Release Boundary | ||
|
|
||
| This slice makes the CLI and documentation release-shaped but does not publish | ||
| an artifact, create a GitHub release, modify `homebrew-tools`, or install the | ||
| formula. A later packaging slice must produce checksummed platform artifacts, | ||
| add the formula to the tap, test installation from the tap, and replace the | ||
| guide's future-release label only after those checks pass. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preserving the current direct-binary entry can persist a versioned Homebrew Cellar executable path; after
brew upgraderemoves that keg, Codex again points at a binary that no longer exists—the exact failure this design is intended to repair. The native Homebrew path should render a stableoptsymlink or another durable launcher path, and the compatibility test should distinguish source-build behavior from Homebrew upgrades.Useful? React with 👍 / 👎.