Skip to main content
Glama
test-mcp-http-sse.sh13.2 kB
#!/bin/bash # Test script for ACF MCP server functionality # # This script tests the core functionality of the Agentic Control Framework's # MCP server. It interacts with the server directly via named pipes to avoid # issues with HTTP proxies or port conflicts. This method tests the underlying # tool handling logic, which is common to all transport layers (HTTP, SSE, etc.). # # NOTE: This test script is designed to be resilient to pre-existing state # in the workspace (e.g., an existing .acf/tasks.json file). Instead of asserting # exact state, it asserts state changes (e.g., task count increasing). set -e # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' NC='\033[0m' log() { echo -e "${BLUE}[INFO]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } header() { echo -e "${PURPLE}[TEST]${NC} $1"; } TEST_WORKSPACE="" MCP_PID="" REQUEST_COUNT=0 RESPONSE_FILE="/tmp/mcp_responses.log" INPUT_PIPE="/tmp/mcp_input.pipe" # Cleanup function cleanup() { log "Cleaning up..." if [ -n "$MCP_PID" ]; then # Give a moment for the server to process final commands before killing sleep 1 kill $MCP_PID 2>/dev/null || true fi if [ -d "$TEST_WORKSPACE" ]; then rm -rf "$TEST_WORKSPACE" fi rm -f "$RESPONSE_FILE" rm -f "$INPUT_PIPE" } trap cleanup EXIT # Setup function for tests setup() { TEST_WORKSPACE=$(mktemp -d -t acf-test-XXXXXX) log "Test workspace created at $TEST_WORKSPACE" # Clear and create response file and input pipe rm -f "$RESPONSE_FILE" "$INPUT_PIPE" touch "$RESPONSE_FILE" mkfifo "$INPUT_PIPE" } # Start MCP server start_mcp_server() { log "Starting ACF MCP server..." # We run the server in the background, reading from a named pipe and writing to a log file. # This ensures we are testing in a clean environment. ./bin/agentic-control-framework-mcp --workspaceRoot "$TEST_WORKSPACE" < "$INPUT_PIPE" > "$RESPONSE_FILE" 2>/tmp/mcp_server_stderr.log & MCP_PID=$! # Give it a moment to start up sleep 2 if ! ps -p $MCP_PID > /dev/null; then error "MCP server failed to start. Stderr: $(cat /tmp/mcp_server_stderr.log)" fi success "MCP server started successfully with PID $MCP_PID." } # Function to send a request to the server send_request() { local request_body=$1 local request_id=$2 echo "$request_body" > "$INPUT_PIPE" # Wait for the response local result="" # Increased timeout for slower systems for i in {1..20}; do # Search for the full JSON object in the stream of responses result=$(grep -o "{\"jsonrpc\":\"2.0\",\"id\":$request_id,.*}" "$RESPONSE_FILE" | jq -c . 2>/dev/null || true) if [ -n "$result" ]; then break fi sleep 0.5 done if [ -z "$result" ]; then error "Did not receive response for request ID $request_id. Check /tmp/mcp_server_stderr.log" fi echo "$result" } # Test: initProject test_init_project() { header "Testing 'initProject' tool" # Create a dummy old rules file to test migration local old_rules_dir="$TEST_WORKSPACE/.cursor/rules" mkdir -p "$old_rules_dir" local old_rules_file="$old_rules_dir/task_manager_workflow.mdc" local old_content="OLD RULES CONTENT" echo "$old_content" > "$old_rules_file" log "Created dummy old rules file for migration test." ((REQUEST_COUNT++)) local request_body="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"initProject\",\"args\":{\"projectName\":\"Test Project\", \"editor\":\"cursor\"}}}" local response=$(send_request "$request_body" "$REQUEST_COUNT") if echo "$response" | grep -q '"success":true'; then success "initProject successful." else error "initProject failed. Response: $response" fi # Verify that the new rules file contains the old content local new_rules_file="$TEST_WORKSPACE/.cursor/rules/acf_rules.md" if [ -f "$new_rules_file" ] && grep -q "$old_content" "$new_rules_file"; then success "Editor-specific rules file created and contains migrated content." else error "Editor-specific rules file was not created or does not contain migrated content." fi # Verify that the old rules file was deleted if [ ! -f "$old_rules_file" ]; then success "Old rules file was successfully deleted after migration." else error "Old rules file was not deleted after migration." fi } # Test: Task management tools test_task_tools() { header "Testing Task Management Tools" # 1. Get initial task count ((REQUEST_COUNT++)) local list_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"listTasks\",\"args\":{}}}" local initial_list_response=$(send_request "$list_req" "$REQUEST_COUNT") # Use jq to robustly count the number of tasks. local initial_task_count=$(echo "$initial_list_response" | jq '.result.tasks | length') log "Initial task count: $initial_task_count" # 2. Add a new task ((REQUEST_COUNT++)) local add_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"addTask\",\"args\":{\"title\":\"My Test Task From Test Script\"}}}" local add_response=$(send_request "$add_req" "$REQUEST_COUNT") if echo "$add_response" | grep -q '"success":true'; then success "addTask successful." else error "addTask failed. Response: $add_response" fi # 3. Get new task count and verify it increased ((REQUEST_COUNT++)) local list_req_2="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"listTasks\",\"args\":{}}}" local final_list_response=$(send_request "$list_req_2" "$REQUEST_COUNT") # Use jq to robustly count the number of tasks. local final_task_count=$(echo "$final_list_response" | jq '.result.tasks | length') log "Final task count: $final_task_count" if [ "$final_task_count" -eq "$((initial_task_count + 1))" ]; then success "Task count increased by 1 as expected." else error "Task count did not increase as expected. Initial: $initial_task_count, Final: $final_task_count" fi } # Test: Filesystem tools test_filesystem_tools() { header "Testing Filesystem Tools" # 1. Write a file ((REQUEST_COUNT++)) local test_file_path="$TEST_WORKSPACE/test_file.txt" local write_file_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"write_file\",\"args\":{\"path\":\"$test_file_path\",\"content\":\"hello world\"}}}" local write_response=$(send_request "$write_file_req" "$REQUEST_COUNT") if echo "$write_response" | grep -q '"success":true'; then success "write_file successful." else error "write_file failed. Response: $write_response" fi # 2. Verify file creation with list_directory ((REQUEST_COUNT++)) local list_dir_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"list_directory\",\"args\":{\"path\":\"$TEST_WORKSPACE\"}}}" local list_response=$(send_request "$list_dir_req" "$REQUEST_COUNT") if echo "$list_response" | grep -q '"name":"test_file.txt"'; then success "Verified file creation using list_directory." else error "File verification failed with list_directory. Response: $list_response" fi # 3. Cleanup created file ((REQUEST_COUNT++)) local delete_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"delete_file\",\"args\":{\"path\":\"$test_file_path\"}}}" local delete_response=$(send_request "$delete_req" "$REQUEST_COUNT") if echo "$delete_response" | grep -q '"success":true'; then success "delete_file successful." else error "delete_file failed. Response: $delete_response" fi } # Test: More filesystem tools test_more_filesystem_tools() { header "Testing More Filesystem Tools" # 1. Create a directory ((REQUEST_COUNT++)) local test_dir_path="$TEST_WORKSPACE/new_dir" local mkdir_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"create_directory\",\"args\":{\"path\":\"$test_dir_path\"}}}" local mkdir_response=$(send_request "$mkdir_req" "$REQUEST_COUNT") if echo "$mkdir_response" | grep -q '"success":true'; then success "create_directory successful." else error "create_directory failed. Response: $mkdir_response" fi # 2. Use 'tree' to verify directory creation ((REQUEST_COUNT++)) local tree_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"tree\",\"args\":{\"path\":\"$TEST_WORKSPACE\"}}}" local tree_response=$(send_request "$tree_req" "$REQUEST_COUNT") if echo "$tree_response" | jq -e '.result.tree.children | any(.name == "new_dir")' > /dev/null; then success "Verified directory creation using tree." else error "Directory verification failed with tree. Response: $tree_response" fi # 3. Test read_file ((REQUEST_COUNT++)) local test_file_path_for_read="$TEST_WORKSPACE/readable_file.txt" # Use shell redirection to create the file directly for this test echo "content to be read" > "$test_file_path_for_read" local read_file_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"read_file\",\"args\":{\"path\":\"$test_file_path_for_read\"}}}" local read_response=$(send_request "$read_file_req" "$REQUEST_COUNT") local content=$(echo "$read_response" | jq -r '.result.content') if [ "$content" = "content to be read" ]; then success "read_file successful." else error "read_file failed. Response: $read_response" fi } # Test: More Task Management tools test_more_task_tools() { header "Testing More Task Management Tools" # 1. Add a task to be updated and removed ((REQUEST_COUNT++)) local title_to_update="Task to be updated" local add_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"addTask\",\"args\":{\"title\":\"$title_to_update\"}}}" send_request "$add_req" "$REQUEST_COUNT" > /dev/null # We don't need to check this again # 2. Find the ID of the task we just added ((REQUEST_COUNT++)) local list_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"listTasks\",\"args\":{}}}" local list_response=$(send_request "$list_req" "$REQUEST_COUNT") local task_id=$(echo "$list_response" | jq -r ".result.tasks[] | select(.title == \"$title_to_update\") | .id") if [ -z "$task_id" ]; then error "Could not find the task to update/remove." fi log "Found task with ID $task_id to modify." # 3. Update the task ((REQUEST_COUNT++)) local new_title="Updated Task Title" local update_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"updateTask\",\"args\":{\"id\":\"$task_id\",\"title\":\"$new_title\"}}}" local update_response=$(send_request "$update_req" "$REQUEST_COUNT") if echo "$update_response" | grep -q '"success":true'; then success "updateTask successful." else error "updateTask failed. Response: $update_response" fi # 4. Remove the task ((REQUEST_COUNT++)) local remove_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"removeTask\",\"args\":{\"id\":\"$task_id\"}}}" local remove_response=$(send_request "$remove_req" "$REQUEST_COUNT") if echo "$remove_response" | grep -q '"success":true'; then success "removeTask successful." else error "removeTask failed. Response: $remove_response" fi } # Test: Terminal command execution test_terminal_tools() { header "Testing Terminal Execution Tools" # 1. Execute a simple command ((REQUEST_COUNT++)) local command_to_run="echo 'hello from terminal'" local exec_req="{\"jsonrpc\":\"2.0\",\"id\":$REQUEST_COUNT,\"method\":\"tools/run\",\"params\":{\"tool\":\"execute_command\",\"args\":{\"command\":\"$command_to_run\"}}}" local exec_response=$(send_request "$exec_req" "$REQUEST_COUNT") # Check for success and expected output if echo "$exec_response" | grep -q '"exitCode":0' && echo "$exec_response" | grep -q 'hello from terminal'; then success "execute_command successful with expected output." else error "execute_command failed or produced unexpected output. Response: $exec_response" fi } # Main execution main() { setup start_mcp_server test_init_project test_task_tools test_filesystem_tools test_more_filesystem_tools test_more_task_tools test_terminal_tools success "All tests passed!" } main

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/FutureAtoms/agentic-control-framework'

If you have feedback or need assistance with the MCP directory API, please join our Discord server