Commit Graph

3 Commits

  • refactor: delete exec-server and move execve wrapper into shell-escalation (#12632)
    ## Why
    
    We already plan to remove the shell-tool MCP path, and doing that
    cleanup first makes the follow-on `shell-escalation` work much simpler.
    
    This change removes the last remaining reason to keep
    `codex-rs/exec-server` around by moving the `codex-execve-wrapper`
    binary and shared shell test fixtures to the crates/tests that now own
    that functionality.
    
    ## What Changed
    
    ### Delete `codex-rs/exec-server`
    
    - Remove the `exec-server` crate, including the MCP server binary,
    MCP-specific modules, and its test support/test suite
    - Remove `exec-server` from the `codex-rs` workspace and update
    `Cargo.lock`
    
    ### Move `codex-execve-wrapper` into `codex-rs/shell-escalation`
    
    - Move the wrapper implementation into `shell-escalation`
    (`src/unix/execve_wrapper.rs`)
    - Add the `codex-execve-wrapper` binary entrypoint under
    `shell-escalation/src/bin/`
    - Update `shell-escalation` exports/module layout so the wrapper
    entrypoint is hosted there
    - Move the wrapper README content from `exec-server` to
    `shell-escalation/README.md`
    
    ### Move shared shell test fixtures to `app-server`
    
    - Move the DotSlash `bash`/`zsh` test fixtures from
    `exec-server/tests/suite/` to `app-server/tests/suite/`
    - Update `app-server` zsh-fork tests to reference the new fixture paths
    
    ### Keep `shell-tool-mcp` as a shell-assets package
    
    - Update `.github/workflows/shell-tool-mcp.yml` packaging so the npm
    artifact contains only patched Bash/Zsh payloads (no Rust binaries)
    - Update `shell-tool-mcp/package.json`, `shell-tool-mcp/src/index.ts`,
    and docs to reflect the shell-assets-only package shape
    - `shell-tool-mcp-ci.yml` does not need changes because it is already
    JS-only
    
    ## Verification
    
    - `cargo shear`
    - `cargo clippy -p codex-shell-escalation --tests`
    - `just clippy`
  • fix: path resolution bug in npx (#7134)
    When running `npx @openai/codex-shell-tool-mcp`, the old code derived
    `__dirname` from `process.argv[1]`, which points to npx’s transient
    wrapper script in
    `~/.npm/_npx/134d0fb7e1a27652/node_modules/.bin/codex-shell-tool-mcp`.
    That made `vendorRoot` resolve to `<npx cache>/vendor`, so the startup
    checks failed with "Required binary missing" because it looked for
    `codex-execve-wrapper` in the wrong place.
    
    By relying on the real module `__dirname` and `path.resolve(__dirname,
    "..", "vendor")`, the package now anchors to its installed location
    under `node_modules/@openai/codex-shell-tool-mcp/`, so the bundled
    binaries are found and npx launches correctly.
  • feat: codex-shell-tool-mcp (#7005)
    This adds a GitHub workflow for building a new npm module we are
    experimenting with that contains an MCP server for running Bash
    commands. The new workflow, `shell-tool-mcp`, is a dependency of the
    general `release` workflow so that we continue to use one version number
    for all artifacts across the project in one GitHub release.
    
    `.github/workflows/shell-tool-mcp.yml` is the primary workflow
    introduced by this PR, which does the following:
    
    - builds the `codex-exec-mcp-server` and `codex-execve-wrapper`
    executables for both arm64 and x64 versions of Mac and Linux (preferring
    the MUSL version for Linux)
    - builds Bash (dynamically linked) for a [comically] large number of
    platforms (both x64 and arm64 for most) with a small patch specified by
    `shell-tool-mcp/patches/bash-exec-wrapper.patch`:
      - `debian-11`
      - `debian-12`
      - `ubuntu-20.04`
      - `ubuntu-22.04`
      - `ubuntu-24.04`
      - `centos-9`
      - `macos-13` (x64 only)
      - `macos-14` (arm64 only)
      - `macos-15` (arm64 only)
    - builds the TypeScript for the [new] Node module declared in the
    `shell-tool-mcp/` folder, which creates `bin/mcp-server.js`
    - adds all of the native binaries to `shell-tool-mcp/vendor/` folder;
    `bin/mcp-server.js` does a runtime check to determine which ones to
    execute
    - uses `npm pack` to create the `.tgz` for the module
    - if `publish: true` is set, invokes the `npm publish` call with the
    `.tgz`
    
    The justification for building Bash for so many different operating
    systems is because, since it is dynamically linked, we want to increase
    our confidence that the version we build is compatible with the glibc
    whatever OS we end up running on. (Note this is less of a concern with
    `codex-exec-mcp-server` and `codex-execve-wrapper` on Linux, as they are
    statically linked.)
    
    This PR also introduces the code for the npm module in `shell-tool-mcp/`
    (the proposed module name is `@openai/codex-shell-tool-mcp`). Initially,
    I intended the module to be a single file of vanilla JavaScript (like
    [`codex-cli/bin/codex.js`](https://github.com/openai/codex/blob/ab5972d447da78d3e4dd8461cf7d43a22e5d2acb/codex-cli/bin/codex.js)),
    but some of the logic seemed a bit tricky, so I decided to port it to
    TypeScript and add unit tests.
    
    `shell-tool-mcp/src/index.ts` defines the `main()` function for the
    module, which performs runtime checks to determine the clang triple to
    find the path to the Rust executables within the `vendor/` folder
    (`resolveTargetTriple()`). It uses a combination of `readOsRelease()`
    and `resolveBashPath()` to determine the correct Bash executable to run
    in the environment. Ultimately, it spawns a command like the following:
    
    ```
    codex-exec-mcp-server \
        --execve codex-execve-wrapper \
        --bash custom-bash "$@"
    ```
    
    Note `.github/workflows/shell-tool-mcp-ci.yml` defines a fairly standard
    CI job for the module (`format`/`build`/`test`).
    
    To test this PR, I pushed this branch to my personal fork of Codex and
    ran the CI job there:
    
    https://github.com/bolinfest/codex/actions/runs/19564311320
    
    Admittedly, the graph looks a bit wild now:
    
    <img width="5115" height="2969" alt="Screenshot 2025-11-20 at 11 44
    58 PM"
    src="https://github.com/user-attachments/assets/cc5ef306-efc1-4ed7-a137-5347e394f393"
    />
    
    But when it finished, I was able to download `codex-shell-tool-mcp-npm`
    from the **Artifacts** for the workflow in an empty temp directory,
    unzip the `.zip` and then the `.tgz` inside it, followed by `xattr -rc
    .` to remove the quarantine bits. Then I ran:
    
    ```shell
    npx @modelcontextprotocol/inspector node /private/tmp/foobar4/package/bin/mcp-server.js
    ```
    
    which launched the MCP Inspector and I was able to use it as expected!
    This bodes well that this should work once the package is published to
    npm:
    
    ```shell
    npx @modelcontextprotocol/inspector npx @openai/codex-shell-tool-mcp
    ```
    
    Also, to verify the package contains what I expect:
    
    ```shell
    /tmp/foobar4/package$ tree
    .
    ├── bin
    │   └── mcp-server.js
    ├── package.json
    ├── README.md
    └── vendor
        ├── aarch64-apple-darwin
        │   ├── bash
        │   │   ├── macos-14
        │   │   │   └── bash
        │   │   └── macos-15
        │   │       └── bash
        │   ├── codex-exec-mcp-server
        │   └── codex-execve-wrapper
        ├── aarch64-unknown-linux-musl
        │   ├── bash
        │   │   ├── centos-9
        │   │   │   └── bash
        │   │   ├── debian-11
        │   │   │   └── bash
        │   │   ├── debian-12
        │   │   │   └── bash
        │   │   ├── ubuntu-20.04
        │   │   │   └── bash
        │   │   ├── ubuntu-22.04
        │   │   │   └── bash
        │   │   └── ubuntu-24.04
        │   │       └── bash
        │   ├── codex-exec-mcp-server
        │   └── codex-execve-wrapper
        ├── x86_64-apple-darwin
        │   ├── bash
        │   │   └── macos-13
        │   │       └── bash
        │   ├── codex-exec-mcp-server
        │   └── codex-execve-wrapper
        └── x86_64-unknown-linux-musl
            ├── bash
            │   ├── centos-9
            │   │   └── bash
            │   ├── debian-11
            │   │   └── bash
            │   ├── debian-12
            │   │   └── bash
            │   ├── ubuntu-20.04
            │   │   └── bash
            │   ├── ubuntu-22.04
            │   │   └── bash
            │   └── ubuntu-24.04
            │       └── bash
            ├── codex-exec-mcp-server
            └── codex-execve-wrapper
    
    26 directories, 26 files
    ```