Expose remote file management and Python code execution via MCP
This commit is contained in:
@@ -183,6 +183,40 @@ class MCPServer:
|
|||||||
},
|
},
|
||||||
"required": ["image_base64"]
|
"required": ["image_base64"]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "write_file",
|
||||||
|
"description": "Write a file (e.g., python script or config) to the board's flash storage.",
|
||||||
|
"inputSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"path": {"type": "string", "description": "The destination file path (e.g. 'my_script.py')"},
|
||||||
|
"content": {"type": "string", "description": "The text content of the file"}
|
||||||
|
},
|
||||||
|
"required": ["path", "content"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "read_file",
|
||||||
|
"description": "Read a text file from the board's flash storage.",
|
||||||
|
"inputSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"path": {"type": "string", "description": "The file path to read (e.g. 'boot.py')"}
|
||||||
|
},
|
||||||
|
"required": ["path"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "execute_python",
|
||||||
|
"description": "Execute arbitrary Python code dynamically on the board. Standard output (prints) and errors will be captured and returned.",
|
||||||
|
"inputSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"code": {"type": "string", "description": "The Python code to execute"}
|
||||||
|
},
|
||||||
|
"required": ["code"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -324,5 +358,54 @@ class MCPServer:
|
|||||||
pass
|
pass
|
||||||
return "Image displayed successfully."
|
return "Image displayed successfully."
|
||||||
|
|
||||||
|
elif name == "write_file":
|
||||||
|
path = str(args.get("path"))
|
||||||
|
content = str(args.get("content"))
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
f.write(content)
|
||||||
|
return f"Successfully wrote {len(content)} characters to '{path}'."
|
||||||
|
|
||||||
|
elif name == "read_file":
|
||||||
|
path = str(args.get("path"))
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
return content
|
||||||
|
|
||||||
|
elif name == "execute_python":
|
||||||
|
code = str(args.get("code"))
|
||||||
|
|
||||||
|
import builtins
|
||||||
|
import sys
|
||||||
|
import io
|
||||||
|
|
||||||
|
output_buffer = []
|
||||||
|
old_print = builtins.print
|
||||||
|
|
||||||
|
def custom_print(*args, **kwargs):
|
||||||
|
sep = kwargs.get('sep', ' ')
|
||||||
|
end = kwargs.get('end', '\n')
|
||||||
|
str_args = [str(arg) for arg in args]
|
||||||
|
msg = sep.join(str_args) + end
|
||||||
|
output_buffer.append(msg)
|
||||||
|
|
||||||
|
builtins.print = custom_print
|
||||||
|
|
||||||
|
error = None
|
||||||
|
try:
|
||||||
|
exec(code, globals())
|
||||||
|
except Exception as e:
|
||||||
|
tb_file = io.StringIO()
|
||||||
|
sys.print_exception(e, tb_file)
|
||||||
|
error_msg = tb_file.getvalue()
|
||||||
|
output_buffer.append(f"\nExecution Failed:\n{error_msg}")
|
||||||
|
error = e
|
||||||
|
finally:
|
||||||
|
builtins.print = old_print
|
||||||
|
|
||||||
|
output = "".join(output_buffer)
|
||||||
|
if error:
|
||||||
|
return output
|
||||||
|
return f"Execution Succeeded. Console output:\n{output}"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unknown tool: {name}")
|
raise ValueError(f"Unknown tool: {name}")
|
||||||
|
|||||||
Reference in New Issue
Block a user