PowerDesigner MCP
<div align="center">
# PowerDesigner MCP
**Let AI agents operate PowerDesigner like a professional database modeling engineer.**
[](#quick-start)
[](#quick-start)
[](#verified-environment)
[](https://modelcontextprotocol.io)
[](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/LICENSE)
**English** | [中文](#中文文档)
An MCP (Model Context Protocol) server that drives **Sybase PowerDesigner 16.5**
through its official **COM Automation API** — never by touching `.pdm` binaries —
covering the full database course-design loop:
```
requirements → data dictionary → CDM → E-R → LDM → PDM
→ constraints → indexes → DDL (SQL) → model checks → save
```
**Verified end-to-end on a real PowerDesigner 16.5 installation**: model creation,
tables, columns, primary keys (single & composite), foreign keys with automatic
FK-column migration, indexes, native MySQL DDL generation, validation, and
save-as — 42 unit tests + live acceptance tests, all passing.
</div>
---
## Why this exists
AI coding assistants can reason about database design, but they cannot *touch*
PowerDesigner. This MCP server is the missing execution layer:
- **The AI does the design reasoning.** The server does reliable execution.
- **55+ granular tools** (not one giant tool), plus high-level batch operations.
- **Safety first**: every mutating tool supports `dry_run`; batch tools are
atomic with automatic rollback; file-level transactions restore the exact
pre-transaction state.
- **Graceful degradation**: without PowerDesigner installed, the server falls
back to an in-memory mock backend with identical tool semantics — so the
whole pipeline is testable anywhere.
## Architecture
```
MCP Client (Cursor / Claude Desktop / Claude Code)
│ MCP stdio (JSON-RPC)
▼
FastMCP Server ──── Tools (55+) / Resources / Prompts
▼
Services (schema orchestration · validation engine · inspection · transactions)
▼
PowerDesignerAdapter (interface)
├── ComAdapter ── single-threaded STA COM dispatcher ── PowerDesigner 16.5 COM
└── MockAdapter ── in-memory model store (tests / PD-less development)
```
Adapter isolation means version differences (16.x / 17.x) stay inside the COM
layer; every assumption is verified against the vendor's own constants file,
`.NET` interop metadata, and live experiments — see
[docs/com-api-notes.md](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/docs/com-api-notes.md).
## Quick start
### Install — one command, no path editing
```powershell
git clone https://github.com/NovolineGast/powerdesigner-mcp.git
cd powerdesigner-mcp
.\install.ps1
```
That is the whole install. There is no path to type and no client JSON to
hand-edit:
1. **The package is installed as a tool** — `uv tool install --editable .` puts
`powerdesigner-mcp` in an isolated environment with a launcher on `PATH`
(without uv it falls back to an editable install in `.venv`).
2. **The client config is written for you** — the installer then runs
`powerdesigner-mcp install`, resolves the launch command for this machine and
merges it into every MCP client it detects: `%USERPROFILE%\.workbuddy\mcp.json`,
`%APPDATA%\Claude\claude_desktop_config.json`, `%USERPROFILE%\.cursor\mcp.json`,
and `claude mcp add` when that CLI is present. A replaced config is backed up
next to the original as `mcp.json.bak-<timestamp>`.
3. **The result is verified** — a real PowerDesigner COM probe and a stdio smoke
test run **on the exact command that was just registered**, so the entry is
proven to launch rather than merely written.
Already installed? Re-register at any time (after moving the project, changing
clients, etc.):
```powershell
powerdesigner-mcp install # detected clients
powerdesigner-mcp install --client workbuddy
powerdesigner-mcp install --dry-run # preview, write nothing
powerdesigner-mcp install --print-only # print the entry JSON
```
> **Why this needed absolute paths before:** the project used to be installed as
> *dependencies only* into a `.venv`, so every client entry had to carry the
> venv's interpreter path **and** a `PYTHONPATH` pointing at `src`. Installing
> the package itself removes both, and `install` computes whatever remains by
> itself — including the uv tool launcher when the host does not inherit `PATH`.
### Even shorter: no clone needed
```powershell
# after the first PyPI release
uvx powerdesigner-mcp install
# straight from the repository (uv must be able to reach GitHub - see note)
uvx --from git+https://github.com/NovolineGast/powerdesigner-mcp powerdesigner-mcp install
```
`uvx` runs in a throw-away environment, which would produce a config pointing
into a cache that gets pruned — so `install` detects that, re-installs the
package as a proper `uv tool` (reusing the recorded source: PyPI name + version,
git URL + commit, or archive URL) and registers *that* launcher instead.
> Some networks (TLS-inspecting proxies) block uv's git transport while the
> `git` CLI still works; uv then fails without an error message. If that
> happens, install from a checkout instead:
> `git clone … ; uv tool install --editable . ; powerdesigner-mcp install`.
### Manual / other platforms
```powershell
uv tool install --editable . # recommended: launcher on PATH
powerdesigner-mcp install # writes the client configs
powerdesigner-mcp probe # COM capability check
powerdesigner-mcp serve # start MCP server (stdio)
# without uv:
py -3 -m venv .venv
.venv\Scripts\python.exe -m pip install -e .
.venv\Scripts\python.exe -m pd_mcp install
```
### MCP client configuration
You normally never write this by hand — `powerdesigner-mcp install` does it.
Here is what it produces, for reference:
<details open>
<summary><b>Claude Desktop</b> — <code>%APPDATA%\Claude\claude_desktop_config.json</code></summary>
```json
{
"mcpServers": {
"powerdesigner": {
"command": "C:\\Users\\<you>\\.local\\bin\\powerdesigner-mcp.exe",
"args": ["serve"],
"env": { "PDMCP_ATTACH_MODE": "auto", "PDMCP_DEFAULT_DBMS": "MySQL 5.0" }
}
}
}
```
</details>
<details>
<summary><b>Cursor</b> — <code>%USERPROFILE%\.cursor\mcp.json</code></summary>
Same structure as above, under the `mcpServers` key.
</details>
<details>
<summary><b>Claude Code</b></summary>
```powershell
claude mcp add powerdesigner -- "$env:USERPROFILE\.local\bin\powerdesigner-mcp.exe" serve
```
</details>
<details>
<summary><b>WorkBuddy</b> — <code>%USERPROFILE%\.workbuddy\mcp.json</code></summary>
Same structure as the Claude Desktop example. Then open **Connector management →
Custom connectors (top-right) → Trust** the `powerdesigner` server; new MCP
servers do not activate automatically.
If your client cannot pass `env` at all, point `command` at
`scripts\powerdesigner-mcp.cmd` (portable wrapper, leave `args` empty) — the
installer also accepts an explicit launcher:
`powerdesigner-mcp install --command <path>`.
</details>
## Tool catalog (55+)
| Group | Tools |
|---|---|
| **Model management** | `get_server_info` · `list_open_models` · `open_model` · `create_model` · `save_model` · `save_model_as` · `close_model` · `get_model_info` · `list_packages` · `get_package` |
| **Read / inspect** | `list_tables` · `get_table` · `search_tables` · `list_columns` · `get_column` · `search_columns` · `list_keys` · `get_key` · `list_indexes` · `get_index` · `list_references` · `get_reference` · `list_relationships` · `get_relationship` · `list_domains` · `get_domain` · `model_snapshot` · `inspect_schema` · `compare_model` |
| **Mutations** (all support `dry_run`) | `create/rename/update/delete_table` · `create/rename/update/delete_column` · `create/set/remove_primary_key` (single & composite) · `create/update/delete_reference` (auto FK migration) · `create/update/delete_index` (normal/unique/composite) |
| **High-level automation** | `create_database_schema` (one JSON → whole schema) · `apply_schema_patch` (16 structured ops, atomic) · `design_from_spec` (materialize a PDM/CDM/LDM design) |
| **Validation loop** | `validate_model` (structural checks) · `check_database_design` (14 machine-checkable rule types, e.g. TABLE_HAS_PK, COLUMN_HAS_COMMENT, naming patterns) |
| **DDL & conversion** | `generate_ddl` (PowerDesigner **native** generation) · `convert_cdm_to_ldm` · `convert_cdm_to_pdm` · `convert_ldm_to_pdm` |
| **Transactions** | `begin_transaction` · `commit_transaction` · `rollback_transaction` · `list_model_backups` · `rollback_model` |
**Resources**: `powerdesigner://models`, `powerdesigner://model/{id}`,
`.../tables`, `.../table/{code}`, `.../relationships`, `.../indexes`
**Prompts**: `database_design_workflow` (full course-design loop), `schema_review`
## The course-design workflow
```
1. get_server_info # verify connection
2. design_from_spec(kind=CDM) # AI designs entities/relations → materialized
3. convert_cdm_to_ldm # resolve M:N
4. convert_cdm_to_pdm(dbms="MySQL 5.0") # physical model
5. create_reference / create_index # FKs & indexes (dry_run first)
6. validate_model # fix every error
7. check_database_design(rules) # your course naming/comment rules
8. fix → re-validate # closed loop
9. generate_ddl # native SQL
10. save_model # save .pdm
```
## Safety model
| Mechanism | Behavior |
|---|---|
| `dry_run: true` | Returns the exact execution plan, touches nothing |
| `apply_schema_patch` / `create_database_schema` | Atomic: any failure rolls the model back |
| `begin_transaction` | Saves + backs up the model file |
| `rollback_transaction` | Restores the exact pre-transaction file and reopens |
| No file backup + destructive op | Explicit error — never fails silently |
## Configuration
| Env var | Default | Description |
|---|---|---|
| `PDMCP_ADAPTER` | `auto` | `com` / `mock` / `auto` |
| `PDMCP_ATTACH_MODE` | `auto` | `auto` / `attach` (ROT) / `launch` (start pdshell) / `new` |
| `PDMCP_PD_EXE` | auto-detect | Path to `pdshell16.exe` |
| `PDMCP_VISIBLE` | `false` | Show PowerDesigner window when we launch it |
| `PDMCP_DEFAULT_DBMS` | PD default | e.g. `MySQL 5.0` for new PDMs |
| `PDMCP_CALL_TIMEOUT` | `300` | Per COM-call timeout (seconds) |
Full list in [`src/pd_mcp/config.py`](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/src/pd_mcp/config.py). A JSON config file
(`pdmcp.json`) is also supported.
## Development & testing
```powershell
.venv\Scripts\python.exe -m pytest tests -m "not live" # unit/smoke tests (mock backend)
$env:PDMCP_LIVE = "1"
.venv\Scripts\python.exe -m pytest tests -m live # live acceptance (real PowerDesigner)
.venv\Scripts\python.exe -m pd_mcp probe # standalone COM capability probe
```
The mock backend mirrors PowerDesigner semantics (PK via `Primary` flags,
reference FK migration, index column binding) so the full pipeline — including
schema orchestration, validation, transactions and DDL — is tested without a
PowerDesigner license.
CI runs the suite on `windows-latest` (Python 3.10 and 3.13) and separately
builds the sdist/wheel, validates the metadata with `twine check --strict`,
asserts the wheel carries the server and its entry point, and installs it before
running the CLI. Releases are cut by pushing a `v*` tag — see
[docs/RELEASING.md](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/docs/RELEASING.md)
for the one-time PyPI Trusted Publisher setup.
## Verified environment & honest limitations
- **Verified**: PowerDesigner **16.5.0.3982** on Windows 10/11, 64-bit Python
3.13. COM facts verified against the vendor's `VBScriptConstants.vbs`,
`Interop.*.dll` metadata, official C# sample and live probes — see
[docs/com-api-notes.md](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/docs/com-api-notes.md).
- `CheckModel()` returns `None` on 16.5 (results go to PD's Result List window);
machine-readable findings come from `validate_model` / `check_database_design`.
- PowerDesigner has **no SaveAs**: saving an unsaved model to a new path is
implemented via ShellNew-template file binding + content copy (returns a
`copied` summary). Diagram symbols are re-attached and auto-laid-out as part
of the copy, and the saved file is verified to hold the model rather than the
ShellNew stub (PD 16.5 sometimes writes to an extension-less sibling).
- CDM/LDM are first-class: entities/attributes, identifiers (primaries), and
conceptual relationships with per-end cardinalities and a dependent side.
Indexes are a physical concept, so index tools reject a CDM/LDM explicitly.
- CDM inheritance is not exposed yet; the adapter interface makes adding it
straightforward.
- Generating for a DBMS different from the model's DBMS returns a clear error —
use `create_model(dbms=...)` / `ChangeDBMS` first.
## License
[MIT](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/LICENSE)
---
<div align="center">
<a name="中文文档"></a>
# PowerDesigner MCP(中文文档)
**让 AI Agent 像专业数据库建模工程师一样操作 PowerDesigner。**
[English](#powerdesigner-mcp) | 中文
一个 MCP(Model Context Protocol)服务器,通过 PowerDesigner 的**官方 COM
Automation API**(绝不直接修改 `.pdm` 二进制)驱动 **Sybase PowerDesigner 16.5**,
覆盖数据库课程设计完整闭环:
```
需求分析 → 数据字典 → CDM → E-R 模型 → LDM → PDM
→ 完整性约束 → 索引 → DDL(SQL) → 模型检查 → 保存模型
```
**已在真实 PowerDesigner 16.5 环境端到端验收**:建模、表、列、主键(单列/联合)、
外键(自动迁移 FK 列)、索引、原生 MySQL DDL 生成、模型校验、另存为——
42 项单元测试 + 真机验收测试全部通过。
</div>
### 中文目录
- [为什么需要它](#为什么需要它-1)
- [架构](#架构-1)
- [快速开始](#快速开始-1)
- [工具目录](#工具目录-1)
- [课程设计工作流](#课程设计工作流-1)
- [安全模型](#安全模型-1)
- [配置](#配置-1)
- [开发与测试](#开发与测试-1)
- [验证环境与诚实声明](#验证环境与诚实声明-1)
### 为什么需要它
AI 助手擅长数据库设计推理,却无法"触碰" PowerDesigner。本 MCP Server 是缺失的
执行层:
- **AI 负责设计推理,服务器负责可靠执行**;
- **55+ 细粒度工具**(拒绝单一巨型工具)+ 高层批量编排;
- **安全第一**:所有修改工具支持 `dry_run`;批量操作原子执行、失败自动回滚;
文件级事务可精确还原事务前状态;
- **优雅降级**:未安装 PowerDesigner时自动切换语义一致的内存 Mock 后端,
整条流水线在任何机器上均可测试。
### 架构
```
MCP 客户端(Cursor / Claude Desktop / Claude Code)
│ MCP stdio(JSON-RPC)
▼
FastMCP Server ──── Tools(55+)/ Resources / Prompts
▼
Services(schema 编排 · 校验规则引擎 · 检查 · 事务)
▼
PowerDesignerAdapter(抽象接口)
├── ComAdapter ── 单线程 STA COM 调度 ── PowerDesigner 16.5 COM
└── MockAdapter ── 内存模型(测试 / 无 PD 环境)
```
Adapter 隔离使版本差异(16.x/17.x)被限制在 COM 层内;所有 API 假设均经厂商
常量文件、.NET Interop 元数据与真机实验验证——见
[docs/com-api-notes.md](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/docs/com-api-notes.md)。
### 快速开始
```powershell
git clone https://github.com/NovolineGast/powerdesigner-mcp.git
cd powerdesigner-mcp
.\install.ps1 # 一条命令:装包 + 注册客户端 + 真机 COM 探测 + 冒烟测试
```
**不需要手写任何路径**,安装脚本自己完成三件事:
1. **把包装成工具**(`uv tool install --editable .`):独立环境 + PATH 上的
启动器;没有 uv 时退回项目 `.venv` 可编辑安装。
2. **自动写客户端配置**:随后执行 `powerdesigner-mcp install`,自行解析本机
启动命令,并合并进它探测到的所有客户端配置(WorkBuddy / Claude Desktop /
Cursor,以及存在 `claude` CLI 时的 `claude mcp add`);被替换的配置会备份为
`mcp.json.bak-<时间戳>`。
3. **验证配置真能启动**:真机 COM 探测 + 用**刚刚注册的那条命令**跑 stdio 冒烟
测试,而不是只把 JSON 写进去。
已装过?随时重新注册(搬目录、换客户端之后):
```powershell
powerdesigner-mcp install # 自动探测客户端
powerdesigner-mcp install --client workbuddy
powerdesigner-mcp install --dry-run # 只预览,不写文件
powerdesigner-mcp install --print-only # 打印配置 JSON
```
> **以前为什么要手写路径**:项目过去只把**依赖**装进 `.venv`,包本身没装,
> 于是每个客户端条目都必须带 venv 解释器路径 **加** 指向 `src` 的 `PYTHONPATH`。
> 现在把包装成工具后两者都不需要,剩下的路径由 `install` 自己算——包括宿主不
> 继承 `PATH` 时改走 uv 工具启动器。
手动安装 / 其他平台:
```powershell
uv tool install --editable .
powerdesigner-mcp install
powerdesigner-mcp probe # COM 能力探测
powerdesigner-mcp serve # 启动 MCP Server(stdio)
# 不用 uv 时:
py -3 -m venv .venv
.venv\Scripts\python.exe -m pip install -e .
.venv\Scripts\python.exe -m pd_mcp install
```
客户端配置样例(正常无需手写,由 `powerdesigner-mcp install` 生成)见上文英文部分。
连 clone 都不需要的一条命令:
```powershell
# PyPI 首次发布之后
uvx powerdesigner-mcp install
# 直接来自仓库(要求 uv 能访问 GitHub,见下方提示)
uvx --from git+https://github.com/NovolineGast/powerdesigner-mcp powerdesigner-mcp install
```
`uvx` 跑在一次性环境里,写进配置的路径会被缓存清理掉;`install` 会识别这一点,
按记录的来源(PyPI 名称+版本 / git 地址+提交 / 归档地址)把包重装成常驻的
`uv tool`,再注册那个启动器。
> 少数网络(会做 TLS 拦截的代理)会让 uv 的 git 传输失败而 `git` 命令行仍可用,
> 此时 uv 不打印任何错误。遇到这种情况请改用本地检出:
> `git clone … ; uv tool install --editable . ; powerdesigner-mcp install`。
发布流程(打标签自动发 PyPI)见
[docs/RELEASING.md](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/docs/RELEASING.md)。
### 工具目录
| 分组 | 工具 |
|---|---|
| **模型管理** | `get_server_info` · `list_open_models` · `open_model` · `create_model` · `save_model` · `save_model_as` · `close_model` · `get_model_info` · `list_packages` · `get_package` |
| **读取/检查** | `list_tables` · `get_table` · `search_tables` · `list_columns` · `get_column` · `search_columns` · `list_keys` · `get_key` · `list_indexes` · `get_index` · `list_references` · `get_reference` · `list_relationships` · `get_relationship` · `list_domains` · `get_domain` · `model_snapshot` · `inspect_schema` · `compare_model` |
| **修改类**(全部支持 `dry_run`) | `create/rename/update/delete_table` · `create/rename/update/delete_column` · `create/set/remove_primary_key`(单列/联合)· `create/update/delete_reference`(自动迁移 FK 列)· `create/update/delete_index`(普通/唯一/联合) |
| **高层自动化** | `create_database_schema`(一份 JSON 建成整库)· `apply_schema_patch`(16 种结构化操作,原子执行)· `design_from_spec`(物化 PDM/CDM/LDM 设计) |
| **校验闭环** | `validate_model`(结构检查)· `check_database_design`(14 种可机检规则类型) |
| **DDL 与转换** | `generate_ddl`(PowerDesigner **原生**生成)· `convert_cdm_to_ldm` · `convert_cdm_to_pdm` · `convert_ldm_to_pdm` |
| **事务** | `begin_transaction` · `commit_transaction` · `rollback_transaction` · `list_model_backups` · `rollback_model` |
**Resources**:`powerdesigner://models`、`powerdesigner://model/{id}` 及 tables /
table / relationships / indexes 子资源 **Prompts**:`database_design_workflow`(课程设计全流程)、`schema_review`
### 课程设计工作流
```
1. get_server_info # 确认连接
2. design_from_spec(kind=CDM) # AI 设计实体/联系 → 一次性物化
3. convert_cdm_to_ldm # 概念 → 逻辑(拆解 M:N)
4. convert_cdm_to_pdm(dbms="MySQL 5.0") # 逻辑 → 物理
5. create_reference / create_index # 补外键与索引(先 dry_run)
6. validate_model # 修复全部 error
7. check_database_design(rules) # 课程规范(命名/注释/PK/必填列)
8. 修复 → 复检 # 闭环
9. generate_ddl # 生成 SQL
10. save_model # 保存 .pdm
```
### 安全模型
| 机制 | 行为 |
|---|---|
| `dry_run: true` | 只返回执行计划,不触碰模型 |
| `apply_schema_patch` / `create_database_schema` | 原子执行:任一步失败自动回滚 |
| `begin_transaction` | 先保存并备份模型文件 |
| `rollback_transaction` | 精确还原事务前文件并重新打开 |
| 无文件备份 + 破坏性操作 | 明确报错——绝不静默失败 |
### 配置
| 环境变量 | 默认 | 说明 |
|---|---|---|
| `PDMCP_ADAPTER` | `auto` | `com` / `mock` / `auto` |
| `PDMCP_ATTACH_MODE` | `auto` | `auto` / `attach`(ROT 附加)/ `launch`(自启动 PD)/ `new` |
| `PDMCP_PD_EXE` | 自动检测 | `pdshell16.exe` 路径 |
| `PDMCP_VISIBLE` | `false` | 自启动时是否显示 PD 窗口 |
| `PDMCP_DEFAULT_DBMS` | PD 默认 | 新建 PDM 的 DBMS,如 `MySQL 5.0` |
| `PDMCP_CALL_TIMEOUT` | `300` | 单次 COM 调用超时(秒) |
完整清单见 [`src/pd_mcp/config.py`](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/src/pd_mcp/config.py);也支持 JSON 配置文件(`pdmcp.json`)。
### 开发与测试
```powershell
.venv\Scripts\python.exe -m pytest tests -m "not live" # 42 项单测/冒烟(Mock 后端)
$env:PDMCP_LIVE = "1"
.venv\Scripts\python.exe -m pytest tests -m live # 真机验收
.venv\Scripts\python.exe -m pd_mcp probe # 独立 COM 能力探测
```
Mock 后端复刻 PowerDesigner 语义(列 Primary 主键、引用 FK 迁移、索引列绑定),
因此 schema 编排、校验、事务与 DDL 全流程在无 PD 许可证的机器上同样可测。
### 验证环境与诚实声明
- **验证环境**:Windows 10/11 + PowerDesigner **16.5.0.3982** + 64 位 Python 3.13。
COM 事实经厂商 `VBScriptConstants.vbs`、`Interop.*.dll` 元数据、官方 C# 样例
与真机实验交叉验证——见 [docs/com-api-notes.md](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/docs/com-api-notes.md)。
- 16.5 的 `CheckModel()` 返回 `None`(结果进 PD Result List 窗口);机器可读的
检查结果由 `validate_model` / `check_database_design` 提供。
- PowerDesigner **没有 SaveAs**:未保存模型另存通过 ShellNew 模板文件绑定 +
内容复制实现(返回 `copied` 统计)。复制过程会重新挂载图符号并自动布局,
且会校验请求路径确实拿到模型内容而非模板壳(PD 16.5 有时会把内容写到
去掉扩展名的同级文件)。
- CDM/LDM 为一等公民:实体/属性、标识符(主标识)、概念联系(两端基数 +
依赖侧)。索引属物理概念,索引类工具对 CDM/LDM 显式报错。
- CDM 继承(Inheritance)暂未暴露;Adapter 接口使补充实现非常直接。
- 生成与模型 DBMS 不符的 SQL 会返回明确错误——请先 `create_model(dbms=...)`
或 ChangeDBMS。
### 许可证
[MIT](https://github.com/NovolineGast/powerdesigner-mcp/blob/main/LICENSE)
TDQS
Scored across 60 tools
Tools are mostly grouped by resource type with clear list/get/create/update/delete distinctions, but there is notable overlap: list_tables vs search_tables, list_columns vs search_columns, model_snapshot vs inspect_schema, and validate_model vs check_database_design. The aliased create_primary_key/set_primary_key pair and multiple batch-modification tools (create_database_schema, apply_schema_patch, design_from_spec) add further selection ambiguity, though descriptions do mitigate confusion.
The overwhelming majority of tools follow a clear verb_noun snake_case pattern: list_tables, get_column, create_reference, update_index, delete_reference. Minor deviations exist: model_snapshot, inspect_schema, design_from_spec, and begin/commit/rollback_transaction use noun-first or non-standard forms, but they are still readable and the pattern is highly consistent overall.
At 60 tools, the surface is extremely large and exceeds the 50+ threshold for extreme mismatch, even accounting for PowerDesigner's broad domain. While each tool is individually meaningful, the sheer count creates a heavy integration burden and overlaps among search/snapshot/batch tools suggest it could be consolidated.
The toolset covers nearly the full lifecycle for models, tables, columns, keys, indexes, and references, and adds transaction management, validation, DDL generation, and model conversion. Minor gaps exist: CDM/LDM relationships only have list/get with no dedicated create/update/delete, domains lack direct CRUD, and there is no delete_model tool, though these can be worked around via apply_schema_patch or design_from_spec.