SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
DB_PATH="${1:-$PROJECT_DIR/db/test.duckdb}"
if [ ! -f "$DB_PATH" ]; then
echo "Error: Database not found at $DB_PATH"
exit 1
fi
echo "Testing create_or_update tools with database: $DB_PATH"
echo "======================================================="
echo ""
cd "$PROJECT_DIR" || exit 1
if [ ! -f "./skraak_mcp" ]; then
echo "Error: skraak_mcp binary not found. Run 'go build' first."
exit 1
fi
send_request() {
local method="$1"
local params="$2"
(
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
sleep 0.2
echo "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"$method\",\"params\":$params}"
sleep 0.5
) | timeout 10 ./skraak_mcp "$DB_PATH" 2>&1 | grep '"id":2' | head -1
}
echo "=== PART 1: CREATE MODE (no id provided) ==="
echo ""
echo "Test 1: Create pattern (valid)"
echo "-------------------------------"
PATTERN_RESULT=$(send_request "tools/call" '{"name":"create_or_update_pattern","arguments":{"record_seconds":120,"sleep_seconds":300}}')
PATTERN_ID=$(echo "$PATTERN_RESULT" | jq -r '.result.structuredContent.pattern.id // empty')
if [ -n "$PATTERN_ID" ]; then
echo "✓ Created pattern: $PATTERN_ID (120s record, 300s sleep)"
else
echo "✗ Failed to create pattern"
echo "$PATTERN_RESULT" | jq '.'
fi
echo ""
echo "Test 2: Create pattern with negative values (should fail)"
echo "----------------------------------------------------------"
INVALID_PATTERN=$(send_request "tools/call" '{"name":"create_or_update_pattern","arguments":{"record_seconds":-10,"sleep_seconds":300}}')
ERROR=$(echo "$INVALID_PATTERN" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
echo "✓ Correctly rejected invalid pattern"
else
echo "✗ Should have rejected negative values"
fi
echo ""
echo "Test 3: Create dataset (organise type)"
echo "---------------------------------------"
DATASET_RESULT=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"name":"Test Dataset 2026","description":"Automated test dataset","type":"organise"}}')
DATASET_ID=$(echo "$DATASET_RESULT" | jq -r '.result.structuredContent.dataset.id // empty')
if [ -n "$DATASET_ID" ]; then
echo "✓ Created dataset: $DATASET_ID"
else
echo "✗ Failed to create dataset"
echo "$DATASET_RESULT" | jq '.'
fi
echo ""
echo "Test 4: Create dataset with invalid type (should fail)"
echo "-------------------------------------------------------"
INVALID_DATASET=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"name":"Bad Dataset","type":"invalid_type"}}')
ERROR=$(echo "$INVALID_DATASET" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
echo "✓ Correctly rejected invalid dataset type"
else
echo "✗ Should have rejected invalid type"
fi
echo ""
echo "Test 5: Create location (Wellington, NZ)"
echo "-----------------------------------------"
LOCATION_RESULT=$(send_request "tools/call" '{"name":"create_or_update_location","arguments":{"dataset_id":"'"$DATASET_ID"'","name":"Wellington Test Location","latitude":-41.2865,"longitude":174.7762,"timezone_id":"Pacific/Auckland","description":"Test location in Wellington"}}')
LOCATION_ID=$(echo "$LOCATION_RESULT" | jq -r '.result.structuredContent.location.id // empty')
if [ -n "$LOCATION_ID" ]; then
echo "✓ Created location: $LOCATION_ID"
else
echo "✗ Failed to create location"
echo "$LOCATION_RESULT" | jq '.'
fi
echo ""
echo "Test 6: Create location with invalid coordinates (should fail)"
echo "---------------------------------------------------------------"
INVALID_LOCATION=$(send_request "tools/call" '{"name":"create_or_update_location","arguments":{"dataset_id":"'"$DATASET_ID"'","name":"Invalid Location","latitude":999,"longitude":174.7762,"timezone_id":"Pacific/Auckland"}}')
ERROR=$(echo "$INVALID_LOCATION" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
echo "✓ Correctly rejected invalid coordinates"
else
echo "✗ Should have rejected invalid latitude"
fi
echo ""
echo "Test 7: Create cluster with pattern"
echo "------------------------------------"
CLUSTER_RESULT=$(send_request "tools/call" '{"name":"create_or_update_cluster","arguments":{"dataset_id":"'"$DATASET_ID"'","location_id":"'"$LOCATION_ID"'","name":"Test Cluster A01","sample_rate":250000,"cyclic_recording_pattern_id":"'"$PATTERN_ID"'"}}')
CLUSTER_ID=$(echo "$CLUSTER_RESULT" | jq -r '.result.structuredContent.cluster.id // empty')
if [ -n "$CLUSTER_ID" ]; then
echo "✓ Created cluster: $CLUSTER_ID"
else
echo "✗ Failed to create cluster"
echo "$CLUSTER_RESULT" | jq '.'
fi
echo ""
echo "Test 8: Create cluster with invalid sample rate (should fail)"
echo "--------------------------------------------------------------"
INVALID_CLUSTER=$(send_request "tools/call" '{"name":"create_or_update_cluster","arguments":{"dataset_id":"'"$DATASET_ID"'","location_id":"'"$LOCATION_ID"'","name":"Bad Cluster","sample_rate":-1000}}')
ERROR=$(echo "$INVALID_CLUSTER" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
echo "✓ Correctly rejected invalid sample rate"
else
echo "✗ Should have rejected negative sample rate"
fi
echo ""
echo "=== PART 2: UPDATE MODE (id provided) ==="
echo ""
echo "Test 9: Update dataset name and description"
echo "--------------------------------------------"
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"id":"'"$DATASET_ID"'","name":"Updated Test Dataset","description":"Updated description after test"}}')
SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.dataset.id // empty')
if [ -n "$SUCCESS" ]; then
echo "✓ Successfully updated dataset"
else
echo "✗ Failed to update dataset"
echo "$UPDATE_RESULT" | jq '.'
fi
echo ""
echo "Test 10: Update dataset type to 'train'"
echo "---------------------------------------"
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"id":"'"$DATASET_ID"'","type":"train"}}')
UPDATED_TYPE=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.dataset.type // empty')
if [ "$UPDATED_TYPE" = "train" ]; then
echo "✓ Successfully updated dataset type to 'train'"
else
echo "✗ Failed to update dataset type"
echo "$UPDATE_RESULT" | jq '.'
fi
echo ""
echo "Test 11: Update location coordinates and name"
echo "----------------------------------------------"
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_location","arguments":{"id":"'"$LOCATION_ID"'","name":"Updated Wellington Location","latitude":-41.2900,"longitude":174.7800}}')
SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.location.id // empty')
if [ -n "$SUCCESS" ]; then
echo "✓ Successfully updated location"
else
echo "✗ Failed to update location"
echo "$UPDATE_RESULT" | jq '.'
fi
echo ""
echo "Test 12: Update cluster name and sample rate"
echo "---------------------------------------------"
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_cluster","arguments":{"id":"'"$CLUSTER_ID"'","name":"Updated Cluster A01","sample_rate":384000,"description":"Updated cluster description"}}')
SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.cluster.id // empty')
if [ -n "$SUCCESS" ]; then
echo "✓ Successfully updated cluster"
else
echo "✗ Failed to update cluster"
echo "$UPDATE_RESULT" | jq '.'
fi
echo ""
echo "Test 13: Update recording pattern durations"
echo "--------------------------------------------"
echo -n "Getting existing pattern from database... "
EXISTING_PATTERN=$(send_request "tools/call" '{"name":"execute_sql","arguments":{"query":"SELECT id, record_s, sleep_s FROM cyclic_recording_pattern WHERE active = true ORDER BY created_at DESC LIMIT 1"}}')
EXISTING_PATTERN_ID=$(echo "$EXISTING_PATTERN" | jq -r '.result.structuredContent.rows[0].id // empty')
CURRENT_RECORD=$(echo "$EXISTING_PATTERN" | jq -r '.result.structuredContent.rows[0].record_s // empty' | sed 's/"//g')
CURRENT_SLEEP=$(echo "$EXISTING_PATTERN" | jq -r '.result.structuredContent.rows[0].sleep_s // empty' | sed 's/"//g')
if [ -n "$EXISTING_PATTERN_ID" ] && [ -n "$CURRENT_RECORD" ] && [ -n "$CURRENT_SLEEP" ]; then
echo "found $EXISTING_PATTERN_ID (${CURRENT_RECORD}s/${CURRENT_SLEEP}s)"
TIMESTAMP_OFFSET=$(($(date +%s) % 100))
NEW_RECORD=$((CURRENT_RECORD + TIMESTAMP_OFFSET))
NEW_SLEEP=$((CURRENT_SLEEP + TIMESTAMP_OFFSET))
UPDATE_RESULT=$(send_request "tools/call" '{"name":"create_or_update_pattern","arguments":{"id":"'"$EXISTING_PATTERN_ID"'","record_seconds":'"$NEW_RECORD"',"sleep_seconds":'"$NEW_SLEEP"'}}')
SUCCESS=$(echo "$UPDATE_RESULT" | jq -r '.result.structuredContent.pattern.id // empty')
if [ -n "$SUCCESS" ]; then
echo "✓ Successfully updated pattern (${NEW_RECORD}s record, ${NEW_SLEEP}s sleep)"
else
echo "✗ Failed to update pattern"
echo "$UPDATE_RESULT" | jq '.'
fi
else
echo "✗ Could not find existing pattern to update"
fi
echo ""
echo "Test 14: Update with non-existent dataset ID (should fail)"
echo "-----------------------------------------------------------"
INVALID_UPDATE=$(send_request "tools/call" '{"name":"create_or_update_dataset","arguments":{"id":"INVALID_ID_123","name":"Should Fail"}}')
ERROR=$(echo "$INVALID_UPDATE" | jq -r '.result.isError // .error.message // empty')
if [ -n "$ERROR" ] && [ "$ERROR" != "false" ]; then
echo "✓ Correctly rejected invalid dataset ID"
else
echo "✗ Should have rejected invalid ID"
fi
echo ""
echo "=== TEST SUMMARY ==="
echo "All create_or_update tool tests complete!"
echo "Check output above for any ✗ failures"
echo ""