Content
# ROSClaw-Native Nav2 MCP Server
[](https://docs.ros.org)
[](https://www.python.org/)
[](https://opensource.org/licenses/Apache-2.0)
[](https://modelcontextprotocol.io/)
> Production-grade MCP server for Nav2 autonomous navigation with ROSClaw OS integration.
> **"Teach Once, Embody Anywhere. Share Skills, Shape Reality."**
[中文文档](README.zh.md) | [Documentation](https://docs.rosclaw.org/nav2-mcp)
---
## Overview
`rosclaw-nav2-mcp` is a ROSClaw-Native MCP (Model Context Protocol) server that bridges Large Language Models (LLMs) with Nav2 autonomous navigation for mobile robots. It implements 6 ROSClaw-Native Standards for production-grade embodied AI applications.
### Key Features
- **Asynchronous ROS 2 Actions**: Non-blocking action clients with async/await
- **Flywheel-Ready Responses**: Structured JSON for Data Flywheel ingestion
- **Digital Twin Firewall**: MuJoCo-based safety validation before real execution
- **Graceful Preemption**: Active task tracking with cancel support
- **State-Aware Affordance**: Local state machine prevents invalid operations
- **Semantic Spatial Binding**: TF2 integration for semantic navigation targets
### Supported Robots
- TurtleBot3 / TurtleBot4
- Unitree Go2 / G1 (with mobile base)
- Clearpath Husky
- Any ROS 2 mobile robot with Nav2
---
## Installation
### Prerequisites
- ROS 2 Humble or Jazzy
- Python 3.10+
- Nav2 installed
### Install from PyPI
```bash
pip install rosclaw-nav2-mcp
```
### Install from Source
```bash
git clone https://github.com/ros-claw/rosclaw-nav2-mcp.git
cd rosclaw-nav2-mcp
pip install -e ".[dev]"
```
---
## Quick Start
### 1. Start ROS 2 and Nav2
```bash
# Terminal 1: Start ROS 2
source /opt/ros/humble/setup.bash
ros2 launch nav2_bringup navigation_launch.py
```
### 2. Start the MCP Server
```bash
# Terminal 2: Start MCP Server
rosclaw-nav2-mcp
```
Or with explicit transport:
```bash
python -m rosclaw_nav2_mcp.server --transport stdio
```
### 3. Configure MCP Client
Add to your MCP client configuration (e.g., Claude Desktop):
```json
{
"mcpServers": {
"rosclaw-nav2": {
"command": "rosclaw-nav2-mcp",
"transportType": "stdio"
}
}
}
```
---
## Available Tools
| Tool | Description | ROSClaw Standard |
|------|-------------|------------------|
| `nav2_get_state` | Get current pose & navigation status | State-Aware |
| `nav2_navigate_to_pose` | Navigate to (x, y, theta) with semantic labels | Async Actions |
| `nav2_navigate_to_pose_firewalled` | Navigate with MuJoCo validation | Firewall |
| `nav2_navigate_through_waypoints` | Multi-waypoint navigation | Async Actions |
| `nav2_cancel_navigation` | Cancel active navigation | Preemption |
| `nav2_lookup_tf_pose` | TF2 semantic pose lookup | TF2 Binding |
| `nav2_get_active_navigations` | List active navigation tasks | State-Aware |
| `nav2_dock_robot` | Dock to charging station | State-Aware |
| `nav2_set_semantic_location` | Set semantic location context | Data Flywheel |
---
## Usage Examples
### Basic Navigation
```python
# Navigate to a specific pose
result = await nav2_navigate_to_pose(
x=2.5, y=1.0, theta=1.57,
semantic_label="Go to kitchen"
)
```
### Semantic Navigation
```python
# Use TF frames for semantic navigation
result = await nav2_navigate_to_pose(
x=0, y=0, theta=0, # Overridden by TF lookup
target_tf_frame="kitchen_table", # Automatic pose lookup
semantic_label="Navigate to kitchen table"
)
```
### Firewalled Navigation
```python
# Validate path in MuJoCo before real execution
result = await nav2_navigate_to_pose_firewalled(
x=2.5, y=1.0, theta=1.57,
semantic_label="Safe navigation to charging dock"
)
# Returns validation status in result.firewall_validated
```
### Waypoint Navigation
```python
# Navigate through multiple waypoints
waypoints = "[[1.0, 2.0, 0.0], [3.0, 4.0, 1.57], [5.0, 2.0, 3.14]]"
result = await nav2_navigate_through_waypoints(
waypoints_json=waypoints,
semantic_label="Patrol route A"
)
```
### Cancel Navigation
```python
# Cancel active navigation
result = await nav2_cancel_navigation(
task_id="nav12345"
)
```
---
## ROSClaw-Native Standards
### 1. Asynchronous ROS 2 Actions
Non-blocking action clients using `rclpy.action.ActionClient` with async/await:
```python
# Non-blocking navigation
result = await nav2_client.navigate_to_pose(...)
# Other operations can run concurrently
```
### 2. Flywheel-Ready Responses
All responses are structured JSON for Data Flywheel ingestion:
```json
{
"status": "SUCCEEDED",
"action_id": "nav12345",
"action_type": "navigate_to_pose",
"semantic_goal": "Go to kitchen",
"timestamp_start": 1234567890.0,
"timestamp_end": 1234567895.0,
"duration_seconds": 5.0,
"start_pose": {"x": 0.0, "y": 0.0, "theta": 0.0},
"goal_pose": {"x": 2.5, "y": 1.0, "theta": 1.57},
"path": {
"waypoints": 1,
"estimated_length_meters": 5.2
},
"execution": {
"success": true,
"error_code": null,
"error_message": null
},
"safety": {
"firewall_validated": true,
"violations": []
}
}
```
### 3. Firewall Integration
MuJoCo-based path validation before real execution:
```python
@mujoco_firewall(
model_path="src/rosclaw/specs/nav2_sim.xml",
safety_level=SafetyLevel.MODERATE
)
async def nav2_navigate_to_pose_firewalled(...):
# Only executes if MuJoCo validation passes
```
### 4. Graceful Preemption
Cancel active navigation without system instability:
```python
async def cancel_navigation(self, task_id: str) -> Dict[str, Any]:
goal_handle = self._active_tasks[task_id]
cancel_future = goal_handle.cancel_goal_async()
cancel_result = await self._await_future(cancel_future)
```
### 5. State-Aware Affordance
Local state machine prevents invalid operations:
```python
if self.state.is_navigating:
return Nav2ActionResult(
status=NavigationStatus.REJECTED,
error_message="Robot is already navigating."
)
```
### 6. Semantic Spatial Binding
TF2 integration for semantic navigation:
```python
# LLM just provides semantic frame names
pose = await lookup_tf_pose("kitchen_table", "map")
# No coordinate math required!
```
---
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ LLM Agent (Claude, etc.) │
└─────────────────────────────────────────────────────────────┘
│ MCP Protocol
▼
┌─────────────────────────────────────────────────────────────┐
│ ROSClaw-Native Nav2 MCP Server │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Async Action │ │ State Machine│ │ TF2 Semantic │ │
│ │ Client │ │ │ │ Binding │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Flywheel JSON│ │ Firewall │ │ Preemption │ │
│ │ Responses │ │ Validation │ │ Support │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ ROS 2 Actions
▼
┌─────────────────────────────────────────────────────────────┐
│ Nav2 Navigation Stack │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Physical Mobile Robot │
└─────────────────────────────────────────────────────────────┘
```
---
## Configuration
### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `ROS_NAMESPACE` | `` | ROS namespace prefix |
| `NAV2_MAP_FRAME` | `map` | Default map frame |
| `FIREWALL_MODEL_PATH` | `nav2_sim.xml` | MuJoCo model for validation |
| `FIREWALL_SAFETY_LEVEL` | `MODERATE` | Safety validation level |
### Robot Configuration
Create `robot_config.yaml`:
```yaml
navigation:
map_frame: "map"
odom_frame: "odom"
base_frame: "base_link"
max_waypoints: 100
velocity_limits:
linear:
max: 0.5
min: 0.1
angular:
max: 1.0
min: 0.1
firewall:
model_path: "models/turtlebot3.xml"
safety_level: MODERATE
```
---
## Development
### Setup Development Environment
```bash
git clone https://github.com/ros-claw/rosclaw-nav2-mcp.git
cd rosclaw-nav2-mcp
# Create virtual environment
python -m venv .venv
source .venv/bin/activate
# Install with dev dependencies
pip install -e ".[dev]"
```
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=rosclaw_nav2_mcp --cov-report=term-missing
# Run specific test
pytest tests/test_navigation.py -v
```
### Code Quality
```bash
# Format code
ruff format .
# Check linting
ruff check .
# Type checking
mypy src/rosclaw_nav2_mcp
```
---
## Data Flywheel Integration
All navigation results are structured for automatic Data Flywheel ingestion:
```python
{
"status": "SUCCEEDED",
"semantic_goal": "Go to kitchen",
"start_pose": {...},
"goal_pose": {...},
"path": {...},
"execution": {...},
"safety": {...}
}
```
This data feeds into:
- **Skill Learning**: VLA model training
- **Path Planning**: Improved navigation algorithms
- **Failure Analysis**: Automatic root cause analysis
---
## Safety Features
### Digital Twin Firewall
All navigation validated in MuJoCo before real execution:
```python
@mujoco_firewall(
model_path="turtlebot3.xml",
safety_level=SafetyLevel.MODERATE
)
```
### Obstacle Avoidance
Nav2's built-in obstacle detection and avoidance.
### Dynamic Replanning
Automatic path replanning when obstacles are detected.
### Emergency Stop
Immediate cancellation via `nav2_cancel_navigation()`.
---
## Troubleshooting
### Server won't start
```bash
# Check ROS 2 environment
echo $ROS_DISTRO
source /opt/ros/humble/setup.bash
# Check Nav2 is running
ros2 topic list | grep navigate_to_pose
```
### Navigation fails
```bash
# Check robot pose
ros2 topic echo /amcl_pose
# Check costmaps
ros2 service call /global_costmap/clear_entirely std_srvs/srv/Empty
# Verify navigation stack
ros2 node list | grep navigator
```
### TF lookup fails
```bash
# Check TF tree
ros2 run tf2_tools view_frames
# Echo specific transform
ros2 topic echo /tf
```
---
## Contributing
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
### Development Workflow
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit changes (`git commit -m 'Add amazing feature'`)
4. Push to branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
---
## Related Projects
- [rosclaw-moveit2-mcp](https://github.com/ros-claw/rosclaw-moveit2-mcp) - MoveIt2 MCP Server
- [rosclaw-firewall](https://github.com/ros-claw/rosclaw-firewall) - Digital Twin Firewall
- [sdk_to_mcp](https://github.com/ros-claw/sdk_to_mcp) - SDK to MCP Generator
- [unitree-sdk2-mcp](https://github.com/ros-claw/unitree-sdk2-mcp) - Unitree Robot MCP Server
---
## Citation
If you use ROSClaw in your research, please cite:
```bibtex
@software{rosclaw_nav2_mcp,
title = {ROSClaw-Native Nav2 MCP Server},
author = {{ROSClaw Team}},
year = {2025},
url = {https://github.com/ros-claw/rosclaw-nav2-mcp}
}
```
---
## License
This project is licensed under the Apache License 2.0 - see [LICENSE](LICENSE) for details.
---
## Support
- 📖 [Documentation](https://docs.rosclaw.org/nav2-mcp)
- 🐛 [Issue Tracker](https://github.com/ros-claw/rosclaw-nav2-mcp/issues)
- 💬 [Discussions](https://github.com/ros-claw/rosclaw-nav2-mcp/discussions)
---
<p align="center">
<strong>ROSClaw - Embodied Intelligence Operating System</strong><br>
<em>Teach Once, Embody Anywhere. Share Skills, Shape Reality.</em>
</p>
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.