
mergeos-bounties/ros2-mcp
Developer toolsros2-mcp — MCP server for AI agents to inspect and control ROS2
Overview
is an MCP (Model Context Protocol) server so AI agents (Grok, Cursor, Claude, …) can graphs — topics, nodes, services, TF, actions — without hand-writing every ros2 CLI call. This installs the (ros2-mcp) and the (skill + MCP server from .mcp.json). After pip install "git+https://github.com/mergeos-bounties/ros2-mcp.git", point any MCP host at: — merge examples/claude_desktop_config.json into Claude MCP config. All packages speak (ros2-mcp serve). Default mode is (offline, no simulator/terminal/GIMP required). All packages ship with as the default. Parameter names and 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. Build a ROS2 Humble image with ros2-mcp installed into an isolated Python environment: Serve MCP over stdio from the container:
README
ros2-mcp
ros2-mcp is an MCP (Model Context Protocol) 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
Install (one command)
Grok — recommended
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:
ros2-mcp version
ros2-mcp doctor
ros2-mcp demo
grok plugin list
grok mcp list
Local clone:
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 into Claude MCP config.
Cursor — merge examples/cursor_mcp.json.
Grok config.toml (manual, without plugin):
[mcp_servers.ros2_mcp]
command = "ros2-mcp"
args = ["serve"]
env = { ROS2_MCP_MODE = "mock" }
Or one-shot:
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 into Claude MCP settings |
| Cursor | Yes | Merge 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
- Highlights
- Screenshots
- Quick start
- Docker image
- CLI reference
- Lappa HTTP bridge tools
- MCP resources
- MCP host config
- Diagrams
- Repository layout
- Development
- MergeOS bounties
- License
- Configuration
- IDE Configuration
Modes
All packages ship with mock mode as the default.
Parameter names and 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
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:
docker build -t ros2-mcp:humble .
docker run --rm ros2-mcp:humble demo
Serve MCP over stdio from the container:
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:
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:
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 serveemits 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 |
{"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:
ros2-mcp serve --verbose 2> ros2-mcp.log
MCP host config
{
"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
Workflow
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
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 for Claude/Cursor setup.
IDE Configuration
- Cursor MCP Config — Copy-paste configuration for Cursor IDE with mock/live modes
- Live vs Mock Safety Matrix — Safety considerations for live vs mock modes
Install
docker run --rm ros2-mcp:humble demoConfiguration
{
"mcpServers": {
"ros2-mcp": {
"command": "ros2-mcp",
"args": ["serve"],
"env": {
"ROS2_MCP_MODE": "mock"
}
}
}
}