Fix inbox creation issues in agent coordinator
- Fixed Task.new/3 to handle both maps and keyword lists - Added robust inbox existence checking in find_available_agent - Ensure inbox creation during agent registration and task assignment - Add helper function ensure_inbox_exists to avoid crashes
This commit is contained in:
13
scripts/mcp_config.json
Normal file
13
scripts/mcp_config.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"agent-coordinator": {
|
||||
"command": "/home/ra/agent_coordinator/scripts/mcp_launcher.sh",
|
||||
"args": [],
|
||||
"env": {
|
||||
"MIX_ENV": "dev",
|
||||
"NATS_HOST": "localhost",
|
||||
"NATS_PORT": "4222"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
109
scripts/mcp_launcher.sh
Executable file
109
scripts/mcp_launcher.sh
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
|
||||
# AgentCoordinator Unified MCP Server Launcher
|
||||
# This script starts the unified MCP server that manages all external MCP servers
|
||||
# and provides automatic task tracking with heartbeat coverage
|
||||
|
||||
set -e
|
||||
|
||||
export PATH="$HOME/.asdf/shims:$PATH"
|
||||
|
||||
# Change to the project directory
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
# Set environment
|
||||
export MIX_ENV="${MIX_ENV:-dev}"
|
||||
export NATS_HOST="${NATS_HOST:-localhost}"
|
||||
export NATS_PORT="${NATS_PORT:-4222}"
|
||||
|
||||
# Log startup
|
||||
echo "Starting AgentCoordinator Unified MCP Server..." >&2
|
||||
echo "Environment: $MIX_ENV" >&2
|
||||
echo "NATS: $NATS_HOST:$NATS_PORT" >&2
|
||||
|
||||
# Start the Elixir application with unified MCP server
|
||||
exec mix run --no-halt -e "
|
||||
# Ensure all applications are started
|
||||
{:ok, _} = Application.ensure_all_started(:agent_coordinator)
|
||||
|
||||
# Start services that are NOT in the application supervisor
|
||||
# TaskRegistry is already started by the application supervisor, so we skip it
|
||||
case AgentCoordinator.MCPServerManager.start_link([config_file: \"mcp_servers.json\"]) do
|
||||
{:ok, _} -> :ok
|
||||
{:error, {:already_started, _}} -> :ok
|
||||
{:error, reason} -> raise \"Failed to start MCPServerManager: #{inspect(reason)}\"
|
||||
end
|
||||
|
||||
case AgentCoordinator.UnifiedMCPServer.start_link() do
|
||||
{:ok, _} -> :ok
|
||||
{:error, {:already_started, _}} -> :ok
|
||||
{:error, reason} -> raise \"Failed to start UnifiedMCPServer: #{inspect(reason)}\"
|
||||
end
|
||||
|
||||
# Log that we're ready
|
||||
IO.puts(:stderr, \"Unified MCP server ready with automatic task tracking\")
|
||||
|
||||
# Handle MCP JSON-RPC messages through the unified server
|
||||
defmodule UnifiedMCPStdio do
|
||||
def start do
|
||||
spawn_link(fn -> message_loop() end)
|
||||
Process.sleep(:infinity)
|
||||
end
|
||||
|
||||
defp message_loop do
|
||||
case IO.read(:stdio, :line) do
|
||||
:eof ->
|
||||
IO.puts(:stderr, \"Unified MCP server shutting down\")
|
||||
System.halt(0)
|
||||
{:error, reason} ->
|
||||
IO.puts(:stderr, \"IO Error: #{inspect(reason)}\")
|
||||
System.halt(1)
|
||||
line ->
|
||||
handle_message(String.trim(line))
|
||||
message_loop()
|
||||
end
|
||||
end
|
||||
|
||||
defp handle_message(\"\"), do: :ok
|
||||
defp handle_message(json_line) do
|
||||
try do
|
||||
request = Jason.decode!(json_line)
|
||||
|
||||
# Route through unified MCP server for automatic task tracking
|
||||
response = AgentCoordinator.UnifiedMCPServer.handle_mcp_request(request)
|
||||
IO.puts(Jason.encode!(response))
|
||||
rescue
|
||||
e in Jason.DecodeError ->
|
||||
error_response = %{
|
||||
\"jsonrpc\" => \"2.0\",
|
||||
\"id\" => nil,
|
||||
\"error\" => %{
|
||||
\"code\" => -32700,
|
||||
\"message\" => \"Parse error: #{Exception.message(e)}\"
|
||||
}
|
||||
}
|
||||
IO.puts(Jason.encode!(error_response))
|
||||
e ->
|
||||
# Try to get the ID from the malformed request
|
||||
id = try do
|
||||
partial = Jason.decode!(json_line)
|
||||
Map.get(partial, \"id\")
|
||||
rescue
|
||||
_ -> nil
|
||||
end
|
||||
|
||||
error_response = %{
|
||||
\"jsonrpc\" => \"2.0\",
|
||||
\"id\" => id,
|
||||
\"error\" => %{
|
||||
\"code\" => -32603,
|
||||
\"message\" => \"Internal error: #{Exception.message(e)}\"
|
||||
}
|
||||
}
|
||||
IO.puts(Jason.encode!(error_response))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
UnifiedMCPStdio.start()
|
||||
"
|
||||
73
scripts/minimal_test.sh
Executable file
73
scripts/minimal_test.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ultra-minimal test that doesn't start the full application
|
||||
|
||||
echo "🔬 Ultra-Minimal AgentCoordinator Test"
|
||||
echo "======================================"
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
echo "📋 Testing compilation..."
|
||||
if mix compile >/dev/null 2>&1; then
|
||||
echo "✅ Compilation successful"
|
||||
else
|
||||
echo "❌ Compilation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📋 Testing MCP server without application startup..."
|
||||
if timeout 10 mix run --no-start -e "
|
||||
# Load compiled modules without starting application
|
||||
Code.ensure_loaded(AgentCoordinator.MCPServer)
|
||||
|
||||
# Test MCP server directly
|
||||
try do
|
||||
# Start just the required processes manually
|
||||
{:ok, _} = Registry.start_link(keys: :unique, name: AgentCoordinator.InboxRegistry)
|
||||
{:ok, _} = Phoenix.PubSub.start_link(name: AgentCoordinator.PubSub)
|
||||
|
||||
# Start TaskRegistry without NATS
|
||||
{:ok, _} = GenServer.start_link(AgentCoordinator.TaskRegistry, [nats: nil], name: AgentCoordinator.TaskRegistry)
|
||||
|
||||
# Start MCP server
|
||||
{:ok, _} = GenServer.start_link(AgentCoordinator.MCPServer, %{}, name: AgentCoordinator.MCPServer)
|
||||
|
||||
IO.puts('✅ Core components started')
|
||||
|
||||
# Test MCP functionality
|
||||
response = AgentCoordinator.MCPServer.handle_mcp_request(%{
|
||||
\"jsonrpc\" => \"2.0\",
|
||||
\"id\" => 1,
|
||||
\"method\" => \"tools/list\"
|
||||
})
|
||||
|
||||
case response do
|
||||
%{\"result\" => %{\"tools\" => tools}} when is_list(tools) ->
|
||||
IO.puts(\"✅ MCP server working (#{length(tools)} tools)\")
|
||||
_ ->
|
||||
IO.puts(\"❌ MCP server not working: #{inspect(response)}\")
|
||||
end
|
||||
|
||||
rescue
|
||||
e ->
|
||||
IO.puts(\"❌ Error: #{inspect(e)}\")
|
||||
end
|
||||
|
||||
System.halt(0)
|
||||
"; then
|
||||
echo "✅ Minimal test passed!"
|
||||
else
|
||||
echo "❌ Minimal test failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🎉 Core MCP functionality works!"
|
||||
echo ""
|
||||
echo "📝 The hanging issue was due to NATS persistence trying to connect."
|
||||
echo " Your MCP server core functionality is working perfectly."
|
||||
echo ""
|
||||
echo "🚀 To run with proper NATS setup:"
|
||||
echo " 1. Make sure NATS server is running: sudo systemctl start nats"
|
||||
echo " 2. Or run: nats-server -js -p 4222 -m 8222 &"
|
||||
echo " 3. Then use: ../scripts/mcp_launcher.sh"
|
||||
54
scripts/quick_test.sh
Executable file
54
scripts/quick_test.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Quick test script to verify Agentecho "💡 Next steps:"
|
||||
echo " 1. Run scripts/setup.sh to configure VS Code integration"
|
||||
echo " 2. Or test manually with: scripts/mcp_launcher.sh"rdinator works without getting stuck
|
||||
|
||||
echo "🧪 Quick AgentCoordinator Test"
|
||||
echo "=============================="
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
echo "📋 Testing basic compilation..."
|
||||
if mix compile --force >/dev/null 2>&1; then
|
||||
echo "✅ Compilation successful"
|
||||
else
|
||||
echo "❌ Compilation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📋 Testing application startup (without persistence)..."
|
||||
if timeout 10 mix run -e "
|
||||
Application.put_env(:agent_coordinator, :enable_persistence, false)
|
||||
{:ok, _apps} = Application.ensure_all_started(:agent_coordinator)
|
||||
IO.puts('✅ Application started successfully')
|
||||
|
||||
# Quick MCP server test
|
||||
response = AgentCoordinator.MCPServer.handle_mcp_request(%{
|
||||
\"jsonrpc\" => \"2.0\",
|
||||
\"id\" => 1,
|
||||
\"method\" => \"tools/list\"
|
||||
})
|
||||
|
||||
case response do
|
||||
%{\"result\" => %{\"tools\" => tools}} when is_list(tools) ->
|
||||
IO.puts(\"✅ MCP server working (#{length(tools)} tools available)\")
|
||||
_ ->
|
||||
IO.puts(\"❌ MCP server not responding correctly\")
|
||||
end
|
||||
|
||||
System.halt(0)
|
||||
"; then
|
||||
echo "✅ Quick test passed!"
|
||||
else
|
||||
echo "❌ Quick test failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🎉 AgentCoordinator is ready!"
|
||||
echo ""
|
||||
echo "🚀 Next steps:"
|
||||
echo " 1. Run ./setup.sh to configure VS Code integration"
|
||||
echo " 2. Or test manually with: ./mcp_launcher.sh"
|
||||
echo " 3. Or run Python example: python3 mcp_client_example.py"
|
||||
246
scripts/setup.sh
Executable file
246
scripts/setup.sh
Executable file
@@ -0,0 +1,246 @@
|
||||
#!/bin/bash
|
||||
|
||||
# AgentCoordinator Setup Script
|
||||
# This script sets up everything needed to connect GitHub Copilot to AgentCoordinator
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
USER_HOME="$HOME"
|
||||
|
||||
echo "🚀 AgentCoordinator Setup"
|
||||
echo "========================="
|
||||
echo "Project Directory: $PROJECT_DIR"
|
||||
echo "User Home: $USER_HOME"
|
||||
|
||||
# Function to check if command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Check prerequisites
|
||||
echo -e "\n📋 Checking prerequisites..."
|
||||
|
||||
if ! command_exists mix; then
|
||||
echo "❌ Elixir/Mix not found. Please install Elixir first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command_exists nats-server; then
|
||||
echo "⚠️ NATS server not found. Installing via package manager..."
|
||||
if command_exists apt; then
|
||||
sudo apt update && sudo apt install -y nats-server
|
||||
elif command_exists brew; then
|
||||
brew install nats-server
|
||||
elif command_exists yum; then
|
||||
sudo yum install -y nats-server
|
||||
else
|
||||
echo "❌ Please install NATS server manually: https://docs.nats.io/nats-server/installation"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✅ Prerequisites OK"
|
||||
|
||||
# Start NATS server if not running
|
||||
echo -e "\n🔧 Setting up NATS server..."
|
||||
if ! pgrep -f nats-server > /dev/null; then
|
||||
echo "Starting NATS server..."
|
||||
|
||||
# Check if systemd service exists
|
||||
if systemctl list-unit-files | grep -q nats.service; then
|
||||
sudo systemctl enable nats
|
||||
sudo systemctl start nats
|
||||
echo "✅ NATS server started via systemd"
|
||||
else
|
||||
# Start manually in background
|
||||
nats-server -js -p 4222 -m 8222 > /tmp/nats.log 2>&1 &
|
||||
echo $! > /tmp/nats.pid
|
||||
echo "✅ NATS server started manually (PID: $(cat /tmp/nats.pid))"
|
||||
fi
|
||||
|
||||
# Wait for NATS to be ready
|
||||
sleep 2
|
||||
else
|
||||
echo "✅ NATS server already running"
|
||||
fi
|
||||
|
||||
# Install Elixir dependencies
|
||||
echo -e "\n📦 Installing Elixir dependencies..."
|
||||
cd "$PROJECT_DIR"
|
||||
mix deps.get
|
||||
echo "✅ Dependencies installed"
|
||||
|
||||
# Test the application
|
||||
echo -e "\n🧪 Testing AgentCoordinator application..."
|
||||
echo "Testing basic compilation and startup..."
|
||||
|
||||
# First test: just compile
|
||||
if mix compile >/dev/null 2>&1; then
|
||||
echo "✅ Application compiles successfully"
|
||||
else
|
||||
echo "❌ Application compilation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Second test: quick startup test without persistence
|
||||
if timeout 15 mix run -e "
|
||||
try do
|
||||
Application.put_env(:agent_coordinator, :enable_persistence, false)
|
||||
{:ok, _} = Application.ensure_all_started(:agent_coordinator)
|
||||
IO.puts('App startup test OK')
|
||||
System.halt(0)
|
||||
rescue
|
||||
e ->
|
||||
IO.puts('App startup error: #{inspect(e)}')
|
||||
System.halt(1)
|
||||
end
|
||||
" >/dev/null 2>&1; then
|
||||
echo "✅ Application startup test passed"
|
||||
else
|
||||
echo "⚠️ Application startup test had issues, but continuing..."
|
||||
echo " (This might be due to NATS configuration - will be fixed during runtime)"
|
||||
fi
|
||||
|
||||
# Create VS Code settings directory if it doesn't exist
|
||||
VSCODE_SETTINGS_DIR="$USER_HOME/.vscode-server/data/User"
|
||||
if [ ! -d "$VSCODE_SETTINGS_DIR" ]; then
|
||||
VSCODE_SETTINGS_DIR="$USER_HOME/.vscode/User"
|
||||
fi
|
||||
|
||||
mkdir -p "$VSCODE_SETTINGS_DIR"
|
||||
|
||||
# Create or update VS Code settings for MCP
|
||||
echo -e "\n⚙️ Configuring VS Code for MCP..."
|
||||
|
||||
SETTINGS_FILE="$VSCODE_SETTINGS_DIR/settings.json"
|
||||
MCP_CONFIG='{
|
||||
"github.copilot.advanced": {
|
||||
"mcp": {
|
||||
"servers": {
|
||||
"agent-coordinator": {
|
||||
"command": "'$PROJECT_DIR'/scripts/mcp_launcher.sh",
|
||||
"args": [],
|
||||
"env": {
|
||||
"MIX_ENV": "dev",
|
||||
"NATS_HOST": "localhost",
|
||||
"NATS_PORT": "4222"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# Backup existing settings
|
||||
if [ -f "$SETTINGS_FILE" ]; then
|
||||
cp "$SETTINGS_FILE" "$SETTINGS_FILE.backup.$(date +%s)"
|
||||
echo "📋 Backed up existing VS Code settings"
|
||||
fi
|
||||
|
||||
# Merge or create settings
|
||||
if [ -f "$SETTINGS_FILE" ]; then
|
||||
# Use jq to merge if available, otherwise manual merge
|
||||
if command_exists jq; then
|
||||
echo "$MCP_CONFIG" | jq -s '.[0] * .[1]' "$SETTINGS_FILE" - > "$SETTINGS_FILE.tmp"
|
||||
mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
|
||||
else
|
||||
echo "⚠️ jq not found. Please manually add MCP configuration to $SETTINGS_FILE"
|
||||
echo "Add this configuration:"
|
||||
echo "$MCP_CONFIG"
|
||||
fi
|
||||
else
|
||||
echo "$MCP_CONFIG" > "$SETTINGS_FILE"
|
||||
fi
|
||||
|
||||
echo "✅ VS Code settings updated"
|
||||
|
||||
# Test MCP server
|
||||
echo -e "\n🧪 Testing MCP server..."
|
||||
cd "$PROJECT_DIR"
|
||||
if timeout 5 ./scripts/mcp_launcher.sh >/dev/null 2>&1; then
|
||||
echo "✅ MCP server test passed"
|
||||
else
|
||||
echo "⚠️ MCP server test timed out (this is expected)"
|
||||
fi
|
||||
|
||||
# Create desktop shortcut for easy access
|
||||
echo -e "\n🖥️ Creating desktop shortcuts..."
|
||||
|
||||
# Start script
|
||||
cat > "$PROJECT_DIR/start_agent_coordinator.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$0")"
|
||||
echo "🚀 Starting AgentCoordinator..."
|
||||
|
||||
# Start NATS if not running
|
||||
if ! pgrep -f nats-server > /dev/null; then
|
||||
echo "Starting NATS server..."
|
||||
nats-server -js -p 4222 -m 8222 > /tmp/nats.log 2>&1 &
|
||||
echo $! > /tmp/nats.pid
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# Start MCP server
|
||||
echo "Starting MCP server..."
|
||||
./scripts/mcp_launcher.sh
|
||||
EOF
|
||||
|
||||
chmod +x "$PROJECT_DIR/start_agent_coordinator.sh"
|
||||
|
||||
# Stop script
|
||||
cat > "$PROJECT_DIR/stop_agent_coordinator.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
echo "🛑 Stopping AgentCoordinator..."
|
||||
|
||||
# Stop NATS if we started it
|
||||
if [ -f /tmp/nats.pid ]; then
|
||||
kill $(cat /tmp/nats.pid) 2>/dev/null || true
|
||||
rm -f /tmp/nats.pid
|
||||
fi
|
||||
|
||||
# Kill any remaining processes
|
||||
pkill -f "scripts/mcp_launcher.sh" || true
|
||||
pkill -f "agent_coordinator" || true
|
||||
|
||||
echo "✅ AgentCoordinator stopped"
|
||||
EOF
|
||||
|
||||
chmod +x "$PROJECT_DIR/stop_agent_coordinator.sh"
|
||||
|
||||
echo "✅ Created start/stop scripts"
|
||||
|
||||
# Final instructions
|
||||
echo -e "\n🎉 Setup Complete!"
|
||||
echo "==================="
|
||||
echo ""
|
||||
echo "📋 Next Steps:"
|
||||
echo ""
|
||||
echo "1. 🔄 Restart VS Code to load the new MCP configuration"
|
||||
echo " - Close all VS Code windows"
|
||||
echo " - Reopen VS Code in your project"
|
||||
echo ""
|
||||
echo "2. 🤖 GitHub Copilot should now have access to AgentCoordinator tools:"
|
||||
echo " - register_agent"
|
||||
echo " - create_task"
|
||||
echo " - get_next_task"
|
||||
echo " - complete_task"
|
||||
echo " - get_task_board"
|
||||
echo " - heartbeat"
|
||||
echo ""
|
||||
echo "3. 🧪 Test the integration:"
|
||||
echo " - Ask Copilot: 'Register me as an agent with coding capabilities'"
|
||||
echo " - Ask Copilot: 'Create a task to refactor the login module'"
|
||||
echo " - Ask Copilot: 'Show me the task board'"
|
||||
echo ""
|
||||
echo "📂 Useful files:"
|
||||
echo " - Start server: $PROJECT_DIR/start_agent_coordinator.sh"
|
||||
echo " - Stop server: $PROJECT_DIR/stop_agent_coordinator.sh"
|
||||
echo " - Test client: $PROJECT_DIR/mcp_client_example.py"
|
||||
echo " - VS Code settings: $SETTINGS_FILE"
|
||||
echo ""
|
||||
echo "🔧 Manual start (if needed):"
|
||||
echo " cd $PROJECT_DIR && ./scripts/mcp_launcher.sh"
|
||||
echo ""
|
||||
echo "💡 Tip: The MCP server will auto-start when Copilot needs it!"
|
||||
echo ""
|
||||
149
scripts/test_mcp_server.exs
Normal file
149
scripts/test_mcp_server.exs
Normal file
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env elixir
|
||||
|
||||
# Simple test script to demonstrate MCP server functionality
|
||||
Mix.install([
|
||||
{:jason, "~> 1.4"}
|
||||
])
|
||||
|
||||
# Start the agent coordinator application
|
||||
Application.ensure_all_started(:agent_coordinator)
|
||||
|
||||
alias AgentCoordinator.MCPServer
|
||||
|
||||
IO.puts("🚀 Testing Agent Coordinator MCP Server")
|
||||
IO.puts("=" |> String.duplicate(50))
|
||||
|
||||
# Test 1: Get tools list
|
||||
IO.puts("\n📋 Getting available tools...")
|
||||
tools_request = %{"method" => "tools/list", "jsonrpc" => "2.0", "id" => 1}
|
||||
tools_response = MCPServer.handle_mcp_request(tools_request)
|
||||
|
||||
case tools_response do
|
||||
%{"result" => %{"tools" => tools}} ->
|
||||
IO.puts("✅ Found #{length(tools)} tools:")
|
||||
Enum.each(tools, fn tool ->
|
||||
IO.puts(" - #{tool["name"]}: #{tool["description"]}")
|
||||
end)
|
||||
error ->
|
||||
IO.puts("❌ Error getting tools: #{inspect(error)}")
|
||||
end
|
||||
|
||||
# Test 2: Register an agent
|
||||
IO.puts("\n👤 Registering test agent...")
|
||||
register_request = %{
|
||||
"method" => "tools/call",
|
||||
"params" => %{
|
||||
"name" => "register_agent",
|
||||
"arguments" => %{
|
||||
"name" => "DemoAgent",
|
||||
"capabilities" => ["coding", "testing"]
|
||||
}
|
||||
},
|
||||
"jsonrpc" => "2.0",
|
||||
"id" => 2
|
||||
}
|
||||
|
||||
register_response = MCPServer.handle_mcp_request(register_request)
|
||||
|
||||
agent_id = case register_response do
|
||||
%{"result" => %{"content" => [%{"text" => text}]}} ->
|
||||
data = Jason.decode!(text)
|
||||
IO.puts("✅ Agent registered: #{data["agent_id"]}")
|
||||
data["agent_id"]
|
||||
error ->
|
||||
IO.puts("❌ Error registering agent: #{inspect(error)}")
|
||||
nil
|
||||
end
|
||||
|
||||
if agent_id do
|
||||
# Test 3: Create a task
|
||||
IO.puts("\n📝 Creating a test task...")
|
||||
task_request = %{
|
||||
"method" => "tools/call",
|
||||
"params" => %{
|
||||
"name" => "create_task",
|
||||
"arguments" => %{
|
||||
"title" => "Demo Task",
|
||||
"description" => "A demonstration task for the MCP server",
|
||||
"priority" => "high",
|
||||
"required_capabilities" => ["coding"]
|
||||
}
|
||||
},
|
||||
"jsonrpc" => "2.0",
|
||||
"id" => 3
|
||||
}
|
||||
|
||||
task_response = MCPServer.handle_mcp_request(task_request)
|
||||
|
||||
case task_response do
|
||||
%{"result" => %{"content" => [%{"text" => text}]}} ->
|
||||
data = Jason.decode!(text)
|
||||
IO.puts("✅ Task created: #{data["task_id"]}")
|
||||
if data["assigned_to"] do
|
||||
IO.puts(" Assigned to: #{data["assigned_to"]}")
|
||||
end
|
||||
error ->
|
||||
IO.puts("❌ Error creating task: #{inspect(error)}")
|
||||
end
|
||||
|
||||
# Test 4: Get task board
|
||||
IO.puts("\n📊 Getting task board...")
|
||||
board_request = %{
|
||||
"method" => "tools/call",
|
||||
"params" => %{
|
||||
"name" => "get_task_board",
|
||||
"arguments" => %{}
|
||||
},
|
||||
"jsonrpc" => "2.0",
|
||||
"id" => 4
|
||||
}
|
||||
|
||||
board_response = MCPServer.handle_mcp_request(board_request)
|
||||
|
||||
case board_response do
|
||||
%{"result" => %{"content" => [%{"text" => text}]}} ->
|
||||
data = Jason.decode!(text)
|
||||
IO.puts("✅ Task board retrieved:")
|
||||
Enum.each(data["agents"], fn agent ->
|
||||
IO.puts(" Agent: #{agent["name"]} (#{agent["agent_id"]})")
|
||||
IO.puts(" Capabilities: #{Enum.join(agent["capabilities"], ", ")}")
|
||||
IO.puts(" Status: #{agent["status"]}")
|
||||
if agent["current_task"] do
|
||||
IO.puts(" Current Task: #{agent["current_task"]["title"]}")
|
||||
else
|
||||
IO.puts(" Current Task: None")
|
||||
end
|
||||
IO.puts(" Pending: #{agent["pending_tasks"]} | Completed: #{agent["completed_tasks"]}")
|
||||
IO.puts("")
|
||||
end)
|
||||
error ->
|
||||
IO.puts("❌ Error getting task board: #{inspect(error)}")
|
||||
end
|
||||
|
||||
# Test 5: Send heartbeat
|
||||
IO.puts("\n💓 Sending heartbeat...")
|
||||
heartbeat_request = %{
|
||||
"method" => "tools/call",
|
||||
"params" => %{
|
||||
"name" => "heartbeat",
|
||||
"arguments" => %{
|
||||
"agent_id" => agent_id
|
||||
}
|
||||
},
|
||||
"jsonrpc" => "2.0",
|
||||
"id" => 5
|
||||
}
|
||||
|
||||
heartbeat_response = MCPServer.handle_mcp_request(heartbeat_request)
|
||||
|
||||
case heartbeat_response do
|
||||
%{"result" => %{"content" => [%{"text" => text}]}} ->
|
||||
data = Jason.decode!(text)
|
||||
IO.puts("✅ Heartbeat sent: #{data["status"]}")
|
||||
error ->
|
||||
IO.puts("❌ Error sending heartbeat: #{inspect(error)}")
|
||||
end
|
||||
end
|
||||
|
||||
IO.puts("\n🎉 MCP Server testing completed!")
|
||||
IO.puts("=" |> String.duplicate(50))
|
||||
46
scripts/test_mcp_stdio.sh
Executable file
46
scripts/test_mcp_stdio.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test script for MCP server stdio interface
|
||||
|
||||
echo "🧪 Testing AgentCoordinator MCP Server via stdio"
|
||||
echo "================================================"
|
||||
|
||||
# Start the MCP server in background
|
||||
./mcp_launcher.sh &
|
||||
MCP_PID=$!
|
||||
|
||||
# Give it time to start
|
||||
sleep 3
|
||||
|
||||
# Function to send MCP request and get response
|
||||
send_mcp_request() {
|
||||
local request="$1"
|
||||
echo "📤 Sending: $request"
|
||||
echo "$request" | nc localhost 12345 2>/dev/null || echo "$request" >&${MCP_PID}
|
||||
sleep 1
|
||||
}
|
||||
|
||||
# Test 1: Get tools list
|
||||
echo -e "\n1️⃣ Testing tools/list..."
|
||||
TOOLS_REQUEST='{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
|
||||
send_mcp_request "$TOOLS_REQUEST"
|
||||
|
||||
# Test 2: Register agent
|
||||
echo -e "\n2️⃣ Testing register_agent..."
|
||||
REGISTER_REQUEST='{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"register_agent","arguments":{"name":"TestAgent","capabilities":["coding","testing"]}}}'
|
||||
send_mcp_request "$REGISTER_REQUEST"
|
||||
|
||||
# Test 3: Create task
|
||||
echo -e "\n3️⃣ Testing create_task..."
|
||||
TASK_REQUEST='{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"create_task","arguments":{"title":"Test Task","description":"A test task","priority":"medium","required_capabilities":["coding"]}}}'
|
||||
send_mcp_request "$TASK_REQUEST"
|
||||
|
||||
# Test 4: Get task board
|
||||
echo -e "\n4️⃣ Testing get_task_board..."
|
||||
BOARD_REQUEST='{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"get_task_board","arguments":{}}}'
|
||||
send_mcp_request "$BOARD_REQUEST"
|
||||
|
||||
# Clean up
|
||||
sleep 2
|
||||
kill $MCP_PID 2>/dev/null
|
||||
echo -e "\n✅ MCP server test completed"
|
||||
Reference in New Issue
Block a user