Atlas / MCP servers / wise-vision / ROS 2

ROS 2BLOCK

mcp/wise-vision/ros-2-1

ROS2 MCP: the MCP server that lets AI agents see, understand and operate ROS 2 robots. MPL-2.0.

Verdict
BLOCK
Grade
F
Trust score
44 /100
Exposed tools
—
Transport
stdio
License
MPL-2.0
Stars
89
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://discord.gg/9aSw6HbUaw) [](https://hub.docker.com/mcp/server/ros2/overview) [](LICENSE) [](https://wisevision.tech) [](https://wisevision.tech/docs/)

ROS2 MCP is an open-source (MPL-2.0) Model Context Protocol (MCP) server for ROS 2 Humble and Jazzy, written in Python. It lets AI tools such as Claude, Cursor and Codex list, subscribe to, publish on and call ROS 2 topics, services and actions over stdio (or SSE). It is listed in Docker's official MCP catalog as `mcp/ros2`.

Every tool is free and open source, including multi-topic subscribe/publish, map-to-image and point-cloud bird's-eye view.

🌐 Website: wisevision.tech · 📚 Documentation: wisevision.tech/docs

🔒 Security: read-only mode

An agent connected to a real robot can move it. Start the server in read-only mode to let the agent observe but not act:

ROS2_MCP_READONLY=1 uv run mcp_ros_2_server      # env var
uv run mcp_ros_2_server --read-only              # or CLI flag
docker run -i --rm -e ROS2_MCP_READONLY=1 mcp/ros2

In read-only mode the tools that change robot state are not registered at all: they do not appear in list_tools, and calling one returns an Unknown tool error. The hidden tools are: ros2_topic_publish, ros2_publish_multiple_topics, ros2_service_call, ros2_send_action_goal, `ros2_ca

Read from source at commit e4ee2af4cdafOBSERVED · 2026-10-07
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.

claude-code (oci)
claude mcp add ros2:latest -- docker run -i --rm docker.io/mcp/ros2:latest:None
03

Trust audit

BLOCKgrade F · trust 44/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)FAIL
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (1 observation(s))
Network
none-observed
Shell
declared (5 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHSupply chain · supply.typosquat · CWE-829, CWE-1357
server/ui/ros2_viewer_app/package.json
preact ~ react
Why it matters. dependency name one edit from a popular package
Fix. verify the package; likely typosquat
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
installation/README.md:10
- ROS 2 installed on your system (humble or later). [Get ROS 2](https://docs.ros.org/en/humble/Installation.html)
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
installation/README.md:11
- Docker installed and running. [Get Docker](https://docs.docker.com/get-docker/)
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
installation/README.md:12
- Visual Studio Code installed. [Get Visual Studio Code](https://code.visualstudio.com/Download)
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
installation/README.md:35
- ROS 2 installed on your system (humble or later). [Get ROS 2](https://docs.ros.org/en/humble/Installation.html)
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
installation/README.md:36
- Docker installed and running. [Get Docker](https://docs.docker.com/get-docker/)
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
server/ros2_manager.py:137
module = importlib.import_module(f"{pkg}.msg")
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
server/ros2_manager.py:818
module = importlib.import_module(f"{pkg}.msg")
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
server/ros2_manager.py:823
module = importlib.import_module(f"{pkg}.srv")
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
server/ros2_manager.py:828
module = importlib.import_module(f"{pkg}.action")
MEDIUMCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
server/ros2_manager.py:847
module = importlib.import_module(f"{pkg}.srv")
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
scripts/tests/test_docs_sync_validate.py:217
"-----BEGIN OPENSSH PRIVATE KEY-----",
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
scripts/tests/test_docs_sync_validate.py:218
"-----BEGIN RSA PRIVATE KEY-----",
LOWInventory / provenance · inv.hidden_file · CWE-1104
.licenserc.json
.licenserc.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.pre-commit-config.yaml
.pre-commit-config.yaml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
scripts/tests/test_docs_sync_validate.py:109
"src/content/docs/../../../.github/workflows/x.yml",
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
scripts/tests/test_docs_sync_validate.py:259
["import Evil from '../../../../src/components/Evil.astro';"],
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
scripts/tests/test_docs_sync_validate.py:192
"[x](https://1.2.3.4/)",
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
server/ros2_manager.py:1391
return list(bytes.fromhex(hex_clean))
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
server/ui/ros2_viewer_app/src/app.tsx:108
const bin = atob(b64);
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
tests/ros2_manager_extended_test.py:189
decoded_bytes = base64.b64decode(msg_1["data"])
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
tests/ros2_manager_extended_test.py:200
decoded_bytes = base64.b64decode(msg_2["data"])
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
tests/ros2_manager_extended_test.py:449
raw = base64.b64decode(image_content.data)
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
server/ui/ros2_viewer_app/package.json
preact, three, @types/node, @types/three, esbuild, typescript
Why it matters. 6 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWInventory / provenance · mcp.no_tools_extracted · CWE-1104
server.json
Why it matters. the tool list is enumerated at runtime by tools/list, not declared in source
Fix. the page says so rather than showing an empty table

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha e4ee2af4cdaffull audit observations/trust-audit/mcp-server/wise-vision__ros-2-1.json · Report an issue / request a re-scan
04

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-07e4ee2af4cdafBLOCKF44first audit
05

Questions

What is the ROS 2 MCP server?

ROS2 MCP: the MCP server that lets AI agents see, understand and operate ROS 2 robots. MPL-2.0.

Is ROS 2 safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (44/100) and found 6 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does ROS 2 need?

No credential environment variables were found in its source, so it appears to need none.

How does ROS 2 run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as ros2-viewer-app.

How current is this page?

The grade is for one exact copy of the source (e4ee2af4cdaf), read on 2026-10-07. The repository is watched and re-audited when it changes.

Advertisement