Commit Graph

76 Commits

Author SHA1 Message Date
Marek Fiala
d648b858bb feat(tools): adopt esp-pylib for mcp-server logging and ports
Migrate the MCP server extension to the shared esp-pylib library:
- replace raw stderr prints with esp_pylib.logger.log (note/err)
- route informational logs to stderr via set_info_stream so stdout
  stays reserved for the MCP JSON-RPC transport
- enumerate connected devices via esp_pylib.serial_ports.get_port_names
- stub the new imports in the mcp_ext unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-11 15:20:45 +02:00
Marek Fiala
3f005c8a4d feat(tools): mcp-server added monitor-device tool
Add a `monitor_device` MCP tool that lets an AI agent run a scripted,
non-interactive `esp-idf-monitor` session against a flashed device and
get back a short status plus a log file path, instead of raw serial
output inline.

Under the hood:

- The agent supplies a plain-text command body (expect/send/sleep/reset/
  exit/comments). `assemble_monitor_script_from_agent_commands()` frames
  it into a script the monitor's non-interactive command mode can
  consume via stdin: it appends `exit` if the agent didn't already end
  with one, and rewrites every bare `expect <regex>` into `expect
  --timeout <timeout_sec> <regex>` via `_monitor_normalize_expect_line()`
  (an already-bounded `expect --timeout ...` line is left untouched so
  the monitor itself reports a bad value). A leading `reset` is not
  prepended - the monitor already resets the chip when it opens the
  port - and any `reset` the agent wrote is left in place.
  `_monitor_parse_sleep_duration()` extracts each `sleep <n>` duration.
  The effective timeout is the sum of every bounded expect duration
  plus every sleep duration. Scripts whose sum exceeds
  `MONITOR_MAX_SCRIPT_SEC` are rejected. If the script has neither
  expect nor sleep (for example only `send`), `timeout_sec` is used so
  the process still has a kill bound.

- `monitor_device()` runs `python -m esp_idf_monitor` via
  `subprocess.run(..., input=script, timeout=2 * effective_timeout)`.
  `no_reset` is forwarded as `--no-reset` so the connection reset can be
  skipped; an explicit `-p` is forwarded when a port is given. Extra
  arguments match `idf.py monitor` where a build exists: baud (`baud`
  tool arg, else `monitor_baud` from `project_description.json`),
  toolchain prefix, `--target`/`--revision`, coredump/panic decode, and
  ELF files with the app ELF first. The 2x hard timeout is a safety net
  independent of the script's own `expect --timeout`/`exit` logic; on
  `TimeoutExpired` the process is killed but any output already captured
  is preserved and logged. `decode_stream()` normalizes that captured
  output, which can be `bytes` on the timeout path even though the
  process otherwise runs in text mode.

- The monitor's exit code drives the reported status via
  `_monitor_status()`, using `EXIT_EXPECT_TIMEOUT` and
  `EXIT_SCRIPT_ERROR` from `esp_idf_monitor.base.constants`: 0 is
  success, 110 means an `expect` pattern never showed up before its
  `--timeout` elapsed, 2 means the monitor rejected the script (bad
  syntax/timeout/regex), anything else is reported generically.

- Serial output and the monitor's own messages share one pipe
  (`stderr=STDOUT`) so decoded panic backtraces stay next to the lines
  that triggered them. `_save_monitor_output()` writes the full merge to
  `<tempdir>/esp_idf_mcp_log/action_monitor/monitor_<timestamp>.log` and
  reports a dedicated `Log file:` line. On non-zero exit or process
  kill, a short tail of that same merge is also returned inline so the
  agent has some failure context without a second file read. If the log
  file can't be written, it falls back to inlining a truncated tail.

Closes https://github.com/espressif/esp-idf/issues/18757
Closes https://github.com/espressif/esp-idf/pull/18385

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-11 15:20:45 +02:00
Roland Dobai
aa03e678f5 Merge branch 'fix/serial_port_target_mismatch' into 'master'
fix(tools): Detect serial port matching the project target

Closes IDF-15356

See merge request espressif/esp-idf!51466
2026-09-04 07:01:30 +02:00
Vojtech Piroch
19676ffa46 fix(tools): Detect serial port matching the project target
Auto-detect used to pick the first Espressif device, even when it did
not match IDF_TARGET. With several boards attached, flash/monitor could
talk to the wrong chip.

