Skip to content

Commit 73c4d19

Browse files
committed
fix: add test that verifies that codex-exec-mcp-server starts up
1 parent 073a853 commit 73c4d19

File tree

6 files changed

+123
-2
lines changed

6 files changed

+123
-2
lines changed

codex-rs/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/exec-server/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[package]
2-
name = "codex-exec-server"
3-
version.workspace = true
42
edition.workspace = true
53
license.workspace = true
4+
name = "codex-exec-server"
5+
version.workspace = true
66

77
[[bin]]
88
name = "codex-execve-wrapper"
@@ -55,5 +55,6 @@ tracing = { workspace = true }
5555
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
5656

5757
[dev-dependencies]
58+
assert_cmd = { workspace = true }
5859
pretty_assertions = { workspace = true }
5960
tempfile = { workspace = true }

codex-rs/exec-server/tests/all.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Single integration test binary that aggregates all test modules.
2+
// The submodules live in `tests/suite/`.
3+
mod suite;
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use std::borrow::Cow;
2+
use std::path::Path;
3+
use std::process::Stdio;
4+
use std::sync::Arc;
5+
6+
use anyhow::Result;
7+
use pretty_assertions::assert_eq;
8+
use rmcp::ServiceExt;
9+
use rmcp::model::Tool;
10+
use rmcp::model::object;
11+
use rmcp::transport::ConfigureCommandExt;
12+
use rmcp::transport::TokioChildProcess;
13+
use serde_json::json;
14+
use tokio::process::Command;
15+
16+
#[tokio::test(flavor = "current_thread")]
17+
async fn auto_approve() -> Result<()> {
18+
let mcp_executable = assert_cmd::Command::cargo_bin("codex-exec-mcp-server")?;
19+
let execve_wrapper = assert_cmd::Command::cargo_bin("codex-execve-wrapper")?;
20+
let bash = Path::new(env!("CARGO_MANIFEST_DIR"))
21+
.join("tests")
22+
.join("suite")
23+
.join("bash");
24+
let transport =
25+
TokioChildProcess::new(Command::new(mcp_executable.get_program()).configure(|cmd| {
26+
cmd.arg("--bash").arg(bash);
27+
cmd.arg("--execve").arg(execve_wrapper.get_program());
28+
29+
// Important: pipe stdio so rmcp can speak JSON-RPC over stdin/stdout
30+
cmd.stdin(Stdio::piped());
31+
cmd.stdout(Stdio::piped());
32+
33+
// Optional but very helpful while debugging:
34+
cmd.stderr(Stdio::inherit());
35+
}))?;
36+
37+
let service = ().serve(transport).await?;
38+
let tools = service.list_tools(Default::default()).await?.tools;
39+
assert_eq!(
40+
vec![Tool {
41+
name: Cow::Borrowed("shell"),
42+
title: None,
43+
description: Some(Cow::Borrowed(
44+
"Runs a shell command and returns its output. You MUST provide the workdir as an absolute path."
45+
)),
46+
input_schema: Arc::new(object(json!( {
47+
"$schema": "https://json-schema.org/draft/2020-12/schema",
48+
"properties": {
49+
"command": {
50+
"description": "The bash string to execute.",
51+
"type": "string",
52+
},
53+
"login": {
54+
"description": "Launch Bash with -lc instead of -c: defaults to true.",
55+
"nullable": true,
56+
"type": "boolean",
57+
},
58+
"timeout_ms": {
59+
"description": "The timeout for the command in milliseconds.",
60+
"format": "uint64",
61+
"minimum": 0,
62+
"nullable": true,
63+
"type": "integer",
64+
},
65+
"workdir": {
66+
"description": "The working directory to execute the command in. Must be an absolute path.",
67+
"type": "string",
68+
},
69+
},
70+
"required": [
71+
"command",
72+
"workdir",
73+
],
74+
"title": "ExecParams",
75+
"type": "object",
76+
}))),
77+
output_schema: None,
78+
annotations: None,
79+
icons: None,
80+
meta: None
81+
}],
82+
tools
83+
);
84+
85+
// TODO(mbolin): Make shell tool calls and verify they work.
86+
87+
Ok(())
88+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env dotslash
2+
3+
{
4+
"name": "codex-bash",
5+
"platforms": {
6+
"macos-aarch64": {
7+
"size": 37003612,
8+
"hash": "blake3",
9+
"digest": "d9cd5928c993b65c340507931c61c02bd6e9179933f8bf26a548482bb5fa53bb",
10+
"format": "tar.gz",
11+
"path": "package/vendor/aarch64-apple-darwin/bash/macos-15/bash",
12+
"providers": [
13+
{
14+
"url": "https://github.com/openai/codex/releases/download/rust-v0.65.0/codex-shell-tool-mcp-npm-0.65.0.tgz"
15+
},
16+
{
17+
"type": "github-release",
18+
"repo": "openai/codex",
19+
"tag": "rust-v0.65.0",
20+
"name": "codex-shell-tool-mcp-npm-0.65.0.tgz"
21+
}
22+
]
23+
}
24+
}
25+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// TODO(mbolin): Open this up to more OS's once the Bash DotSlash file includes other platforms.
2+
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
3+
mod auto_approve;

0 commit comments

Comments
 (0)