Skip to main content
Glama
taskhub-sh

Terminal Control MCP

by taskhub-sh

terminal_capture

Capture terminal screen output as a base64-encoded PNG image. Input the session ID to generate visual terminal snapshots for analysis or integration into AI workflows.

Instructions

Capture terminal screen as PNG screenshot

Args: session_id: ID of the terminal session

Returns: Dictionary with base64-encoded PNG image and metadata

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
session_idYes

Implementation Reference

  • The FastMCP tool handler for terminal_capture. Retrieves the XTermSession by ID and delegates to its capture_screenshot method, returning base64 PNG image data with metadata.
    @mcp.tool() async def terminal_capture(session_id: str) -> Dict[str, Any]: """Capture terminal screen as PNG screenshot Args: session_id: ID of the terminal session Returns: Dictionary with base64-encoded PNG image and metadata """ if session_id not in sessions: return {"status": "error", "error": f"Session {session_id} not found"} session = sessions[session_id] try: screenshot_data = await session.capture_screenshot() logger.info(f"Captured screenshot for session {session_id}") return { "session_id": session_id, "status": "captured", "image_data": screenshot_data["image_data"], "metadata": screenshot_data["metadata"], } except Exception as e: logger.error( f"Failed to capture screenshot for session {session_id}: {e}" ) return {"status": "error", "error": str(e)}
  • Core implementation of screenshot capture in XTermSession class. Uses ImageMagick 'import -window root' on the virtual Xvfb display, encodes PNG to base64, includes metadata, and handles temp files.
    async def capture_screenshot(self) -> Dict[str, Any]: """Capture terminal screen as PNG screenshot and return base64 data""" env = os.environ.copy() env["DISPLAY"] = self.display # Create temporary file for screenshot if not self.temp_dir: self.temp_dir = tempfile.mkdtemp(prefix=f"terminal_mcp_{self.session_id}_") screenshot_path = Path(self.temp_dir) / f"screenshot_{int(time.time())}.png" logger.debug(f"Taking screenshot: {screenshot_path}") try: # Take screenshot using ImageMagick import proc = await asyncio.create_subprocess_exec( "import", "-window", "root", str(screenshot_path), env=env, stdout=asyncio.subprocess.DEVNULL, stderr=asyncio.subprocess.PIPE, ) _, stderr = await proc.communicate() if proc.returncode != 0: error_msg = stderr.decode() if stderr else "Unknown error" raise RuntimeError(f"Screenshot capture failed: {error_msg}") if not screenshot_path.exists(): raise RuntimeError("Screenshot file was not created") # Read and encode the image with open(screenshot_path, "rb") as f: image_data = base64.b64encode(f.read()).decode("utf-8") # Get file metadata file_stats = screenshot_path.stat() metadata = { "timestamp": int(time.time()), "file_size": file_stats.st_size, "display_size": f"{self.display_width}x{self.display_height}", "terminal_size": f"{self.terminal_width}x{self.terminal_height}", "session_id": self.session_id, } # Clean up the temporary file screenshot_path.unlink() return {"image_data": image_data, "metadata": metadata} except Exception as e: logger.error(f"Failed to capture screenshot: {e}") # Clean up partial file if it exists if screenshot_path.exists(): screenshot_path.unlink() raise

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/taskhub-sh/terminal-driver-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server