Docs / Contact / ai/local-dev-server
Local Dev Server
The local dev server (tendrl-dev-mcp) lets AI assistants interact with physical MicroPython devices over USB serial. It runs as a local binary on your machine, no cloud connection needed.
Installing
One command — it detects your platform, verifies checksums, and installs the binary as tendrl-dev-mcp on your PATH, which is exactly the bare command the MCP config below and every example on this page invoke:
# macOS / Linux
curl -fsSL https://app.tendrl.com/api/public/tools/dev-mcp/v1/latest/install.sh | sh
# Windows
powershell -c "irm https://app.tendrl.com/api/public/tools/dev-mcp/v1/latest/install.ps1 | iex"
Direct per-platform downloads are listed on the Resources page, alongside SHA256SUMS.txt for verifying one. Those artifacts are named for their platform (e.g. tendrl-dev-mcp-darwin-arm64) — rename onto your PATH, or give the MCP config the full path.
Single binary, no runtime dependencies. For firmware flashing you'll also need:
- ESP32 boards:
pip install esptool - Pico W:
brew install picotool(macOS) orapt install picotool(Linux)
Available tools
| Tool | Description |
|---|---|
list_serial_ports |
Discover connected microcontroller boards |
detect_board |
Get board type, MicroPython version, memory stats |
flash_micropython |
Flash MicroPython firmware (ESP32, Pico W) |
upload_sdk |
Install the Tendrl MicroPython SDK to a device over serial |
install_client |
Install the SDK over Wi-Fi (device downloads via mip) |
write_config |
Write API key, WiFi credentials, and endpoint to device config |
upload_file |
Upload any file to the device filesystem |
list_files |
List files on the device |
read_device_file |
Read a file from the device (credentials auto-redacted) |
run_script |
Execute Python code on the device and return output |
reset_device |
Soft-reset the device |
serial_monitor |
Read serial output for debugging (max 10 seconds) |
capture_frame |
Capture one frame from an OpenMV camera and return it as an image, so the assistant can see the scene |
start_camera_preview |
Stream the camera live to a local URL, where you watch the same camera the assistant sees. USB only, nothing leaves the machine |
stop_camera_preview |
Stop the preview and release the serial port |
start_serial_log |
Stream the device's stdout to a local URL to watch a boot sequence or a running script live in a browser |
stop_serial_log |
Stop the serial log and release the serial port |
provision_device |
One shot: flash → write config → install SDK → upload main.py → reset → read the boot log |
diagnose_device |
One shot: detect board → check config → probe WiFi/filesystem/memory → read serial |
Client setup
Add the local dev server alongside Contact in your MCP config:
{
"mcpServers": {
"contact": {
"url": "https://app.tendrl.com/contact/mcp",
"headers": { "Authorization": "Bearer <CONTACT_API_KEY>" }
},
"tendrl-dev": {
"command": "tendrl-dev-mcp"
}
}
}
AI Skills
When you add the local dev server to your MCP config, skills are served automatically; no plugins needed. The binary must be on your PATH.
Included skills
| Skill | What it does | Example triggers |
|---|---|---|
dev-provision |
Flash firmware, configure WiFi, install the Tendrl SDK | "flash this ESP32", "set up a new device", "install MicroPython" |
dev-files |
Upload code, list/read files, run scripts on devices | "upload main.py to the device", "what files are on the board" |
dev-debug |
Monitor serial output, reset devices, diagnose issues | "device stopped reporting", "check serial output", "reset the board" |
vision-build |
Look through an OpenMV camera, write a detector, run it, tune it | "tell me when the coffee pot is empty", "watch this lamp", "alert me if the gate is open" |
tendrl-orchestrate |
End-to-end workflows across Contact and dev-mcp | "provision a device end to end", "deploy a fleet of sensors" |
The tendrl-orchestrate skill guides Claude through multi-step workflows that hand data between Contact and the local device: creating an entity, taking the API key you provide, writing it to the board, installing the SDK, and verifying data flow.
The Contact MCP server has no tool to create an API key; it can only list key metadata (list_api_keys), never the token itself. Create the device's API key yourself in the dashboard under Access Control → API Keys and paste it into the conversation when the orchestration reaches the credential step. The AI then writes that key to the board with write_config.
Security notes
Approve tool calls for hardware operations. MCP clients prompt you before each tool call. Pay attention to flash_micropython (erases device flash) and run_script (executes arbitrary code on the device).
API keys pass through the conversation. When the AI reads an API key from Contact and writes it to a device via write_config, the key is visible in the chat. Use development keys during prototyping.
Device config files contain plaintext credentials. WiFi passwords and API keys are written in cleartext to the MicroPython filesystem, a hardware constraint. Anyone with physical access and a USB cable could read them.
read_device_file redacts secrets automatically. Credentials are masked (e.g., "tk_ab****") so they don't leak into conversation history.
Examples
Provision a device end-to-end
"Set up this ESP32 as a temperature sensor"
With both plugins installed, the AI orchestrates across Contact and dev-mcp:
contact→create_entity(register the device)- You create the device's API key in the dashboard (Access Control → API Keys) and paste it in, since the AI cannot mint keys
tendrl-dev→list_serial_ports→flash_micropython(flash firmware)tendrl-dev→write_config(inject API key + WiFi)tendrl-dev→install_client(install SDK)tendrl-dev→upload_file(deploy application code)tendrl-dev→reset_device→serial_monitor(verify boot)contact→list_messages(confirm data arriving)
Debug a device
"Why isn't this sensor sending data?"
The AI uses serial_monitor to check device output, read_device_file to verify config, and run_script to test WiFi connectivity, then correlates with contact:search_messages to find where the pipeline breaks.
Tendrl