Pass the project target into esptool so unmatched ports are skipped.
Resolve the port after ensure_build_directory() so the target is known.
For monitor on an unconfigured project, probe the connected chip and
pass it directly to idf_monitor without configuring the project.
2026-09-02 17:18:57 +08:00
Sudeep Mohanty
dfe99a4a41 feat(idf_py): hint at the BUILD_COMPONENTS migration path
Reading the BUILD_COMPONENTS build property aborts the build with a bare
message stating that the property is unsupported, without naming a
replacement. Add a hint that points at the $<TARGET_EXISTS:idf::component>
generator expression and at the documentation section describing the
migration, so the guidance lives with the other build hints instead of
being spelled out in the build system sources.
2026-08-26 15:28:18 +02:00
Marek Fiala
9060b31790 fix(tools): support mcp Python SDK 2.0 for mcp-server
FastMCP was renamed to MCPServer in mcp 2.0, which made idf.py mcp-server
report a false "MCP dependencies not available" error. Prefer MCPServer
and keep a FastMCP fallback for mcp 1.x.

Closes https://github.com/espressif/esp-idf/issues/18904

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-04 11:25:08 +02:00
Ivan Grokhotkov (bot)
b3a0e166fe feat: add compile_options support to idf.py build-file
Allow specifying extra compiler flags (warning flags, preprocessor
definitions, etc.) via a new 'compile_options' entry in the
idf-build-file frontmatter. The options are applied to the source
file via target_compile_options in the generated main component
CMakeLists, with CMake quoting so that flags like -DMSG="hello world"
reach the compiler exactly as written.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:04:41 +02:00
Ivan Grokhotkov
16275df0a1 feat: add idf.py build-file command for standalone C files
Add a new idf.py extension that allows building standalone C files
without requiring full project boilerplate. Source files can include
optional YAML frontmatter in block comments to specify sdkconfig
options, component dependencies, and target configuration.

When the frontmatter configuration changes, the stale sdkconfig is
removed so the new defaults are applied, and a target change also
clears the build directory since IDF_TARGET is pinned in the CMake
cache.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 22:04:41 +02:00
Marek Fiala
8c08c75f48 feat(tools): adopt esp-pylib for idf.py logging and errors
Migrate idf.py and its actions to the shared esp-pylib library:
- add esp-pylib (and esp-pylib[ide]) to the core/ide requirements
- base FatalError on esp_pylib.errors.FatalError, keeping the idf.py ctx cleanup
- replace the local raw-ANSI helpers (red_print/yellow_print/print_warning/
  color_print) with esp_pylib.logger.log (warn/err/note/hint) across the
  idf.py actions
- install esp_pylib exception reporting at the idf.py entry point and silence
  the logger during shell completion
- update affected tests for the new prefixes/line wrapping
- add normalize_output() helper and unify terminal env in conftest to handle
  Rich line-wrapping in CI assertions

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 20:19:07 +08:00
Aditya Patwardhan
5f1074045f fix(esp-tls): update secure element build hint for PSA integration 2026-06-29 19:20:23 +05:30
Aditya Patwardhan
08b567ef3b fix(esp-tls): address MR review comments for SE PSA driver
- esp_tls_mbedtls: require cert when PSA-backed server/client key is set
- esp_tls_mbedtls: drop redundant pk_init/x509_crt_init (calloc handles it)
- psa SE driver: copy callbacks/opaque_key by value (no lifetime coupling)
- psa SE driver: replace atomic CAS with simple null check on register
- psa SE driver: use sig_len from sign callback with bounds validation
- psa SE driver: validate pubkey_len returned by export_pubkey callback
- psa SE driver: check hash sub-alg in RSA PKCS1V15 branch of validate_request
- psa SE driver: align secure_element_register_callbacks doc with value-copy impl
- esp_https_server: initialize server_key in HTTPD_SSL_CONFIG_DEFAULT
- mbedtls: move SECURE_ELEMENT_DRIVER_ENABLED to esp_config.h for parity
  with ESP_ECDSA_DRIVER_ENABLED; drop target_compile_definitions
- docs: fix esp_tls_cfg_t -> esp_http_client_config_t cross-reference
- docs: check psa_import_key() status in ESP-TLS PSA example
- hints/error_output: point at CONFIG_MBEDTLS_SECURE_ELEMENT_DRIVER_ENABLED
2026-06-29 19:20:22 +05:30
Marek Fiala
12ea480988 feat(tools): Improved verification of ESP-IDF project
Closes https://github.com/espressif/esp-idf/issues/18675
2026-06-24 18:46:39 +08:00
Marek Fiala
1be844551a feat(tools): mcp-server added create-project tool 2026-06-24 18:46:39 +08:00
Marek Fiala
2dd6b604fa feat(tools): mcp-server accepts project_dir from chat
At the same time, it's possible to start idf.py mcp-server
outside ESP-IDF project directory.

