Skip to content

Commit cf77884

Browse files
rjohn-vlpigeonstex2005
authored
Release/v2.1.7 (#176)
* update the paths in the examples appropriately * Fix: Removed Optional for IP and PORT in connect_to_robot. This sometimes generates truncation, no need for optional as they are intrinsically optional. * Added ip and port information on config yaml file * Added turtlesim.yaml * ruff format fix * Added configuration file for local_rosbridge.yaml * trigger ruff check * Revert "Added ip and port information on config yaml file" This reverts commit 131fae4. * Removed ip/port * Add ROS 2 Parameters API (#135) * Added get_parameters set_param get_param etc. Inspect parameters missing. * Fixed inspect_all_parameters. Now tested with background color of turtlesim. * Fixed parameter type in inspect_all_parameters + added get_parameter_details * Added note that parameters are supported on ROS 2 only * Added get_actions tool * Added get_action_type tool * Added get_action_details and inspect_all_actions tools * Added send_action_goal, non-blocking, no feedback or result. * Fixed send_action_goal to: - Be blocking and waiting for action_result or timeout. - Return action_result when action is completed. - Return the last action_feedback, if available, when timeout. - Return timeout/success:false if no action_feedback or action_result is detected. - Fixed bug with timeout input tools (no Optional) * Added cancel_action_goal. Non-blocking. No response is available. Tested with fibonacci server. * Added note for ROS 2 support only. * Added get_action_status tool * Modified get_action_status to work with action_name and not action_type * Added action_feedback through ctx.report_progress. Tested and working in Cursor, not showing in ChatGPT. * Refactor: replace Optional with union syntax (Type | None) (#143) - Remove Optional imports and usage - Update server.py and websocket_manager.py * Add ROS 2 Launch System (#138) * Created ROS2 launch files for rosbridge and turtlesim demo, removed manual launch_ros.sh + Added docs on launch system * Modified documentation * Improved launch_mcp_tunnel to include default options for port and domain. * Moved robot specifications folder to root * updated Manifest and pyproject to point to correct locations * Type hint fix in server.py from previous PR on ros actions * updated config_utils to access specification files using Path * updated tool names and descriptions for getting robot spec * updated name of get verified robots list based on issue feedback * Fixed inconsistent tool names of topic subscribers and publishers, solving #141 * Modify WSL installation documents (#169) docs: add WSL path best practices to prevent common issues - Add warnings to recommend using /home/username/ instead of /mnt/c/Users/username/ - Fix incorrect path labeling - Add explanatory comment to config/mcp.json template - Closes #102 * Cleared naming convention and removed optional scaffolding to state spec file directory explicitly (YAGNI principle) * changed print statements from stdout to stderr for errors * ruff * Bump version to v2.1.7 * Update version to v2.1.7 in server.json and uv.lock --------- Co-authored-by: Jungsoo Lee <dlwjdtn7083@gmail.com> Co-authored-by: Stefano Dalla Gasperina <stefano.dallagasperina@austin.utexas.edu>
1 parent ac75c8c commit cf77884

File tree

24 files changed

+2828
-938
lines changed

24 files changed

+2828
-938
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,7 @@ pyrightconfig.json
178178
.vs/
179179

180180
# camera
181-
/camera/*
181+
camera/*
182+
183+
# tests
184+
tests/

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
include server.json
2+
recursive-include robot_specifications *.yaml

docs/installation.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ Below are detailed instructions for each of these steps.
2323
git clone https://github.com/robotmcp/ros-mcp-server.git
2424
```
2525

26-
Note the **absolute path** to the cloned directory — you’ll need this later when configuring your language model client.
26+
> ⚠️ **WSL Users**: Clone the repository in your WSL home directory (e.g., `/home/username/`) instead of the Windows filesystem mount (e.g., `/mnt/c/Users/username/`). Using the native Linux filesystem provides better performance and avoids potential permission issues.
27+
28+
Note the **absolute path** to the cloned directory — you'll need this later when configuring your language model client.
2729

2830
---
2931

docs/launch_system.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# ROS2 Launch System for Robot Integration
2+
3+
## Overview
4+
5+
This guide provides template launch files for developers to integrate their robots with the ROS-MCP Server. These templates demonstrate how to combine your robot's existing launch files with rosbridge for MCP communication.
6+
7+
## Template Launch Files
8+
9+
### `ros_mcp_rosbridge.launch.py` - Basic Rosbridge Template
10+
**Purpose**: Minimal rosbridge WebSocket server for robot integration
11+
**Use Case**: Add MCP communication to any existing robot setup
12+
13+
```bash
14+
# Basic usage
15+
ros2 launch ros_mcp_rosbridge.launch.py
16+
17+
# Custom port
18+
ros2 launch ros_mcp_rosbridge.launch.py port:=9090
19+
20+
# Specific address
21+
ros2 launch ros_mcp_rosbridge.launch.py address:=127.0.0.1
22+
```
23+
24+
## Integration Patterns
25+
26+
### How to add Rosbridge to Existing Robot
27+
28+
#### Method 1: Include Rosbridge Launch File
29+
```python
30+
# Your existing robot launch file (e.g., my_robot.launch.py)
31+
from launch import LaunchDescription
32+
from launch.actions import IncludeLaunchDescription
33+
from launch.launch_description_sources import PythonLaunchDescriptionSource
34+
from launch_ros.actions import Node
35+
36+
def generate_launch_description():
37+
# Your existing robot nodes
38+
robot_node = Node(
39+
package='my_robot_pkg',
40+
executable='robot_node',
41+
name='my_robot'
42+
)
43+
44+
sensor_node = Node(
45+
package='my_robot_pkg',
46+
executable='sensor_node',
47+
name='sensor_node'
48+
)
49+
50+
# Include rosbridge for MCP communication
51+
rosbridge_launch = IncludeLaunchDescription(
52+
PythonLaunchDescriptionSource([
53+
'ros_mcp_server', '/launch/ros_mcp_rosbridge.launch.py'
54+
]),
55+
launch_arguments={
56+
'port': '9090',
57+
'address': '',
58+
'log_level': 'info'
59+
}.items()
60+
)
61+
62+
return LaunchDescription([
63+
robot_node,
64+
sensor_node,
65+
rosbridge_launch, # Add this line
66+
])
67+
```
68+
69+
#### Method 2: Add Rosbridge Node Directly
70+
71+
```python
72+
# Add rosbridge node to your existing launch file
73+
from launch.actions import DeclareLaunchArgument, LogInfo
74+
from launch.substitutions import LaunchConfiguration
75+
from launch_ros.actions import Node
76+
77+
from launch import LaunchDescription
78+
79+
80+
def generate_launch_description():
81+
"""Generate the launch description for rosbridge only."""
82+
83+
# Declare launch arguments
84+
port_arg = DeclareLaunchArgument(
85+
"port", default_value="9090", description="Port for rosbridge websocket server"
86+
)
87+
88+
address_arg = DeclareLaunchArgument(
89+
"address",
90+
default_value="",
91+
description="Address for rosbridge websocket server (empty for all interfaces)",
92+
)
93+
94+
log_level_arg = DeclareLaunchArgument(
95+
"log_level", default_value="info", description="Log level for rosbridge server"
96+
)
97+
98+
# Rosbridge websocket server node
99+
rosbridge_node = Node(
100+
package="rosbridge_server",
101+
executable="rosbridge_websocket",
102+
name="rosbridge_websocket",
103+
output="screen",
104+
parameters=[
105+
{
106+
"port": LaunchConfiguration("port"),
107+
"address": LaunchConfiguration("address"),
108+
"use_compression": False,
109+
"max_message_size": 10000000,
110+
"send_action_goals_in_new_thread": True,
111+
"call_services_in_new_thread": True,
112+
"default_call_service_timeout": 5.0,
113+
}
114+
],
115+
arguments=["--ros-args", "--log-level", LaunchConfiguration("log_level")],
116+
)
117+
118+
return LaunchDescription(
119+
[
120+
port_arg,
121+
address_arg,
122+
log_level_arg,
123+
rosbridge_node,
124+
]
125+
)
126+
```
127+
128+
129+
#### Method 3: Separate Launch Files (Recommended)
130+
```bash
131+
# Terminal 1: Launch your robot
132+
ros2 launch my_robot_pkg my_robot.launch.py
133+
134+
# Terminal 2: Launch rosbridge for MCP
135+
ros2 launch ros_mcp_server ros_mcp_rosbridge.launch.py port:=9090
136+
```
137+
138+
| Argument | Default | Description |
139+
|----------|---------|-------------|
140+
| `port` | 9090 | WebSocket server port |
141+
| `address` | "" | Bind address (empty = all interfaces) |
142+
| `log_level` | info | Log level (debug, info, warn, error) |
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
ROS2 Launch file for ROS-MCP Server
5+
Replaces the functionality of scripts/launch_ros.sh with proper ROS2 launch system.
6+
7+
This launch file starts:
8+
- rosbridge_websocket server
9+
- turtlesim node
10+
- Provides proper process management and cleanup
11+
"""
12+
13+
from launch.actions import DeclareLaunchArgument, LogInfo
14+
from launch.substitutions import LaunchConfiguration
15+
from launch_ros.actions import Node
16+
17+
from launch import LaunchDescription
18+
19+
20+
def generate_launch_description():
21+
"""Generate the launch description for ROS-MCP Server."""
22+
23+
# Declare launch arguments
24+
rosbridge_port_arg = DeclareLaunchArgument(
25+
"port", default_value="9090", description="Port for rosbridge websocket server"
26+
)
27+
28+
rosbridge_address_arg = DeclareLaunchArgument(
29+
"address",
30+
default_value="",
31+
description="Address for rosbridge websocket server (empty for all interfaces)",
32+
)
33+
34+
turtlesim_name_arg = DeclareLaunchArgument(
35+
"turtlesim_name", default_value="turtlesim", description="Name for the turtlesim node"
36+
)
37+
38+
# Rosbridge websocket server node
39+
rosbridge_node = Node(
40+
package="rosbridge_server",
41+
executable="rosbridge_websocket",
42+
name="rosbridge_websocket",
43+
output="screen",
44+
parameters=[
45+
{
46+
"port": LaunchConfiguration("port"),
47+
"address": LaunchConfiguration("address"),
48+
"use_compression": False,
49+
"max_message_size": 10000000,
50+
"send_action_goals_in_new_thread": True,
51+
"call_services_in_new_thread": True,
52+
}
53+
],
54+
arguments=["--ros-args", "--log-level", "info"],
55+
)
56+
57+
# Turtlesim node
58+
turtlesim_node = Node(
59+
package="turtlesim",
60+
executable="turtlesim_node",
61+
name=LaunchConfiguration("turtlesim_name"),
62+
output="screen",
63+
arguments=["--ros-args", "--log-level", "info"],
64+
)
65+
66+
# Log info about what's being launched
67+
log_info = LogInfo(
68+
msg=[
69+
"Starting ROS-MCP Server with:",
70+
" - Rosbridge WebSocket on port: ",
71+
LaunchConfiguration("port"),
72+
" - Turtlesim node: ",
73+
LaunchConfiguration("turtlesim_name"),
74+
]
75+
)
76+
77+
return LaunchDescription(
78+
[
79+
rosbridge_port_arg,
80+
rosbridge_address_arg,
81+
turtlesim_name_arg,
82+
log_info,
83+
rosbridge_node,
84+
turtlesim_node,
85+
]
86+
)

examples/3_limo_mobile_robot/isaac_sim/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ If the above steps have been executed successfully, press the Connect button on
5656
Copy the USD file of the LIMO robot created for this example to Isaac Sim.
5757

5858
```bash
59-
cd /<ABSOLUTE_PATH>/ros-mcp-server/examples/limo/isaac_sim/usd/
59+
cd /<ABSOLUTE_PATH>/ros-mcp-server/examples/3_limo_mobile_robot/isaac_sim/usd/
6060
docker exec <container_name> mkdir -p /example # default container_name : isaac-sim
6161
docker cp ./limo_example.usd <container_name>:/example/limo_example.usd
6262
```

examples/4_unitree_go2/real_robot/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ By default, the Unitree GO2 publishes camera data through a custom topic called
114114
115115
- **move the script to the Unitree GO2** (User PC side)
116116
```bash
117-
cd /<ABSOLUTE_PATH>/ros-mcp-server/examples/unitree_go2/real_robot/scripts
117+
cd /<ABSOLUTE_PATH>/ros-mcp-server/examples/4_unitree_go2/real_robot/scripts
118118
scp ./camera_bridge.py unitree@192.168.123.18:/home/unitree/cyclonedds_ws/src/image_process/
119119
```
120120
- **check the script** (Unitree GO2 side)

examples/6_chatgpt/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ git clone https://github.com/robotmcp/ros-mcp-server.git
132132
cd ros-mcp-server
133133
```
134134

135+
> ⚠️ **WSL Users**: Clone the repository in your WSL home directory (e.g., `/home/username/`) instead of the Windows filesystem mount (e.g., `/mnt/c/Users/username/`). Using the native Linux filesystem provides better performance and avoids potential permission issues.
136+
135137

136138
## 1.2 Run ROS-MCP Server
137139

examples/7_cursor/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ git clone https://github.com/robotmcp/ros-mcp-server.git
6969
cd ros-mcp-server
7070
```
7171

72+
> ⚠️ **WSL Users**: Clone the repository in your WSL home directory (e.g., `/home/username/`) instead of the Windows filesystem mount (e.g., `/mnt/c/Users/username/`). Using the native Linux filesystem provides better performance and avoids potential permission issues.
73+
7274
## 1.4 Connect ROS-MCP to Cursor
7375

7476
* Open Cursor Desktop
@@ -109,11 +111,11 @@ uv run server.py --transport http
109111
- Automatic server management
110112

111113
**Important Configuration Notes:**
112-
- Make sure to move ros-mcp-server folder to your `/home/<YOUR_USER>` (note: ~ for home directory may not work in JSON files)
114+
- Make sure to clone the ros-mcp-server folder to your `/home/<YOUR_USER>` directory (note: ~ for home directory may not work in JSON files)
113115
```
114-
"/home/<YOUR_USER>/ros-mcp-server" # Linux home directory
115-
"/mnt/c/Users/<YOUR_USER>/ros-mcp-server" # WSL home directory
116+
"/home/<YOUR_USER>/ros-mcp-server" # Recommended: WSL/Linux home directory
116117
```
118+
- **Avoid using `/mnt/c/Users/<YOUR_USER>/` paths** - these point to the Windows filesystem which can cause performance issues and permission problems
117119
- Use the correct WSL distribution name (e.g., "Ubuntu" or "Ubuntu-22.04")
118120
- Make sure to replace `<YOUR_USER>` with your actual WSL username
119121

examples/8_images/ros_mcp_images_demo.launch.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import os
22

33
from ament_index_python.packages import get_package_share_directory
4-
from launch import LaunchDescription
54
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
65
from launch.launch_description_sources import AnyLaunchDescriptionSource
76
from launch.substitutions import LaunchConfiguration
87
from launch_ros.actions import Node
98

9+
from launch import LaunchDescription
10+
1011

1112
def generate_launch_description():
1213
# Declare port argument for rosbridge

0 commit comments

Comments
 (0)