Skip to main content
Glama
README.md
# ros-mcp-server

`ros-mcp-server` is a TypeScript MCP server for controlling AMRs through a fixed MQTT contract. It does not talk to ROS2 directly. Instead, it sits between RCS, an external LLM bridge, and an AMR-side MQTT bridge.

Current flow:

`User -> RCS chat UI -> ros-mcp-server (chat/tool orchestration) -> Ollama -> robot tools -> MQTT Broker -> AMR MQTT Server -> ROS2 Humble/Nav2`

## Architecture

This MVP combines two roles:

- MCP tool server for robot actions
- RCS-facing orchestration entry point via the `chat` tool

RCS remains a thin chat UI:

- the operator types natural-language requests
- RCS forwards them to MCP `chat`
- `ros-mcp-server` calls a local or network LLM bridge
- the LLM decides whether robot tools are needed
- tool results are folded into the final Korean response

The server is split into four layers:

- `rms_mcp_server`: MCP server creation, chat orchestration, and the WebSocket transport exposed at `ws://127.0.0.1:3001/mcp`
- `rms_mqtt`: MQTT connection management, protocol loading, symbolic topic resolution, and request-response helpers
- `rms_core`: shared config, logger, types, and error classes
- `rms_utils`: low-level JSON and timeout helpers

The MQTT topic contract is defined in editable JSON at [rms_mqtt/protocols/amr-mqtt-protocol.json](/C:/ws/src/ros-mcp-server/rms_mqtt/protocols/amr-mqtt-protocol.json). MCP tools resolve symbolic keys such as `navigation.command` instead of hardcoding topic strings.

## Folder Structure

```text
ros-mcp-server/
  package.json
  tsconfig.base.json
  .env.example
  README.md

  rms_mcp_server/
    src/
      index.ts
      orchestrator.ts
      server.ts
      transport.ts
      tooling.ts

  rms_mqtt/
    src/
      mqttClient.ts
      protocolLoader.ts
      topicResolver.ts
      requestResponse.ts
    protocols/
      amr-mqtt-protocol.json

  rms_core/
    src/
      config.ts
      logger.ts
      types.ts
      errors.ts

  rms_utils/
    src/
      json.ts
      timeout.ts
    scripts/
      pkill.sh
```

## Install

```bash
npm install
```

## Run

```bash
npm run dev
```

To start both the RMS server and a local Ollama runtime together:

```bash
npm run dev:all
```

`dev:all` checks whether Ollama is already available at the configured bridge URL. If not, it tries to start `ollama serve` first and then launches the RMS dev server.

The MCP WebSocket endpoint will be available at:

```text
ws://127.0.0.1:3001/mcp
```

## Configuration

Copy `.env.example` to `.env` and adjust values as needed.

Core values:

- `MQTT_BROKER_URL`: broker endpoint used by the MQTT client
- `MQTT_CLIENT_ID`: MQTT client identifier
- `DEFAULT_ROBOT_ID`: fallback robot id when a tool omits `robot_id`
- `REQUEST_TIMEOUT_MS`: default timeout for MQTT request-response operations
- `RMS_HOST`, `RMS_PORT`, `RMS_MCP_PATH`: MCP WebSocket bind settings
- `RCS_MCP_SERVER_URL`: convenience value for the RCS-side MCP configuration

LLM bridge values:

- `LLM_BRIDGE_PROVIDER=ollama`
- `LLM_BRIDGE_URL=http://127.0.0.1:11434/api/chat`
- `LLM_BRIDGE_MODEL=qwen3`
- `LLM_BRIDGE_TIMEOUT_MS=30000`
- `LLM_BRIDGE_THINK=` optional
- `LLM_BRIDGE_KEEP_ALIVE=5m`

Recommended local setup:

1. Install Ollama
2. Pull a model with tool-calling support such as `qwen3`
3. Start Ollama
4. Keep `LLM_BRIDGE_URL=http://127.0.0.1:11434/api/chat`

### Windows 11 Ollama Setup

1. Download the Windows installer from the official site: `https://ollama.com/download/windows`
2. Run the installer and finish the setup
3. Open a new PowerShell window and confirm installation:

```powershell
ollama --version
```

4. Pull a model with tool-calling support:

```powershell
ollama pull qwen3
```

5. Check available models:

```powershell
ollama list
```

6. Start the local Ollama server if it is not already running:

```powershell
ollama serve
```

7. In another terminal, start the full local stack:

```powershell
npm run dev:all
```

## MQTT Topics

Topics are resolved from symbolic keys. For example:

```ts
resolveTopic("navigation.command", { robot_id: "burger1" });
// => /amr/burger1/navigation/command
```

Example resolved topics:

- `/amr/burger1/navigation/command`
- `/amr/burger1/navigation/result`
- `/amr/burger1/pose/set`
- `/amr/burger1/route/request`
- `/amr/burger1/system/ping`

## MCP Tools

The server exposes these high-level tools:

- `chat`
- `navigate_to_poses`
- `cancel_navigation`
- `set_initial_pose`
- `save_map`
- `send_motion_command`
- `request_plan_segment`
- `request_plan_route`
- `ping_robot`
- `change_robot_id`

Each request automatically includes `request_id` and `timestamp`, and request-response tools subscribe to the matching response topic and correlate by `request_id`.

## `chat` Tool

`chat` is the main entry point for RCS natural-language interaction.

Expected behavior:

- RCS sends the latest operator utterance to the `chat` tool
- `ros-mcp-server` sends the conversation to Ollama
- Ollama requests robot tools when needed
- `ros-mcp-server` executes the requested tools
- the final Korean response is returned to RCS

Typical arguments:

```json
{
  "message": "burger1을 map 기준 x=1.25, y=0.4 위치로 보내줘",
  "robot_id": "burger1"
}
```

## Example MCP Tool Calls

After connecting your MCP client to `ws://127.0.0.1:3001/mcp` and completing MCP initialization, you can call tools like this.

`chat`:

```json
{
  "jsonrpc": "2.0",
  "id": 9,
  "method": "tools/call",
  "params": {
    "name": "chat",
    "arguments": {
      "message": "burger1을 map 기준 x=1.25, y=0.4 위치로 보내줘",
      "robot_id": "burger1"
    }
  }
}
```

`navigate_to_poses`:

```json
{
  "jsonrpc": "2.0",
  "id": 10,
  "method": "tools/call",
  "params": {
    "name": "navigate_to_poses",
    "arguments": {
      "robot_id": "burger1",
      "poses": [
        {
          "frame_id": "map",
          "position": { "x": 1.25, "y": 0.4, "z": 0 },
          "orientation": { "x": 0, "y": 0, "z": 0, "w": 1 }
        }
      ]
    }
  }
}
```

## RCS Integration

RCS should connect its MCP client transport to:

```text
ws://127.0.0.1:3001/mcp
```

Recommended client behavior:

- keep the current chat-style UI
- let the operator choose the UI label such as ChatGPT or Claude if desired
- send the operator message to MCP `chat`
- show the returned Korean response in the same chat thread
- avoid direct OpenAI API handling in the UI when using the RMS-side Ollama bridge

This keeps RCS thin while `ros-mcp-server` owns natural-language orchestration and robot tool execution.