Metadata-Version: 2.4
Name: multitool-mcp
Version: 0.2.0
Summary: MCP server for debugging devices under test through WE Multitool
Author: Wise Electronics
License-Expression: GPL-3.0-or-later
Project-URL: Homepage, https://github.com/we-devices/multitool-mcp
Project-URL: Repository, https://github.com/we-devices/multitool-mcp.git
Project-URL: Issues, https://github.com/we-devices/multitool-mcp/issues
Keywords: mcp,embedded,hardware,debugging,we-multitool
Classifier: Development Status :: 3 - Alpha
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development :: Debuggers
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Dynamic: license-file

# WE Multitool DUT MCP

`multitool-mcp` is a dependency-free [Model Context Protocol](https://modelcontextprotocol.io/) server for inspecting and debugging a device under test (DUT) through a Wise Electronics WE Multitool.

It runs over standard input/output and bridges the Multitool's JSON-over-WebSocket API. It exposes bounded MCP tools for GPIO, I2C, SPI, UART, PWM, GPIO ownership, SWD debugging, and SWO trace. SWD/SWO tools manage a host OpenOCD process connected to the Multitool CMSIS-DAP TCP probe.

## Requirements

- Python 3.11 or later
- A WE Multitool reachable over WebSocket

## Install

Install from PyPI once published:

```shell
python -m pip install multitool-mcp
```

For development from a clone:

```shell
python -m pip install -e .
```

## Configure an MCP client

Run the installed command:

```toml
[mcp_servers.we_multitool_dut]
command = "multitool-mcp"
env_vars = ["WE_MULTITOOL_URL", "WE_MULTITOOL_TIMEOUT_SECONDS"]
startup_timeout_sec = 10
tool_timeout_sec = 150
default_tools_approval_mode = "prompt"
```

By default, the server connects to `ws://we-multitool.local/ws`. Set these environment variables before starting the MCP client to change that:

```shell
WE_MULTITOOL_URL=ws://10.0.0.1/ws
WE_MULTITOOL_TIMEOUT_SECONDS=8
```

On PowerShell:

```powershell
$env:WE_MULTITOOL_URL = "ws://10.0.0.1/ws"
$env:WE_MULTITOOL_TIMEOUT_SECONDS = "8"
```

## Safety and firmware behavior

Read `pins_get` before configuring pins, and verify wiring, voltage, bus role, and DUT limits before driving signals.

`gpio_configure` accepts `input`, `output`, and `open-drain` directions. Open-drain mode requires firmware with `open-drain` GPIO setup support and an appropriate external pull-up.

- Commands are serialized because firmware responses do not carry request IDs.
- UART data received while another command awaits a response is buffered.
- The `gpio_set` firmware command has no acknowledgement; `gpio_write` reports it as dispatched but unverified.
- The firmware tracks one active WebSocket response socket. Do not use the browser UI and MCP bridge concurrently.

## SWD and SWO

Version 0.2.0 adds these tools:

| Tools | Purpose |
| --- | --- |
| `swd_status`, `swd_enable`, `swd_disable` | Configure the probe and reserve/release its pins |
| `swd_session_start`, `swd_session_status`, `swd_session_stop` | Manage one owned host OpenOCD process and inspect logs |
| `swd_control`, `swd_set_speed` | Halt/resume, instruction-step, reset/halt, and request clock speed |
| `swd_read_memory`, `swd_write_memory`, `swd_flash` | Bounded memory access and ELF program/verify/reset |
| `swo_start`, `swo_read`, `swo_stop` | Capture UART/NRZ SWO and decode software ITM ports |

Install an OpenOCD build with the **CMSIS-DAP TCP backend**. The Espressif build used here supports it; some stock 0.12.0 builds do not. Python still requires no runtime packages. Provide trusted local OpenOCD configuration files that select CMSIS-DAP TCP port 4441, read the host from `WE_MULTITOOL_HOST`, and configure the target. The server sets this environment variable from its WebSocket URL. Target flash algorithms and SWO pin routing belong in these files.

OpenOCD GDB/Tcl/trace ports bind to localhost (defaults 3333/6666/3443). Only one OpenOCD client can connect to the probe: stop a VSCode debug session before starting an MCP session. MCP client shutdown stops its owned process and normally resumes a halted DUT. Stopping a session keeps probe pins reserved; `swd_disable` releases them to inputs. Use direct wiring only with 3.3 V compatible targets and a shared ground.

### Hardware verification

MCP tools were tested on the connected Nucleo L452: probe enable/disable/status, OpenOCD startup/cleanup, halt/resume/reset, single-step in `debug_init`, and two matching 64-byte Flash reads at requested 4 MHz. SWO at 100 kbaud with an 80 MHz trace clock returned 184 raw bytes / 92 ITM port-0 bytes, including the startup banner, with zero reported overflow packets or decoder errors. This MCP smoke test did not reflash the target.

Single-step waits for the target to halt again. Stepping a sleeping RTOS idle instruction can time out; the tool reports an error instead of reporting successful completion while the target is still running.

SWO reads return raw `base64`/`hex`, decoded `itm_ports` with text and payload bytes, overflow counts, and decoder errors. Decoding persists across reads, including split packets and UTF-8 sequences. Hardware event and timestamp packets are not interpreted as text. A quiet read can return zero bytes. No lossless throughput is promised; overflow counts describe ITM overflow packets, not every possible capture loss.

Memory writes and flashing are marked destructive. Flashing verifies an existing ELF and resets the target; it does not automatically remove protection. Set the MCP client tool timeout to at least 150 seconds for flash operations. Requested SWD speed is not a measurement of the physical clock. Prior direct OpenOCD tests on this L452 passed repeated reads at requested 4 MHz; retest your wiring before using a higher speed.

After installing the updated server, restart the MCP client to discover the new tools. To use this checkout on Windows, set its MCP `command` to `D:/_projects/wise-electronics/multitool-mcp/.venv/Scripts/multitool-mcp.exe` after installing with `.venv/Scripts/python.exe -m pip install -e .`.

## Development

```shell
python -m pip install -e ".[test]"
python -m pytest
```

The runtime has no third-party dependencies. The optional `test` extra installs pytest.

## License

Licensed under the GNU General Public License, version 3 or later
(GPL-3.0-or-later). See [LICENSE](LICENSE).
