Macro MCP 实体类工具怎么用:列实体、取属性、改属性的调用顺序与写操作边界
让 Agent 接管一个协作工具,最先卡住的往往不是”连上 MCP”,而是连上之后发现:模型能把邮件读出来,却改不动那条任务的状态。Macro 的 MCP 工具参考页一共列了十六个工具,其中真正能碰”结构化字段”的只有三个——ListEntities、GetEntityProperties、SetEntityProperty。搜索类、内容类、邮件类工具都绕不到这块。
麻烦在于,这三页文档写得极简。官方在页头明确写了一句:这些页面是从 Macro 的 Rust MCP 工具注册表生成的(Generated from the Macro Rust tool registry)。所以每页只有一张参数表,没有返回值结构、没有调用示例、没有取值枚举。生成器把注册表里的字段名和描述倒出来就结束了,剩下的语义要靠读者自己拼。
这篇就是把这三张表摊开来拼一遍:每个参数官方原文怎么写的、三者之间的依赖关系是什么、写操作到底能改什么、以及哪些地方文档根本没说、你得自己在接入前试出来。想先看 MCP 服务整体范围的,可以从 Macro 的 MCP 服务能做什么 那篇进来;想理解 properties 这套字段体系本身的,看 properties:给任何东西挂结构化字段。
三个工具的参数,官方原文是这样
先把三张表原样列出来,后面所有推断都以这三张表为准。
ListEntities:
| 参数 | 类型 | Required | 官方描述 |
|---|---|---|---|
includeTypes | array | Yes | 过滤到特定的 item 类型。若未提供则返回所有类型。示例:["document", "email"] 只返回文档和邮件 |
sortBy | string | Yes | 结果排序方式:recently_viewed(默认)、recently_updated 或 recently_created |
GetEntityProperties:
| 参数 | 类型 | Required | 官方描述 |
|---|---|---|---|
entity_id | string | Yes | 要取属性的实体 ID |
entity_type | string | Yes | 实体类型 |
SetEntityProperty 的参数最多,十三个:
| 参数 | 类型 | 官方描述 |
|---|---|---|
entity_id | string | 要更新的实体 ID |
entity_type | string | 实体类型 |
property_definition_id | string | 属性定义 ID。从 GetEntityProperties 的结果里取 |
string_value | string | 用于字符串属性 |
number_value | number | 用于数字属性 |
boolean_value | boolean | 用于布尔属性 |
date_value | string | 用于日期属性(ISO 8601 date-time) |
option_id | string | 用于单选属性。选项 UUID,取自 available options |
option_ids | array | 用于多选属性。选项 UUID 列表 |
entity_ref | object | 用于单实体引用属性 |
entity_refs | array | 用于多实体引用属性 |
link_url | string | 用于单链接属性 |
link_urls | array | 用于多链接属性 |
注意这十三个在生成页里的 Required 列全部是 Yes。这一点后面单独说。
为什么必须按 List → Get → Set 的顺序走
三个工具不是并列关系,是一条链。串起这条链的是两个 ID。
第一个是 entity_id。GetEntityProperties 和 SetEntityProperty 都强制要 entity_id + entity_type,但两页都没说这个 ID 从哪来。而 ListEntities 是这组工具里唯一不需要任何前置 ID 就能调用的——它只要 includeTypes 和 sortBy。所以它天然是入口:先列出实体,才有 ID 往下传。
第二个是 property_definition_id。这个参数的官方描述里直接写了出处:从 GetEntityProperties 的结果里取。这是三页文档中唯一一处明确的跨工具依赖,也是为什么 SetEntityProperty 不能单独用——你不可能凭空知道”Priority”这个字段在当前工作区的定义 ID 是什么,必须先读一次。
对于单选、多选属性还有第三层依赖:option_id 要的是”available options 里的选项 UUID”。也就是说改一个状态字段,不是传字符串 "Done",而是要传那个选项的 UUID,而 UUID 同样只能来自前一次读取。这一点在实操上很容易翻车——模型很擅长自信地编一个看起来像 UUID 的字符串。
properties 概念页对这条链有一句总结性的描述:Agent 通过 MCP 实体工具读写属性,GetEntityProperties 读、SetEntityProperty 更新(状态、负责人、日期、自定义字段)、ListEntities 浏览。跟参数表推出来的顺序是一致的。
按参数表拼一个调用示意(注意:这不是官方示例,官方生成页没给示例,只是把文档里的参数名按类型摆好):
// 第一步:浏览
{ "includeTypes": ["document", "email"], "sortBy": "recently_updated" }
// 第二步:读某个实体的属性,拿 property_definition_id / 选项 UUID
{ "entity_id": "<上一步得到的 ID>", "entity_type": "<实体类型>" }
// 第三步:只写与该属性类型对应的那一个值字段
{
"entity_id": "<同上>",
"entity_type": "<同上>",
"property_definition_id": "<第二步得到的定义 ID>",
"option_id": "<第二步得到的选项 UUID>"
}
十三个值字段选哪一个:按属性类型对号入座
SetEntityProperty 把所有数据类型的写入口摊平成了十三个平行参数。properties 概念页列出了这套系统支持的数据类型,两边对起来就是一张映射表:
| 属性类型(properties 页) | 对应写入字段(SetEntityProperty) |
|---|---|
| STRING(文本) | string_value |
| NUMBER | number_value |
| BOOLEAN | boolean_value |
| DATE | date_value(ISO 8601 date-time) |
| SELECT_STRING / SELECT_NUMBER | 单选 option_id、多选 option_ids |
| ENTITY(引用另一个实体) | 单个 entity_ref、多个 entity_refs |
| LINK(URL) | 单个 link_url、多个 link_urls |
有两处对不齐,接入前值得留意。
一是 SELECT_STRING 和 SELECT_NUMBER 在写入侧没有区分。参数表只按”单选 / 多选”分了 option_id 和 option_ids,没说数字选项要不要走别的字段。按描述”选项 UUID”来看,两者应该都是传 UUID,但官方文档没有明说。
二是 entity_ref 的类型是 object,而不是字符串 ID。这个对象里该放什么键,生成页没有给出结构。properties 页倒是列了实体引用可以指向哪些类型:User、Company、Contact、Document、Project、Channel、Chat、Task、Thread——但这是”能引用谁”,不是”这个 object 长什么样”。真要用引用类属性,得先读一次同类字段的返回,照着回填。
“Required 全是 Yes”是生成器的锅,别当真
这三页最容易误导人的地方,是 Required 那一列。
十三个值字段全标 Yes,但语义上它们互斥——一个属性要么是布尔要么是日期,不可能同时既传 boolean_value 又传 date_value。ListEntities 更直白:includeTypes 标着 Required = Yes,描述里却写着”若未提供则返回所有类型”;sortBy 标着 Required = Yes,描述里却写着”recently_viewed(默认)“。既然有默认值、有”未提供”的行为,那就不是真必填。
结论很清楚:这一列是注册表导出时的机械产物,读文档时应当以描述文字为准,而不是以 Required 列为准。这不是抠字眼——如果照着这一列去写工具调用的 schema 校验,会把本来合法的调用全拦掉。
顺带一句,这也提醒了这批文档的可信边界:参数名和描述是从代码注册表来的,可信度高;表格结构本身(Required、类型)是生成器填的,会失真;返回值结构则完全没有——三页都没有 Returns 一节。所以你没法从文档预知 ListEntities 返回的实体对象里有哪些字段、有没有分页游标、单次最多返回多少条。这些只能在真实连接上之后打一次日志看。
写操作的边界与几个没兜底的地方
SetEntityProperty 是这十六个工具里少数几个会改变工作区状态的写操作,接进自动化流程前要想清楚几件事。
它能改到系统字段。 properties 页说属性分 system(内置、不可删除,比如任务的 Status)和 custom(自己加的)两类,而 Agent 访问那一节明确写了 SetEntityProperty 用于更新状态、负责人、日期和自定义字段。也就是说”不可删除”不等于”不可写”——任务的 Status、Assignees 这些默认置顶的字段,Agent 是能动的。任务默认置顶 Status、Priority、Assignees 三项,改动会直接出现在别人看到的卡片上。
文档里没有 dry-run,也没有撤销。 三页参数表里不存在预览、校验、回滚一类的参数,官方也没有在这几页提及批量写入的行为。一次调用改一个属性,改错了只能再调一次改回去——前提是你还知道原值。所以真接自动化,建议在 SetEntityProperty 之前先 GetEntityProperties 存一份原值,这是文档没要求、但代价很低的自保。
自动维护的字段要绕开。 properties 页提到 CRM 公司(Customers)有一个 Last Interaction 时间戳,会从同步的工作区邮件自动更新。这类由系统写入的字段,官方没有说明是否允许通过 SetEntityProperty 覆盖、覆盖后会不会被下一次同步冲掉。在文档没说清之前,把它们排除在 Agent 可写清单之外更稳妥。
权限这三页没讲。 SetEntityProperty 只要 entity_id 和 entity_type,参数里不带任何权限或作用域信息。也就是说 Agent 的可写范围完全取决于 MCP 连接背后那个身份能看到什么,这三页文档不负责解释这件事。团队工作区里放开写权限之前,这块要单独确认。
这三个工具解决不了的事
先说范围:ListEntities 是”浏览”不是”搜索”。它的参数只有类型过滤和三种排序,没有关键词、没有条件筛选、也没有文档记载的分页参数。想按内容或名字找东西,得用另外一组工具,见 搜索类工具:内容搜索与名称搜索;想读正文、元数据或新建文档,是内容类工具的活,见 内容类工具:读内容、读元数据、建文档。实体三件套只管”结构化字段”这一层。
再说几处文档确实没有覆盖、不要靠猜的地方:
entity_type的合法取值没有枚举。ListEntities示例里出现的是小写的"document"、"email",properties 页里实体引用能指向的是首字母大写的 User、Company、Contact、Document、Project、Channel、Chat、Task、Thread——两处的大小写和集合都不一样,不能直接互相套用。- 返回结构一律缺失。三页都没有 Returns 一节,
GetEntityProperties返回的属性对象里property_definition_id具体挂在哪一层、available options 以什么形式给出,文档里查不到。 - 错误行为没写。传了不匹配的值字段、传了不存在的选项 UUID、对没有该属性的实体写入,分别会返回什么,官方生成页没有说明。
- 批量与并发没写。一次调用改一个属性是参数表暗示的形态,但官方没有明确说不支持批量,也没有说并发写同一实体会怎样。
这三个工具本身的设计是清楚的——一条”浏览拿 ID、读拿定义 ID、写回一个值”的链路,能覆盖改状态、指派人、填日期、写自定义字段这些最常见的 Agent 动作。真正需要你补的是文档没给的那一半:返回结构、类型枚举和错误行为。接入时把第一次真实调用的返回完整存下来,比反复读这三张生成表有用得多。
延伸阅读
- 从头读起:Macro 是什么:邮件、任务、文档、CRM 共用一个双向数据库的开源工作区
- 本专题共 40 篇,完整分组目录见专题页
- Macro MCP 的两个搜索工具:ContentSearch 搜正文、NameSearch 搜标题,别用混
- Macro MCP 内容类工具怎么用:ReadContent、ReadMetadata 与 CreateDocument 的参数与陷阱
本文依据 Macro 官方仓库(github.com/macro-inc/macro,AGPL-3.0 协议)的 apps/docs/ 产品文档、
MCP 工具参考与自托管说明整理,核对日 2026-08-17。
我们没有注册或运行过 Macro,因此不涉及界面外观与操作手感;
官方标注为计划中的能力文中已如实标明,不代表当前可用。
价格与额度以官网 macro.com 最新页面为准;许可证相关问题请咨询专业人士并以官方许可证原文为准。