Skip to main content
Glama
README.md
# RSAP MCP — Robot Structural Analysis ↔ Claude

MCP server cho **Autodesk Robot Structural Analysis Professional 2027** — dùng với **Claude**
hoặc **Codex**.

## Mục lục / Contents

- [Yêu cầu / Requirements](#yêu-cầu--requirements)
- [Bước 1 — Cài đặt / Install](#bước-1--cài-đặt--install)
- [Bước 2 — Đăng ký với Claude Desktop / Register with Claude Desktop](#bước-2--đăng-ký-với-claude-desktop--register-with-claude-desktop)
- [Bước 3 — Dùng thử / First run](#bước-3--dùng-thử--first-run)
- [Dùng với Codex / Use with Codex](#dùng-với-codex--use-with-codex)
- [Kiểm thử bằng client rời / Test with the standalone client](#kiểm-thử-bằng-client-rời--test-with-the-standalone-client)
- [Thêm công cụ mới / Add a new tool](#thêm-công-cụ-mới--add-a-new-tool)
- [Danh sách công cụ / Tool list](#danh-sách-công-cụ--tool-list)
- [Xử lý sự cố / Troubleshooting](#xử-lý-sự-cố--troubleshooting)
- [Cấu trúc thư mục / Repository layout](#cấu-trúc-thư-mục--repository-layout)

---

## Yêu cầu / Requirements

| | |
|---|---|
| OS | Windows 10/11 (64-bit) |
| Robot | Robot Structural Analysis Professional **2027**, đã cài & mở ít nhất một lần |
| Python | **3.10+**, 64-bit |
| uv | `powershell -c "irm https://astral.sh/uv/install.ps1 \| iex"` |
| Host | Claude Desktop hoặc Codex |

---

## Bước 1 — Cài đặt / Install

```powershell
git clone https://github.com/nhantruong96/rsap-mcp.git
cd rsap-mcp
uv sync
```

Chạy lại `uv sync` sau mỗi `git pull`.

Kiểm tra (không cần Robot):

```powershell
uv run python -m rsap_mcp --selfcheck
# -> [selfcheck] 35 tools registered ... OK
```

Tùy chọn thêm / optional extras:

```powershell
uv sync --extra dev     # + ruff
```

Tùy chọn — chép `.env.example` thành `.env` rồi sửa `RSAP_VISIBLE`, `RSAP_INTERACTIVE`,
`RSAP_AUTO_CONNECT`, `RSAP_LOG_LEVEL`, `RSAP_LOG_FILE`, `RSAP_PROJECT_DIR`.

Không có `uv`:

```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1
```

---

## Bước 2 — Đăng ký với Claude Desktop / Register with Claude Desktop

```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\register_claude_desktop.ps1
```

Hoặc sửa tay `%APPDATA%\Claude\claude_desktop_config.json`: chép **một** trong hai khối dưới đây,
thay `C:\path\to\rsap-mcp` bằng đường dẫn thật (mẫu: `config/claude_desktop_config.example.json`).

**A. Qua `uv`** — khuyến nghị:

```json
{
  "mcpServers": {
    "rsap": {
      "command": "uv",
      "args": ["--directory", "C:/path/to/rsap-mcp", "run", "rsap-mcp"]
    }
  }
}
```

**B. Trỏ thẳng Python của venv** — khi `uv` không có trong PATH của Claude Desktop:

```json
{
  "mcpServers": {
    "rsap": {
      "command": "C:\\path\\to\\rsap-mcp\\.venv\\Scripts\\python.exe",
      "args": ["-m", "rsap_mcp"],
      "env": {
        "PYTHONPATH": "C:\\path\\to\\rsap-mcp\\src",
        "RSAP_VISIBLE": "true",
        "RSAP_LOG_LEVEL": "INFO"
      }
    }
  }
}
```

Sau khi sửa: **thoát hẳn** rồi mở lại Claude Desktop.
Log: `%APPDATA%\Claude\logs\mcp-server-rsap.log`.

---

## Bước 3 — Dùng thử / First run

Mở Claude Desktop và ra lệnh bằng lời:

> "Kết nối Robot, tạo dự án khung 2D, dựng khung cổng nhịp 6 m cao 4 m bằng thép S235 IPE300, ngàm
> 2 chân, thêm trọng lượng bản thân và tải mái 10 kN/m, chạy tổ hợp ULS 1.35×TT+1.5×HT rồi cho biết
> phản lực chân cột và mô men lớn nhất ở xà."

> *"Connect to Robot, make a 2D frame, build a 6×4 m portal in S235 IPE300, fix both bases, add
> self-weight and a 10 kN/m roof load, run a 1.35G+1.5Q ULS combination, then tell me the base
> reactions and peak rafter moment."*

Trình tự chuẩn / the workflow:

```
connect → new_project → add_nodes → add_bars → define_section/material → assign →
define_support → assign_support → add_load_case → add_*_load → add_combination →
calculate → bar_forces / node_displacement / node_reaction → save_project
```

- Đơn vị: m, N, N·m.
- Chuỗi chọn đối tượng: `'1to10'`, `'1 2 3'`, `'1to20by2'`.
- Chờ lâu ở tool đầu tiên — Robot đang mở.

---

## Dùng với Codex / Use with Codex

1. Mở `C:\Users\<YOU>\.codex\config.toml` (macOS/Linux: `~/.codex/config.toml`).
2. Thêm khối sau, sửa đường dẫn (mẫu: `config/codex_config.example.toml`):

   ```toml
   [mcp_servers.rsap]
   enabled = true
   command = 'C:\path\to\rsap-mcp\.venv\Scripts\python.exe'
   args = ["-m", "rsap_mcp"]
   startup_timeout_sec = 30
   tool_timeout_sec = 600                      # rsap_calculate chạy lâu
   default_tools_approval_mode = "prompt"      # "auto" nếu không muốn hỏi từng tool

   [mcp_servers.rsap.env]
   RSAP_VISIBLE = "true"
   RSAP_INTERACTIVE = "true"
   RSAP_AUTO_CONNECT = "true"
   RSAP_LOG_LEVEL = "INFO"
   ```

   Hoặc thêm bằng một dòng lệnh / or add it with the CLI:

   ```powershell
   codex mcp add rsap --env RSAP_VISIBLE=true --env RSAP_AUTO_CONNECT=true -- `
     "C:\path\to\rsap-mcp\.venv\Scripts\python.exe" -m rsap_mcp
   ```

3. Kiểm tra: `codex mcp list`.
4. Thoát hẳn và mở lại app Codex, gõ `/mcp` để thấy `rsap` và 35 tools.

Giới hạn tool: thêm `enabled_tools = [...]` hoặc `disabled_tools = [...]` vào khối `[mcp_servers.rsap]`.

---

## Kiểm thử bằng client rời / Test with the standalone client

```powershell
uv run python client\test_client.py                # liệt kê tool qua MCP thật
uv run python client\test_client.py --call rsap_status
uv run python client\examples\01_portal_frame.py   # end-to-end (cần Robot)
uv run ruff check .                                # lint
```

---

## Thêm công cụ mới / Add a new tool

1. Mở module phù hợp trong `src/rsap_mcp/tools/` (`project_`, `modeling_`, `property_`, `support_`,
   `load_`, `analysis_`, `results_tools.py`).
2. Viết hàm bên trong `register(mcp)`, gắn `@mcp.tool()` rồi `@com_call`, kèm type hints và
   docstring Google-style:

   ```python
   def register(mcp):
       @mcp.tool()
       @com_call
       def rsap_count_objects() -> dict:
           """Return node and bar counts."""
           c = conn()
           return {"nodes": c.count(c.nodes), "bars": c.count(c.bars)}
   ```

3. Gọi hằng RobotOM bằng tên qua `const("I_...")`, không ghi số trực tiếp.
4. Trả về `dict` hoặc model Pydantic; lỗi thì `raise`.
5. Không dùng `print()`; log qua `config.py`.
6. Chạy `uv run python -m rsap_mcp --selfcheck` và `uv run ruff check .`.

---

## Danh sách công cụ / Tool list

35 tool (tiền tố `rsap_`) và 3 resource. Dấu `*` = tham số bắt buộc.

### Session & Project

| Tool | Mô tả / Description | Tham số / Parameters |
|---|---|---|
| `rsap_connect` | Connect to (or launch) Autodesk Robot Structural Analysis Professional. | `visible`:boolean, `interactive`:boolean |
| `rsap_status` | Report connection status and a summary of the current Robot model. | (none) |
| `rsap_new_project` | Create a new, empty Robot project. | `project_type`:string |
| `rsap_open_project` | Open an existing Robot model from an absolute .rtd path. | `path`:string `*` |
| `rsap_save_project` | Save the current model. Pass a path to Save As, or omit to Save in place. | `path`:string/null |
| `rsap_close_project` | Close the current project (Robot itself stays open). | (none) |

### Modeling

| Tool | Mô tả / Description | Tham số / Parameters |
|---|---|---|
| `rsap_add_node` | Create a single node at the given coordinates (metres). | `x`:number `*`, `y`:number `*`, `z`:number `*`, `number`:integer/null |
| `rsap_add_nodes` | Create many nodes at once. | `nodes`:array `*` |
| `rsap_add_bar` | Create a bar (beam/column) between two existing nodes, optionally assigning section/material. | `start_node`:integer `*`, `end_node`:integer `*`, `number`:integer/null, `section`:string/null, `material`:string/null |
| `rsap_add_bars` | Create many bars at once. | `bars`:array `*` |
| `rsap_list_nodes` | List nodes with their coordinates. | `limit`:integer |
| `rsap_list_bars` | List bars with their start/end node numbers. | `limit`:integer |
| `rsap_delete_objects` | Delete nodes or bars matching a selection string. | `object_type`:string `*`, `selection`:string `*` |

### Sections & Materials

| Tool | Mô tả / Description | Tham số / Parameters |
|---|---|---|
| `rsap_define_section` | Define a bar section label by loading a profile from Robot's active database. | `name`:string `*`, `db_section`:string/null, `material`:string/null |
| `rsap_define_material` | Define a material label, either loaded from Robot's material database or from explicit properties. | `name`:string `*`, `from_database`:string/null, `material_type`:string/null, `e`:number/null, `nu`:number/null, `ro`:number/null, `kirchoff`:number/null |
| `rsap_assign_section` | Assign an existing section label to a set of bars. | `section_name`:string `*`, `bars`:string `*` |
| `rsap_assign_material` | Assign an existing material label to a set of bars. | `material_name`:string `*`, `bars`:string `*` |
| `rsap_list_sections` | List the names of section labels defined in the model. | (none) |

### Supports

| Tool | Mô tả / Description | Tham số / Parameters |
|---|---|---|
| `rsap_define_support` | Define a support (boundary condition) label. True = restrained. | `name`:string `*`, `ux`:boolean, `uy`:boolean, `uz`:boolean, `rx`:boolean, `ry`:boolean, `rz`:boolean |
| `rsap_assign_support` | Assign an existing support label to a set of nodes. | `support_name`:string `*`, `nodes`:string `*` |

### Loads & Combinations

| Tool | Mô tả / Description | Tham số / Parameters |
|---|---|---|
| `rsap_add_load_case` | Create a simple load case. | `name`:string `*`, `nature`:string, `analysis`:string, `number`:integer/null |
| `rsap_add_self_weight` | Add a self-weight (dead) load to a case. | `case_number`:integer `*`, `direction`:string, `factor`:number, `selection`:string |
| `rsap_add_nodal_force` | Add a nodal force/moment to a case (global axes). | `case_number`:integer `*`, `nodes`:string `*`, `fx`:number, `fy`:number, `fz`:number, `cx`:number, `cy`:number, `cz`:number |
| `rsap_add_bar_uniform_load` | Add a uniformly distributed load along bars. | `case_number`:integer `*`, `bars`:string `*`, `px`:number, `py`:number, `pz`:number, `local`:boolean, `projected`:boolean |
| `rsap_add_bar_point_load` | Add a concentrated (point) force/moment on bars. | `case_number`:integer `*`, `bars`:string `*`, `fx`:number, `fy`:number, `fz`:number, `cx`:number, `cy`:number, `cz`:number, `position`:number, `relative`:boolean, `local`:boolean |
| `rsap_add_combination` | Create a load combination from weighted load cases. | `name`:string `*`, `factors`:array `*`, `combo_type`:string, `nature`:string, `number`:integer/null |
| `rsap_list_load_cases` | List load cases and combinations in the model. | (none) |

### Analysis

| Tool | Mô tả / Description | Tham số / Parameters |
|---|---|---|
| `rsap_generate_mesh` | Generate the finite-element mesh. | (none) |
| `rsap_calculate` | Run the structural analysis (solve the model). | (none) |
| `rsap_calculation_status` | Report whether analysis results are currently available. | (none) |

### Results

| Tool | Mô tả / Description | Tham số / Parameters |
|---|---|---|
| `rsap_bar_forces` | Internal forces at a point along a bar (local axes). | `bar`:integer `*`, `case`:integer `*`, `position`:number |
| `rsap_bar_force_envelope` | Sample a bar along its length and return the extreme internal forces. | `bar`:integer `*`, `case`:integer `*`, `samples`:integer |
| `rsap_node_displacement` | Nodal displacement (global axes). | `node`:integer `*`, `case`:integer `*` |
| `rsap_node_reaction` | Support reaction at a node (global axes). | `node`:integer `*`, `case`:integer `*` |
| `rsap_results_summary` | Summarise results for a case: peak nodal displacement and peak bar moment. | `case`:integer `*`, `max_nodes`:integer, `max_bars`:integer |

### Resources

| URI | Nội dung / Content |
|---|---|
| `rsap://reference/enums` | Bản đồ friendly → hằng RobotOM. |
| `rsap://reference/sections` | Hướng dẫn tiết diện & vật liệu. |
| `rsap://reference/cheatsheet` | Quy trình end-to-end. |

Tham chiếu RobotOM COM API để mở rộng server: [`docs/RobotOM_API_Reference.md`](docs/RobotOM_API_Reference.md).

---

## Xử lý sự cố / Troubleshooting

| Triệu chứng / Symptom | Xử lý / Fix |
|---|---|
| Server không hiện trong Claude | Kiểm tra `command`/`PYTHONPATH`, khởi động lại Claude, xem `mcp-server-rsap.log`. |
| `/mcp` trong Codex không thấy `rsap` | Thoát hẳn & mở lại Codex; chạy `codex mcp list`; kiểm tra `command` trong `config.toml`. |
| `constant 'I_...' not found` | Mở Robot một lần để đăng ký type library; đối chiếu tên hằng trong `enums.py`. |
| Kết nối COM thất bại | Dùng Python 64-bit; kiểm tra Robot đã cài đúng bitness. |
| Giao thức hỏng ngay khi khởi động | Tìm thư viện đang in ra stdout; chuyển log sang stderr/file. |
| `ModuleNotFoundError: mcp.server.fastmcp` | Đang dùng `mcp` 2.x; gói đã ghim `mcp[cli]<2` — chạy lại `uv sync`. |
| `ModuleNotFoundError: mcp` khi chạy client | Chạy qua venv: `uv run python client\...`. |
| `Could not read results` | Chạy `rsap_calculate()` trước; kiểm tra số bar/node/case có tồn tại. |
| `LoadFromDBase` lỗi | Đặt đúng CSDL tiết diện/vật liệu trong Job Preferences (IPE300 cần catalog châu Âu). |
| Treo khi Calculate | Đóng hộp thoại đang chờ trong cửa sổ Robot. |
| Tool đầu tiên rất chậm / timeout | Robot đang khởi động — tăng `tool_timeout_sec` hoặc mở Robot sẵn. |
| Model gọi tool sai thứ tự | Nhắc trong prompt "làm tuần tự theo cheatsheet". |

---

## Cấu trúc thư mục / Repository layout

```
rsap-mcp/
├── src/rsap_mcp/          # MCP server (server.py, robot_app.py, com_utils.py,
│   │                      #   enums.py, config.py)
│   ├── tools/             # 35 tool rsap_* theo nhóm
│   ├── models/            # pydantic schemas
│   └── resources/         # rsap://reference/*
├── client/                # client MCP rời + examples
├── scripts/               # install / run / register (PowerShell)
├── config/                # claude_desktop_config.example.json, codex_config.example.toml
├── native/RsapHelper/     # DLL C# tùy chọn
├── docs/                  # RobotOM_API_Reference.md
├── pyproject.toml
└── uv.lock                # `uv sync` đọc file này
```

---

## License

MIT. © 2026 PORTCOAST Taskforce.

TDQS

A3.7/5.0

Scored across 35 tools

Disambiguation5/5

Each tool targets a distinct resource and action: define/create/assign/query are cleanly separated, and singular vs. bulk variants (e.g., add_node vs. add_nodes) are clearly named. Even similar results tools (bar_forces vs. bar_force_envelope) differ in purpose and are unambiguous.

Naming Consistency3/5

All tools share the 'rsap_' prefix and snake_case, but the verb-noun pattern is not universal: results tools (bar_forces, node_displacement, node_reaction, results_summary) omit the verb, while most others use verb_first (add_, list_, define_). This mixed convention is readable but not fully predictable.

Tool Count3/5

35 tools is above the typical well-scoped range, but the domain (full structural analysis lifecycle) justifies the breadth. The count feels heavy yet each tool covers a distinct need; a smaller set would require awkward multi-purpose tools.

Completeness4/5

The set covers the core workflow: project management, geometry (nodes/bars), properties, supports, loads, analysis, and results. Notable gaps exist for shell/plate modeling (despite project types including shell) and there are no update/edit tools for existing objects, but the main frame/bar analysis pathway is complete.

Maintenance

ActivityMaintained
ResponsivenessNo issues