内容
# acc-forma-mcp-server
> 安全第一的MCP服务器,适用于 **Autodesk Forma** (前身为Autodesk Construction Cloud)。
> 每次写入都是干燥可运行的、审计日志记录的和作用域保护的。
**阅读所有内容 · 预览每次写入 · 审计每次操作。**
[](https://github.com/KenLP/acc-forma-mcp-server/actions)
[](LICENSE)
[](package.json)
---
## 为什么使用此服务器?
| 功能 | 其他ACC/APS MCP服务器 | acc-forma-mcp-server |
|---|---|---|
| 问题读取 + 写入(完整CRUD + 评论 + 附件) | 部分 | ✅ |
| 审查读取 + 写入 | 部分 | ✅ |
| AEC数据模型(BIM元素查询) | 单独的.NET服务器 | ✅ |
| **AECDM元素位置查询(问题定位支持)** | ❌ | ✅ |
| **写入前干燥运行预览** | ❌ | ✅ |
| **篡改证据审计日志(JSONL + 哈希链)** | ❌ | ✅ |
| **项目/中心允许列表强制执行** | ❌ | ✅ |
| **只读模式切换** (`FORMA_READONLY=true`) | ❌ | ✅ |
| **每工具每小时速率治理** | ❌ | ✅ |
| **业务规则验证器** | ❌ | ✅ |
| TypeScript严格模式 | 部分 | ✅ |
---
## 快速入门
### 步骤1 — APS凭证(一次性)
您需要一个 **Autodesk Platform Services(APS)** 应用程序和一个 **SSA(安全服务账户)** 。SSA是一个机器人身份,可以限定为特定项目,无需人类登录。
参见 [docs/AUTH.md](docs/AUTH.md) 了解完整的操作指南。快速总结:
1. 在 [aps.autodesk.com](https://aps.autodesk.com) 上创建一个应用程序 → 启用 **Autodesk Construction Cloud** API
2. 应用程序 → **安全 → 服务账户** → 生成密钥对 → 下载PEM私钥(永远不要提交)
3. 记录您的 `APS_CLIENT_ID`、`APS_CLIENT_SECRET`、`SSA_ID`、`SSA_KEY_ID` 和PEM文件路径
4. **中心管理员 → 成员** → 邀请SSA电子邮件 → 分配项目管理员角色
5. **中心管理员 → 自定义集成** → 通过客户端ID添加您的应用程序(必需 - 如果没有此操作,所有项目调用都会返回403)
### 步骤2 — 配置环境变量
在项目根目录中创建一个 `.env` 文件(或在MCP客户端配置中将这些变量作为环境变量传递 - 参见步骤3):
```env
APS_AUTH_MODE=ssa
APS_CLIENT_ID=您的客户端ID
APS_CLIENT_SECRET=您的客户端密钥
SSA_ID=您的SSA ID
SSA_KEY_ID=您的密钥ID
SSA_KEY_PATH=/绝对路径/到/private-key.pem
```
完整变量参考: [配置](#配置)
### 步骤3 — 添加到您的MCP客户端
该服务器通过 **stdio** (JSON-RPC)进行通信。它由您的MCP客户端启动 - 不需要在终端中单独运行。
**选项A — npx** (无需克隆;需要在npm上发布包)
```json
{
"mcpServers": {
"forma": {
"command": "npx",
"args": ["-y", "acc-forma-mcp-server"],
"env": {
"APS_CLIENT_ID": "您的客户端ID",
"APS_CLIENT_SECRET": "您的客户端密钥",
"APS_AUTH_MODE": "ssa",
"SSA_ID": "您的SSA ID",
"SSA_KEY_ID": "您的密钥ID",
"SSA_KEY_PATH": "/绝对路径/到/private-key.pem"
}
}
}
}
```
**选项B — 克隆并在本地构建**
```bash
git clone https://github.com/KenLP/acc-forma-mcp-server.git
cd acc-forma-mcp-server
pnpm install
pnpm build
```
然后将您的MCP客户端指向已构建的文件:
```json
{
"mcpServers": {
"forma": {
"command": "node",
"args": ["/绝对路径/到/acc-forma-mcp-server/dist/index.js"],
"env": {
"APS_CLIENT_ID": "您的客户端ID",
"APS_CLIENT_SECRET": "您的客户端密钥",
"APS_AUTH_MODE": "ssa",
"SSA_ID": "您的SSA ID",
"SSA_KEY_ID": "您的密钥ID",
"SSA_KEY_PATH": "/绝对路径/到/private-key.pem"
}
}
}
}
```
> **提示:** 通过MCP客户端配置(如下所示)传递凭证,而不是依赖 `.env` 文件。当客户端启动进程时,工作目录可能不是仓库根目录。
**MCP客户端配置文件位置**
| 客户端 | 配置路径 |
|---|---|
| Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Claude Desktop (Windows) | `%APPDATA%\Claude\claude_desktop_config.json` |
| VS Code (MCP扩展) | `.vscode/mcp.json` 在您的工作区中 |
---
## 可用工具
## 工具(43)
所有工具按领域分组。读取工具无需审批;写入/变异工具(标记为 ✍️)遵循 [两步干燥运行协议](#安全).
### 账户管理员(4)
| 工具 | 用途 |
|---|---|
| `admin_list_projects` | 列出中心下的所有项目(通过2LO的中心范围可见性)。 |
| `admin_get_project` | 获取单个项目的元数据、范围和关系。 |
| `admin_list_users` | 列出账户/项目成员资格中的用户。 |
| `admin_list_companies` | 列出账户中注册的公司。 |
### 数据管理(6)
| 工具 | 用途 |
|---|---|
| `dm_list_hubs` | 列出应用程序可访问的ACC/BIM 360中心。 |
| `dm_list_projects` | 列出中心中的项目。 |
| `dm_list_top_folders` | 列出项目的顶级文件夹(计划、项目文件等)。 |
| `dm_list_folder_contents` | 列出文件夹中的项目(文件 + 子文件夹)。 |
| `dm_get_item` | 获取单个项目的元数据。 |
| `dm_list_versions` | 列出文件的所有版本,版本编号和时间戳。 |
### 问题(12)
| 工具 | 用途 |
|---|---|
| `issues_list` | 列出项目中的问题,带有过滤器(状态、类型、分配人)。 |
| `issues_get` | 获取单个问题的完整详细信息,包括当前用户的`permittedStatuses`和`permittedAttributes`。 |
| `issues_create` ✍️ | 创建带有子类型、位置、截止日期、分配和可选定位链接的新问题。 |
| `issues_pin_element` ✍️ | 创建一个问题,带有自动放置在BIM元素上的3D定位图标 - 解析查看器GUID、objectId、globalOffset和从元素的External ID调用的查看器位置。 |
| `issues_update` ✍️ | 更新现有问题 - 状态、标题、描述、分配人、截止日期、子类型、位置(稀疏PATCH;仅提供字段更改)。 |
| `issues_add_comment` ✍️ | 向现有问题添加评论。 |
| `issues_list_comments` | 列出问题的评论线程,分页。 |
| `issues_list_types` | 列出项目有效的問題类型和子类型(带有`isActive`标志)。 |
| `issues_list_root_causes` | 列出项目配置的根原因类别。 |
| `issues_get_user_me` | 获取当前身份的问题模块的权限标志(canCreate、canUpdate、canCreateComments)。 |
| `issues_list_attrs` | 列出项目的自定义属性定义 - 用于获取`customAttributes`在创建/更新中所需的UUID。 |
| `issues_list_attachments` | 列出附加到问题的文件和链接,分页。 |
> **状态值(从实时ACC API确认):** `draft` \| `open` \| `pending` \| `in_review` \| `closed` \| `void`. 有效的转换取决于项目工作流 - 在更新前检查 `permittedStatuses` 从 `issues_get`。
### 审查(4)
| 工具 | 用途 |
|---|---|
| `reviews_list` | 列出项目审查容器中的审查。 |
| `reviews_get` | 获取单个审查,包括状态和审查者。 |
| `reviews_create` ✍️ | 创建带有审查者、截止日期、工作流、链接文档的新审查。 |
| `reviews_transition` ✍️ | 提交/批准/拒绝/无效/重新打开审查。 |
### AEC数据模型 - BIM GraphQL(8)
| 工具 | 用途 |
|---|---|
| `aecdm_list_hubs` | 列出AECDM原生中心(与DM中心不同)。从这里开始任何AECDM工作流。 |
| `aecdm_list_projects` | 列出AECDM中心中的项目。 |
| `aecdm_list_element_groups` | 列出发布到AECDM项目的BIM模型文件(Revit/IFC),包括`fileVersionUrn`。 |
| `aecdm_list_categories` | 列出元素组中的BIM类别(Walls、Structural Columns、MEP设备等),通过并行探测〜60个众所周知的Revit类别。 |
| `aecdm_query_elements` | 按类别查询BIM元素,带有完整属性。支持多词类别,如`Structural Columns`、`Electrical Equipment`。 |
| `aecdm_get_element_properties` | 通过节点ID(需要原始类别)重新获取特定元素的完整属性。 |
| `aecdm_aggregate_by_parameter` | 按参数值对元素进行计数在类别内(例如,按类型名称对墙进行快速查询)- 快速查询。 |
| `aecdm_query_element_positions` | 查询带有原点位置(x,y,z)的元素 **以米为单位**,以及每个元素的`external_id`(Revit UniqueId)。主要用途:填充ACC问题定位图标。对于3D定位图标,将转换为查看器空间:`meters × 3.280839895 − globalOffset`(英制)。注意:返回一个原点 *点*(不是AABB)。只有点放置的元素(Pipe Fittings、Fixtures、Columns、Doors)具有几何形状 - 线性(Pipes、Ducts)和平面(Walls、Floors)返回`position: null`。使用AECDM `geometryDataByElements`公共测试版字段。 |
### 模型派生 - SVF2翻译(3)
| 工具 | 用途 |
|---|---|
| `md_get_manifest` | 检查SVF2翻译状态并列出模型版本的可用3D/2D查看器GUID。 |
| `md_get_properties` | 从SVF2翻译的模型中获取Revit元素属性(名称、参数、类别)。支持类别和objectId过滤。 |
| `md_trigger_translation` ✍️ | 为模型版本提交新的SVF2翻译作业。通过`md_get_manifest`轮询。 |
> **注意:** 边界框不可从MD Properties API获得任何SVF2模型 - 这是APS平台限制。对于元素边界框,Model Properties API (`/construction/index/v2/`) 是正确的路径(需要3LO身份验证 - 第3阶段)。
### 模型协调 - 碰撞检测(2)
| 工具 | 用途 |
|---|---|
| `mc_list_modelsets` | 列出项目中的协调模型集(协调空间)。SSA需要 **Model Coordination产品访问**(成员/管理员),否则API返回404。 |
| `mc_list_clashes` | 拉取模型集的碰撞检测结果 - 每个碰撞对及其两个模型、元素标识(objectId/dbId)和穿透深度(`distance` 为负 = 硬碰撞)。连接碰撞/实例/文档结果文件;按最差排序。可用于 `issues_pin_element` 将碰撞转为固定问题。 |
### 模型属性 - 版本差异(1)
| 工具 | 用途 |
|---|---|
| `mp_diff_versions` | 差异两个相同模型的版本(ACC的*比较版本*的后端):返回整个模型的`added/removed/modified`统计数据,以及按 **Revit类别** 和更改类型(`Transform`与`Geometry`与仅属性)的元素汇总。适用于 **SSA** (无3LO)。异步 - 如果仍在处理,则返回可续签的`diff_id`。使用每个类别的计数驱动 **跨学科更改警报**(例如,架构 `Rooms`更改 → 标记结构重新检查负载;`Ducts`/`Mechanical Equipment`更改 → 标记MEP)。 |
### ACC文档 - 可视化(1)
| 工具 | 用途 |
|---|---|
| `docs_get_viewables` | 解析ACC Docs-native **`viewableId`** (例如`"Layout1"`)和文档版本URN的页面/纸张名称,以便您可以放置2D PDF定位图标(`issues_create`带有`type=TwoDRasterPushpin`)。这是清单 `viewableID` 字段 - **与SVF2 `guid`** 不同,由 `md_get_manifest` 返回,后者markup服务拒绝用于栅格PDF图标。 `markupCapable: false` 表示文档没有Docs-native可视化(例如,通过DM API上传的原始PDF,ACC未处理 - 通过ACC Docs或Sheets API重新发布)。 |
### 元/可观察性(2)
| 工具 | 用途 |
|---|---|
| `meta_list_changelog` | 读取带有工具、时间或项目过滤器的本地审计日志条目。 |
| `meta_verify_audit_chain` | 验证审计日志哈希链未被篡改。 |
第3阶段待办事项:非差异模型属性单个版本索引(`POST indexes` + `queries`)用于版本上的bbox/属性查询 - 与 `mp_diff_versions` 相同的API系列,尚未包装。
---
## 安全防护
### 1. 默认干燥运行
每个变异工具默认为 `dry_run=true`。在第一次调用时,服务器:
- 验证允许列表、只读模式、速率限制、业务规则
- 解析确切的APS API请求(方法、URL、正文)
- 返回 **预览** + 单次使用的 `approval_token`
- **不** 调用APS
要执行,请使用 `dry_run=false, approval_token=<token>` 再次调用相同的工具。
```
Claude: "在项目xyz中创建一个标题为'Leak at Level 3'的问题"
Tool: issues_create(dry_run=true)
→ {
preview: { method: "POST", url: "...issues", body: {...} },
approval_token: "appr_01JXW...",
next_step: "Re-call with dry_run=false and approval_token to execute"
}
Tool: issues_create(dry_run=false, approval_token="appr_01JXW...")
→ 问题创建:ID abc-456
```
### 2. 篡改证据审计日志
所有工具调用都追加到 `~/.acc-forma-mcp/audit/audit-YYYY-MM-DD.jsonl`,带有SHA-256哈希链接。在任何时候验证完整性:
```bash
# 使用MCP工具
meta_verify_audit_chain()
# 或直接读取JSONL
cat ~/.acc-forma-mcp/audit/audit-$(date +%F).jsonl | jq .
```
### 3. 项目允许列表
```env
FORMA_ALLOWED_PROJECTS=proj-uuid-1,proj-uuid-2
FORMA_ALLOWED_HUBS=hub-id-1
```
服务器拒绝任何工具调用引用不在此列表中的项目/中心 - 独立于SSA权限。
### 4. 只读模式
```env
FORMA_READONLY=true
# 或
FORMA_MUTATION_MODE=readonly
```
阻止所有变异工具立即,无需触及APS。
### 5. 变异模式
| `FORMA_MUTATION_MODE` | 行为 |
|---|---|
| `preview_required`(默认) | 必须dry_run=true;再调用带有approval_token |
| `client_approval_only` | 单次调用;信任MCP客户端的内置批准UI |
| `readonly` | 所有变异阻止 |
---
## 配置
复制 `.env.example` 到 `.env` 并填写您的值。所有选项在 `.env.example` 中有注释。
关键变量:
| 变量 | 默认值 | 描述 |
|---|---|---|
| `APS_CLIENT_ID` | - | 必需 |
| `APS_CLIENT_SECRET` | - | 必需 |
| `APS_AUTH_MODE` | `ssa` | `ssa`, `2lo`, 或 `3lo`(3lo:第3阶段) |
| `SSA_ID` | - | SSA模式下必需 |
| `SSA_KEY_ID` | - | SSA模式下必需 |
| `SSA_KEY_PATH` | - | PEM私钥文件路径 |
| `FORMA_READONLY` | `false` | 阻止所有变异 |
| `FORMA_MUTATION_MODE` | `preview_required` | 参见安全部分 |
| `FORMA_ALLOWED_HUBS` | `*` | 逗号分隔的中心ID |
| `FORMA_ALLOWED_PROJECTS` | `*` | 逗号分隔的项目UUIDs |
| `FORMA_AUDIT_DIR` | `~/.acc-forma-mcp/audit` | JSONL审计日志目录 |
| `FORMA_AUDIT_FAIL_CLOSED` | `false` | 表面审计写入失败作为错误。当 `true` | 当失败后APS变异时,表面写失败。 |
| `FORMA_AUDIT_DIR` | `~/.acc-forma-mcp/audit` | JSONL审计日志目录 |
---
## 核心SDK (`acc-forma-mcp-server/core`)
类型化的APS客户端层(身份验证提供者,`apsRequest`/`apsGraphQL`, 八个API域)也可以作为 **库** 消费 - 无需MCP服务器,无需 `APS_*`/`FORMA_*` 环境变量:
```ts
import { SsaAuthProvider, issuesApi, mcApi } from 'acc-forma-mcp-server/core';
const auth = new SsaAuthProvider(['data:read', 'data:write'], {
clientId, clientSecret, ssaId, ssaKeyId,
privateKey: pemString, // 直接来自凭证库 - 无需密钥文件
});
const issues = await issuesApi.listIssues(auth, projectId, { status: 'open' });
```
这是共享内核,用于兄弟自动化产品(n8n节点,跨CDE提取器)。完整的指南: [docs/CORE_SDK.md](docs/CORE_SDK.md) · 理由: [ADR 0002](docs/adr/0002-core-subpath-export.md).
> 安全层(干燥运行,批准令牌,审计链)是MCP服务器行为,**不** 故意作为核心的一部分 - 写入保护属于服务器,而不是HTTP客户端。
---
## 开发
```bash
# 安装
pnpm install
# 构建
pnpm run build
# 类型检查
pnpm run typecheck
# 测试
pnpm run test
# 监视模式
pnpm run test:watch
```
---
## 执照
MIT - 参见 [LICENSE](LICENSE).
**不隶属于Autodesk公司。** Autodesk Forma®、Autodesk Construction Cloud® 和 Autodesk Platform Services® 是Autodesk公司的商标。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器