ROS MCP Server: exposing a live ROS graph to an LLM through rosbridge
Connect AI models like Claude & GPT with robots using MCP and ROS.
At a glance
- What is it?
- ROS MCP Server is an Apache-2.0 Python MCP server that lets Claude, GPT, Gemini or any MCP client read and write a running ROS 1 or ROS 2 graph by talking to a rosbridge node. The install path is documented, the ROS-version coverage is broad, and the design deliberately puts no code inside your robot stack.
- Who is it for?
- Adopt it if you already run a ROS graph and want an MCP client to inspect and drive it without editing robot source code, and if you accept that rosbridge is a network-facing interface to that graph. Do not adopt it if your robot has no rosbridge node and you cannot add one, or if you need the LLM to run inside the control loop rather than above it.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap ROS MCP Server fills: an LLM that can read a live ROS graph
An LLM asked to help with a robot has no way to see what the robot is doing. It can read your launch files and your URDF, but it cannot list the topics currently being published, check the type of a custom service, or call that service and read the response. ROS MCP Server exists to close that gap. It is an MCP server, so it plugs into any MCP-compatible client, and it speaks to the robot through rosbridge rather than through a library linked into your nodes. The README states the core promise directly: bidirectional communication with no changes to existing robot source code, achieved by adding the rosbridge node to an existing ROS setup. That is the audience. People who already have a working ROS 1 or ROS 2 system, who want an assistant to observe and operate it, and who are unwilling to refactor their nodes to get there. The README's own examples are industrial end effector diagnosis, a Nav2 and MoveIt robot fetching a drink, and a simulated Unitree Go2 in Isaac Sim. Those are all cases where the graph already exists and the missing piece is an operator that can query it.
How the pieces connect: MCP client, MCP server, rosbridge, robot graph
The topology image in the README shows the data flow, and the README describes the capabilities in prose. An MCP client (Claude Code, Codex CLI, Gemini CLI, Claude Desktop, ChatGPT, Cursor) holds a session with the Python MCP server. The MCP server holds a connection to a rosbridge node running inside your ROS system. Everything the LLM does travels that path. According to the README, the server can publish and subscribe to topics, call services and actions, set parameters, read sensor data, and monitor robot state in real time. The interesting design decision is discovery. The README says the server guides the LLM to discover available topics, services, actions and their types, including custom ones, so the model can construct correct calls without manual configuration. That matters more than it sounds. A custom message type with nested fields is exactly where a language model produces plausible but wrong syntax, and the README's industrial gripper example leans on this: Claude discovers the robot's custom topic and service types and their syntax on its own, using only technician manuals as reference. The mechanism is therefore not a fixed tool list with hardcoded ROS commands. It is a discovery layer over whatever the running graph happens to expose.
Getting it running: rosbridge first, then the MCP client config
The README does not inline the commands. It points to docs/install/installation.md and says to follow the installation guide. What the README does commit to is the prerequisite and the shape of the setup. You need a running ROS system with the rosbridge node added. The badges state Python 3.10+ and pip 23.0+, and the repository ships a dev container, so the Python side has a documented floor even though the exact pip invocation lives in the installation guide rather than the README. On the client side, the server is configured like any other MCP server, and the README lists the clients it works with rather than one blessed integration. The README also carries the MCP name io.github.robotmcp/ros-mcp-server in a comment, which is the identifier a registry-aware client would use. The honest summary is that the README is a landing page, not a runbook. Anyone evaluating this should read docs/install/installation.md before assuming a single command gets them from zero to a working session, because the rosbridge side is a ROS-side change and the MCP side is a client-side change, and they are configured in different places.
Where the rosbridge dependency becomes the limitation
The no-source-changes claim is real, but it is paid for with a network hop. The MCP server does not link against your nodes. It talks to rosbridge, and rosbridge is a service that accepts connections and executes ROS operations on behalf of whoever connects. That means the trust boundary has moved. Anything that can reach the rosbridge port can publish to your topics and call your services, and the README does not describe an authentication or permission layer. The contributing section lists permissions as a feature it would like contributions for, which is a fair signal that the current state is not a hardened one. Treat this as the first thing to resolve in any deployment where the robot can hurt someone or something. The second limitation is latency and determinism. Every action the LLM takes is a round trip through the model, then the MCP server, then rosbridge, then the graph. That is fine for inspection, diagnosis, and high-level commands like navigate to a waypoint. It is the wrong tool for anything inside a control loop, and the README's examples are consistent with that: diagnosis, navigation, manipulation at the task level. If you need a policy that runs at control rate, this architecture is not aimed at you.
ROS 1 and ROS 2 in one server, and what that costs
The badges claim both ROS and ROS 2 are available, and the README says compatibility across ROS 2 (Jazzy, Humble, and others) and ROS 1 distros. Supporting two ecosystems that differ in their client libraries, their build systems and their service semantics is a genuine maintenance burden, and it is the main reason to check the release history before committing. The recent releases shown are v3.0.0 and v3.0.1 in January 2026, then v3.1.0 in June 2026, with the last push in September 2026. That cadence suggests active work rather than a frozen artifact, but it also means the API surface the LLM sees can shift between minor versions. If you pin an MCP client configuration to this server, pin the server version too, and read the release notes for the version you pin. The ROS 1 path is the one to scrutinize hardest. ROS 1 is end-of-life upstream, so a bug that only reproduces on a ROS 1 distro may sit longer than one on Humble or Jazzy, and the README does not break down which capabilities are verified on which distro.
The alternative: writing a purpose-built tool layer instead of a generic one
The obvious alternative is to skip the generic bridge and expose a small set of your own MCP tools, each wrapping one specific operation: pick up at this pose, report gripper vacuum level, return to dock. The difference in approach is scope. ROS MCP Server exposes the whole graph and relies on discovery so the model can figure out what to call. A hand-written tool layer exposes three or four verbs and nothing else. The generic approach wins when the graph is large, changing, or unfamiliar, which is exactly the industrial diagnosis case in the README where the model has to discover custom types on a robot nobody on the team has instrumented for an LLM. The narrow approach wins when the operation set is fixed and the cost of a wrong call is high, because a tool that only accepts a pose cannot be talked into publishing to the wrong topic. There is also a middle path worth naming: keep ROS MCP Server for read-only observation and put a separate, tightly scoped tool set in front of anything that actuates. The README's framing supports that split, since observation and control are described as two directions of the same connection rather than one capability.
Maintenance, licence, and what to verify before you commit
The project is Apache-2.0, which permits commercial use and modification and includes an explicit patent grant, with the usual obligations around preserving notices and stating changes. That is a permissive licence and it is not a reason to hesitate. It is also not legal advice; if you redistribute a modified server inside a product, have counsel read the NOTICE and modification clauses rather than relying on a summary. On maintenance cost, the realistic picture is two moving parts. The Python server upgrades on its own release cadence, and the ROS side depends on rosbridge and rosapi packages that track your ROS distribution. An upgrade to a new ROS distro can change rosbridge behaviour independently of any ROS MCP Server release, so the two upgrade paths have to be tested together. The repository's dev container badge suggests the maintainers have made the Python environment reproducible, which lowers the cost of the server half. The ROS half is yours. Before adopting, verify in your own environment that the MCP server can connect to your rosbridge instance, that it can enumerate your custom message and service types correctly, and that the port rosbridge listens on is not reachable from anywhere you would not want publishing to your robot.
Editorial conclusion
Adopt it if you already run a ROS graph and want an MCP client to inspect and drive it without editing robot source code, and if you accept that rosbridge is a network-facing interface to that graph. Do not adopt it if your robot has no rosbridge node and you cannot add one, or if you need the LLM to run inside the control loop rather than above it. Before wiring it into anything that moves, verify three things in your own setup: that the rosbridge and rosapi services are reachable from the machine running the MCP server, that the LLM can enumerate your custom message types correctly, and what your rosbridge port is exposed to.
Community notes