ros2-mcp
README.md
# ros2-mcp
[](https://www.python.org/downloads/)
[](pyproject.toml)
[](LICENSE)
[](https://modelcontextprotocol.io)
[](https://github.com/mergeos-bounties)
**ros2-mcp** is an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server so AI agents (Grok, Cursor, Claude, …) can **inspect and control ROS2** graphs — topics, nodes, services, TF, actions — without hand-writing every `ros2` CLI call.
**Product:** [mergeos-bounties/ros2-mcp](https://github.com/mergeos-bounties/ros2-mcp)
---
## Install (one command)
### Grok — recommended
```bash
pip install "git+https://github.com/mergeos-bounties/ros2-mcp.git" && grok plugin install mergeos-bounties/ros2-mcp --trust
```
This installs the **Python CLI** (`ros2-mcp`) and the **Grok plugin** (skill + MCP server from `.mcp.json`).
Check:
```bash
ros2-mcp version
ros2-mcp doctor
ros2-mcp demo
grok plugin list
grok mcp list
```
Local clone:
```bash
git clone https://github.com/mergeos-bounties/ros2-mcp.git
cd ros2-mcp
pip install -e ".[dev]"
grok plugin install . --trust
```
### Other agents (stdio MCP)
After `pip install "git+https://github.com/mergeos-bounties/ros2-mcp.git"`, point any MCP host at:
| Field | Value |
| --- | --- |
| command | `ros2-mcp` |
| args | `["serve"]` |
| env | `ROS2_MCP_MODE=mock` |
**Claude Desktop** — merge [examples/claude_desktop_config.json](examples/claude_desktop_config.json) into Claude MCP config.
**Cursor** — merge [examples/cursor_mcp.json](examples/cursor_mcp.json).
**Grok config.toml** (manual, without plugin):
```toml
[mcp_servers.ros2_mcp]
command = "ros2-mcp"
args = ["serve"]
env = { ROS2_MCP_MODE = "mock" }
```
Or one-shot:
```bash
pip install "git+https://github.com/mergeos-bounties/ros2-mcp.git"
grok mcp add ros2-mcp -- ros2-mcp serve
```
## Supported AI agents / hosts
| Agent / Host | MCP support | Setup |
| --- | --- | --- |
| **Grok** (CLI / TUI / Build) | **Yes** | `grok plugin install mergeos-bounties/ros2-mcp --trust` then `pip install "git+https://github.com/mergeos-bounties/ros2-mcp.git"` |
| **Claude Desktop** | **Yes** | Copy [examples/claude_desktop_config.json](examples/claude_desktop_config.json) into Claude MCP settings |
| **Cursor** | **Yes** | Merge [examples/cursor_mcp.json](examples/cursor_mcp.json) into Cursor MCP config |
| **Claude Code** | **Yes** | stdio MCP: same `command`/`args` as Claude Desktop / Grok |
| **VS Code** (MCP / Continue / Cline) | **Yes** | Generic stdio server config pointing at `ros2-mcp serve` |
| **Windsurf / Cascade** | **Yes** | stdio MCP entry with `ros2-mcp` + `serve` |
| **Codex CLI** | **Yes** (stdio) | Register MCP server command `ros2-mcp serve` in Codex MCP settings |
| **ChatGPT Desktop** | **Partial** | Only if host supports custom MCP stdio servers |
| **Gemini CLI** | **Partial** | Only if MCP stdio plugins are enabled |
All packages speak **MCP over stdio** (`ros2-mcp serve`). Default mode is **mock** (offline, no simulator/terminal/GIMP required).
---
## Table of contents
- [Modes](#modes)
- [Highlights](#highlights)
- [Screenshots](#screenshots)
- [Quick start](#quick-start)
- [Docker image](#docker-image)
- [CLI reference](#cli-reference)
- [Lappa HTTP bridge tools](#lappa-http-bridge-tools)
- [MCP resources](#mcp-resources)
- [MCP host config](#mcp-host-config)
- [Diagrams](#diagrams)
- [Repository layout](#repository-layout)
- [Development](#development)
- [MergeOS bounties](#mergeos-bounties)
- [License](#license)
- [Configuration](#configuration)
- [IDE Configuration](#ide-configuration)
---
## Modes
All packages ship with **mock mode** as the default.
Parameter names and `value: "<redacted-live-value>"` so MCP host transcripts
and CI logs do not accidentally capture runtime configuration. Use
`ROS2_MCP_MODE=live` only when a live ROS2 graph is available.
| Feature | Mock | Live |
| --- | ---: | ---: |
| Topic list | ✅ | ✅ |
| Topic echo | ✅ | ✅ |
| Topic publish | ✅ | ✅ |
| Node list | ✅ | ✅ |
| Service list | ✅ | ✅ |
| Service call | ✅ | ✅ |
| TF tree | ✅ | ✅ |
| Actions | ✅ | ✅ |
| **Requires ROS2** | No | Yes |
---
## Highlights
| Capability | Description |
| --- | --- |
| **Offline demo** | `ros2-mcp demo` exercises doctor, topics, pub/echo, spawn, TF, actions |
| **MCP stdio serve** | Plug into agent hosts as an MCP server |
| **One-shot call** | `ros2-mcp call` without a full MCP host |
| **Tool list** | Discover registered MCP tools |
---
## Quick start
```bash
git clone https://github.com/mergeos-bounties/ros2-mcp.git
cd ros2-mcp
pip install -e ".[dev]"
ros2-mcp version
ros2-mcp demo
ros2-mcp tools list
```
---
## Docker image
Build a ROS2 Humble image with `ros2-mcp` installed into an isolated Python
environment:
```bash
docker build -t ros2-mcp:humble .
docker run --rm ros2-mcp:humble demo
```
Serve MCP over stdio from the container:
```bash
docker run --rm -i ros2-mcp:humble serve
```
---
## CLI reference
| Command | Description |
| --- | --- |
| `ros2-mcp version` | Version + mode |
| `ros2-mcp demo` | Offline smoke of core backend APIs |
| `ros2-mcp serve` | MCP server over **stdio** (for hosts) |
| `ros2-mcp serve --verbose` | Same, plus structured JSON tool-call logs on **stderr** |
| `ros2-mcp call …` | One-shot tool call (mock/live) |
| `ros2-mcp tools list` | List MCP tools |
| `ros2-mcp call topic_hz topic=/scan` | Parsed mock topic publish-rate sample |
| `ros2-mcp call lappa_pose base_url=http://127.0.0.1:8765` | Read Lappa `/sim/pose` with mock-safe fallback |
| `ros2-mcp call lappa_cmd_vel linear_x=0.3 angular_z=0.1` | Send Lappa `/sim/cmd_vel` with mock-safe fallback |
---
## Lappa HTTP bridge tools
Issue #33 adds optional Lappa simulator HTTP bridge helpers while keeping the
package safe for offline CI and MCP hosts. Configure a live bridge with:
```bash
export ROS2_MCP_LAPPA_URL=http://127.0.0.1:8765
```
Available tools:
| Tool | HTTP path | Fallback |
| --- | --- | --- |
| `ros2_lappa_pose` | `GET /sim/pose` | returns deterministic mock pose when Lappa is down |
| `ros2_lappa_cmd_vel` | `POST /sim/cmd_vel` | echoes a mock-safe cmd_vel + synthetic pose when Lappa is down |
CLI examples:
```bash
ros2-mcp call lappa_pose
ros2-mcp call lappa_cmd_vel linear_x=0.3 angular_z=0.1
```
Both commands avoid secrets and only use a local/user-configured base URL.
---
## MCP resources
In addition to tools, the server exposes an **MCP resource template** so hosts can
inspect the ROS2 graph structure.
> Note: the MCP SDK's URI-template matcher binds a single path segment, so a
> `ros2-mcp serve` emits **structured JSON logs to stderr only**. The MCP stdio transport uses **stdout** for the JSON-RPC protocol stream, so any log written to stdout would corrupt the protocol and break the host connection. All logging goes to stderr, leaving stdout clean for MCP.
| Command | Level | Description |
| --- | --- | --- |
| `ros2-mcp serve` | INFO | Lifecycle only: one `serve_start` record (transport, mode, tool count, version) |
| `ros2-mcp serve --verbose` (`-v`) | DEBUG | Per-tool-call records: `tool_call_start`, `tool_call` (with `duration_ms`, `status`), and `tool_call_error` (with traceback) on failure |
```json
{"ts": 1712345678.9, "level": "DEBUG", "logger": "ros2_mcp", "msg": "tool_call", "tool": "ros2_list_topics", "duration_ms": 1.42, "status": "ok"}
```
To capture logs to a file:
```bash
ros2-mcp serve --verbose 2> ros2-mcp.log
```
---
## MCP host config
```json
{
"mcpServers": {
"ros2-mcp": {
"command": "ros2-mcp",
"args": ["serve"],
"env": {
"ROS2_MCP_MODE": "mock"
}
}
}
}
```
Set `ROS2_MCP_MODE=live` only on machines with a working ROS2 environment.
---
## Diagrams
### Architecture
<img src="docs/diagrams/architecture.svg" alt="ros2-mcp architecture" width="100%" />
### Workflow
<img src="docs/diagrams/workflow.svg" alt="ros2-mcp workflow" width="100%" />
---
## Repository layout
```
ros2-mcp/
├── src/ros2_mcp/
│ ├── __init__.py
│ ├── server.py # FastMCP tools
│ ├── mock_backend.py # Mock ROS2 graph
│ └── live_backend.py # Live ROS2 graph
├── tests/
├── docs/
├── examples/
├── scripts/
├── .mcp.json
└── pyproject.toml
```
---
## Development
```bash
git clone https://github.com/mergeos-bounties/ros2-mcp.git
cd ros2-mcp
pip install -e ".[dev]"
pytest -q
ruff check src/
ros2-mcp demo
```
---
## MergeOS bounties
Star → claim → PR **master** → MRG **25–200**. Evidence: CLI logs / MCP host config snippets (redact secrets).
---
## License
MIT
---
## Configuration
See [MCP_HOST_CONFIG.md](docs/MCP_HOST_CONFIG.md) for Claude/Cursor setup.
---
## IDE Configuration
- [Cursor MCP Config](docs/CURSOR_MCP_CONFIG.md) — Copy-paste configuration for Cursor IDE with mock/live modes
- [Live vs Mock Safety Matrix](docs/LIVE_VS_MOCK_SAFETY_MATRIX.md) — Safety considerations for live vs mock modes
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessUnresponsive