Skip to main content
Glama
eoinjordan

arduino-claude-mcp

by eoinjordan
README.md
# arduino-claude-mcp

[![npm version](https://img.shields.io/npm/v/arduino-claude-mcp.svg)](https://www.npmjs.com/package/arduino-claude-mcp)
[![publish](https://github.com/eoinjordan/arduino-mcp/actions/workflows/publish.yml/badge.svg)](https://github.com/eoinjordan/arduino-mcp/actions/workflows/publish.yml)
[![docker publish](https://github.com/eoinjordan/arduino-mcp/actions/workflows/docker-publish.yml/badge.svg)](https://github.com/eoinjordan/arduino-mcp/actions/workflows/docker-publish.yml)

MCP server for Arduino IDE 2.0 sketches. It exposes a small REST API plus an MCP stdio bridge so agents can read and write the main `.ino` file, list sources, and optionally compile with `arduino-cli`.

## Features
- Validate an Arduino sketch folder
- Read and write source files (defaults to main `.ino`)
- List .ino/.h/.cpp/.c files
- Compile with `arduino-cli` (optional)
- REST + MCP stdio transport

## Requirements
- An Arduino sketch folder (Arduino IDE 2.0 format)
- Node.js 18+
- Optional: `arduino-cli` for builds

## Installation

Global install:

```sh
npm install -g arduino-claude-mcp
```

Local dev:

```sh
npm install
npm run build
npm run build:mcp
```

Container image:

```sh
docker pull eoinedge/arduino-mcp:latest
```

## Usage

### Run the REST server

```sh
arduino-claude-mcp
```

Defaults to port `3080`. Override with:

```sh
$env:PORT=3081
arduino-claude-mcp
```

### Run with Docker (Pi/OpenClaw)

```sh
docker run --rm --network host \
  -e PORT=3080 \
  -e ARDUINO_FQBN=arduino:mbed_nano:nano33ble \
  -v /home/pi/pi-openclaw-mcp-stack/workspace/Arduino:/workspace \
  eoinedge/arduino-mcp:latest
```

### Run the MCP stdio server

```sh
node build/mcp.js
```

If your REST server is not on the default port, set one of:
- `ARDUINO_API_URL` (full URL, for example `http://localhost:3081`)
- `ARDUINO_API_PORT` (port only, for example `3081`)

### MCP client config

```json
{
  "mcpServers": {
    "arduino-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/build/mcp.js"]
    }
  }
}
```

## Tutorial (10 minutes)

1) Create a sketch folder whose main `.ino` matches the folder name.
2) Validate it:
   - `POST /validate`
   - Body: `{ "projectRoot": "/path/to/MySketch" }`
3) Read the main sketch:
   - `POST /read_source`
   - Body: `{ "projectRoot": "/path/to/MySketch" }`
4) Write a small change:
   - `POST /write_source`
   - Body: `{ "projectRoot": "/path/to/MySketch", "content": "// your code" }`
5) Build (optional):
   - Set `ARDUINO_FQBN` (example `arduino:avr:uno`)
   - `POST /build`
   - Body: `{ "projectRoot": "/path/to/MySketch" }`

## Environment variables
- `PORT`: REST server port (default `3080`)
- `ARDUINO_API_URL`: REST base URL for the MCP bridge
- `ARDUINO_API_PORT`: REST port for the MCP bridge
- `ARDUINO_CLI`: arduino-cli executable (default `arduino-cli`)
- `ARDUINO_FQBN`: fully qualified board name for compile
- `ARDUINO_BUILD_TIMEOUT_MS`: build timeout in ms (default `120000`)

## REST API

### Health
- `GET /health` -> `{ status: "ok" }`

### Validate
- `POST /validate` body: `{ projectRoot: string }`
- Returns `{ valid, inoPath, projectRoot }`

### List sources
- `POST /list_sources` body: `{ projectRoot: string }`
- Returns `{ files: string[] }`

### Read source
- `POST /read_source` body: `{ projectRoot: string, relativePath?: string }`
- Returns `{ path, content }`

### Write source
- `POST /write_source` body: `{ projectRoot: string, relativePath?: string, content: string }`
- Returns `{ success, path, bytes }`

### Append source
- `POST /append_source` body: `{ projectRoot: string, relativePath?: string, content: string }`
- Returns `{ success, path, bytes }`

### Build
- `POST /build` body: `{ projectRoot: string, timeoutMs?: number }`
- Returns `{ success, exitCode, stdout, stderr }`
- Requires `arduino-cli` and `ARDUINO_FQBN`

## Clawdbot / Moltbot compatibility
This repo ships a skill at `skills/arduino-mcp/SKILL.md`.

Enable it in Moltbot:

```json
{
  "skills": {
    "load": {
      "extraDirs": ["~/.clawdbot/skills"],
      "watch": true,
      "watchDebounceMs": 250
    },
    "entries": {
      "arduino-mcp": {
        "enabled": true,
        "env": {}
      }
    }
  }
}
```

## Example prompts
- "Open this Arduino sketch and add a blinking LED on pin 13."
- "List all source files and explain what each does."
- "Append a serial debug line and recompile for an Uno board."

## Testing

```sh
npm test
```

Tests use a temporary sketch folder and do not require `arduino-cli`.

## Publishing
1. Update `package.json` version
2. Build:
   ```sh
   npm run build
   npm run build:mcp
   ```
3. Publish:
   ```sh
   npm publish --access public
   ```
4. Tag and push to trigger `.github/workflows/publish.yml`

## Docker publishing

Manual push:

```sh
docker login
docker buildx build --platform linux/amd64,linux/arm64 \
  -t eoinedge/arduino-mcp:latest \
  -t eoinedge/arduino-mcp:<version> \
  --push .
```

GitHub Actions:
- `docker-publish.yml` pushes Docker images on `main` and version tags.
- Required repo secrets:
  - `DOCKERHUB_USERNAME`
  - `DOCKERHUB_TOKEN`

## Project structure
- `src/index.ts` REST API
- `src/mcp.ts` MCP stdio bridge
- `skills/arduino-mcp/SKILL.md` agent skill
- `server.json` MCP registry metadata

## Contributing
PRs welcome. Please keep changes small and include tests where possible.

## License
MIT