tinySA_mcp
This project is an MCP server for controlling the TinySA device through a serial port. It provides various MCP tools for connecting, commanding, and interacting with the device, using a Tkinter-based GUI for user interaction and threading for concurrent operations.
tinysa-mcp
MCP server for operating TinySA through serial port
Sorry, I'm currently experimenting and cannot guarantee that it will work properly.
Overview
This project is an MCP server designed to operate a TinySA device via a serial port. It leverages Python libraries such as pyserial, httpx, numpy, Pillow, and FastMCP to provide a tool-based interface for connecting to the device, executing commands, and retrieving device version information.
Architecture and Threading Model
This project uses both a Tkinter-based GUI and an MCP server. Due to Tkinter's requirement to run in the main thread, the following design is used:
flowchart TD
subgraph MainThread
A[main()] --> B[tk.Tk() & TinySALogMonitor]
B --> C[root.mainloop()]
end
subgraph MCPThread
D[run_mcp_server(mcp_server)]
D --> E[mcp_server.run()]
end
E -- log_callback --> F[log_monitor.log_queue]
F -- root.afterで定期ポーリング --> B
D -- サーバー終了時 --> G[root.after(0, root.destroy)]
-
Tkinter GUI runs in the main thread:
The main thread initializes the Tkinter root window and starts the main event loop. All GUI operations are performed in this thread. -
MCP server runs in a background thread:
The MCP server is started in a separate thread using Python'sthreading.Thread
. This allows the server to handle requests concurrently with the GUI. -
Thread-safe communication via queue:
Log messages and other data from the MCP server (or other background threads) are sent to the GUI using aqueue.Queue
. The GUI periodically polls this queue usingroot.after
to update the display safely. -
Graceful shutdown:
When the MCP server stops, it schedules the GUI to close usingroot.after(0, root.destroy)
, ensuring all Tkinter operations remain in the main thread.
Example (main function):
def main():
root = tk.Tk()
log_monitor = TinySALogMonitor(root)
mcp_server = create_mcp_server(log_monitor.add_log)
mcp_thread = threading.Thread(target=run_mcp_server, args=(mcp_server,), daemon=True)
mcp_thread.start()
root.mainloop()
Notes
- Do not access Tkinter objects from background threads.
Always use the provided queue androot.after
for thread-safe communication. - This design ensures both the MCP server and the GUI can run concurrently without violating Tkinter's threading requirements.
Features
- Send commands and retrieve responses from the device.
- Retrieve firmware and hardware version information.
- Exposes MCP tools for integration with other systems.
- Supports image capture from the device screen, and optional file saving with timestamps.
MCP Tools
The following MCP tools are available:
- get_version: Retrieve version information from the TinySA device.
- execute_command: Send a command to the TinySA device and get the response.
- connect: Connect to the TinySA device on a specified port.
- disconnect: Disconnect the TinySA device.
- get_device_info: Retrieve detailed information about the connected device.
- capture_image: Capture the TinySA screen image and optionally save it to a file with a timestamp.
Usage Example
Invoke the MCP tools using an MCP client. For example, to get the device version:
mcp call get_version --args '{"port": "COM4"}'
Troubleshooting
- Connection Issues: Ensure the specified serial port is correct and that your user has appropriate permissions.
- Command Failures: Check the MCP server logs (if available) for error messages.
- Image Capture: Verify that the device returns sufficient data (307200 bytes) during image capture.
- Refer to the Model Context Protocol documentation for more information on MCP integration.
Materials
Refer to the material
directory for additional documentation, it will be good to add the file "USB interface.txt" as a AI knowledge.
License
This project is licensed under the MIT License.