MCP server by YI-TING-EE13
ROS2 MCP Server
A production-oriented Model Context Protocol (MCP) server that bridges LLM tooling with ROS 2 using rclpy.
This project focuses on reliable ROS graph access, standardized MCP tool contracts, async action lifecycle management, and deployment-ready operational checks.
Key Features
- Strict Layering
- All ROS operations are isolated in
bridge/ros2_bridge.py - Protocol and transport layers never call ROS APIs directly
- All ROS operations are isolated in
- Standard Tool Envelope
- Every tool response uses a fixed schema:
ok,code,error,result,request_id
- Every tool response uses a fixed schema:
- Action Execution Models
- Synchronous action API:
call_action - Asynchronous lifecycle APIs:
start_action,get_action_status,cancel_action
- Synchronous action API:
- Incremental Event Stream
get_action_events(action_id, since_seq, limit)for progress and feedback polling
- Protocol Extensions
get_capabilities,list_tool_metadata,list_resources_snapshot- Input schema validation via Pydantic
- Stable error-code mapping
- Security Controls
- Allowlist + wildcard policy for topics/services/actions
- Read/write policy gate (
write_enabled) - Request rate limit (
rate_limit_per_minute)
- Deployment Readiness
- Built-in preflight checker for new-machine setup validation
Project Structure
ros2-mcp-server/
config/
settings.yaml
scripts/
preflight_check.py
call_mcp_tool.py
phase1_*_smoke.sh
src/ros2_mcp_server/
main.py
bridge/ros2_bridge.py
protocol/
server.py
envelope.py
schemas.py
transport.py
core/
tests/
Installation
Prerequisites
- Linux environment with ROS 2 installed (smoke scripts assume
bash) - Python 3.10+
uv- ROS 2 Humble or Jazzy (default path pattern:
/opt/ros/<distro>)
Optional (for mock action integration tests):
sudo apt-get update
sudo apt-get install -y ros-humble-example-interfaces
Setup
cd ros2-mcp-server
uv sync --group dev
ROS Environment Setup
Before running ROS CLI tools or MCP integration checks, load your ROS environment:
source /opt/ros/humble/setup.bash
ros2 node list
If you see ros2: command not found, your shell has not sourced ROS yet.
To auto-load ROS in every new shell:
echo 'source /opt/ros/humble/setup.bash' >> ~/.bashrc
source ~/.bashrc
Configuration
Default file: config/settings.yaml
Override via environment variable:
export MCP_CONFIG_PATH=/absolute/path/to/settings.yaml
Security example:
security:
allowlist_enabled: true
write_enabled: true
rate_limit_per_minute: 120
allowed_topics:
- "/perception/*"
allowed_services:
- "/safe/*"
allowed_actions:
- "/mock/*"
Run the Server
Recommended: stdio
uv run python -m ros2_mcp_server.main
Optional: network transports (runtime dependent)
uv run python -m ros2_mcp_server.main --transport http --host 0.0.0.0 --port 8000 --path /mcp
uv run python -m ros2_mcp_server.main --transport streamable-http --host 0.0.0.0 --port 8001 --path /mcp
If you get an error like Unknown transport, your current FastMCP runtime does not support that transport version. Use stdio or upgrade the mcp package.
Available MCP Tools
list_ros_graph(type)get_node_info(node_name)read_topic(topic_name, timeout)call_service(service_name, request_data, timeout)list_actions()call_action(action_name, goal_data, timeout, feedback_limit)start_action(action_name, goal_data, timeout, feedback_limit)get_action_status(action_id)cancel_action(action_id)get_action_events(action_id, since_seq, limit)health()get_capabilities()list_tool_metadata()list_resources_snapshot()
Validation and Testing
Quick preflight check
uv run python scripts/preflight_check.py
Full preflight (includes tests)
uv run python scripts/preflight_check.py --full
Preflight + smoke test
uv run python scripts/preflight_check.py --with-smoke
Unit tests
uv run pytest -q
Smoke tests
bash scripts/phase1_1_smoke.sh
bash scripts/phase1_2_allowlist_smoke.sh
bash scripts/phase1_3_action_smoke.sh
bash scripts/phase1_4_action_lifecycle_smoke.sh
Code Standards
This codebase follows:
- PEP 8 style conventions
- Type hints on public functions
- Google-style docstrings for public classes and functions
- No blocking ROS 2 calls on the main MCP event loop
All blocking ROS operations are isolated in bridge worker execution paths (asyncio.to_thread(...)).
Compatibility Matrix
- ROS 2 Humble: full support
- ROS 2 Jazzy: best-effort support (feature-dependent fallback/degradation)
Open Source Governance
Troubleshooting
ROS2 runtime is unavailable
- Ensure ROS setup is sourced in the process environment:
source /opt/ros/humble/setup.bash - Verify ROS CLI availability:
ros2 --help - Confirm graph visibility:
ros2 node list
Unknown transport: http or streamable-http
- Your runtime may not support those transports in current FastMCP version.
- Use
stdiofirst, or upgrade themcpdependency.
address already in use
- Another process is already bound to the selected port.
- Change
--portor stop the process using that port.
License
MIT. See LICENSE.