mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
d363a0968e
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 ```
32 lines
1.9 KiB
Markdown
32 lines
1.9 KiB
Markdown
# @openai/codex-shell-tool-mcp
|
|
|
|
This package wraps the `codex-exec-mcp-server` binary and its helpers so that the shell MCP can be invoked via `npx @openai/codex-shell-tool-mcp`. It bundles:
|
|
|
|
- `codex-exec-mcp-server` and `codex-execve-wrapper` built for macOS (arm64, x64) and Linux (musl arm64, musl x64).
|
|
- A patched Bash that honors `BASH_EXEC_WRAPPER`, built for multiple glibc baselines (Ubuntu 24.04/22.04/20.04, Debian 12/11, CentOS-like 9) and macOS (15/14/13).
|
|
- A launcher (`bin/mcp-server.js`) that picks the correct binaries for the current `process.platform` / `process.arch`, specifying `--execve` and `--bash` for the MCP, as appropriate.
|
|
|
|
## Usage
|
|
|
|
```bash
|
|
npx @openai/codex-shell-tool-mcp --help
|
|
```
|
|
|
|
The launcher selects a Rust target triple based on the host and chooses the closest Bash variant by inspecting `/etc/os-release` on Linux or the Darwin major version on macOS.
|
|
|
|
## Patched Bash
|
|
|
|
We carry a small patch to `execute_cmd.c` (see `patches/bash-exec-wrapper.patch`) that adds support for `BASH_EXEC_WRAPPER`. The original commit message is “add support for BASH_EXEC_WRAPPER” and the patch applies cleanly to `a8a1c2fac029404d3f42cd39f5a20f24b6e4fe4b` from https://github.com/bminor/bash. To rebuild manually:
|
|
|
|
```bash
|
|
git clone https://github.com/bminor/bash
|
|
git checkout a8a1c2fac029404d3f42cd39f5a20f24b6e4fe4b
|
|
git apply /path/to/patches/bash-exec-wrapper.patch
|
|
./configure --without-bash-malloc
|
|
make -j"$(nproc)"
|
|
```
|
|
|
|
## Release workflow
|
|
|
|
`.github/workflows/shell-tool-mcp.yml` builds the Rust binaries, compiles the patched Bash variants, assembles the `vendor/` tree, and creates `codex-shell-tool-mcp-npm-<version>.tgz` for inclusion in the Rust GitHub Release. When the version is a stable or alpha tag, the workflow also publishes the tarball to npm using OIDC. The workflow is invoked from `rust-release.yml` so the package ships alongside other Codex artifacts.
|