HORUS/blog

Sep 5, 2026 · mcp-robotics · llm-robotics · robot-software · ros-2

MCP for Robots: What It Means to Give a Model Hands

MCP is a good way to let a model choose among actions your robot already performs safely, and a poor way to drive motors. Where it fits, and where ROS 2 wins.

Use MCP as the doorway between a model and a robot that already moves safely, with ROS 2 or HORUS underneath. MCP standardises how a model discovers and calls the actions you expose, which is genuinely useful once each action is safe on its own. That flips when the robot has no tested actions yet, because MCP then decorates an empty room. The rest of this post is for someone who builds with models and tools every day and is now deciding what to put between a sentence and a motor.

You have shipped things with tools before. The model asks for the weather, your function answers, the conversation carries on, and the whole arrangement took an afternoon. So when someone hands you an arm on a desk and says wire it up the same way, the shape looks familiar and you start writing tool definitions.

Then the questions arrive in a different key. Your weather tool returned in a moment; the move tool takes seconds, and the world changes during those seconds. Your weather tool could not fail halfway; the move tool can stop with a gripper half closed around a mug. Your weather tool was safe to retry; retrying a move knocks something onto the floor.

You look for the part of the documentation that covers this, and it is not there, because a protocol describes tools rather than explaining what happens when a tool has mass. Meanwhile every demonstration online shows a sentence going in and an arm moving, cut before the fifth attempt. You are left holding a question nobody answered: what goes between the model and the machine, and who is responsible when both are wrong at once?

Should you use MCP to give a model control of a robot?

Yes, if the robot already performs a small set of actions safely with no model involved, and no if it does not. MCP is a description layer. It tells a model which actions exist, what each one needs, and what came back, in a format models are already good at using. What MCP never supplies is the part that makes an action safe: the limit refusing a reach past the table edge, the check confirming the gripper actually closed, the stop that works when software is wedged. Builders who add MCP to a robot with three tested behaviours get something useful within a weekend. Builders who add MCP hoping it will substitute for those behaviours end up with a machine that describes its abilities beautifully and then drives into a wall. There is an honest test to run before writing a single tool definition: can a person invoke each action from a plain script, ten times over, and correctly predict what the robot does? A no means the protocol is not your next task.

What is MCP in plain terms?

MCP, the Model Context Protocol, is an agreed way of telling a model what tools exist and of carrying the call and the answer back and forth. Think of it as a menu format rather than a kitchen. The menu says a dish exists, lists what you must specify, and promises a description of what arrives. It says nothing about whether the kitchen can cook, how long the order takes, or what happens if the chef drops the plate. Before MCP, every project invented its own menu format, so a model wired to one system had to be rewired for the next. A shared format means a tool written once can be offered to different models and different assistants without translation. For a robot, that convenience is real and it is narrow. The hard parts of a robot were never the menu. They were the kitchen: the driver, the loop, the limits, and the honest report of what happened when the plate did hit the floor.

What are the real options for wiring a model to a machine?

There are roughly eight arrangements people actually ship, and they differ in where the model sits and how much of the robot it is allowed to touch. At the plain end, a hosted model calls a small command server over the network with three or four endpoints and no protocol ceremony at all. In the middle sit the arrangements borrowing an existing stack: ROS 2 already expresses long-running work as actions with progress and cancellation, which is exactly the shape a tool call wants, so a thin MCP server in front of ROS 2 is often the shortest path for a robot that already navigates or plans motion, while HORUS, an open-source real-time middleware for Rust, Python and C++, suits the case where the model process, the perception code and the control loop all live on one computer and should share the same ring buffers instead of copying data across a language boundary. At the far end, a learned policy takes images and instructions and produces motion with no tool layer in between. Read the table as situations rather than a ranking.

OptionWho it is forWhat it assumes you knowWhen to pick itWhen not to
MCP server over a few tested robot actionsBuilders whose robot already does two or three things reliablyWriting a small service and describing its inputs plainlyYou want assistants and models to share one tool layerThe actions underneath are not trustworthy yet
A plain command server with no protocolSomeone proving the idea before committing to anythingOne HTTP handler and how to call it from a scriptThis week, to find out whether the idea holds at allSeveral different models and tools must reuse the same layer
MCP in front of ROS 2 actionsRobots that already navigate, map or plan motionROS 2 actions, goals and how a goal is cancelledThe valuable parts of the robot are ROS 2 packagesThe robot is one script and a motor driver
Tool calling built into your model SDKTeams already deep in one vendor's assistant toolingThat vendor's schema and its retry behaviourThe robot is one project inside a larger productYou expect to swap models or expose the robot elsewhere
HORUSMixed-language builders whose robot is a single computerYour message shapes and how your loops are scheduledA Python model process must share data with C++ or Rust controlBorrowed ROS 2 packages are the point of the project
The vendor's own assistant hookOwners of a finished arm or mobile baseThe vendor's documented task list and its account modelThe machine already does what you want described in wordsYou need behaviour the vendor never planned for
A queue a person approves one action at a timeAnyone working near people or near expensive equipmentYour own patience for reviewing every proposed actionEarly deployment, safety cases, stakeholder demonstrationsNobody is free to sit and approve
Simulation-only tool layerBeginners with no robot, and anyone tuning instructionsA simulator, a robot model, and where the simulator liesYou want to fail many times before lunchThe interesting failures are grip, friction and calibration

