Start with your working RIG. No firmware changes are needed to connect its existing tools.
Choose a direction
| What you want | Where to start | What you copy |
|---|---|---|
| Let a desktop AI client control RIG | Your robot's settings, in the MCP device-control section. | The generated client configuration. |
| Let RIG use Home Assistant or your computer's tools | The agent's MCP access-point section. | The generated WebSocket access-point address. |
| Add a new function inside robot firmware | The optional firmware workshop at the end of this page. | Source code, followed by a build and flash. |
The first two entries are the product's two MCP workflows. Keep their connection information separate: a device-control configuration belongs in an AI client; an external-tool access point belongs in the HA integration or your local tool bridge.
Use your own account in the international RIG dashboard. Domestic and international accounts and connection details are operated separately. Copy the configuration or access point generated for your international account; do not reuse a screenshot's address, token or device identifier. If a described card is absent in your international account, confirm its availability with RIG support before continuing.
1. Connect a desktop AI client to your RIG
Get the configuration for the correct robot
Power on your RIG and confirm ordinary conversation works. Open that device's settings in the dashboard and find its MCP device-control card. Use Copy configuration. The generated configuration identifies both the service connection and the particular robot.
Keep a private copy while setting up the client. Do not share the authorization value or replace the device ID with a guessed name. A display name such as RIG-Puppy-80 is the entry label, not the address of the robot.
Import it without removing your other tools
Open the MCP server configuration in a compatible desktop AI client. The configuration format must match what that client supports. For a client accepting the exported JSON structure:
- Back up its existing MCP configuration.
- If you have no configured servers, import the complete generated configuration.
- If you already have servers, merge the new robot entry into the existing mcpServers object. Keep the other entries. Do not nest a second mcpServers object inside the first.
- Save, reconnect or reload the client, and complete its trust/enable prompts.
- Inspect the robot's discovered tools before requesting an action.
Read the exported fields: the transport tells the client how to connect; the URL identifies the service; authorization grants access; X-Device-Id, where present, selects the device. Preserve the generated values. A client using another configuration format needs the equivalent supported fields, not a blindly pasted JSON file.
Verify a real request
Use the connected RIG robot tools to read its current device status.
Do not move the robot. Tell me which tool ran and the result it returned.
If no status tool is available, show the discovered tool names rather than guessing.
Check the actual tool result and the selected robot. Once this works, you can request one supported model-specific action with the robot in a clear working area. Tool availability depends on the installed firmware and model; a successful client connection does not add new robot actions.
Checkpoint: the client lists your RIG tools and returns a real result from the right robot. A conversational response alone is not proof of connection. USB serial monitoring is optional for inspecting firmware logs; it is not how the exported desktop MCP connection is established.
2. Let your RIG use external tools
In the dashboard, find the agent's MCP access point. Copy its complete generated WebSocket address to the external integration. The external process connects to this access point and supplies tools; the RIG agent can then request them during conversation.
- Home Assistant: use the official LuwuDynamics integration and the RIG-to-HA walkthrough.
- Your computer: use the official LuwuDynamics browser/calculator example. Its bridge receives the copied address through MCP_ENDPOINT and runs a selected local tool process. Start with the repository's calculator example, then verify a tool call in the conversation history. A browser example opens the browser on the computer running that process, not on the robot.
Keep the HA instance or computer bridge running while using its tools. Refresh the access-point status after connection. For your first experiment, connect one provider at a time so you can tell where each tool comes from.
These addresses are different: do not put the exported device-control JSON into a WebSocket address field, and do not paste the external-tool WebSocket address into a desktop client's HTTP server field. Use the specific copy action for the direction you chose.
Something isn't working? Check your chosen direction
| Symptom | What to check |
|---|---|
| Client rejects the JSON | Check the merge, commas, braces and the client's supported configuration format. Restore the backup if needed. |
| Client connects to the wrong robot | Recopy the configuration from the intended device; inspect the device identifier. |
| Robot tools are missing | Confirm the robot is online, reconnect the client, and inspect discovery errors. |
| External access point stays disconnected | Check that HA/the bridge is running with the complete address copied from the matching international account. |
| HA tools are absent | Follow the HA integration, Assist selection and exposed-entity checks on the linked RIG-to-HA page. |
| Robot says it acted but nothing changes | Check conversation tool activity and the actual target/result, rather than adding another prompt or reflashing. |
Ask AI to help with configuration
I am connecting a RIG robot using the configuration generated by its international dashboard.
My direction is: [desktop client controls RIG / RIG uses external tools].
My client or integration is: [name and version].
Here is the configuration structure with all tokens and device identifiers removed: [structure only].
Explain where to put it and how to preserve my existing entries.
Do not invent an endpoint, change service region, or write firmware for a configuration task.
Give one connection check and one observable tool-call test.
Optional developer workshop · Add your own firmware tool
Existing tools work through the configuration flow above. Expand this workshop only when you want to implement a new device function. The steps below involve firmware changes.
3. Prepare for the first custom tool
Before editing, complete one original build and flash for your actual robot. You should already have the ESP-IDF version from your model workshop installed (5.5.3 for TARS), the public source downloaded, the correct board and Overseas region selected, and the real serial port identified. If you have not done that yet, complete the setup in your Puppy, Hover, Arm or TARS workshop once, then return here.
TARS public source is available. Select RIG-Tars in the public board configuration. The TARS beginner workshop now covers its complete build, first edit, MCP tools and recovery. Use ESP-IDF 5.5.3 for that workshop; the repository documents TARS builds with this version.
Open the project root in your editor and use a local experiment branch. Preserve any existing edits. Choose the file for your actual model:
| Your robot | File to open |
|---|---|
| RIG-Puppy | main/boards/puppy/puppy_board.cc |
| RIG-Hover | main/boards/hover/hover_board.cc |
| RIG-Arm | main/boards/arm/arm_board.cc |
| RIG-TARS | main/boards/tars/tars_board.cc |
Find void InitializeTools(). Inside it, find the existing line auto& mcp_server = McpServer::GetInstance();. Place the example immediately after that line, keeping the original tools underneath. Add custom model tools here rather than editing the shared common-tool registrations.
4. Add the hello tool
If you already added self.robot.hello in the development workshop, keep that registration and skip to building/testing. Search before pasting: register each name only once.
mcp_server.AddTool(
"self.robot.hello",
"Run the hello test without moving the robot.",
PropertyList(std::vector<Property>{}),
[](const PropertyList&) -> ReturnValue {
ESP_LOGI(TAG, "Hello tool called");
return true;
});
| Read this part | Meaning |
|---|---|
| AddTool | Registers one callable function during initialization. |
| self.robot.hello | The name to look for in the client's tool list. |
| Description string | Helps the assistant decide when this tool is useful. |
| Empty PropertyList | This example has no input values. |
| [](const PropertyList&) | The callback's input. The example does not read any properties. |
| ESP_LOGI | Prints Hello tool called to the serial log when invoked. |
| return true | Sends success back to the caller. It does not play audio. |
The code between the callback's braces does not run just because it was registered. It runs when the tool is called. Keep the surrounding braces, commas and final semicolon exactly as shown.
Save the file and run git diff in the project terminal. Check that your intended board file contains one new registration and that existing tools are intact. If other files already had edits, distinguish those from this experiment.
5. Build, flash and keep the log open
In the activated ESP-IDF terminal at the project root, first run:
idf.py build
Continue only after a successful build. Close an existing monitor with Ctrl + ]. Replace COM5 below with the port you previously identified:
idf.py -p COM5 flash monitor
Keep the robot supported and its moving parts clear: this tool adds no motion, but the existing startup behavior still runs. Wait for normal startup and network connection. To reopen the monitor without flashing, run idf.py -p COM5 monitor with your actual port.
Expected so far: the firmware starts normally. You do not need to see Hello tool called yet; no call has been made. A successful compile proves the code built, not that a client can invoke it.
6. Make a real call and verify it
Connect and refresh the tools
- Power on the correct robot and confirm it is online in the international account you normally use. Confirm ordinary conversation works before diagnosing a custom tool.
- After flashing, reconnect the existing robot conversation/client session so it can discover the updated tools. If your interface has a refresh-tools action, use it. Interface labels vary; this tutorial does not assume a hidden developer panel exists.
- If a tool list is available, look for the exact name self.robot.hello. Tool discovery is different from invoking the tool: seeing its name means it was advertised, not that its callback ran.
- If the client provides a tool inspector, select that name and use {} as the arguments. This means “no arguments.” Do not paste C++ or a shell command into the argument field.
- Otherwise ask the connected assistant: “Call the self.robot.hello tool once and tell me its result.” Watch the serial log for Hello tool called. The client may not expose manual invocation; a voice request still depends on its tool support and selection.
Using a separate desktop AI client? Only proceed if your international service supplies a compatible MCP connection method for that client. Use its actual endpoint, transport and authentication instructions. The robot's Wi-Fi address, GitHub URL and serial-port name are not interchangeable MCP endpoints. If no compatible connection is provided, use the existing robot assistant and keep desktop-client setup as a separate task.
What success looks like: the callback message appears when you make the request and the tool returns success. In this firmware, a boolean result is represented as text in the MCP response; a client may display true rather than a spoken sentence. A friendly spoken reply alone does not prove a device tool was called.
| What you observed | What it proves |
|---|---|
| Build succeeded | The selected firmware compiles. |
| Tool appears in the client's list | This connection discovered the registration. |
| Hello tool called appears at invocation | The robot entered your callback. |
| Client receives the success result | The return path completed. |
| Normal robot behavior still works | Your basic regression check passed. |
Use one explicit request at a time. If a client retries, you may see more than one invocation; use its request activity and the log timing to investigate rather than assuming every spoken request always produces exactly one device call.
7. Optional: give a tool one input
Keep this section closed until hello works. It teaches argument handling without touching motors.
Second exercise · Double a number and check its result
Add this separate registration after the same existing McpServer instance line, alongside hello. It does not replace the hello callback:
mcp_server.AddTool(
"self.robot.double_number",
"Double a whole number from 0 to 10 without moving hardware.",
PropertyList({
Property("number", kPropertyTypeInteger, 0, 10)
}),
[](const PropertyList& properties) -> ReturnValue {
const int number = properties["number"].value<int>();
const int result = number * 2;
ESP_LOGI(TAG, "Double test: %d -> %d", number, result);
return result;
});
Here number is required. The four-argument Property constructor declares an integer with minimum 0 and maximum 10; it does not set a default. The callback reads it as an int and returns twice its value. The log uses two %d placeholders for the two integers.
Save, inspect the diff, build, flash and refresh the connected client's tools as before. Select self.robot.double_number in a tool inspector and put this in the arguments field:
{"number": 3}
Expected: the device log contains Double test: 3 -> 6 and the tool result contains 6. The firmware encodes the integer result as text in the response; your interface may show it inside a result object. Do not paste this JSON into the ESP-IDF terminal.
Ask the connected assistant: “Use the double-number tool with number 3 and tell me its returned result.” The tool log, not the assistant's ability to calculate 3 × 2 itself, proves the exercise worked.
| Arguments to test | Expected behavior |
|---|---|
| {"number": 0} | Result 0. |
| {"number": 10} | Result 20. |
| {} | Missing required input: the callback should not execute. |
| {"number": "3"} | String instead of number: reject the input. |
| {"number": -1} or {"number": 11} | Outside the declared range: reject the input. |
Use the inspector for invalid-input tests where available; a conversational assistant might correct your input before sending it. Check that rejected requests do not print the callback's Double test message. A client may reject an invalid request before it reaches the device, so inspect both its error and the device log. These checks do not establish behavior for every possible JSON value.
Undo: remove only the double_number registration, rebuild/flash, and refresh the tools. Keep hello if you still want it.
8. Let AI help with the smallest change
Open the actual project in your coding assistant. If it cannot read files, provide the relevant InitializeTools function and MCP type definitions. A repository URL alone does not guarantee file access. Choose one model in the prompt before submitting it.
I am a beginner using [RIG-Puppy / RIG-Hover / RIG-Arm].
Read my actual checkout of https://github.com/LuwuDynamics/rig_omni.
My original firmware already builds and runs with ESP-IDF 5.5.2 and Overseas configuration.
Inspect the model's InitializeTools function and main/mcp_server.h before editing.
Help me add self.robot.hello: no arguments, log "Hello tool called", return true, no movement.
If that name already exists, help me test it instead of registering it twice.
Explain the insertion point and each part in plain English. Show the smallest diff.
Keep existing tools, hardware settings, dependencies and account configuration unchanged.
Give the build command, manual flash/monitor steps, expected log/result and an undo step.
Do not flash, erase or invoke hardware tools automatically. Say which checks you actually ran.
If this checkout lacks support for my model, explain the missing support instead of inventing it.
Review the edited file, build it and observe the real call yourself. An AI message saying “the tool works” is not a substitute for the log and client result.
After hello succeeds, a good second request is: “Add a separate non-moving double_number tool accepting a required integer from 0 through 10. Verify the existing Property constructor, return the doubled value, and show valid, missing, wrong-type and out-of-range input tests.” Compare its proposal with the example above before applying it.
Something isn't working? Locate the failing step
| Symptom | What to check next |
|---|---|
| Cannot compile AddTool / Property | Check braces and insertion location; compare the API with your checkout's mcp_server.h. Read the first compiler error. |
| Normal conversation is offline | Fix the existing network/account connection before changing the tool. |
| Tool missing from list | Verify selected model, saved source and flashed build; refresh/reconnect the client. Check for an existing duplicate name. |
| Tool listed, callback never logs | Inspect whether an actual call was sent, its exact name and arguments; check the live serial port and informational log level. |
| Assistant says hello but no call evidence | It may have answered conversationally. Use an inspector if available or explicitly request the exact tool. |
| Unknown tool | Compare exact name, flashed firmware and client tool cache. The client may be using another device/session. |
| Invalid or missing arguments | Send an object; hello uses {}, while double_number needs an unquoted integer value under number. |
| Log appears but the assistant gives no result | Inspect client/service errors on the return path. Do not add motion to diagnose a response problem. |
| Result says true but robot is silent | That is expected for hello. Returning success does not synthesize speech. |
| Tool still appears after deleting code | Rebuild and flash the edited firmware, then refresh the client. Editor changes alone do not update the robot. |
Copy the first error and a small amount of surrounding output. Remove credentials before sharing. For AI-assisted diagnosis:
My model and source revision: [fill in].
Tool name: [exact name].
Build and flash outcome: [actual results].
Client tool list: [present / missing / no inspector available].
Arguments sent: [sanitized JSON].
Device log at invocation: [sanitized lines].
Client result or error: [sanitized output].
Find the failing stage: registration, discovery, invocation, argument validation, callback or return path.
Explain the smallest next check. Do not rewrite unrelated code or invent a server endpoint.
9. Keep your work or undo it
To undo hello, remove only its AddTool registration. If you tried double_number, remove its registration separately. Review git diff, build, flash the same model/region and refresh the tools. Confirm normal startup still works. Do not erase flash to remove a tool.
Your first milestone is complete when you can explain the tool name, arguments and result; observe the callback; and remove the change. Keep the working source/configuration and your test notes.
Later: extending a tool to real robot actions
First locate an existing bounded action for your exact model. Follow its implementation and document units, ranges, calibration requirements, duration and stop behavior. Begin with a callback that only logs the intended action. Keep balance loops, servo IDs and zero positions unchanged during beginner exercises.
Before a physical test, account for repeated calls, overlapping requests and interruptions. A description such as “safe movement” does not enforce limits. Use validated arguments and the model's established motion/scheduling mechanisms; avoid long blocking loops in the callback. Require an explicit action request and keep the documented stop control available. For TARS, use the TARS tool reference: speed is signed amplitude, time is milliseconds, and time=0 means continuous movement until stopped.
Reference when you need it
The examples follow the public RIG source, especially MCP types and tool results and registration and request handling. For the general host/client/server concepts, see the official MCP architecture guide. These are optional references; the first exercises are complete on this page.
