control_tools.py•5.04 kB
import logging
from typing import Optional
from . import mcp
@mcp.tool()
async def type_text(text: str, interval: float = 0.0) -> str:
"""
Simulate typing the given text using the keyboard.
Args:
text: The text to type.
interval: Delay between each character (in seconds, default 0.0).
Returns:
Success or error message.
"""
try:
import pyautogui
except ImportError:
return "pyautogui is not installed. Please install it to use this tool."
try:
pyautogui.write(text, interval=interval)
logging.info("Typed text: %r", text)
return f"Typed text: {text!r}"
except Exception as e:
logging.error("Error typing text: %s", e)
return f"Error typing text: {e}"
@mcp.tool()
async def press_hotkey(*keys: str) -> str:
"""
Press a combination of keys as a hotkey (e.g., ctrl, tab).
Args:
*keys: The keys to press in combination (e.g., "ctrl", "tab").
Returns:
Success or error message.
"""
try:
import pyautogui
except ImportError:
return "pyautogui is not installed. Please install it to use this tool."
try:
pyautogui.hotkey(*keys)
logging.info("Pressed hotkey: %s", " + ".join(keys))
return f"Pressed hotkey: {' + '.join(keys)}"
except Exception as e:
logging.error("Error pressing hotkey: %s", e)
return f"Error pressing hotkey: {e}"
@mcp.tool()
async def switch_to_window(window_title: str) -> str:
"""
Switch focus to a window with the specified title.
Args:
window_title: The (partial or full) title of the window to activate.
Returns:
Success or error message.
"""
try:
import pygetwindow as gw
except ImportError:
return "pygetwindow is not installed. Please install it to use this tool."
try:
windows = gw.getWindowsWithTitle(window_title)
if not windows:
return f"No window found with title containing: {window_title!r}"
win = windows[0]
win.activate()
logging.info("Switched to window: %s", win.title)
return f"Switched to window: {win.title}"
except Exception as e:
logging.error("Error switching window: %s", e)
return f"Error switching window: {e}"
@mcp.tool()
async def list_open_windows() -> str:
"""
List the titles of all currently open windows.
Returns:
A formatted list of window titles.
"""
try:
import pygetwindow as gw
except ImportError:
return "pygetwindow is not installed. Please install it to use this tool."
try:
windows = gw.getAllTitles()
windows = [w for w in windows if w.strip()]
if not windows:
return "No open windows found."
output = "Open Windows:\n" + "\n".join(f"- {w}" for w in windows)
logging.info("Listed %d open windows", len(windows))
return output
except Exception as e:
logging.error("Error listing open windows: %s", e)
return f"Error listing open windows: {e}"
@mcp.tool()
async def move_mouse_to(x: int, y: int, duration: float = 0.0) -> str:
"""
Move the mouse cursor to the specified screen coordinates.
Args:
x: X coordinate.
y: Y coordinate.
duration: Time in seconds for the movement (default 0.0 for instant).
Returns:
Success or error message.
"""
try:
import pyautogui
except ImportError:
return "pyautogui is not installed. Please install it to use this tool."
try:
pyautogui.moveTo(x, y, duration=duration)
logging.info("Moved mouse to (%d, %d)", x, y)
return f"Moved mouse to ({x}, {y})"
except Exception as e:
logging.error("Error moving mouse: %s", e)
return f"Error moving mouse: {e}"
@mcp.tool()
async def click_mouse(
x: Optional[int] = None, y: Optional[int] = None, button: str = "left"
) -> str:
"""
Click the mouse at the specified coordinates, or at the current position if not specified.
Args:
x: X coordinate (optional).
y: Y coordinate (optional).
button: Mouse button to click ("left", "right", "middle").
Returns:
Success or error message.
"""
try:
import pyautogui
except ImportError:
return "pyautogui is not installed. Please install it to use this tool."
try:
if x is not None and y is not None:
pyautogui.click(x, y, button=button)
logging.info("Clicked %s mouse button at (%d, %d)", button, x, y)
return f"Clicked {button} mouse button at ({x}, {y})"
else:
pyautogui.click(button=button)
logging.info("Clicked %s mouse button at current position", button)
return f"Clicked {button} mouse button at current position"
except Exception as e:
logging.error("Error clicking mouse: %s", e)
return f"Error clicking mouse: {e}"