feat(mcp): add OpenClaw MCP bridge plugin#1412
Conversation
Greptile SummaryThis PR introduces the OpenClaw MCP bridge plugin at Key changes:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant OpenClaw TUI/Agent
participant OpenClaw Gateway
participant Plugin (index.ts)
participant DimOS MCP Server
participant Robot
Note over Plugin (index.ts), DimOS MCP Server: Plugin registration (startup)
Plugin (index.ts)->>DimOS MCP Server: POST /mcp initialize (child process)
DimOS MCP Server-->>Plugin (index.ts): initialized
Plugin (index.ts)->>DimOS MCP Server: POST /mcp tools/list (child process)
DimOS MCP Server-->>Plugin (index.ts): [{name, description, inputSchema}, ...]
Plugin (index.ts)->>OpenClaw Gateway: registerTool() × N
Note over User, Robot: Runtime tool execution
User->>OpenClaw TUI/Agent: "move forward 1 meter"
OpenClaw TUI/Agent->>OpenClaw Gateway: resolve tool call
OpenClaw Gateway->>Plugin (index.ts): execute(toolCallId, params)
Plugin (index.ts)->>DimOS MCP Server: POST /mcp tools/call {name, arguments}
DimOS MCP Server->>Robot: execute skill
Robot-->>DimOS MCP Server: result
DimOS MCP Server-->>Plugin (index.ts): {content: [{type:"text", text:"..."}]}
Plugin (index.ts)-->>OpenClaw Gateway: {content, details}
OpenClaw Gateway-->>OpenClaw TUI/Agent: tool result
OpenClaw TUI/Agent-->>User: response
Last reviewed commit: b02e1e3 |
| ): Promise<string> { | ||
| const url = mcpUrl(host, port); | ||
| const result = (await rpc(url, "tools/call", { name, arguments: args })) as { |
There was a problem hiding this comment.
callTool skips the MCP initialize handshake
discoverToolsSync correctly sends an initialize request before tools/list (line 137), but callTool calls tools/call directly via rpc() without any prior initialize. While stateless Streamable HTTP transports often tolerate this, the MCP spec requires an initialize/initialized exchange before any other messages. If the DimOS server enforces this (or is updated to do so), every tool execution will fail silently with an HTTP error or a JSON-RPC error, while tool discovery continues to succeed.
Consider either:
- Sending a lightweight
initializeincallToolbeforetools/call, or - Confirming in a code comment that the DimOS MCP server is unconditionally stateless and does not require initialization per request.
|
Just to understand, openclaw is not able to interact with dimos directly via MCP? Asking since the whole idea of MCP is that other tooling can just use dimos out of the box |
|
@ruthwikdasyam Reminder to add @Kaweees as a co-author when PR so both of yall are on this PR |
Co-authored-by: Miguel Villa Floran <miguel.villafloran@gmail.com>
Right. openclaw doesn't have built in MCP servers. it has its own plugin-based tool system. So, this plugin is to bridge the gap - on startup, this discovers robot skills from DimOS MCP server and registers them as openclaw agent tools. then, forwards tool calls back to DimOS over HTTP when the openclaw agent uses them @Kaweees anything to add? |
Not having an MCP client is such a glaring hole I assume there is a popular plugin for MCP for openclaw, did you investigate this and try it out on default |
| @@ -1,55 +1,142 @@ | |||
| # DimOS MCP Server | |||
| # DimOS MCP Server with OpenClaw | |||
There was a problem hiding this comment.
dimOS MCP Server OR openclaw. we support mcp wihtout openclaw of course need to make clear
|
|
||
| ```bash | ||
| cd dimos/web/plugin_openclaw | ||
| pnpm openclaw tui |
There was a problem hiding this comment.
isnt it just openclaw tui?
There was a problem hiding this comment.
that works if openclaw is installed globally. we install it locally via pnpm install in plugin dir. so need to pnpm openclaw tui to run it from local node_modules
if we do pnpm add -g openclaw sets global_path, then openclaw tui works
| # DimOS MCP Server with OpenClaw | ||
|
|
||
| Expose DimOS robot skills to Claude Code via Model Context Protocol. | ||
| The OpenClaw plugin lives at `dimos/web/plugin_openclaw/`. It bridges DimOS MCP tools into the OpenClaw agent system. |
There was a problem hiding this comment.
We can't have Openclaw take over the MCP readme. Revert all the changes to this file and add "Roboclaw" readme to the botton or put roboclaw readme as a seperate readme.
There was a problem hiding this comment.
pushed MCP readme to bottom and added Openclaw instructions on the top. Nothing is removed.
Readme is 2 parts - MCP with Openclaw, and MCP with ClaudeCode.
Maybe, I can add a section at the top specifying this
| @@ -0,0 +1,223 @@ | |||
| import { execFileSync } from "node:child_process"; | |||
There was a problem hiding this comment.
small nitpick but change the directory to web/roboclaw
There was a problem hiding this comment.
There's a 'roboclawz' trademark and a motor controller called 'RoboClaw'.
Not sure if it's the best name...
There was a problem hiding this comment.
Legally speaking, I think we will be fine, since it seems the trademarks are only applicable for physical manipulators
| <td align="center" width="50%"> | ||
| <h3><a href="docs/capabilities/agents/readme.md">Agentive Control, MCP</a></h3> | ||
| "hey Robot, go find the kitchen"<br><a href="https://x.com/stash_pomichter/status/2015912688854200322">Watch video</a> | ||
| "hey Robot, go find the kitchen"<br><a href="https://x.com/stash_pomichter/status/2015912688854200322">Watch video</a><br><a href="dimos/agents/mcp/README.md">Run with OpenClaw</a> |
|
And then we probably should have unit tests here. Ideally a test that tests end to end whether openclaw sees 100% of the tools and can call them etc @ruthwikdasyam |
| ## Setup | ||
| ## How It Works | ||
|
|
||
| 1. DimOS starts a FastAPI MCP server on port 9990, exposing robot skills as JSON-RPC tools |
There was a problem hiding this comment.
There's no need to mention FastAPI. It would be more useful to mention the transport used.
DimOS starts an MCP server on port 9990 using the SSE transport (HTTP), exposing robot skills as tools.
| ## Terminal 2 — OpenClaw gateway | ||
|
|
||
| First time only — install and configure the plugin: |
There was a problem hiding this comment.
Em dashes are signs that the docs were AI generated.
| ## Terminal 2 — OpenClaw gateway | |
| First time only — install and configure the plugin: | |
| ## Terminal 2: OpenClaw gateway | |
| Install and configure the plugin: |
| ``` | ||
|
|
||
| It will open a browser window. | ||
| # DimOS MCP Server with Claude Code |
There was a problem hiding this comment.
# is h1 so you can only have one per page. Maybe you should have # Model Context Protocol at the top of the page and add an extra # to all titles.
| function discoverToolsSync(host: string, port: number): McpToolDef[] { | ||
| const url = mcpUrl(host, port); | ||
| const script = ` | ||
| const http = require('http'); |
There was a problem hiding this comment.
This is quite ugly. It should be a separate file.
Blocking the thread is also bad, but it looks like it's required as openclaw's API expects all tools to be known at registration time synchronously.
Looks like it might be possible to register tools asynchronously, by using api.registerService (https://docs.openclaw.ai/tools/plugin#register-background-services) and define the tools in async start() {...}, but I haven't tried it and I'm not sure.
| ): Promise<unknown> { | ||
| const body = { | ||
| jsonrpc: "2.0", | ||
| id: 1, |
There was a problem hiding this comment.
The ids are supposed to be unique. It technically works if you don't have two concurrent calls, but we should be able to support it.
| import { Type } from "@sinclair/typebox"; | ||
| import type { AnyAgentTool } from "openclaw/agents/tools/common.js"; | ||
|
|
||
| const DEFAULT_HOST = "127.0.0.1"; |
There was a problem hiding this comment.
This only works if you run both openclaw and dimos on the same machine, right?
Currently, the MCP server has no auth, but we should probably add auth so we can connect to it from a remote server. Otherwise we will have to run openclaw and dimos on the same machine.
I think most people run openclaw on AWS or on a local minipc. People probably can't run dimos there.
(Personally, I run openclaw in a VM, for security reasons.)
We probably need instructions for how to run them on separate machines. Do you agree?
| const url = mcpUrl(host, port); | ||
| const script = ` | ||
| const http = require('http'); | ||
| function post(body) { |
There was a problem hiding this comment.
This would be a lot shorter if you used fetch.
Also, we probably need some re-try logic in here because otherwise we always have to start the gateway after the MCP server has started... and I'm sure people will probably start both at the same time.
Summary
dimos/web/plugin_openclaw/bridging DimOS MCP tools into OpenClaw.gitignorepackage.json to repo root only, ignore pnpm-lock.yamlBreaking Changes
None
How to Test
uv sync --extra base --extra unitreeuv run dimos --simulation run unitree-go2-agentic-mcpdimos/web/plugin_openclaw/:pnpm install, install & enable plugin, set API keys in~/.openclaw/.envpnpm openclaw gateway run --port 18789 --verbose- verify tools discoveredpnpm openclaw tui- send commands like "rotate in place"Contributor License Agreement
Note
More tests needed to verify robustness. This PR covers primary installation instructions and connection setup between DimOS<>OpenClaw