# How to Set Up the MCP Server for External LLM Agent Integration in DimOS

> Integrate external LLM agents with DimOS by setting up the MCP server. Discover and invoke robot capabilities via JSON-RPC and HTTP POST requests to the /mcp endpoint.

- Repository: [Dimensional/dimos](https://github.com/dimensionalOS/dimos)
- Tags: how-to-guide
- Published: 2026-03-15

---

**DimOS exposes every `@skill` method as JSON‑RPC tools via the Modular Control Protocol (MCP) server, allowing external LLMs to discover and invoke robot capabilities by sending HTTP POST requests to the `/mcp` endpoint.**

The **dimensionalOS/dimos** repository provides a built-in MCP server that transforms your robot’s modular skills into a standard JSON‑RPC interface. By adding the `McpServer` blueprint to your robot stack, external agents from OpenAI, Anthropic, or other providers can remotely call any method decorated with `@skill` without direct hardware access.

## How the MCP Server Works in DimOS

The server is implemented in [`dimos/agents/mcp/mcp_server.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/mcp/mcp_server.py) and follows a blueprint-based activation model. When you include `McpServer.blueprint()` in your robot configuration, the system performs the following actions:

1. **Skill Introspection**: During blueprint construction, `on_system_modules()` scans every loaded module for `@skill` decorators and builds an internal map of **SkillInfo** objects.
2. **HTTP Endpoint Creation**: The `_start_server()` method launches a FastAPI application wrapped by uvicorn, binding to the configured host and port (default `0.0.0.0:9990`).
3. **JSON‑RPC Dispatch**: The single POST endpoint `/mcp` accepts standard JSON‑RPC 2.0 requests and routes them to `_handle_initialize`, `_handle_tools_list`, or `_handle_tools_call` based on the `method` field.

## Step‑by‑Step Setup Guide

### 1. Include the MCP Server Blueprint

Add `McpServer.blueprint()` to your robot’s blueprint definition. The reference implementation in [`dimos/robot/unitree/go2/blueprints/agentic/unitree_go2_agentic_mcp.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/robot/unitree/go2/blueprints/agentic/unitree_go2_agentic_mcp.py) demonstrates this pattern:

```python
from dimos.agents.mcp.mcp_server import McpServer
from dimos.agents.mcp.mcp_client import mcp_client
from dimos.core.blueprints import autoconnect
from my_robot.modules import perception, navigation, control

my_robot_mcp = autoconnect(
    perception,
    navigation,
    control,
    McpServer.blueprint(),   # Starts the HTTP server

    mcp_client(),            # Optional on-device LLM client

)

```

Place `McpServer.blueprint()` before any on-device clients so the client can discover all registered skills.

### 2. Configure Host and Port

The `GlobalConfig` class in [`dimos/core/global_config.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/global_config.py) manages network settings. Defaults are `mcp_host=0.0.0.0` and `mcp_port=9990`. Override these via CLI flags or environment variables:

```bash

# CLI flag

dimos run my_robot_mcp --mcp-port 8080 --mcp-host 192.168.1.100

# Environment file (.env)

DIMOS_MCP_PORT=8080
DIMOS_MCP_HOST=0.0.0.0

```

### 3. Start the Server and Verify

Launch your blueprint using the DimOS CLI:

```bash
dimos run my_robot_mcp

```

Verify the server is listening by sending a test request (expect a JSON‑RPC error for missing body, confirming the endpoint is active):

```bash
curl -s http://localhost:9990/mcp

```

## Interacting with External LLM Agents

Once running, the MCP server exposes three primary JSON‑RPC methods at `http://<host>:<port>/mcp`.

### JSON‑RPC Endpoint Overview

- **Initialize**: `{"method":"initialize"}` – Handshake for protocol version negotiation.
- **Tools List**: `{"method":"tools/list"}` – Returns all `@skill` methods as tool definitions.
- **Tools Call**: `{"method":"tools/call","params":{"name":"<skill>","arguments":{}}}` – Executes the specified skill.

### Discovering Available Tools

External agents query the skill registry using standard HTTP POST:

```bash
curl -X POST http://localhost:9990/mcp \
     -H "Content-Type: application/json" \
     -d '{ "jsonrpc":"2.0", "id":1, "method":"tools/list" }'

```

The response contains a JSON array of tool objects, each derived from the **SkillInfo** metadata gathered by `on_system_modules()`.

### Invoking Tools from an External Agent

To execute a skill such as `move` with specific parameters:

```bash
curl -X POST http://localhost:9990/mcp \
     -H "Content-Type: application/json" \
     -d '{
           "jsonrpc":"2.0",
           "id":2,
           "method":"tools/call",
           "params":{
             "name":"move",
             "arguments":{"x":0.3,"duration":2.0}
           }
         }'

```

For programmatic access, use Python with the `requests` library:

```python
import requests

URL = "http://localhost:9990/mcp"

def call_tool(name, arguments):
    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "tools/call",
        "params": {"name": name, "arguments": arguments}
    }
    response = requests.post(URL, json=payload)
    return response.json()["result"]

# Execute the move skill

result = call_tool("move", {"x": 0.5, "duration": 1.5})
print(result)

```

## Optional: Adding an On‑Device MCP Client

While external LLMs connect via HTTP, on-device agents can use the `McpClient` helper defined in [`dimos/agents/mcp/mcp_client.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/mcp/mcp_client.py). This client connects to the local MCP server through internal channels, enabling edge-based reasoning without network exposure. Include it in your blueprint as shown in the setup example above.

## Core Implementation Details

The following components manage the MCP lifecycle according to the DimOS source code:

| Component | File Path | Role |
|-----------|-----------|------|
| **Server Blueprint** | [`dimos/agents/mcp/mcp_server.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/mcp/mcp_server.py) | `McpServer.blueprint()` factory method that returns the module configuration. |
| **Skill Discovery** | [`dimos/agents/mcp/mcp_server.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/mcp/mcp_server.py) | `on_system_modules()` method populates `app.state.skills` and `app.state.rpc_calls` by introspecting `@skill` decorators from [`dimos/agents/annotation.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/annotation.py). |
| **HTTP Transport** | [`dimos/agents/mcp/mcp_server.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/mcp/mcp_server.py) | FastAPI app with CORS middleware; `_start_server()` runs uvicorn in a background thread. |
| **JSON‑RPC Handlers** | [`dimos/agents/mcp/mcp_server.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/mcp/mcp_server.py) | `_handle_initialize`, `_handle_tools_list`, and `_handle_tools_call` process incoming requests. |
| **Configuration** | [`dimos/core/global_config.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/global_config.py) | Reads `mcp_host` and `mcp_port` from CLI flags (`--mcp-host`, `--mcp-port`) or environment variables. |
| **Reference Stack** | [`dimos/robot/unitree/go2/blueprints/agentic/unitree_go2_agentic_mcp.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/robot/unitree/go2/blueprints/agentic/unitree_go2_agentic_mcp.py) | Working example combining `McpServer` and `mcp_client` in a Unitree Go2 robot configuration. |

## Summary

- **Add `McpServer.blueprint()`** to your robot’s blueprint to activate the JSON‑RPC interface.
- **Configure network binding** via `GlobalConfig` using CLI flags (`--mcp-port`, `--mcp-host`) or `.env` variables.
- **Verify the endpoint** at `http://<host>:<port>/mcp` using cURL or Python requests.
- **Discover skills** with the `tools/list` method, which reflects all `@skill` decorated methods from loaded modules.
- **Invoke capabilities** using `tools/call` with the skill name and required arguments.
- **Optionally include `mcp_client`** for on-device LLM agents that communicate internally.

## Frequently Asked Questions

### What is the default port for the DimOS MCP server?

The default port is **9990**, bound to `0.0.0.0` (all interfaces). You can override this in [`dimos/core/global_config.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/core/global_config.py) by setting the `DIMOS_MCP_PORT` environment variable or passing `--mcp-port` when running the blueprint.

### Can I run the MCP server without an on-device LLM client?

Yes. The `McpServer` operates independently. You only need `mcp_client` (from [`dimos/agents/mcp/mcp_client.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/mcp/mcp_client.py)) if you want an on-device agent to consume the same skill registry locally. External LLMs connect directly via HTTP to the server endpoint.

### How does the server know which methods to expose as tools?

During blueprint initialization, `on_system_modules()` in [`mcp_server.py`](https://github.com/dimensionalOS/dimos/blob/main/mcp_server.py) scans every loaded module for methods decorated with `@skill` (defined in [`dimos/agents/annotation.py`](https://github.com/dimensionalOS/dimos/blob/main/dimos/agents/annotation.py)). It extracts metadata into **SkillInfo** objects and registers them as JSON‑RPC callable tools.

### What JSON‑RPC version does the MCP server support?

The server implements **JSON‑RPC 2.0**. All requests must include the `jsonrpc: "2.0"` field, a unique `id`, and the appropriate `method` (`initialize`, `tools/list`, or `tools/call`). Responses follow the standard result-or-error schema.