Skip to content

Commit 074e9ad

Browse files
committed
init commit
0 parents  commit 074e9ad

File tree

8 files changed

+491
-0
lines changed

8 files changed

+491
-0
lines changed

.idea/.gitignore

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.python-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.11.0

README.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Currently, this MCP supports simple project builds with logging, and automatic issue fixing based on logs for esp-idf build command.
2+
3+
### Install
4+
5+
First, clone this MCP repository:
6+
7+
```bash
8+
git clone [email protected]:horw/esp-mcp.git
9+
```
10+
11+
Then, configure it in your chatbot.
12+
13+
14+
```json
15+
{
16+
"mcpServers": {
17+
"esp-run": {
18+
"command": "/home/horw/.pyenv/shims/uv",
19+
"args": [
20+
"--directory",
21+
"/home/horw/PycharmProjects/esp-mcp", <- your cloned path
22+
"run",
23+
"main.py"
24+
],
25+
"env": {
26+
"IDF_PATH": "~/esp-idf" <- your ESP-IDF path
27+
}
28+
}
29+
}
30+
}
31+
```
32+
![Result](./result.gif)

esp_utils.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""
2+
Utility functions for ESP-IDF tools
3+
"""
4+
import os
5+
import asyncio
6+
from typing import Tuple
7+
8+
9+
async def run_command_async(command: str) -> Tuple[int, str, str]:
10+
"""Run a command asynchronously and capture output
11+
12+
Args:
13+
command: The command to run
14+
15+
Returns:
16+
Tuple[int, str, str]: Return code, stdout, stderr
17+
"""
18+
try:
19+
process = await asyncio.create_subprocess_shell(
20+
command,
21+
stdout=asyncio.subprocess.PIPE,
22+
stderr=asyncio.subprocess.PIPE
23+
)
24+
stdout, stderr = await process.communicate()
25+
return process.returncode, stdout.decode(), stderr.decode()
26+
except Exception as e:
27+
return 1, "", f"Error executing command: {str(e)}"
28+
29+
def get_esp_idf_dir() -> str:
30+
"""Get the ESP-IDF directory path
31+
32+
Returns:
33+
str: Path to the ESP-IDF directory
34+
"""
35+
36+
idf_dir = os.environ["IDF_PATH"]
37+
return os.path.join(idf_dir, "esp-idf")
38+
39+
def get_export_script() -> str:
40+
"""Get the path to the ESP-IDF export script
41+
42+
Returns:
43+
str: Path to the export script
44+
"""
45+
return os.path.join(get_esp_idf_dir(), "export.sh")
46+
47+
def check_esp_idf_installed() -> bool:
48+
"""Check if ESP-IDF is installed
49+
50+
Returns:
51+
bool: True if ESP-IDF is installed, False otherwise
52+
"""
53+
return os.path.exists(get_esp_idf_dir())

main.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import logging
2+
3+
from mcp.server.fastmcp import FastMCP
4+
import os
5+
from esp_utils import run_command_async, get_export_script
6+
7+
mcp = FastMCP("esp-mcp")
8+
9+
command_history = []
10+
11+
@mcp.tool()
12+
async def build_esp_related_project(project_path: str) -> (str, str):
13+
"""Build an esp project.
14+
15+
Args:
16+
project_path: Path to the ESP-IDF project
17+
18+
Returns:
19+
str: Build logs
20+
"""
21+
os.chdir(project_path)
22+
export_script = get_export_script()
23+
returncode, stdout, stderr = await run_command_async(f"bash -c 'source {export_script} && idf.py build'")
24+
open('mcp-process.log', 'w+').write(str((stdout, stderr)))
25+
logging.warning(f"build result {stdout} {stderr}")
26+
return stdout, stderr
27+
28+
if __name__ == '__main__':
29+
mcp.run(transport='stdio')

pyproject.toml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[project]
2+
name = "esp-mcp"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.11.0"
7+
dependencies = [
8+
"mcp[cli]>=1.5.0",
9+
]

result.gif

11.6 MB
Loading

uv.lock

+359
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)