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`](
|
||
|---|---|---|
| .. | ||
| patches | ||
| src | ||
| tests | ||
| .gitignore | ||
| jest.config.cjs | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
@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-serverandcodex-execve-wrapperbuilt 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 currentprocess.platform/process.arch, specifying--execveand--bashfor the MCP, as appropriate.
Usage
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:
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.