Added ESP-IDF mcp server tests
2026-06-24 18:46:39 +08:00
Marek Fiala
eb91e45092 feat(tools): Replaced click with rich_click 2026-06-01 20:07:27 +08:00
Roland Dobai
9bea09a081 fix(tools): seed IDF_VERSION before idf.py parses dependencies.lock
Any idf.py invocation could hang indefinitely with no output while
spawning an unbounded chain of "idf.py --version" subprocesses,
eventually exhausting system memory.

During init_cli(), idf.py parses the project's dependencies.lock to
vet trusted component-provided idf_ext.py extensions. If the lock
contains a component whose manifest has an "if: idf_version" clause,
evaluating it calls idf-component-manager's _get_idf_version(). Outside
a CMake build the IDF_VERSION environment variable is not set, so that
function falls back to running "idf.py --version" as a subprocess,
which re-enters init_cli() and recurses without bound.

During a normal CMake build the component manager runs as a subprocess
that already has IDF_VERSION in its environment (see build/config.env),
so the fallback is never reached. The recursion happens only because
idf.py runs component-manager code in-process during its own CLI
startup, outside that context.

Seed IDF_VERSION into os.environ early in init_cli(), before any
dependencies.lock parsing, using the subprocess-free
idf_version_from_cmake() helper. This gives in-process component-manager
code the same IDF_VERSION a CMake build would provide.
2026-05-15 14:06:40 +08:00
Jakub Kocka
6e4ed2c204 fix(tools): Forward build subprocess stdout as UTF-8 bytes on Windows 2026-05-12 18:14:27 +08:00
Fu Hanxi
a38c7e9242 ci: windows with VM 2026-04-27 12:41:53 +02:00
Fu Hanxi
a3281516c4 test: stop patching env vars by tearDownClass 2026-03-17 21:02:49 +08:00
Jakub Kocka
d860da47c0 ci(tools): Avoiding full rebuilds where not needed to improve performance 2026-03-16 08:53:41 +01:00
Jakub Kocka
229e07bdf6 fix: Improved encoding requirement check
Closes https://github.com/espressif/esp-idf/issues/17542
2025-12-09 21:09:37 +08:00
Peter Dragun
3f0fde84e1 fix(tools/idf.py): Add implicit dependencies to flash targets 2025-12-02 08:45:59 +01:00
Marek Fiala
3c9ad9c091 Revert "fix: Updated locale handling to prevent issues with build tools"
This reverts commit 7e09b471ab.
2025-10-28 04:02:21 +01:00
Jakub Kocka
7e09b471ab fix: Updated locale handling to prevent issues with build tools
Closes https://github.com/espressif/esp-idf/issues/17542
2025-10-17 09:58:44 +02:00
Marek Fiala
854f6b0a3e fix(test_idf_py): Added extension API version into test extensions files 2025-10-02 15:37:29 +02:00
Marek Fiala
248c3a996e change(test_idf_py): ruff formatting idf_ext.py & some_ext.py 2025-10-02 15:34:31 +02:00
Peter Dragun
9eb07f92ba docs: Update unify and update espefuse command outputs 2025-09-30 15:28:55 +02:00
Peter Dragun
e3198fff3c feat: Update esptool to v5 2025-09-30 15:28:55 +02:00
Roland Dobai
5dad2a4884 ci(test): Improve test failures on Windows
Tests are made cancellable and to print STDOUT and STDERR upon failures.
2025-09-24 13:43:23 +02:00
Roland Dobai
ef878f4d25 ci(test): Test requiring pexpect.spawn cannot be run on Windows 2025-09-24 13:43:23 +02:00
Roland Dobai
9e8962c6cc change(tools): Fix pre-commit checks for test_idf_qemu.py 2025-09-24 13:43:23 +02:00
Roland Dobai
26ae9e8589 ci(gitlab): Split up Windows tests into (more) parallel jobs 2025-09-24 13:43:23 +02:00
Jakub Kocka
2affbb9509 refactor(tools): Updated tests to corespond with massage changes 2025-08-26 13:50:45 +02:00
Peter Dragun
eba6b814ba feat: Add support for esptool v5 and keep v4 for now 2025-08-21 15:53:39 +02:00
Marek Fiala
9d35d63651 feat(cmake): Update minimum cmake version to 3.22 (whole repository) 2025-08-19 14:44:32 +02:00
Marek Fiala
d7faae9ae4 change(tools): ruff formating test_hints.py 2025-08-19 14:44:31 +02:00
Fu Hanxi
87a5aedb85 ci: disable idf-ci plugin
this plugin will be re-enabled with compatible code in !38755
2025-06-03 08:37:56 +02:00
Ashish Sharma
4c23ba3c1f feat(security): update idf.py extensions to support security feature application 2025-03-17 18:23:14 +08:00
Alexey Lapshin
48a49c8154 feat(debugging): move gdbinit generation to CMake
This feature is useful for 3rd-party software to run GDB with predefined
options that described in project_description.json file