What should you do if you are a software developer who has never touched a robot?

Borrow or buy a machine that already works without you, then spend a fortnight making it do one dull task the same way every time from a plain script with no model anywhere near it. Your existing instincts transfer better than roboticists tend to admit. You already know how to design an interface, sort failures into categories, distrust a demo that only works on inputs you chose, and treat anything crossing a network as suspect. What does not transfer is physical. Objects move while you are thinking. A gripper slips on the same mug it held an hour ago. Calibration drifts across an afternoon, so a correct plan is now aimed slightly beside the target. In software a retry costs nothing; on hardware a retry moves mass. So do not begin with the tool definitions, and do not begin by building an arm. Begin with the smallest machine you can get running, and keep a written log of every way the dull task failed. That log becomes the specification for everything your tool layer will later have to survive.

What hardware does an MCP robot actually need?

You need two computers' worth of work, even when both halves run on one board: something steady that keeps the robot honest, and something that thinks. The steady half runs the driver, the loop and the limits, and carries nothing that can pause unexpectedly. The thinking half needs either a network connection to a hosted model or an accelerator holding a smaller local one. Where each piece runs follows from a single rule: anything that must happen whether or not the model replies stays on the robot. Motor control, limits, the stop path, and the code noticing an empty gripper all live below, always. Perception can go either way, though shipping every frame across a network gets expensive and brittle sooner than people expect. The test that settles arguments is to unplug the network mid-task. A robot split properly finishes the current action, notices nothing more is coming, and stops in a state you would happily walk up to. A robot split badly keeps executing a plan for a world that no longer exists.

How long does this take before it is worth showing anyone?

A convincing demonstration takes a couple of weekends; a robot you would leave running with a stranger in the room is a different order of work entirely. The demonstration is quick because the pieces exist already: a hosted model, a small server, two or three actions, a microphone if you fancy one. The first time a spoken sentence turns into motion, the thing feels finished. It is not, and the missing work is not in the protocol layer. The long stretch is making each action succeed or fail cleanly and say which, because a model handed the word error and nothing else will retry from a position it does not understand. Budget the failure handling rather than the demo. An order that holds up: one action from a script this week, a second action plus a refusal path next, the model choosing between the two in simulation after that, then hardware with a person on the stop button. Reverse that order and you get a video quickly, followed by two seasons of discovering what the video hid.

What do you need to know before you write your first robot tool?

Enough of one language to write a small service, plus an honest mental model of what the control loop is doing while the model thinks. You do not need kinematics, driver internals or C++ in the first month. You do need four things. First, how an action is invoked and how you learn it finished, since everything above rests on that answer being trustworthy. Second, what state the robot is in when an action stops halfway, because a half-open gripper is a condition your model will meet. Third, enough about coordinate frames to know what the word left means to the robot as opposed to the camera. Fourth, the habit of treating model output as untrusted input, the way a web service treats a form from a stranger. If the timing side is the unfamiliar part, what a control loop is doing between decisions is worth reading before you design a single tool, because tool design that ignores the loop produces tools the loop cannot honour.

What does it look like when an MCP robot goes wrong?

It looks like a machine doing something reasonable at the wrong moment, with a clean log showing everyone behaved correctly. The model asks to pick up the blue mug. Perception saw a blue mug four seconds ago. The arm sets off, someone moves the mug, and the gripper closes on air with complete confidence. Nothing errored. Another shape: the tool blocks until the motion ends, so the model cannot be told the person walked into the workspace, and the only thing that saves the situation is the hardware stop. A third: the model retries a failed pick, but the failed pick left the gripper holding half a mug, so the retry starts from a state nobody wrote code for. The pattern behind all three is that the tool reported on the request rather than on the world. A tool answering only did the call succeed will produce robots that fail politely. A tool answering what is true now gives the model something worth reasoning about, which is the difference between a demonstration and a machine.

What do people try first, and why does it stop working?

