bump
This commit is contained in:
863
mcp/main.go
863
mcp/main.go
@@ -2440,6 +2440,869 @@ func main() {
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Drag and drop tools
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_drag_and_drop_cremotemcp",
|
||||
Description: "Perform drag and drop operation from source element to target element",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"source": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the source element to drag",
|
||||
},
|
||||
"target": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the target element to drop on",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"source", "target"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
// Convert arguments to map
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
source := getStringParam(params, "source", "")
|
||||
target := getStringParam(params, "target", "")
|
||||
tab := getStringParam(params, "tab", "")
|
||||
timeout := getIntParam(params, "timeout", 5)
|
||||
|
||||
if source == "" {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent("Error: source parameter is required"),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if target == "" {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent("Error: target parameter is required"),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
err := cremoteServer.client.DragAndDrop(tab, source, target, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Error performing drag and drop: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Drag and drop completed successfully from %s to %s", source, target)),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_drag_and_drop_coordinates_cremotemcp",
|
||||
Description: "Perform drag and drop operation from source element to specific coordinates",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"source": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the source element to drag",
|
||||
},
|
||||
"x": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Target X coordinate",
|
||||
},
|
||||
"y": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Target Y coordinate",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"source", "x", "y"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
// Convert arguments to map
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
source := getStringParam(params, "source", "")
|
||||
x := getIntParam(params, "x", 0)
|
||||
y := getIntParam(params, "y", 0)
|
||||
tab := getStringParam(params, "tab", "")
|
||||
timeout := getIntParam(params, "timeout", 5)
|
||||
|
||||
if source == "" {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent("Error: source parameter is required"),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
err := cremoteServer.client.DragAndDropToCoordinates(tab, source, x, y, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Error performing drag and drop to coordinates: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Drag and drop to coordinates (%d, %d) completed successfully from %s", x, y, source)),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_drag_and_drop_offset_cremotemcp",
|
||||
Description: "Perform drag and drop operation from source element by relative offset",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"source": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the source element to drag",
|
||||
},
|
||||
"offset_x": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Horizontal offset in pixels",
|
||||
},
|
||||
"offset_y": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Vertical offset in pixels",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"source", "offset_x", "offset_y"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
// Convert arguments to map
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
source := getStringParam(params, "source", "")
|
||||
offsetX := getIntParam(params, "offset_x", 0)
|
||||
offsetY := getIntParam(params, "offset_y", 0)
|
||||
tab := getStringParam(params, "tab", "")
|
||||
timeout := getIntParam(params, "timeout", 5)
|
||||
|
||||
if source == "" {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent("Error: source parameter is required"),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
err := cremoteServer.client.DragAndDropByOffset(tab, source, offsetX, offsetY, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Error performing drag and drop by offset: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Drag and drop by offset (%d, %d) completed successfully from %s", offsetX, offsetY, source)),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_right_click tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_right_click_cremotemcp",
|
||||
Description: "Right-click on an element",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"selector": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the element to right-click",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"selector"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
selector, ok := params["selector"].(string)
|
||||
if !ok || selector == "" {
|
||||
return nil, fmt.Errorf("selector is required")
|
||||
}
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.RightClick(tab, selector, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to right-click: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent("Right-click completed successfully"),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_double_click tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_double_click_cremotemcp",
|
||||
Description: "Double-click on an element",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"selector": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the element to double-click",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"selector"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
selector, ok := params["selector"].(string)
|
||||
if !ok || selector == "" {
|
||||
return nil, fmt.Errorf("selector is required")
|
||||
}
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.DoubleClick(tab, selector, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to double-click: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent("Double-click completed successfully"),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_hover tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_hover_cremotemcp",
|
||||
Description: "Hover over an element",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"selector": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the element to hover over",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"selector"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
selector, ok := params["selector"].(string)
|
||||
if !ok || selector == "" {
|
||||
return nil, fmt.Errorf("selector is required")
|
||||
}
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.Hover(tab, selector, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to hover: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent("Hover completed successfully"),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_middle_click tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_middle_click_cremotemcp",
|
||||
Description: "Middle-click on an element (typically opens links in new tabs)",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"selector": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the element to middle-click",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"selector"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
selector, ok := params["selector"].(string)
|
||||
if !ok || selector == "" {
|
||||
return nil, fmt.Errorf("selector is required")
|
||||
}
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.MiddleClick(tab, selector, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to middle-click: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent("Middle-click completed successfully"),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_mouse_move tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_mouse_move_cremotemcp",
|
||||
Description: "Move mouse to specific coordinates without clicking",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"x": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "X coordinate to move mouse to",
|
||||
},
|
||||
"y": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Y coordinate to move mouse to",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"x", "y"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
xFloat, ok := params["x"].(float64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("x coordinate is required")
|
||||
}
|
||||
x := int(xFloat)
|
||||
|
||||
yFloat, ok := params["y"].(float64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("y coordinate is required")
|
||||
}
|
||||
y := int(yFloat)
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.MouseMove(tab, x, y, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to move mouse: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Mouse moved to coordinates (%d, %d) successfully", x, y)),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_scroll_wheel tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_scroll_wheel_cremotemcp",
|
||||
Description: "Scroll with mouse wheel at specific coordinates",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"x": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "X coordinate for scroll wheel",
|
||||
},
|
||||
"y": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Y coordinate for scroll wheel",
|
||||
},
|
||||
"delta_x": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Horizontal scroll delta (negative = left, positive = right)",
|
||||
"default": 0,
|
||||
},
|
||||
"delta_y": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Vertical scroll delta (negative = up, positive = down)",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"x", "y", "delta_y"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
xFloat, ok := params["x"].(float64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("x coordinate is required")
|
||||
}
|
||||
x := int(xFloat)
|
||||
|
||||
yFloat, ok := params["y"].(float64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("y coordinate is required")
|
||||
}
|
||||
y := int(yFloat)
|
||||
|
||||
deltaXFloat := float64(0)
|
||||
if deltaXParam, exists := params["delta_x"]; exists {
|
||||
if deltaXVal, ok := deltaXParam.(float64); ok {
|
||||
deltaXFloat = deltaXVal
|
||||
}
|
||||
}
|
||||
deltaX := int(deltaXFloat)
|
||||
|
||||
deltaYFloat, ok := params["delta_y"].(float64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("delta_y is required")
|
||||
}
|
||||
deltaY := int(deltaYFloat)
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.ScrollWheel(tab, x, y, deltaX, deltaY, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to scroll with mouse wheel: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Mouse wheel scroll at (%d, %d) with delta (%d, %d) completed successfully", x, y, deltaX, deltaY)),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_key_combination tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_key_combination_cremotemcp",
|
||||
Description: "Send key combinations like Ctrl+C, Alt+Tab, Shift+Enter, etc.",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"keys": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Key combination to send (e.g., 'Ctrl+C', 'Alt+Tab', 'Shift+Enter', 'Ctrl+Shift+T')",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"keys"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
keys, ok := params["keys"].(string)
|
||||
if !ok || keys == "" {
|
||||
return nil, fmt.Errorf("keys parameter is required")
|
||||
}
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.KeyCombination(tab, keys, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to send key combination: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Key combination '%s' sent successfully", keys)),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_special_key tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_special_key_cremotemcp",
|
||||
Description: "Send special keys like Enter, Escape, Tab, F1-F12, Arrow keys, etc.",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"key": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Special key to send (e.g., 'Enter', 'Escape', 'Tab', 'F1', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'PageUp', 'PageDown', 'Delete', 'Backspace')",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"key"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
key, ok := params["key"].(string)
|
||||
if !ok || key == "" {
|
||||
return nil, fmt.Errorf("key parameter is required")
|
||||
}
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.SpecialKey(tab, key, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to send special key: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Special key '%s' sent successfully", key)),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Register web_modifier_click tool
|
||||
mcpServer.AddTool(mcp.Tool{
|
||||
Name: "web_modifier_click_cremotemcp",
|
||||
Description: "Click on an element with modifier keys (Ctrl+click, Shift+click, Alt+click, etc.)",
|
||||
InputSchema: mcp.ToolInputSchema{
|
||||
Type: "object",
|
||||
Properties: map[string]any{
|
||||
"selector": map[string]any{
|
||||
"type": "string",
|
||||
"description": "CSS selector for the element to click",
|
||||
},
|
||||
"modifiers": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Modifier keys to hold while clicking (e.g., 'Ctrl', 'Shift', 'Alt', 'Ctrl+Shift', 'Ctrl+Alt')",
|
||||
},
|
||||
"tab": map[string]any{
|
||||
"type": "string",
|
||||
"description": "Tab ID (optional, uses current tab)",
|
||||
},
|
||||
"timeout": map[string]any{
|
||||
"type": "integer",
|
||||
"description": "Timeout in seconds (default: 5)",
|
||||
"default": 5,
|
||||
},
|
||||
},
|
||||
Required: []string{"selector", "modifiers"},
|
||||
},
|
||||
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
params, ok := request.Params.Arguments.(map[string]any)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid arguments format")
|
||||
}
|
||||
|
||||
selector, ok := params["selector"].(string)
|
||||
if !ok || selector == "" {
|
||||
return nil, fmt.Errorf("selector is required")
|
||||
}
|
||||
|
||||
modifiers, ok := params["modifiers"].(string)
|
||||
if !ok || modifiers == "" {
|
||||
return nil, fmt.Errorf("modifiers parameter is required")
|
||||
}
|
||||
|
||||
tab := ""
|
||||
if tabParam, exists := params["tab"]; exists {
|
||||
if tabStr, ok := tabParam.(string); ok {
|
||||
tab = tabStr
|
||||
}
|
||||
}
|
||||
|
||||
timeout := 5
|
||||
if timeoutParam, exists := params["timeout"]; exists {
|
||||
if timeoutFloat, ok := timeoutParam.(float64); ok {
|
||||
timeout = int(timeoutFloat)
|
||||
}
|
||||
}
|
||||
|
||||
err := cremoteServer.client.ModifierClick(tab, selector, modifiers, timeout)
|
||||
if err != nil {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Failed to perform modifier click: %v", err)),
|
||||
},
|
||||
IsError: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
mcp.NewTextContent(fmt.Sprintf("Modifier click with '%s' on %s completed successfully", modifiers, selector)),
|
||||
},
|
||||
IsError: false,
|
||||
}, nil
|
||||
})
|
||||
|
||||
// Start the server
|
||||
log.Printf("Cremote MCP server ready")
|
||||
if err := server.ServeStdio(mcpServer); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user