mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'fix/mcp_subprocess_stdin_v6.1' into 'release/v6.1'
fix(tools): detach MCP tool subprocess stdin from JSON-RPC pipe (v6.1) See merge request espressif/esp-idf!52282
This commit is contained in:
@@ -153,6 +153,9 @@ def action_extensions(base_actions: dict, project_path: str) -> dict:
|
||||
mcp = _MCPServer('ESP-IDF')
|
||||
|
||||
# === TOOLS (Actions) ===
|
||||
# Tool handlers spawn idf.py with stdin=subprocess.DEVNULL. The MCP server's
|
||||
# stdin is the long-lived JSON-RPC transport pipe; a child that inherits it
|
||||
# can hang instead of exiting.
|
||||
@mcp.tool(description=f'Build the ESP-IDF project (runs `idf.py build`). {bound_hint}')
|
||||
def build_project(project_dir: str | None = None) -> str:
|
||||
"""Build the ESP-IDF project.
|
||||
@@ -176,7 +179,7 @@ def action_extensions(base_actions: dict, project_path: str) -> dict:
|
||||
'build',
|
||||
]
|
||||
print(f'INFO: Building project with command: {" ".join(cmd)} in path: {effective_dir}', file=sys.stderr)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, stdin=subprocess.DEVNULL)
|
||||
if result.returncode == 0:
|
||||
print('INFO: Build successful', file=sys.stderr)
|
||||
return 'Successfully built project'
|
||||
@@ -217,7 +220,7 @@ def action_extensions(base_actions: dict, project_path: str) -> dict:
|
||||
target,
|
||||
]
|
||||
print(f'INFO: Setting target with command: {" ".join(cmd)} in path: {effective_dir}', file=sys.stderr)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, stdin=subprocess.DEVNULL)
|
||||
if result.returncode == 0:
|
||||
print(f'INFO: Target set to: {target}', file=sys.stderr)
|
||||
return f'Target set to: {target}'
|
||||
@@ -259,7 +262,7 @@ def action_extensions(base_actions: dict, project_path: str) -> dict:
|
||||
effective_dir,
|
||||
] + flash_args
|
||||
print(f'INFO: Flashing project with command: {" ".join(cmd)} in path: {effective_dir}', file=sys.stderr)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, stdin=subprocess.DEVNULL)
|
||||
|
||||
if result.returncode == 0:
|
||||
print('INFO: Flash successful', file=sys.stderr)
|
||||
@@ -300,7 +303,7 @@ def action_extensions(base_actions: dict, project_path: str) -> dict:
|
||||
name,
|
||||
]
|
||||
print(f'INFO: Creating project "{name}" in {parent_dir}', file=sys.stderr)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, stdin=subprocess.DEVNULL)
|
||||
if result.returncode == 0:
|
||||
project_path_new = os.path.join(parent_dir, name)
|
||||
print(f'INFO: Project "{name}" created at {project_path_new}', file=sys.stderr)
|
||||
@@ -336,7 +339,7 @@ def action_extensions(base_actions: dict, project_path: str) -> dict:
|
||||
'clean',
|
||||
]
|
||||
print(f'INFO: Cleaning project with command: {" ".join(cmd)} in path: {effective_dir}', file=sys.stderr)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, stdin=subprocess.DEVNULL)
|
||||
if result.returncode == 0:
|
||||
print('INFO: Project cleaned successfully', file=sys.stderr)
|
||||
return 'Project cleaned successfully'
|
||||
@@ -434,15 +437,16 @@ def action_extensions(base_actions: dict, project_path: str) -> dict:
|
||||
except Exception as e:
|
||||
return f'Error getting devices: {str(e)}'
|
||||
|
||||
# Start the MCP server
|
||||
print('MCP Server running on stdio...')
|
||||
# Start the MCP server. Diagnostics should go to stderr — stdout is reserved
|
||||
# for the JSON-RPC transport and any non-JSON bytes can confuse MCP clients.
|
||||
print('MCP Server running on stdio...', file=sys.stderr)
|
||||
|
||||
try:
|
||||
mcp.run()
|
||||
except KeyboardInterrupt:
|
||||
print('\nMCP Server stopped.')
|
||||
print('\nMCP Server stopped.', file=sys.stderr)
|
||||
except Exception as e:
|
||||
print(f'MCP Server error: {e}')
|
||||
print(f'MCP Server error: {e}', file=sys.stderr)
|
||||
|
||||
# Return the action extension
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user