Almost everyone starts by exposing low-level motion as tools, letting the model send positions or velocities, which works on a tidy desk and comes apart the moment anything moves. The failure has one cause wearing several faces. A model writes its answer for the world you described a moment ago; it has no clock, no feedback, and no way to notice the mug shifted while the sentence was being composed, so the command is aimed at a memory. The second common attempt piles the entire robot state into one enormous context that grows weekly until the model answers confidently about the wrong object. The third calls the model on every cycle, which makes the robot hesitate between corrections and turns smooth motion into a stutter. Every repair has the same shape: fewer decisions for the model, more structure around each one, and a layer beneath able to say no. The model picks a tested behaviour, the behaviour re-checks the world as it begins, and the loop runs underneath whether or not anything upstairs replied. Why a model that writes software cannot pick up a cup covers the same gap.

What do you give up by putting a model in charge of choosing actions?

You give up the ability to state in advance exactly what the machine will do. A state machine is dull and inspectable: you can print every path and hand the list to a colleague, a customer or a safety reviewer. A model choosing among tools cannot be enumerated, which turns testing from proof into sampling. You fix a bad behaviour by editing a description or an instruction, and nothing tells you which of yesterday's good behaviours you just broke, so you accumulate scenarios and re-run them, which is evaluation work rather than engineering work. With a hosted model you also take on a dependency you do not control, and a provider updating that model changes your robot's behaviour on a morning when your code did not change at all. You give up the crisp answer to why did it do that. All of it is worth paying when the task space is genuinely open and nobody could write the branches ahead of time. It is a poor trade when the robot does five known things and somebody merely wanted it to accept spoken instructions.

When is ROS 2 the better choice?

ROS 2 is the better choice the moment the hard part of your robot is perception, navigation or manipulation rather than the language layer above it. A machine that must map a building and drive to a named room is a ROS 2 project, because that navigation work represents years you will not reproduce alongside your model work. An arm planning around obstacles qualifies for the same reason. If the lidar you bought has exactly one driver anyone has tested and that driver is a ROS 2 package, the decision was made in the shop. ROS 2 also already models long-running work as actions with progress and cancellation, which is the shape a tool layer needs, so the bridge in front of it stays thin. HORUS is not the answer for those projects: choosing it there means rebuilding plumbing that already exists in order to lose the packages that were the point of the robot. And if you are joining a lab or a company that already speaks ROS 2, shared vocabulary beats any comparison you could run on your own.

Does MCP make a robot autonomous?

No, and here is why: autonomy is the ability to keep behaving sensibly when nothing arrives from above, and a protocol for calling tools has nothing to say about that case. A robot is autonomous because someone wrote the part that notices a stalled motor, the part that stops before the table, the part that gives up and parks when the plan has clearly failed, and the part that keeps the wheels straight while everything upstairs is quiet. MCP moves requests and answers. Removing MCP from a genuinely autonomous robot leaves a machine that still works and can no longer be instructed in words. Removing MCP from a robot that only appeared autonomous leaves nothing at all, and that is the useful diagnostic. Ask what your machine does with the model deleted. Whatever remains is your actual robot. The protocol is a convenience for the conversation, valuable in the way a good API is valuable, and never a source of judgement the machine did not already have.

Is MCP just a REST API with better manners?

Partly, but not the way you think. Mechanically, yes: a call goes out, a result comes back, and nothing in that description would surprise anyone who has written a web service. What is genuinely different is the audience. A REST API is read once by a developer who then writes code that calls it correctly forever. A tool description is read on every single call by something that will interpret it slightly differently depending on what else is in the conversation. That changes what good design means. Names carry weight, because a tool called move gets used for things you never intended. Descriptions must state preconditions in plain sentences, since the caller cannot read your source. Error messages become instructions rather than diagnostics, because the model will act on the text. And the caller may invent a plausible argument value that your validation has to reject on the robot's behalf. So the plumbing is familiar, and the discipline around it belongs closer to writing for an unpredictable colleague than to publishing an endpoint.

How do you decide whether to build this at all?

Decide by asking what the robot does with the model switched off, and build the answer first. If that answer is nothing, you do not have a tool-layer problem, you have a robot problem, and the fastest route to a working demonstration is still to make one dull action succeed and fail cleanly from a script. If the answer is a real list of behaviours, then the protocol layer is a short and pleasant piece of work that will pay off, because it lets you swap models and reuse the same tools from different assistants without rewriting anything underneath. Two further questions settle most remaining arguments. Which failure would embarrass you in front of the person funding this? Name it, then make it impossible in the layer beneath the model rather than discouraged in the layer above, because a sentence is a request and a limit is a fact. And would you leave this running unattended for an hour? If not, find out which layer you distrust, and fix that one instead of adding tools. An honest look at what happens when a chat model drives a machine is a useful second opinion here.

Decide by situation rather than by ambition:

When the foundation question arrives underneath all of this, weigh the candidates on the five axes of the HORUS Fit Framework — ecosystem size, setup effort, team size fit, deployment target and licence — and take the option that loses on the fewest, with no scoring involved. If your robot is becoming one computer running a model process beside C++ or Rust control, star HORUS on GitHub so it is in your list when you start building.

Found this useful? Share it:Discuss on HNShare on X