{
  "markdown": "# Rigol DHO824 MCP Server\n\n[![PyPI version](https://img.shields.io/pypi/v/rigol-dho824-mcp.svg)](https://pypi.org/project/rigol-dho824-mcp/)\n[![GHCR](https://ghcr-badge.yuchanns.xyz/aimoda/rigol-dho824-mcp/tags?n=4&label=ghcr)](https://github.com/aimoda/rigol-dho824-mcp/pkgs/container/rigol-dho824-mcp)\n\nAn MCP (Model Context Protocol) server for controlling and querying the Rigol DHO824 oscilloscope.\n\n![Demo of oscilloscope in action](https://raw.githubusercontent.com/aimoda/rigol-dho824-mcp/main/demo.webp)\n\nBuilt by [ai.moda](https://www.ai.moda/en/?utm_campaign=rigol-dho824-mcp).\n\n## Hardware Requirements\n\n### Supported Models\n\nThis project **only supports DHO804/DHO824** oscilloscopes (identical hardware). We recommend purchasing a **DHO804**.\n\n### Firmware Requirements\n\n**IMPORTANT:** The DHO804 must be flashed to DHO824 firmware before using this MCP server. Use the [rigol_vendor_bin](https://github.com/zelea2/rigol_vendor_bin) project to flash your oscilloscope.\n\n**Supported Firmware Version:** 00.01.04\n\nThis is the only firmware version we test and support. Other firmware versions may work but are not guaranteed.\n\n### Compatibility Note\n\nOther Rigol oscilloscope models may work with this MCP server, but we have no way to test them or guarantee functionality. Use with other models at your own risk.\n\n## Installation\n\nThe recommended way to use this MCP server is via Docker, which eliminates dependency management and provides isolation.\n\n### Quick Start\n\nPull the pre-built image from GitHub Container Registry:\n\n```bash\ndocker pull ghcr.io/aimoda/rigol-dho824-mcp:latest\n```\n\n### Using Environment Variables with Docker\n\n**IMPORTANT:** You must provide the `RIGOL_RESOURCE` environment variable with your oscilloscope's IP address (e.g., `TCPIP0::192.168.1.100::inst0::INSTR`).\n\nYou can configure the Docker container with environment variables in two ways:\n\n1. **Hardcoded values** (shown in examples below): `-e RIGOL_RESOURCE=\"TCPIP0::192.168.1.100::inst0::INSTR\"`\n2. **Pass-through from host** (recommended): `-e RIGOL_RESOURCE` (without `=value`)\n\nWhen you use `-e VARIABLE_NAME` without a value, Docker automatically passes through the variable from your host environment. This is useful if you have environment variables already set in your shell (e.g., in `~/.bashrc` or `~/.zshrc`).\n\n### Environment Variables\n\n- `RIGOL_RESOURCE`: **Required** - VISA resource string for connecting to the oscilloscope (e.g., `TCPIP0::192.168.1.100::inst0::INSTR`)\n- `RIGOL_TEMP_DIR`: **Required for Docker** - Host-side path for returned file paths. The container always writes to `/tmp/rigol` internally and translates paths to this value in responses. Must match the host path in your `-v` mount. Outside Docker, this sets the directory for temporary files (waveforms, screenshots); if not set, uses system default temp directory.\n- `VISA_TIMEOUT`: Communication timeout in milliseconds (default: 30000)\n- `RIGOL_BEEPER_ENABLED`: Enable/disable oscilloscope beeper sounds (default: false)\n- `RIGOL_AUTO_SCREENSHOT`: Automatically capture screenshot after each MCP tool execution for visualization/debugging (default: false). Screenshots are saved with human-readable timestamp format (e.g., `auto_screenshot_20251030_143045_123.png`) for chronological sorting.\n\n## MCP Client Configuration\n\n<details>\n  <summary>Claude Code</summary>\n\n**Option 1: Using `.mcp.json` file**\n\nCreate a `.mcp.json` file in your project directory (or copy from `.mcp.json.example`):\n\n```json\n{\n  \"mcpServers\": {\n    \"rigol-dho824\": {\n      \"type\": \"stdio\",\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\",\n        \"-i\",\n        \"--rm\",\n        \"-v\",\n        \"/tmp/rigol-data:/tmp/rigol\",\n        \"-e\",\n        \"RIGOL_RESOURCE\",\n        \"-e\",\n        \"VISA_TIMEOUT\",\n        \"-e\",\n        \"RIGOL_BEEPER_ENABLED\",\n        \"-e\",\n        \"RIGOL_AUTO_SCREENSHOT\",\n        \"-e\",\n        \"RIGOL_TEMP_DIR\",\n        \"ghcr.io/aimoda/rigol-dho824-mcp:latest\"\n      ],\n      \"env\": {\n        \"RIGOL_RESOURCE\": \"TCPIP0::192.168.1.100::inst0::INSTR\",\n        \"VISA_TIMEOUT\": \"30000\",\n        \"RIGOL_BEEPER_ENABLED\": \"false\",\n        \"RIGOL_AUTO_SCREENSHOT\": \"false\",\n        \"RIGOL_TEMP_DIR\": \"/tmp/rigol-data\"\n      }\n    }\n  }\n}\n```\n\n**Option 2: Using CLI**\n\n```bash\nclaude mcp add --scope local rigol-dho824 -- \\\n  docker run -i --rm \\\n  -v /tmp/rigol-data:/tmp/rigol \\\n  -e RIGOL_RESOURCE=\"TCPIP0::192.168.1.100::inst0::INSTR\" \\\n  -e VISA_TIMEOUT=30000 \\\n  -e RIGOL_BEEPER_ENABLED=false \\\n  -e RIGOL_AUTO_SCREENSHOT=false \\\n  -e RIGOL_TEMP_DIR=/tmp/rigol-data \\\n  ghcr.io/aimoda/rigol-dho824-mcp:latest\n```\n\nReplace `192.168.1.100` with your oscilloscope's IP address.\n\n</details>\n\n<details>\n  <summary>Codex</summary>\n\n```bash\ncodex mcp add rigol-dho824 -- \\\n  docker run -i --rm \\\n  -v /tmp/rigol-data:/tmp/rigol \\\n  -e RIGOL_RESOURCE=\"TCPIP0::192.168.1.100::inst0::INSTR\" \\\n  -e VISA_TIMEOUT=30000 \\\n  -e RIGOL_BEEPER_ENABLED=false \\\n  -e RIGOL_AUTO_SCREENSHOT=false \\\n  -e RIGOL_TEMP_DIR=/tmp/rigol-data \\\n  ghcr.io/aimoda/rigol-dho824-mcp:latest\n```\n\nReplace `192.168.1.100` with your oscilloscope's IP address.\n\n</details>\n\n**Note:** After adding the server to your MCP client, restart the client to load the MCP server. The server will translate container paths (`/tmp/rigol/*`) to host paths (`/tmp/rigol-data/*`) in all returned file paths.\n\n### Your first prompt\n\nEnter the following prompt in your MCP Client to verify your setup:\n\n```\nCapture a waveform from channel 1 of my oscilloscope\n```\n\nYour MCP client should connect to the oscilloscope and capture the waveform data.\n\n### Accessing Temp Files in Docker\n\nThe container writes temporary files (waveform captures, screenshots) to `/tmp/rigol` internally. To access these files from your host machine:\n\n1. **Create a directory on your host** for storing temporary files:\n   ```bash\n   mkdir -p /tmp/rigol-data\n   ```\n\n2. **Mount this directory as a volume** and **set `RIGOL_TEMP_DIR`** in your Docker configuration:\n   ```bash\n   docker run -i --rm \\\n     -v /tmp/rigol-data:/tmp/rigol \\\n     -e RIGOL_TEMP_DIR=/tmp/rigol-data \\\n     ...\n   ```\n\nThe server automatically translates all returned file paths from the container path (`/tmp/rigol/*`) to the host path (`/tmp/rigol-data/*`), so you can directly access files at the paths shown in tool responses.\n\n**Important notes:**\n- The host directory (`/tmp/rigol-data` in examples) must exist before starting the server\n- `RIGOL_TEMP_DIR` must match the host-side path in your `-v` mount\n- Temporary files are **not automatically cleaned up**\n- You are responsible for manually cleaning up old waveform and screenshot files\n- Files will be organized in subdirectories like `waveform_capture_<timestamp>/` for waveforms and `screenshot_<timestamp>.png` for screenshots\n\n**Example: Manual cleanup**\n```bash\n# Remove waveform captures older than 7 days\nfind /tmp/rigol-data -type d -name \"waveform_capture_*\" -mtime +7 -exec rm -rf {} \\;\n\n# Remove screenshots older than 7 days\nfind /tmp/rigol-data -type f -name \"screenshot_*.png\" -mtime +7 -delete\n```\n\n### Troubleshooting\n\n#### Container exits immediately\n- Ensure you're using the `-i` flag (interactive mode)\n- Verify `RIGOL_RESOURCE` is set correctly\n\n#### Cannot connect to oscilloscope\n- Verify oscilloscope IP address and network connectivity (`ping <ip-address>`)\n- Check oscilloscope's remote control settings are enabled\n\n#### Environment variables not working\n- Ensure you're using `-e VARIABLE_NAME` in the Docker args array\n- Set the actual values in the `env` field of `.mcp.json`\n\n### Building Locally\n\nTo build the Docker image yourself:\n\n```bash\ndocker build -t rigol-dho824-mcp:local .\n```\n\nThen use `rigol-dho824-mcp:local` as the image name in your configuration.\n\n## Development Setup\n\nFor local development and contributions, you can install the MCP server in a Python virtual environment.\n\n### Create and activate virtual environment\n```bash\npython3 -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n```\n\n### Install the package\n```bash\n# Install in editable mode for development\npip install -e .\n\n# Or just install dependencies\npip install -r requirements.txt\n```\n\n### Add to MCP Client\n\nAfter completing the setup steps above, add the local development MCP server to your MCP client:\n\n**Claude Code:**\n```bash\nclaude mcp add --scope local rigol-dho824 -- <path-to-this-repo>/venv/bin/rigol-dho824-mcp\n```\n\n**Codex CLI:**\n```bash\ncodex mcp add \\\n  --env RIGOL_RESOURCE=\"TCPIP0::192.168.1.100::inst0::INSTR\" \\\n  --env VISA_TIMEOUT=\"30000\" \\\n  --env RIGOL_BEEPER_ENABLED=\"false\" \\\n  --env RIGOL_AUTO_SCREENSHOT=\"false\" \\\n  rigol-dho824 -- <path-to-this-repo>/venv/bin/rigol-dho824-mcp\n```\n\nReplace:\n- `<path-to-this-repo>` with the actual path to this repository\n- `192.168.1.100` with your oscilloscope's IP address\n\n**Note:** Unlike Claude Code, Codex requires explicit environment variables via `--env` flags (before the server name) as it runs MCP servers in a sanitized environment.\n\n### Development Scripts\n\nThe `scripts/` directory contains utilities for development:\n- `convert_png_to_webp.sh` - Convert PNG frame sequences to animated WebP (e.g., `./scripts/convert_png_to_webp.sh \"~/screenshots/*.png\" output.webp`)\n\n## Development Configuration\n\nThe server can be configured using environment variables. Create a `.env` file from the example:\n\n```bash\ncp .env.example .env\n```\n\nThen edit `.env` to set your configuration:\n\n- `RIGOL_RESOURCE`: VISA resource string for the oscilloscope (required)\n  - Example: `TCPIP0::192.168.1.100::inst0::INSTR`\n- `VISA_TIMEOUT`: Communication timeout in milliseconds (default: 5000)\n\n## Running the Server (Development)\n\nFor local development and testing, you can run the server directly with Python:\n\n### STDIO Transport\n```bash\n# Set resource string via environment variable\nexport RIGOL_RESOURCE=\"TCPIP0::192.168.1.100::inst0::INSTR\"\npython -m rigol_dho824_mcp.server\n```\n\n### HTTP Transport\n```bash\n# Default HTTP server (http://127.0.0.1:8000/mcp)\npython -m rigol_dho824_mcp.server --http\n\n# Custom host and port\npython -m rigol_dho824_mcp.server --http --host 0.0.0.0 --port 3000\n\n# Custom path\npython -m rigol_dho824_mcp.server --http --path /api/mcp\n```\n\n<!-- mcp-name: io.github.aimoda/rigol-dho824-mcp -->\n",
  "bytes": 10278,
  "sha": "38d4eb1592230e2303983a29e80367c65608853b81aada5c5f1783af45935a7d",
  "repo_slug": "aimoda/rigol-dho824-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_aimoda_rigol_dho824_mcp_c1c8ac80/readme"
}