# ROS1 Noetic MCP Server
An MCP (Model Context Protocol) server that provides LLM access to ROS1 Noetic robotic systems. Built with [FastMCP](https://gofastmcp.com) and deployed as a Docker container.
## Claude Code Quick Start
Add ROS MCP to Claude Code with a single command:
```bash
claude mcp add ros \
-e ROS_MASTER_URI=http://localhost:11311 \
-- docker run -i --rm --network host \
-e ROS_MASTER_URI \
ghcr.io/lopisan/ros-mcp --transport stdio
```
For remote ROS master:
```bash
claude mcp add ros \
-e ROS_MASTER_URI=http://192.168.1.100:11311 \
-e ROS_IP=192.168.1.50 \
-- docker run -i --rm --network host \
-e ROS_MASTER_URI -e ROS_IP \
ghcr.io/lopisan/ros-mcp --transport stdio
```
## Features
- **Topic Management**: List, publish, subscribe, and echo ROS topics
- **Service Management**: List and call ROS services
- **Parameter Management**: Get, set, list, and delete ROS parameters
- **Node Inspection**: List nodes and get detailed node information
- **TF Transforms**: Query coordinate frame transforms, transform points/poses
- **Message Introspection**: View message and service definitions
## Quick Start
### Prerequisites
- Docker and Docker Compose
- Running ROS1 Noetic system with roscore
### Running with Docker Compose
1. Clone this repository:
```bash
git clone <repository-url>
cd ros_mcp
```
2. Set environment variables (optional):
```bash
export ROS_MASTER_URI=http://localhost:11311
export ROS_IP=127.0.0.1
```
3. Start the MCP server:
```bash
docker compose up -d
```
The server will be available at `http://localhost:8000/mcp`.
### Running with stdio transport (for local development)
```bash
docker compose --profile stdio up ros-mcp-server-stdio
```
## Testing the Server
### Using MCP Inspector
The easiest way to test the MCP server is using the official MCP Inspector:
```bash
npx @modelcontextprotocol/inspector http://localhost:8000/mcp
```
This opens an interactive web UI where you can:
- Browse available tools and resources
- Test tool calls with custom parameters
- View server responses in real-time
## Configuration
### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `ROS_MASTER_URI` | `http://localhost:11311` | URI of the ROS master |
| `ROS_IP` | `127.0.0.1` | IP address of this machine for ROS networking |
| `MCP_TRANSPORT` | `http` | Transport mode: `http`, `sse`, or `stdio` |
| `MCP_PORT` | `8000` | Port for HTTP transport |
### MCP Client Configuration
Add to your MCP client configuration (e.g., Claude Desktop):
```json
{
"mcpServers": {
"ros": {
"url": "http://localhost:8000/mcp"
}
}
}
```
### Claude Code Configuration
Add the MCP server to Claude Code using stdio transport:
```bash
# Local ROS master
claude mcp add ros \
-e ROS_MASTER_URI=http://localhost:11311 \
-- docker run -i --rm --network host \
-e ROS_MASTER_URI \
ros_mcp-ros-mcp-server --transport stdio
```
```bash
# Remote ROS master
claude mcp add ros \
-e ROS_MASTER_URI=http://192.168.1.100:11311 \
-e ROS_IP=192.168.1.50 \
-- docker run -i --rm --network host \
-e ROS_MASTER_URI -e ROS_IP \
ros_mcp-ros-mcp-server --transport stdio
```
Other useful commands:
```bash
# List configured MCP servers
claude mcp list
# Remove the server
claude mcp remove ros
```
## Available Tools
### Topic Tools
| Tool | Description |
|------|-------------|
| `ros_list_topics` | List all active ROS topics |
| `ros_get_topic_info` | Get detailed information about a topic |
| `ros_publish` | Publish a message to a topic |
| `ros_subscribe_once` | Get a single message from a topic |
| `ros_echo_topic` | Get multiple messages from a topic |
### Service Tools
| Tool | Description |
|------|-------------|
| `ros_list_services` | List all available services |
| `ros_get_service_info` | Get service details |
| `ros_call_service` | Call a ROS service |
### Parameter Tools
| Tool | Description |
|------|-------------|
| `ros_list_params` | List all parameters |
| `ros_get_param` | Get a parameter value |
| `ros_set_param` | Set a parameter value |
| `ros_delete_param` | Delete a parameter |
| `ros_has_param` | Check if parameter exists |
| `ros_search_param` | Search for a parameter |
### Node Tools
| Tool | Description |
|------|-------------|
| `ros_list_nodes` | List all active nodes |
| `ros_get_node_info` | Get node publications, subscriptions, services |
| `ros_ping_node` | Check if a node is responsive |
| `ros_get_master_info` | Get ROS master information |
### Message Tools
| Tool | Description |
|------|-------------|
| `ros_show_msg` | Show message type definition |
| `ros_show_srv` | Show service type definition |
| `ros_list_msg_types` | List available message types |
| `ros_list_srv_types` | List available service types |
| `ros_msg_md5` | Get message type MD5 sum |
### TF Transform Tools
| Tool | Description |
|------|-------------|
| `ros_list_frames` | List all TF frames |
| `ros_lookup_transform` | Get transform between frames |
| `ros_can_transform` | Check if transform is available |
| `ros_get_frame_tree` | Get TF tree structure |
| `ros_transform_point` | Transform a point between frames |
| `ros_transform_pose` | Transform a pose between frames |
## Available Resources
| Resource URI | Description |
|--------------|-------------|
| `ros://system/status` | System connectivity status |
| `ros://topics` | List of all topics |
| `ros://nodes` | List of all nodes |
| `ros://services` | List of all services |
| `ros://params` | List of all parameters |
| `ros://topic/{name}` | Topic info and latest message |
| `ros://node/{name}` | Node information |
| `ros://param/{name}` | Parameter value |
| `ros://tf/frames` | List of TF frames |
## Example Usage
### List all topics
```
Use the ros_list_topics tool to see what topics are available.
```
### Get robot position
```
Use ros_subscribe_once on the /odom topic to get the current odometry.
```
### Send a velocity command
```
Use ros_publish to send a geometry_msgs/Twist message to /cmd_vel with linear.x = 0.5.
```
### Check TF transform
```
Use ros_lookup_transform to get the transform from base_link to map.
```
## Development
### Building locally
```bash
# Build the Docker image
docker build -t ros-mcp-server .
# Run with custom settings
docker run --network host \
-e ROS_MASTER_URI=http://localhost:11311 \
ros-mcp-server
```
### Running without Docker
Requires ROS Noetic environment:
```bash
# Source ROS
source /opt/ros/noetic/setup.bash
# Install dependencies
pip install -e .
# Run the server
python -m ros_mcp_server --transport http --port 8000
```
### Project Structure
```
ros_mcp/
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml
├── requirements.txt
├── README.md
└── src/
└── ros_mcp_server/
├── __init__.py
├── __main__.py
├── server.py
├── tools/
│ ├── topics.py
│ ├── services.py
│ ├── params.py
│ ├── nodes.py
│ ├── messages.py
│ └── transforms.py
├── resources/
│ └── ros_resources.py
└── utils/
├── ros_bridge.py
└── message_utils.py
```
## Troubleshooting
### Cannot connect to ROS master
1. Ensure roscore is running
2. Check `ROS_MASTER_URI` is correct
3. Verify network connectivity (use `network_mode: host` in Docker)
### Transform lookup fails
1. Wait for TF data to be published
2. Check that both frames exist with `ros_list_frames`
3. Verify the transform chain exists with `ros_get_frame_tree`
### Message type not found
1. Ensure the message package is installed in the Docker container
2. For custom messages, mount the workspace or rebuild the Docker image
## License
MIT License
## References
- [FastMCP Documentation](https://gofastmcp.com)
- [ROS Noetic Documentation](http://wiki.ros.org/noetic)
- [MCP Protocol](https://modelcontextprotocol.io)