Improved parameter validation

Change-Id: If2e7ec1b063a6e114a6c5582463af784b75c37b8
diff --git a/tools/metadata_test.go b/tools/metadata_test.go
index e5d60cd..04a067c 100644
--- a/tools/metadata_test.go
+++ b/tools/metadata_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"context"
+	"strings"
 	"testing"
 
 	"github.com/korap/korap-mcp/service"
@@ -32,6 +33,9 @@
 
 	// Verify it's an object type
 	assert.Equal(t, "object", schema["type"])
+	assert.Equal(t, "KorAP Metadata Parameters", schema["title"])
+	assert.Contains(t, schema["description"], "Parameters for retrieving corpus metadata")
+	assert.Equal(t, false, schema["additionalProperties"])
 
 	// Verify properties exist
 	properties, ok := schema["properties"].(map[string]interface{})
@@ -43,6 +47,7 @@
 	action, ok := properties["action"].(map[string]interface{})
 	assert.True(t, ok)
 	assert.Equal(t, "string", action["type"])
+	assert.Contains(t, action["description"], "Type of metadata operation")
 
 	enum, ok := action["enum"].([]string)
 	assert.True(t, ok)
@@ -50,10 +55,23 @@
 	assert.Contains(t, enum, "statistics")
 	assert.Equal(t, "list", action["default"])
 
+	actionExamples, ok := action["examples"].([]string)
+	assert.True(t, ok)
+	assert.Contains(t, actionExamples, "list")
+	assert.Contains(t, actionExamples, "statistics")
+
+	// Verify corpus property details
+	corpus, ok := properties["corpus"].(map[string]interface{})
+	assert.True(t, ok)
+	assert.Equal(t, "string", corpus["type"])
+	assert.Contains(t, corpus["description"], "Virtual corpus query")
+	assert.Contains(t, corpus["examples"], "corpusSigle = \"GOE\"")
+
 	// Verify required fields
 	required, ok := schema["required"].([]string)
 	assert.True(t, ok)
 	assert.Contains(t, required, "action")
+	assert.Len(t, required, 1) // Only action should be required
 }
 
 func TestNewMetadataTool(t *testing.T) {
@@ -284,3 +302,126 @@
 	assert.Contains(t, result, "Documents: 100")
 	assert.Contains(t, result, "Tokens: 50000")
 }
+
+func TestMetadataTool_SchemaCompliance(t *testing.T) {
+	// Test various parameter combinations against the schema
+	client := &service.Client{}
+	tool := NewMetadataTool(client)
+
+	tests := []struct {
+		name        string
+		arguments   map[string]interface{}
+		expectValid bool
+		errorMsg    string
+	}{
+		{
+			name: "valid_list_minimal",
+			arguments: map[string]interface{}{
+				"action": "list",
+			},
+			expectValid: true,
+		},
+		{
+			name: "valid_statistics_minimal",
+			arguments: map[string]interface{}{
+				"action": "statistics",
+			},
+			expectValid: true,
+		},
+		{
+			name: "valid_statistics_with_corpus",
+			arguments: map[string]interface{}{
+				"action": "statistics",
+				"corpus": "test-corpus",
+			},
+			expectValid: true,
+		},
+		{
+			name: "valid_list_with_corpus_ignored",
+			arguments: map[string]interface{}{
+				"action": "list",
+				"corpus": "test-corpus", // Should be ignored for list action
+			},
+			expectValid: true,
+		},
+		{
+			name: "missing_required_action",
+			arguments: map[string]interface{}{
+				"corpus": "test-corpus",
+			},
+			expectValid: false,
+			errorMsg:    "action parameter is required",
+		},
+		{
+			name: "invalid_action",
+			arguments: map[string]interface{}{
+				"action": "invalid",
+			},
+			expectValid: false,
+			errorMsg:    "invalid action",
+		},
+		{
+			name: "empty_action",
+			arguments: map[string]interface{}{
+				"action": "",
+			},
+			expectValid: false,
+			errorMsg:    "action is required and cannot be empty",
+		},
+		{
+			name: "invalid_corpus_format",
+			arguments: map[string]interface{}{
+				"action": "statistics",
+				"corpus": "invalid@corpus#format",
+			},
+			expectValid: false,
+			errorMsg:    "collection query contains invalid characters",
+		},
+		{
+			name: "valid_corpus_with_boolean",
+			arguments: map[string]interface{}{
+				"action": "statistics",
+				"corpus": "corpus1 & corpus2",
+			},
+			expectValid: true,
+		},
+		{
+			name: "valid_collection_query",
+			arguments: map[string]interface{}{
+				"action": "statistics",
+				"corpus": "textClass = \"politics\" & pubDate in 2020",
+			},
+			expectValid: true,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			request := mcp.CallToolRequest{
+				Params: mcp.CallToolParams{
+					Arguments: tt.arguments,
+				},
+			}
+
+			_, err := tool.Execute(context.Background(), request)
+
+			if tt.expectValid {
+				// For valid requests, we expect authentication/client errors, not validation errors
+				if err != nil {
+					assert.NotContains(t, err.Error(), "validation")
+					// Should fail at authentication or client configuration
+					assert.True(t,
+						strings.Contains(err.Error(), "authentication") ||
+							strings.Contains(err.Error(), "KorAP client not configured"),
+						"Expected authentication or client error, got: %s", err.Error())
+				}
+			} else {
+				// For invalid requests, we expect validation errors
+				assert.Error(t, err)
+				if tt.errorMsg != "" {
+					assert.Contains(t, err.Error(), tt.errorMsg)
+				}
+			}
+		})
+	}
+}