esp32sim-mcp
Provides tools for booting, driving, and testing ESP32 firmware built with ESP-IDF in a local emulator, using official Espressif mask ROMs and supporting ESP32/S3/C3/C6 chips and related boards.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@esp32sim-mcpbuild and boot my ESP-IDF firmware, then assert the UART log contains 'Hello world'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
esp32sim-mcp
Your agent writes ESP32 firmware, boots it and tests it. No board, no account.
A real Claude Code session, recorded live (only the idle tail is trimmed): it edits ESP-IDF's hello_world, builds it in Docker because ESP-IDF isn't installed, and checks the console in the emulator.
Coding agents are good at writing embedded C. They are blind when it comes to running it: without a board on the desk, "it compiles" is where the feedback loop ends.
esp32sim-mcp closes that loop. It gives Claude Code, Codex, Cursor or any MCP client a set of tools that boot the firmware the agent just built inside esp32sim, a local instruction-level ESP32 emulator, and hand back what the chip printed, whether it crashed, and what was on the display. The agent reads the result, fixes the code and tries again, the way you would with a board on the bench.
π No hardware, no cloud. Everything runs on your machine. No account, no token, no board.
𧬠Real boot chain. Espressif's mask ROM, the ESP-IDF bootloader and your unmodified app, on ESP32-S3, C3, C6 and the classic ESP32.
π‘ More than a console. Virtual WiFi access point with DHCP, DNS and NAT, buttons, rotary encoder, GPIO, UART input, touch, and display screenshots.
π§ͺ Assertions, not vibes.
sim_expectreturns pass/fail and the exact line that is missing, so the agent knows what to fix.β‘ Fast. Emulation usually runs ahead of real time: on Apple silicon, 8 emulated seconds of a WiFi station joining a network take about 0.6 s.
π€ Comes with a skill.
initinstalls an agent skill that teaches the write β build β simulate β fix loop, including building in Docker when ESP-IDF is not installed.
Quickstart
npx -y esp32sim-mcp setup # emulator + mask ROMs, pinned and SHA-256 verified
cd your-esp-idf-project
npx -y esp32sim-mcp init # registers the MCP server and the skill for your agentsThen ask your agent for something you can see on the serial console:
Add a counter that prints once a second, build it, and check in the simulator that it reaches 5.
Requirements: Node.js 22+, and ESP-IDF or Docker to build firmware. Prebuilt emulator binaries cover macOS (Apple silicon) and Linux (x64, arm64); see other platforms.
Related MCP server: Chiplab
What the agent sees
From a real session, the agent calls:
{
"tool": "sim_expect",
"projectDir": ".",
"chip": "s3",
"board": "none",
"maxSeconds": 10,
"patterns": ["Hello world!", "Counter: 1", "Counter: 2", "Counter: 3", "Counter: 4", "Counter: 5"]
}and gets back:
### Expect Test: β
PASSED
Matched 6 / 6 patterns.
- β
Matched (line 54): `Hello world!`
- β
Matched (line 55): `Counter: 1`
...
- β
Matched (line 65): `Counter: 5`
#### Full UART Logs:
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0xf (SPI_FAST_FLASH_BOOT)
...When something goes wrong, it gets the panic instead (Guru Meditation Error, stack overflow, failed assert, heap corruption) with the log leading up to it, and the missing pattern spelled out.
Tools
Tool | What it does |
| Boots the firmware and returns the console log, stop reason, emulated time and any panic. |
| Runs the firmware and asserts that strings or regexes appear on the console, in order by default. |
| Drives the hardware at emulated timestamps: |
| Returns a PNG of the board's display at a given emulated time. |
| Lists chips, boards, displays and inputs. |
| Checks the emulator and ROMs and says how to fix what is missing. |
All tools take a projectDir (the ESP-IDF build is found through build/flasher_args.json) or explicit appBin/bootloaderBin/ptableBin paths, plus chip, board and wifi (e.g. ssid=demo,psk=secret). Both UART0 and the USB-Serial/JTAG console are captured, so output shows up whichever one the project logs to.
How it works
flowchart LR
A["Coding agent<br/>(Claude Code, Codex, Cursor)"] -- "edits code,<br/>runs idf.py build<br/>(local or Docker)" --> B["ESP-IDF build/"]
A -- "MCP: sim_expect, sim_run, ..." --> C["esp32sim-mcp"]
C -- "flasher_args.json" --> B
C -- "spawns" --> D["esp32sim emulator<br/>mask ROM β bootloader β app"]
D -- "UART / USB-JTAG, panics,<br/>display, virtual WiFi" --> C
C -- "pass/fail, logs, PNG" --> Aesp32sim-mcp is a thin, tested layer: it finds the build, translates tool calls into esp32sim's command line, separates and de-duplicates the two consoles, detects panics, and shapes the result for an agent. The emulation itself is esp32sim's work.
Use it in CI
The same checks run without an agent, with exit code 0 on pass and 1 on fail. A GitHub Actions job that builds your firmware and asserts its boot log:
jobs:
firmware:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 22
- name: Build
run: docker run --rm -v "$PWD:/project" -w /project espressif/idf:v5.5.4 idf.py set-target esp32s3 build
- name: Install the emulator
run: npx -y esp32sim-mcp setup
- name: Boot and check the console
run: npx -y esp32sim-mcp expect --max-seconds 10 --pattern "app_main" "Counter: 5"This is what this repository's own CI does with examples/hello-esp32, including a scripted button press.
esp32sim-mcp setup # install emulator + ROMs (or: install-emulator, fetch-roms)
esp32sim-mcp init [--global] [--agent claude-code|codex|cursor|claude-desktop] [--dry-run]
esp32sim-mcp run [-p dir] [--chip s3] [--board none] [--max-seconds 5] [--wifi ssid=x,psk=y]
esp32sim-mcp expect --pattern "a" "b" [--unordered] [--script actions.txt] [...run options]
esp32sim-mcp list [--chip c6]
esp32sim-mcp doctor
esp32sim-mcp serve # the MCP server (what agents launch)Supported chips and boards
Chip | Boards ( |
ESP32-S3 |
|
ESP32-C3 | console only (no board models) |
ESP32-C6 |
|
ESP32 (classic) |
|
Use none for stock ESP-IDF projects. The virtual WiFi access point works on all four chips.
Agent setup
init detects the agents you have and configures each one. It runs in your firmware project by default; --global writes user-level settings instead.
Agent | MCP server (project / | Skill (project / |
Claude Code |
|
|
Codex |
|
|
Cursor |
|
|
Claude Desktop |
| β |
Existing entries are kept, reruns are no-ops, and a config file that does not parse is left untouched.
Claude Code plugin. Instead of init, install the server and skill together as a plugin, for every project:
/plugin install esp32sim --marketplace stramanu/esp32sim-mcpMCP registry. The server is published to the official MCP registry as io.github.stramanu/esp32sim-mcp. For any other MCP client:
{
"mcpServers": {
"esp32sim": { "command": "npx", "args": ["-y", "esp32sim-mcp", "serve"] }
}
}Other platforms
setup installs prebuilt binaries on macOS arm64 and Linux x64/arm64. They are built from source by this repository's emulator workflow with signed build provenance (gh attestation verify <archive> -R stramanu/esp32sim-mcp). Elsewhere, build esp32sim with Cargo (rustup), pinned to the commit this release is tested against:
cargo install --locked --git https://github.com/mikroverk/esp32sim --rev f535f3b42293a76ab64c231a0425f35857ab6cf1 esp32sim
npx esp32sim-mcp fetch-romsESP32SIM_PATH points at an emulator binary elsewhere and ESP32SIM_ROM_DIR at another ROM directory; ROMs inside an ESP-IDF install are found automatically.
How it compares
Runs without a board | Needs an account or token | Built for agents | |
esp32sim-mcp | β local emulator | No | β MCP server + skill |
β | Yes ( | β οΈ experimental | |
esparagus (Espressif) | β flashes real hardware | No | β |
esp32sim on its own | β | No | β CLI and web UI |
esparagus is the natural next step: simulate first with esp32sim-mcp, then confirm on a real board.
Limitations
An emulator is not silicon. Peripherals esp32sim does not model, RF timing and Bluetooth are out of reach here; confirm on hardware before you ship.
The agent builds the firmware itself (
idf.py, locally or in Docker); the MCP server does not compile.Windows is untested.
Contributing
Issues and pull requests are welcome. See CONTRIBUTING.md for the development setup and how the end-to-end tests run against the real emulator, and CHANGELOG.md for what changed.
Credits
esp32sim by Joakim Eriksson, Alice and Mattia Fiumara: the emulator that does the real work (MIT).
Espressif: ESP-IDF and the mask ROM ELFs (Apache-2.0).
License
MIT Β© Emanuele Strazzullo
Available Tools
6 toolssim_doctorA
Validates local environment: checks if esp32sim binary is installed, checks Rust/Cargo, and provides setup instructions.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully signals that this is an informational diagnostic (checks + provides instructions, implying no mutation), but it never explicitly states that it is side-effect free or describes what the validation report looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with a colon-separated list of checks; every clause earns its place and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-argument diagnostic with no output schema and no annotations, the description conveys enough to call it correctly β what it inspects and that it emits setup guidance. Only the shape of the returned report is left unstated, a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and the schema confirms an empty object, so there is nothing for the description to disambiguate. Baseline 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Validates local environment') and enumerates exactly what it inspects: the esp32sim binary, Rust/Cargo, plus setup instructions. This clearly separates it from the simulation-execution siblings, though it never names those siblings for contrast.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance is given. With siblings sim_run/sim_script/sim_expect, the natural question β run this before simulating, or only after a failure? β is left entirely to inference, and no alternatives or prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_expectB
Runs firmware in simulation and asserts that specific text or regex patterns appear on UART. Ideal for automated unit & integration testing in a Red-Green-Refactor agent loop.
| Name | Required | Description | Default |
|---|---|---|---|
| chip | No | Target chip family. Default is s3 (ESP32-S3). | |
| wifi | No | Attach a virtual access point with DHCP/DNS/NAT. Spec like 'ssid=demo,psk=secret' (keys: ssid, psk, chan, bssid), or a bare SSID for an open network. Station gets 10.0.2.15. | |
| board | No | Board model: S3 'atech14' (default), 'waveshare-lcd4b', 'waveshare-amoled18-v2', 'waveshare-cam'; C6 'waveshare-c6-lcd147'; ESP32 'ttgo-tdisplay', 'esp32dev-loopback'; 'none' for a bare module. Omit on the C3, which has no boards. See sim_list_boards. | |
| appBin | No | Direct path to the application binary (.bin). | |
| events | No | Optional interaction events before checking patterns. | |
| ordered | No | Whether patterns must appear in exact chronological sequence (default: true). | |
| patterns | Yes | Expected console output. Plain text matches as a substring of a line ("Counter: 5"); write a regular expression between slashes ("/Counter: \\d+/", "/wifi.*connected/i"). | |
| ptableBin | No | Direct path to partition-table.bin (needed with appBin for a real ROM boot). | |
| maxSeconds | No | Max emulated seconds to wait for patterns (default 10). | |
| projectDir | No | Path to the ESP-IDF project root or build folder. If omitted, uses current working directory. | |
| bootloaderBin | No | Direct path to bootloader.bin (needed with appBin for a real ROM boot). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full behavioral disclosure burden. It says the tool runs firmware and asserts UART patterns, but it does not explain failure behavior, whether state is modified, how events affect execution, or what the assertion result contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with the core action front-loaded. Every sentence contributes relevant information without unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter simulation tool with no annotations and no output schema, the description covers the central assertion purpose but leaves output and failure semantics thin. The schema fills in the parameter details, but the overall definition does not fully explain what an agent should expect from the assertion result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already well documented by the schema. The description restates the meaning of patterns but adds no meaningful parameter guidance beyond what the schema provides, making the baseline score appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: runs firmware in simulation and asserts that text or regex patterns appear on UART. This is clear enough to distinguish the core assertion behavior, but it does not explicitly differentiate the tool from siblings such as sim_run or sim_script.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives useful context by saying it is ideal for automated unit and integration testing in a Red-Green-Refactor loop, which implies when to use it. However, it names no alternatives and gives no explicit when-not-to-use guidance relative to the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_list_boardsA
Returns the catalogue of all supported ESP32 chips, boards, displays, peripherals and capabilities.
| Name | Required | Description | Default |
|---|---|---|---|
| chip | No | Filter boards by chip family. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'Returns the catalogue' implies a safe, read-only lookup, which is the key behavioral trait, but it does not disclose whether a running simulator/session is required, whether the data is static, or any other operational constraint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the verb and resource lead, and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, read-only listing tool with no output schema, enumerating the catalogue's contents (chips, boards, displays, peripherals, capabilities) is reasonably complete. The main gap is that the optional chip filter is not acknowledged, which could matter for the agent's filtering decision.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'chip' parameter has a documented enum, so the schema already explains filtering. The description adds no syntax or semantics beyond that, and saying it returns the catalogue of 'all' chips arguably understates the existence of the filter; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Returns') and a concrete resource (catalogue of ESP32 chips, boards, displays, peripherals, capabilities). The resource is unambiguous and clearly distinct from the action-oriented siblings (sim_run, sim_script, sim_expect, sim_screenshot, sim_doctor), but the description never names or contrasts with them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The listing/catalogue nature implies a discovery use case, so usage is inferable. However, there is no explicit statement of when to call this versus the simulation siblings, and no mention that the 'chip' filter can be used to narrow the catalogue, which is the one meaningful usage decision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_runB
Boots and simulates ESP32 firmware in a local emulator without hardware. Captures UART logs, FreeRTOS asserts, memory faults, and stop reason.
| Name | Required | Description | Default |
|---|---|---|---|
| chip | No | Target chip family. Default is s3 (ESP32-S3). | |
| wifi | No | Attach a virtual access point with DHCP/DNS/NAT. Spec like 'ssid=demo,psk=secret' (keys: ssid, psk, chan, bssid), or a bare SSID for an open network. Station gets 10.0.2.15. | |
| board | No | Board model: S3 'atech14' (default), 'waveshare-lcd4b', 'waveshare-amoled18-v2', 'waveshare-cam'; C6 'waveshare-c6-lcd147'; ESP32 'ttgo-tdisplay', 'esp32dev-loopback'; 'none' for a bare module. Omit on the C3, which has no boards. See sim_list_boards. | |
| appBin | No | Direct path to the application binary (.bin). | |
| console | No | Console source to capture (default: both = UART0 + USB-Serial/JTAG). Lines ESP-IDF mirrors on both consoles are shown once. | |
| ptableBin | No | Direct path to partition-table.bin (needed with appBin for a real ROM boot). | |
| maxSeconds | No | Maximum emulated time in seconds (default: 10s). Emulation usually runs faster than real time. | |
| projectDir | No | Path to the ESP-IDF project root or build folder. If omitted, uses current working directory. | |
| bootloaderBin | No | Direct path to bootloader.bin (needed with appBin for a real ROM boot). | |
| stopAfterExceptions | No | Stop after N CPU exceptions (unset by default). Counts every exception, including the window overflow/underflow ones Xtensa firmware takes constantly, so it is a debugging aid, not a crash detector. Panics are detected from the log regardless. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses that execution is hardware-free and enumerates what is captured (UART logs, FreeRTOS asserts, memory faults, stop reason), but says nothing about blocking behavior, whether artifacts are written to disk, or how failures surface to the caller.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, with the core action front-loaded and the diagnostic outputs listed compactly. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description partially compensates by naming the captured artifacts. However, for a 10-parameter tool with two distinct input modes (projectDir vs explicit appBin/ptableBin/bootloaderBin), it gives no guidance on which mode to choose or what a run session returns beyond the diagnostic list.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 10 parameters are already documented with rich detail (chip defaults, wifi spec syntax, board models, console modes). The description adds no parameter-level meaning beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (boots and simulates ESP32 firmware) plus the execution mode (local emulator, no hardware), which is unambiguous on its own. It never names or contrasts with siblings like sim_script or sim_expect, so an agent must infer that this is the raw run entry point rather than a scripted/scenario runner.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites (e.g. firmware must be built first), and no routing to sim_script / sim_expect / sim_doctor. The only implicit hint is that this is a run action, leaving the agent to guess how it relates to the other five sim_* tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_screenshotC
Captures a snapshot image of the virtual LCD/TFT display buffer at a specified emulated time.
| Name | Required | Description | Default |
|---|---|---|---|
| chip | No | Target chip family. Default is s3 (ESP32-S3). | |
| board | No | Board with a display: 'atech14', 'waveshare-lcd4b', 'waveshare-amoled18-v2' (S3), 'waveshare-c6-lcd147' (C6), 'ttgo-tdisplay' (ESP32). | atech14 |
| appBin | No | Direct path to the application binary (.bin). | |
| ptableBin | No | Direct path to partition-table.bin (needed with appBin for a real ROM boot). | |
| projectDir | No | Path to the ESP-IDF project root or build folder. If omitted, uses current working directory. | |
| timeSeconds | No | Emulated second at which to take the screenshot. | |
| bootloaderBin | No | Direct path to bootloader.bin (needed with appBin for a real ROM boot). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It says what is captured but not where the image goes (file path, base64 return), whether the emulator boots the ROM on its own, whether a prior build/run is required, or any cost/time implications of advancing emulation to timeSeconds.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or redundancy. It is efficient, though its brevity leaves the gaps noted in other dimensions rather than wasting words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter tool with no annotations and no output schema, the description omits the return value entirely (image path vs inline data) and says nothing about build/boot prerequisites implied by appBin, ptableBin and bootloaderBin. An agent would have to guess how to consume the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 7 parameters including chip, board, binary paths and timeSeconds. The phrase 'at a specified emulated time' merely restates timeSeconds, adding no syntax or format detail beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (captures) and a precise resource (snapshot image of the virtual LCD/TFT display buffer) plus the timing scope. An agent can tell this apart from sim_run/sim_script by the display-capture framing, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use, when-not-to-use, or alternative guidance. It does not clarify the relationship to sim_run (does the emulator need to be running/built first?) or when a screenshot is preferable to scripted assertions via sim_expect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sim_scriptB
Simulates hardware interactions (button presses, GPIO levels, rotary encoder turns, touch, UART/console input) at specific emulated timestamps, capturing interactive firmware behavior.
| Name | Required | Description | Default |
|---|---|---|---|
| chip | No | Target chip family. Default is s3 (ESP32-S3). | |
| wifi | No | Attach a virtual access point with DHCP/DNS/NAT. Spec like 'ssid=demo,psk=secret' (keys: ssid, psk, chan, bssid), or a bare SSID for an open network. Station gets 10.0.2.15. | |
| board | No | Board model: S3 'atech14' (default), 'waveshare-lcd4b', 'waveshare-amoled18-v2', 'waveshare-cam'; C6 'waveshare-c6-lcd147'; ESP32 'ttgo-tdisplay', 'esp32dev-loopback'; 'none' for a bare module. Omit on the C3, which has no boards. See sim_list_boards. | |
| appBin | No | Direct path to the application binary (.bin). | |
| events | No | Host actions at emulated times. | |
| ptableBin | No | Direct path to partition-table.bin (needed with appBin for a real ROM boot). | |
| maxSeconds | No | Total simulation duration in seconds (default 15). | |
| projectDir | No | Path to the ESP-IDF project root or build folder. If omitted, uses current working directory. | |
| bootloaderBin | No | Direct path to bootloader.bin (needed with appBin for a real ROM boot). | |
| scriptContent | No | Raw esp32sim script text instead of events (e.g. "1.5 press btn1 150\n3.0 stop"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are absent, so the description must carry the full behavioral burden. It states that events fire at emulated timestamps and that interactive firmware behavior is captured, but it omits the execution model, side effects, permissions, error behavior, and whether the simulation is isolated or modifies persistent state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence that efficiently packs the tool's scope and key interaction types. There is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The rich input schema covers parameters, but the description does not explain the overall workflow, output or return behavior (no output schema exists), or how this tool relates to sim_run and sim_expect. For a complex simulation tool with no annotations, this leaves important contextual gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all ten parameters in detail. The description adds no parameter-level meaning beyond the general scope, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the verb 'Simulates', the resource 'hardware interactions', and enumerates concrete interaction categories (button presses, GPIO levels, rotary encoder turns, touch, UART/console input). It does not explicitly differentiate this tool from siblings such as sim_run or sim_expect, which keeps it below a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use guidance or alternatives are given. The description implies the tool injects timed inputs into an emulated firmware session, but an agent must infer this from the purpose statement rather than being told directly when to choose it over sim_run or sim_expect.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.2.6- Changed
sim_expect1 field changed- changed
Input schema / properties / patterns / descriptionPrevious value: -"List of expected strings or regex patterns on UART output."New value: +"Expected console output. Plain text matches as a substring of a line (\"Counter: 5\"); write a regular expression between slashes (\"/Counter: \\\\d+/\", \"/wifi.*connected/i\")."
6 tool updates
v0.1.1- First observed
sim_doctor - First observed
sim_expect - First observed
sim_list_boards - First observed
sim_run - First observed
sim_screenshot - First observed
sim_script
TDQS
Scored across 6 tools
Most tools have distinct purposes: sim_run boots firmware, sim_script injects hardware interactions, sim_expect asserts UART output, and sim_screenshot captures the display. However, sim_run, sim_script, and sim_expect all execute simulation and their boundaries could occasionally blur, especially between generic running and scripted/asserted runs.
All tools use a consistent sim_ prefix and snake_case, making the set readable and predictable. The suffix conventions vary slightly (verbs like run/expect/list_boards vs nouns like screenshot/script/doctor), but this is a minor deviation rather than a real inconsistency.
Six tools is well-scoped for an ESP32 emulator MCP: run, script, expect, screenshot, environment check, and board catalogue. Each tool appears to earn its place without excessive surface area.
The surface covers core simulation workflows: booting firmware, injecting inputs, asserting UART output, capturing display state, and environment/board discovery. Minor gaps exist around explicit stop/reset or mid-run state inspection, but agents can likely work around these through the existing run/script/expect tools.
Maintenance
Related MCP Connectors
Run, build, and validate firmware on virtual hardware from your AI agent. Hardware knowledge corpus.
Disposable cloud Android emulators for coding agents: run an APK or PR build, tap, type, screenshot.
Cloud iPhone Simulators for AI agents: build the Xcode project, read the screen, tap by label, test.
Official MCP server for Agentwork β delegate tasks to AI agents with human-in-the-loop
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceAn MCP server for managing ESP-IDF workflows, enabling LLMs to build, flash, and test firmware for ESP32 and related microcontrollers. It provides tools for project creation, target configuration, and serial port management to simplify embedded development.156-
- AlicenseNot gradedqualityBmaintenanceMCP server for simulating firmware on virtual microcontroller instances, allowing AI agents to upload, run, and read UART output from supported boards such as STM32 and Nordic.18MIT
- AlicenseAqualityBmaintenanceAgentic Hardware-in-the-Loop (Agentic HIL) lets coding agents develop firmware on real embedded boards: flash, reset, read UART and exchange CAN traffic, diagnose and fix. Local, policy-gated MCP tools support OpenOCD, pyOCD and STM32CubeProgrammer, with pytest for CI.441,737 PyPI24Apache 2.0
- AlicenseNot gradedqualityDmaintenanceAn MCP server that lets AI coding agents drive the full STM32 development loopβcode generation, build, flash, debug, serial monitoring, and fault diagnosisβend to end via CubeIDE, CubeMX, CubeProgrammer, OpenOCD, and GDB.1MIT