Skip to content

Commit 8187182

Browse files
committed
test(cli): Add integration test for MCP custom tool support
This commit adds integration tests for the Model Context Protocol (MCP) custom tool functionality. The test verifies that: - Custom tools can be properly configured via config files - The CLI can communicate with MCP servers - Tool invocations work as expected through the CLI The test uses a mock MCP server to simulate tool interactions in a controlled environment. 🤖 Assisted by [Amazon Q Developer](https://aws.amazon.com/q/developer)
1 parent f0fdcc4 commit 8187182

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Import necessary dependencies for our test
2+
use std::process::Command;
3+
4+
use assert_cmd::prelude::*;
5+
use serde_json::json;
6+
use tempfile::TempDir;
7+
use tokio::fs;
8+
9+
mod common;
10+
11+
#[tokio::test]
12+
async fn test_custom_tool_initialization() {
13+
// Create a temporary directory for our test files
14+
let temp_dir = TempDir::new().unwrap();
15+
16+
// Create mock MCP server script
17+
let mock_server_path = temp_dir.path().join("mock_mcp_server.sh");
18+
let mock_server_content = r#"#!/bin/bash
19+
# Simple mock MCP server that responds to JSON-RPC requests
20+
21+
while read -r line; do
22+
# Parse the JSON-RPC request
23+
request_id=$(echo "$line" | jq -r '.id')
24+
method=$(echo "$line" | jq -r '.method')
25+
26+
if [ "$method" = "initialize" ]; then
27+
# Respond to initialize request
28+
echo "{\"jsonrpc\":\"2.0\",\"id\":$request_id,\"result\":{\"capabilities\":{\"tools\":true}}}"
29+
elif [ "$method" = "tools/list" ]; then
30+
# Respond with tool list
31+
echo "{\"jsonrpc\":\"2.0\",\"id\":$request_id,\"result\":{\"tools\":[{\"name\":\"hello_world\",\"description\":\"Says hello world\",\"inputSchema\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\",\"description\":\"Name to greet\"}}}}]}}"
32+
elif [ "$method" = "tools/call" ]; then
33+
# Extract the tool name and arguments
34+
tool_name=$(echo "$line" | jq -r '.params.name')
35+
name_arg=$(echo "$line" | jq -r '.params.arguments.name // "World"')
36+
37+
if [ "$tool_name" = "hello_world" ]; then
38+
# Respond to hello_world tool call
39+
echo "{\"jsonrpc\":\"2.0\",\"id\":$request_id,\"result\":{\"output\":\"Hello, $name_arg!\"}}"
40+
else
41+
# Unknown tool
42+
echo "{\"jsonrpc\":\"2.0\",\"id\":$request_id,\"error\":{\"code\":-32601,\"message\":\"Unknown tool: $tool_name\"}}"
43+
fi
44+
else
45+
# Unknown method
46+
echo "{\"jsonrpc\":\"2.0\",\"id\":$request_id,\"error\":{\"code\":-32601,\"message\":\"Method not found\"}}"
47+
fi
48+
done
49+
"#;
50+
fs::write(&mock_server_path, mock_server_content).await.unwrap();
51+
52+
// Make the script executable
53+
let status = Command::new("chmod")
54+
.arg("+x")
55+
.arg(&mock_server_path)
56+
.status()
57+
.expect("Failed to make mock server executable");
58+
assert!(status.success());
59+
60+
// Create MCP config file
61+
let config_path = temp_dir.path().join("mcp_config.json");
62+
let config = json!({
63+
"mcpServers": {
64+
"mock_server": {
65+
"command": mock_server_path.to_str().unwrap(),
66+
"args": []
67+
}
68+
}
69+
});
70+
71+
fs::write(&config_path, config.to_string()).await.unwrap();
72+
73+
// Set the config path in the environment for the test
74+
std::env::set_var("FIG_SETTINGS_MCP_CONFIG", config_path.to_str().unwrap());
75+
76+
// Now we'll run the CLI with a command that would use our mock tool
77+
let mut cmd = common::cli();
78+
cmd.arg("chat")
79+
.arg("--verbose")
80+
.arg("Use the hello_world tool to say hello to Integration Test")
81+
.assert()
82+
.success();
83+
}

0 commit comments

Comments
 (0)