allow to pass custom options to "idf.py gdb":

  --gdb-commands: command line arguments for gdb. (without changes)
  -ex: pass command to gdb.
  -x: pass gdbinit file to gdb. Alias for old --gdbinit command
2024-11-19 16:41:38 +07:00
Jan Beran
d77d1f5a95 fix(uf2): Ignore ESPBAUD, ESPPORT when calling idf.py uf2[-app] 2024-09-23 15:48:59 +02:00
harshal.patil
e5f22521da docs(secure_boot_v2): Mention idf.py and openssl commands to generate and verify signatures
- Adds support for verify_signature command in idf.py

Closes https://github.com/espressif/esptool/issues/942
2024-08-27 15:44:05 +05:30
Radim Karniš
4ccdc51b07 ci(espefuse_test): Comply with esptool v4.8 2024-08-22 16:12:16 +02:00
Ivan Grokhotkov
0773caf283 Merge branch 'feature/idf_py_efuse_qemu' into 'master'
feat(idf.py): support efuse-related commands in QEMU

Closes QEMU-193

See merge request espressif/esp-idf!29809
2024-08-21 16:13:54 +08:00
Ivan Grokhotkov
7b228ce8ab feat(idf.py): allow running idf.py efuse-* commands with QEMU 2024-08-15 16:57:08 +02:00
Ivan Grokhotkov
c521fcb6fd fix(cmake): report correct error on unknown component name
Previously the error message was

CMake Error at /home/user/esp-idf/tools/cmake/build.cmake:296 (__component_get_property):
  __component_get_property Function invoked with incorrect arguments for
  function named: __component_get_property
Call Stack (most recent call first):
  /home/user/esp-idf/tools/cmake/build.cmake:341 (__build_resolve_and_add_req)
  /home/user/esp-idf/tools/cmake/build.cmake:638 (__build_expand_requirements)
  /home/user/esp-idf/tools/cmake/project.cmake:710 (idf_build_process)
  CMakeLists.txt:6 (project)

Now it will be:

CMake Error at /home/user/esp-idf/tools/cmake/build.cmake:298 (message):
  Failed to resolve component 'whatever' required by component 'main'.
Call Stack (most recent call first):
  /home/user/esp-idf/tools/cmake/build.cmake:345 (__build_resolve_and_add_req)
  /home/user/esp-idf/tools/cmake/build.cmake:642 (__build_expand_requirements)
  /home/user/esp-idf/tools/cmake/project.cmake:710 (idf_build_process)
  CMakeLists.txt:6 (project)

Also improved the hint to show the component name in quotes.
2024-08-12 17:54:44 +02:00
Jan Beran
832c3f265a fix: Generate secure keys in project dir instead of build dir 2024-06-28 12:36:49 +02:00
Jan Beran
b286105d5f feat: Add unit tests for new wrapper commands 2024-06-24 10:56:10 +02:00
Frantisek Hrbata
fbe8bf89ee fix: properly resolve component dependencies
There is currently a bug in the __build_resolve_and_add_req function in
tools/cmake/build.cmake where the check for registered component
requirements is incorrectly applied to the component itself rather than
its dependencies. This issue likely originated from a typo, using
component_target instead of _component_target. To prevent further
confusion, _component_target has been renamed to _req_target.

Fixing this revealed multiple incorrect dependencies for the Linux
target, which have now been resolved by explicitly specifying the
dependencies for the Linux target.

Closes https://github.com/espressif/esp-idf/issues/13447

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2024-05-30 22:01:55 +08:00
Marek Fiala
a97e355e74 feat(tools): Run Tools related host tests on Win 2024-02-02 14:58:04 +01:00
Frantisek Hrbata
a773072734 fix: harden input parsing in component_requirements hint module
Currently we silently ignore when the original component is not found
in a hope we can provide at least some meaningful hint. As it turned
out it's not true. Instead of providing misleading hint, just return
error. This adds several checks for situations, which should not happen,
but when they do it should be easier to identify the root cause of the
problem.

For example when hint module received malformed output with extra new
lines, e.g. caused by a bug in RunTool, it wrongly reported the original
component as source component.

This should also fix the tests on Windows.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2024-01-23 18:22:08 +01:00