mcpField
U
use-semantius

use-semantius

github.com/semantius数据与数据库150 次安装今天更新
代码仓库

关于 use-semantius

use-semantius 是通过 Semantius 官方 CLI 操作语义数据模型和业务数据的技能,面向使用命令行或 Agent 管理数据的场景。它按建模、单表记录操作和跨表分析划分工作层级。

主要功能

  1. 01管理实体、字段、关系与权限
  2. 02读写 PostgreSQL 业务记录
  3. 03跨表分析与指标查询
  4. 04CSV 检查及主机间迁移

适用场景

  1. 01创建或调整数据模型及访问规则
  2. 02查询或修改单表业务记录
  3. 03汇总多个表的数据并分析趋势

MCP 相关

该技能通过 `semantius` CLI 为 shell 和 Agent 提供对 `crud`、`cube` 与 `utils` 三个服务器的访问。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/semantius/semantius-cli --skill use-semantius

安装后在 Claude Code 中输入/use-semantius确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
cli-usage.md
crud-tools.md
cube-queries.md
cube-tools.md
data-modeling.md
entity-families.md
jsonlogic.md
lucide-icon-checker.ts
lucide-icon-finder.ts
lucide-icon-tags.json
rbac.md
select-rule.md
vendor-names.ts
webhooks.md

详细介绍

use-semantius Skill

Semantius 是一个低代码平台,可让你定义语义数据模型、实体、字段、关系和访问规则,并立即获得完全托管的 PostgreSQL 数据库、REST API、自动生成的 UI,以及背后的分析层。你定义数据的结构(第 1 层),Semantius 负责存储、查询(第 2 层)和跨表分析(第 3 层)。

semantius 是官方 CLI,可通过 Shell 和 Agent 访问三个服务:crud(架构管理 + 记录操作)、cube(兼容 CubeJS 的分析),以及内置的 utils(CSV 解析、在主机之间迁移实体和模块)。


架构:三个不同的层

了解你正在使用哪一层,才能确定应该使用哪些工具:

┌─────────────────────────────────────────────────────────────┐
│  Layer 1: Semantic Data Model                               │
│  Defines entities, fields, modules, relationships, RBAC     │
│  Tables: entities, fields, modules, permissions, roles...   │
│  Tools: create_entity, create_field, create_permission...   │
├─────────────────────────────────────────────────────────────┤
│  Layer 2: Business Data (PostgreSQL via PostgREST)          │
│  Actual records in your entity tables: /products, /orders   │
│  Tools: postgrestRequest (GET/POST/PATCH/DELETE)            │
│         sqlToRest for SQL→PostgREST conversion              │
├─────────────────────────────────────────────────────────────┤
│  Layer 3: Analytics (CubeJS-compatible API)                 │
│  Multi-table queries, aggregations, metrics, time-series    │
│  Tools: cube discover → validate → load / chart             │
└─────────────────────────────────────────────────────────────┘

经验法则:

  • 定义存在什么(架构、权限、角色)→ 第 1 层类型化工具
  • 操作单个表中的实际记录 → 第 2 层 postgrestRequest
  • 跨表查询或需要聚合/指标 → 第 3 层 cube

参考文件

文件阅读时机
references/cli-usage.mdCLI 命令及其级别、凭据和主机、选项、Shell 模式、命令串联、安装;§“在主机之间迁移实体和模块”
references/data-modeling.md第 1 层、实体、字段、模块、关系、安全演进;§“枚举值和标签”
references/entity-families.md第 1 层、子类型和扩展(id_type: is_a / has_a、id_refentity):何时使用、创建顺序、跨层级读写、限制、删除、错误代码。首次对这类实体调用 create_entity 前请先阅读
references/jsonlogic.md第 1 层、JsonLogic 规则:computed_fields、validation_rules、扩展运算符、跨实体查找、动态 input_type_rule(条件式只读/隐藏/必填)
references/select-rule.md第 1 层、行级安全:select_rule、谁能看到哪些行、REPLACE 与 AND 语义、管理员锁定风险
references/rbac.md第 1 层、权限、角色、用户分配、层级结构
references/crud-tools.md第 1 层类型化工具 + 第 2 层 postgrestRequest/sqlToRest 参考;§“批量操作”(数组 data / id,每组记录调用一次)
references/cube-queries.md第 3 层、CubeJS 查询 DSL、日期筛选、分析模式
references/cube-tools.md第 3 层、发现/验证/加载/图表工具签名
references/webhooks.md通过已签名的 Webhook 接收器接收外部系统的记录:设置、签名、日志
references/lucide-icon-finder.ts运行它(bun),不要阅读它:<query…>(每个查询包含一个或多个词,按具体程度从高到低排列)按顺序列出每个查询对应的 Lucide 图标名称;参见 data-modeling.md →“图标使用 Lucide 图标”
references/lucide-icon-checker.ts运行它(bun),不要阅读它:<name…> 会在写入图标前确认 Lucide 图标名称,退出码为 1 时会列出未知名称;参见 data-modeling.md →“图标使用 Lucide 图标”
references/vendor-names.ts运行它(bun),不要阅读它:entity:<Name>… 和 field:<Name>… 会将你所跟踪产品的记录名称和字段名称(使用单数形式,拼写方式与产品一致)转换为 table_name 和标签,或 field_name 和标签;切勿手动转换。由 semantius-architect(stage-2-naming.md)和 semantius-analyst(stage-4-fields.md)使用

快速决策指南

管理架构、创建/修改实体、字段或模块? → 第 1 层,阅读 references/data-modeling.md,遵循强制创建顺序

同一事物有多种类型(“电子邮件和电话都是活动”),或者某个记录也可以是另一种事物(“业务合作伙伴也可以是客户”)? → 第 1 层,创建任何内容前先阅读 references/entity-families.md:它会决定使用 is_a、has_a、枚举字段还是独立实体,并会改变创建顺序(每个层级调用一次 create_entity,先创建基类)。创建时即会锁定此选择,因此请与用户确认

计算字段、验证规则或条件字段行为(根据记录设置只读/隐藏/必填)? → 第 1 层,阅读 references/jsonlogic.md,了解实体级和字段级 JsonLogic、运算符及跨实体查询

只有部分用户可以对记录执行某项操作(删除、关闭、批准记录或修改某个字段)? → 第 1 层,阅读 references/jsonlogic.md § 检测操作。实体的 edit_permission 会同时涵盖插入、更新和删除,因此,针对单项操作或状态转换的限制应使用验证规则:检查 $mode(或变更的字段),再检查调用者身份。如果是所有者匹配,例如 $old.owner_user_id == $user_id,则无需权限;如果使用 has_permission,则需要先根据 references/rbac.md 创建权限

配置权限、角色或用户? → 第 1 层,阅读 references/rbac.md

限制用户可见的行(通过 select_rule 实现行级安全)? → 第 1 层,阅读 references/select-rule.md。注意:非空规则会在读取时替代 view_permission——不含 has_permission 子句的规则会将管理员拒之门外

在单个表中插入、读取、更新或删除记录? → 第 2 层,使用 postgrestRequest,参见 references/crud-tools.md

创建、更新或删除多个同类记录(许多字段、许多权限或许多行)? → 一次调用,绝不循环:create_* 的 data 使用数组;update_*/delete_* 的 id/table_name 使用数组;postgrestRequest POST 使用数组 body(键保持一致)。参见黄金规则 7 和 references/crud-tools.md §“批量操作”

跨多个表查询、聚合、分析趋势、查找前 N 项或指标? → 第 3 层,使用 cube,阅读 references/cube-queries.md + references/cube-tools.md

编写 shell 脚本或串联 CLI 命令? → 阅读 references/cli-usage.md

导入 CSV 文件? → semantius-importer 技能是入口:它会检查文件(utils/get_csvschema),创建或复用实体,并分批批量加载数据。

将实体或模块迁移到另一台主机、备份或还原导出内容? → 使用 semantius-transfer 技能执行工作流;references/cli-usage.md §“在主机之间迁移实体和模块”介绍具体操作。

发送事务性电子邮件? → 第 2 层工具,使用 crud sendEmail,参见 references/crud-tools.md §“sendEmail”

基于现成配方(例如由 semantius-skill-maker 生成的技能)执行时,遇到意外的 409/422 错误,并怀疑架构已发生变化? → 使用 read_entity/read_field 实时检查,参见 references/data-modeling.md §“运行时架构检查(实时外键/结构查询)”。不要悄悄调整配方;应中止操作、说明架构变化,并建议重新生成领域技能。


环境设置

1. 是否已安装 semantius? 运行 semantius --version。如果 shell 找不到该命令(POSIX 下会显示 command not found / 退出码 127,PowerShell 下会显示 CommandNotFoundException),可能是已经安装,但尚未加入当前会话的 PATH。请检查 %LOCALAPPDATA%\Programs\Semantius\semantius.exe(Windows)或 /usr/local/bin/semantius 和 ~/.local/bin/semantius(Linux / macOS)。如果文件存在,在这些技能写明 semantius 的地方都使用它的完整路径(references/cli-usage.md § "Installing from an agent")。如果这些位置都没有,请停止:不要运行任何 semantius 命令,并告知用户尚未安装,同时提供 references/cli-usage.md § "Installation" 中适用于其 shell 的安装命令,以及指南 **https://www.semantius.com/docs/cli/use-semantius/**。

2. 是否已连接? 按照 references/cli-usage.md § "Checking the connection" 操作。简而言之:

  • 探测(运行 semantius whoami,或调用你本来就需要的 getCurrentUser)。退出码为 0:已连接。需要确认使用的是哪个凭据时,请指出主机、其 host_source 和 auth_method;退出码为 0 仍可能存在 § "Credential, first match wins" 中的两个陷阱之一。
  • 退出码为 3: 重试一次,然后显示错误并停止。
  • MISSING_ENV_VAR 或退出码为 5: 使用 semantius use <host> 为用户登录;除非 whoami 显示主机为 current,否则先询问用户要使用哪个主机。尚无实例的用户请前往 https://app.semantius.com 注册;该网站会提供其主机(<org>.semantius.app)及连接步骤。例外:如果在有意配置密钥或令牌时,错误中提到 SEMANTIUS_API_KEY 或 SEMANTIUS_JWT,则显示错误并停止。
  • 其他任何情况: 显示错误并停止。

为用户登录(§ "Signing the user in"):semantius use <host> 会为所有目录中的后续命令切换主机,因此只能对用户指定要操作的主机运行;semantius login --host <host> 会登录,但不切换主机。绝不要运行 logout。在后台运行登录,并将 URL 转发给用户;如果用户不在这台机器的屏幕前操作,则始终添加 --login-flow device。

whoami、ping 和 hosts 是安全的只读诊断命令。命令、层级、主机和凭据优先级:references/cli-usage.md。


核心 CLI 命令

semantius                              # List all servers and tools
semantius -d                           # List with descriptions
semantius info <server>               # Show tools for a server
semantius info <server> <tool>        # Get tool JSON schema
semantius grep "<pattern>"            # Search tools by glob
semantius call <server> <tool> '{}'   # Call tool with inline JSON
semantius call <server> <tool>        # Call tool — reads JSON from stdin

Windows(PowerShell):始终传入内联 JSON;如果工具不接受参数,则通过管道传入空输入。 省略 JSON 参数会使 CLI 阻塞并持续从 stdin 读取,直到遇到 EOF。在持久化 PowerShell 会话中(某些 Agent 运行环境会在多次调用间保留状态),stdin 管道永远不会关闭,因此调用会无限期挂起,既不报错也不超时——这不是网络或身份验证问题,重试也无济于事。始终显式提供 JSON,即使内容为空:

semantius call crud getCurrentUser '{}'     # inline JSON, never blocks
"" | semantius call crud getCurrentUser     # or explicitly pipe stdin closed

在 Windows / PowerShell 上,调用不带参数的 semantius call ... 时,绝不要直接裸调用;必须使用上述两种形式之一。

info <server> <tool> 和 info <server>/<tool> 两种写法可互换。


两个服务

crud:架构管理 + 记录操作(第 1 层和第 2 层)

第 1 层类型化工具用于管理语义数据模型:create_entity、create_field、create_module、create_permission、create_role 等。它们操作的是 Semantius 自身的架构表。每个 create_* 的 data 都可以是单个对象,也可以是对象数组(一次调用即可创建多个字段、权限或角色);每个 update_* / delete_* 的 id(实体使用 table_name,权限使用 permission_name)都可以是单个值,也可以是数组。

**第 2 层 postgrestRequest**用于操作实际业务数据。你定义的任何实体都会成为可通过 PostgREST 访问的 PostgreSQL 表:

# Read records from your 'products' entity
semantius call crud postgrestRequest '{"method":"GET","path":"/products?status=eq.active&order=name.asc"}'

# Insert a new order record
semantius call crud postgrestRequest '{"method":"POST","path":"/orders","body":{"customer_id":"123","total":99.99}}'

# Insert several records in ONE call — array body; every row carries the same keys (raw PostgREST rule)
semantius call crud postgrestRequest '{"method":"POST","path":"/orders","body":[{"customer_id":"123","total":99.99},{"customer_id":"124","total":15.00}]}'

# Update matching records
semantius call crud postgrestRequest '{"method":"PATCH","path":"/products?category=eq.electronics","body":{"on_sale":true}}'

完整参考:references/crud-tools.md

cube:兼容 CubeJS 的分析(第 3 层)

Cube 服务实现了兼容 CubeJS 的 API。如果你熟悉 CubeJS,查询 DSL 是相同的。对于需要连接、聚合或 PostgREST 无法高效表达的指标,请使用它。

始终先调用 discover,它会返回架构、完整的查询语言参考和日期筛选指南。

完整参考:references/cube-queries.md、references/cube-tools.md


链接到 Web UI

每当你想在 Semantius Web 应用中向用户展示某条记录或记录列表时——例如创建后、查找后、报告查询结果时,或任何可点击链接优于原始 JSON 的场景——请根据 getCurrentUser 的 ui_baseurl 构建链接。无论是否涉及架构工作,这条规则都适用:既适用于第 2 层记录操作,也适用于第 1 层架构变更。

  • 某个实体的记录列表:{ui_baseurl}/{module_slug}/{table_name}
  • 某条特定记录:{ui_baseurl}/{module_slug}/{table_name}/{id}

示例:https://mytest.semantius.app/it-ops-starter/service_requests/5

  • 从 getCurrentUser 获取 ui_baseurl(semantius call crud getCurrentUser '{}')——绝不要将组织主机名硬编码。
  • 路径中使用小写的 module_slug,切勿使用显示名称 module_name。

完整说明:references/crud-tools.md § getCurrentUser。


黄金规则

  1. 先读后写:在执行任何 create_* 之前,先调用 read_* 检查是否存在重复项。务必先读。
    • 执行 create_module 前 → 先运行 read_module
    • 执行 create_entity 前 → 先运行 read_entity
    • 执行 create_permission 前 → 先运行 read_permission
    • 执行 create_role 前 → 先运行 read_role
    • 如果读取返回结果,请使用这些 ID,而不是创建重复项。只有在结果为空时才创建。
    • 批量创建时,一个带有 in.(...) 过滤条件的 read_* 就能涵盖所有项("filters": "field_name=in.(description,cost)&table_name=eq.services");切勿对每条记录分别执行一次 --single 读取。
  2. 先处理架构:模块 → 权限 → 所有实体 → 字段。绝不跳过步骤;先创建某个模型的所有实体,再创建其中任何字段,这样每个字段的 reference_table(包括自引用)都已存在。**例外:**对于 is_a / has_a 实体,先创建基类,再按层级创建基于它们的实体;每层调用一次 create_entity。所有层级的实体都创建完后,再创建字段(references/entity-families.md)。
  3. 绝不创建自动生成的字段:id、label、created_at、updated_at 和 label_column 字段由 create_entity 自动创建。对于 is_a / has_a 实体,也绝不要创建其基类中的字段;只创建该实体自身的字段。create_field 中也不要设置 field_order:平台会按数组顺序追加新字段,而手动指定的值可能会与自动创建的字段意外相同(标签字段位于 20)。只有在用户需要特定位置时才设置;设置前先读取实体当前的 field_order 值。
  4. reference_table 必须使用关系格式:任何带有 reference_table 的字段都必须使用 format: "reference" 或 format: "parent"。没有例外。
  5. 高风险变更前先警告:重命名 table_name / field_name,以及删除实体或字段,都需要用户明确确认。
  6. 在有帮助时始终提供 UI 链接:架构变更后,以及记录操作(创建 / 查找 / 更新)后。格式:{ui_baseurl}/{module_slug}/{table_name};单条记录则追加 /{id}。有关规则,请参阅上文的“链接到 Web UI”(从 getCurrentUser 获取 ui_baseurl;使用小写的 module_slug)。
  7. **始终批量处理:每组记录调用一次,绝不循环逐条调用。**待处理的同类记录超过一条时(某个实体的多个字段、某个模块的多个权限、多个 role_permission 行、多个待更新或删除的 ID、某个表的多行记录),都要在一次调用中发送:向 create_* 的 data 传入数组('{"data": [{...}, {...}]}'),或向 update_* / delete_* 的 id 传入数组(实体使用 table_name,权限使用 permission_name),例如 '{"id": [4, 5, 6]}';相同的 data 会应用于每个 ID。数组项不必包含相同的键(某项省略的键会采用列默认值)。一次调用就是一个请求和一个事务(要么全部成功,要么全部失败);响应始终是受影响记录的数组。每次调用控制在约 100 行 / 个 ID。明明可以用一次数组调用,却发出 N 次单条记录调用,是错误做法。唯一的顺序例外是实体族:每层调用一次 create_entity,先创建基类。postgrestRequest 也接受数组 body,但须遵循原始 PostgREST 规则(每项的键必须相同,或者在路径中使用 ?columns=,省略的键会变为 NULL)。请参阅 references/crud-tools.md 中的 §“批量操作”。

响应处理:仅凭退出码还不够

默认情况下,即使查询恰好匹配一行,crud 服务也会返回 JSON 数组。若 GET 未找到任何行,则退出码为 0,响应体为 []。这在协议层面表示成功,在领域层面则表示“未找到”。仅将退出码视为成功信号,会悄无声息地将空结果传递到下游,并破坏所有依赖它的写入操作。

这适用于每个 crud 工具,而不只是 postgrestRequest。 类型化的 Layer-1 工具也会返回数组:read_entity、 read_module 和所有 create_* / update_* / delete_* 工具都会 输出 [{...}],而不是单个对象;批量调用(数组 data、数组 id)则会在该数组中输出每条受影响的记录。因此,在 create_role 响应上运行 jq -r '.id' 会失败,并报错 Cannot index array with string——应对数组进行索引:jq -r '.[0].id',或者传入 --single 以获取单个对象(仅限单条记录调用;若 data / body / id / table_name 是数组,则会拒绝 --single)。更好的做法是,不要直接从新行自身的创建响应中读取其 id:回显的表示形式并不是可靠的 id / 自然键载体。创建后按自然键重新读取(建模器的 ensure / ensureMany 辅助函数正是这样做的——对整个批次执行一次 in.(...) 读取),这样数组与对象的形状就不会传到你的 jq。

针对 crud 读取有两种方式。请选择符合调用意图的方式:

模式 A:预期恰好一行时使用 --single

对于任何必须恰好解析出一行的读取(按 id、唯一列或 该配方已证明唯一的复合键查询),都向 postgrestRequest 传入 --single。CLI 会在底层设置 PostgREST 的 Accept: application/vnd.pgrst.object+json 标头,并将响应转换为符合 Agent shell 约定的格式:

结果退出码标准输出
恰好一行0{"id":"...", ...}(单个对象,不是数组)
零行1标准错误上输出错误
两行或更多2标准错误上输出错误
参数 / 配置 / JSON 无效1标准错误上输出错误信息
网络 / 传输(暂时性、可重试)3标准错误上输出错误信息
工具执行失败(RLS、重复键、架构)4标准错误上输出错误信息
身份验证失败(缺少 / 无效的 API 密钥、401、403)5标准错误上输出错误信息

请注意,退出码 1 涵盖两种不同情况——“零行”和“参数 无效”。对于格式正确且处于稳定状态的脚本,运行时只会触发零行这一情况,因此规范的防护逻辑(“未找到或存在歧义”)是明确的;参数无效导致的 1 表示配方存在错误,绝不应出现在最终用户面前。

退出码 3 和 5 是有意区分的:3 表示暂时性错误(重试 一两次),5 表示永久性错误(立即告知用户,以便他们修复凭据)。根据这些情况分支的配方可以直接使用 case $? in 3) retry ;; 5) abort ;; esac,而无需解析标准错误。

现在,退出码会直接表示未找到的情况。规范脚本模式可简化为一个防护逻辑:

row=$(semantius call crud postgrestRequest --single "{\"method\":\"GET\",\"path\":\"/<table>?<unique-filter>\"}") \
  || { echo "step N: <entity> '<value>' not found or ambiguous" >&2; exit 1; }
# $row is the bare object: {"id":"...", ...}
# Parse with jq '.id' or grep -oE '"id":"[^"]+"' (no head -n1, no [0] index).

对于领域技能中的绝大多数读取,--single 都是正确的模式:每次“按 id 查询”、每次通过 eq.<unique-column> 解析,以及关联表配方中的每次父行读取都应使用它。如果零行或多行结果属于领域错误,而不是正常分支,就应使用 --single。

模式 B:数组(默认),适用于预期返回零行或多行的情况

对于结果数量本身就是答案的读取操作,请省略 --single: 去重检查(“这条关联表记录是否已存在?”)、列表 查询、批量读取。在这种情况下,响应是一个数组, Agent 必须检查响应内容才能知道返回了什么。

结果退出码stdout操作
找到记录0[{...}, ...]使用这些记录
未找到记录0[]去重/列表查询的答案是“无”;据此采取相应操作
参数/配置/JSON 错误1stderr 中的错误消息修正参数;不要重试
网络/传输错误(暂时性)3stderr 中的错误消息重试一到两次,然后反馈错误
工具执行失败(RLS、重复键、架构)4stderr 中的错误消息向用户反馈;这通常是实际错误或写入冲突
身份验证失败(缺少/无效 API 密钥、401、403)5stderr 中的错误消息中止并向用户反馈;不要重试

以下是数组读取的标准模式,其业务含义取决于结果是否为空:

rows=$(semantius call crud postgrestRequest "{\"method\":\"GET\",\"path\":\"/<table>?<filter>&select=id\"}") \
  || { echo "step N (<what>) failed" >&2; exit 2; }
if ! printf '%s' "$rows" | grep -q '"id"'; then
  # zero rows, the recipe's "go ahead and create / no duplicate" branch
  ...
else
  # one or more rows, the recipe's "already exists / use existing" branch
  ...
fi
如何选择
读取意图模式
将 <title> 解析为功能记录--single(标题必须存在,否则无法继续执行该方案)
按 id 读取父记录--single
检查 (feature_id, user_id) 关联表记录是否存在数组(零行是正常的“创建”分支)
列出某个状态下的所有功能数组
验证写入是否生效--single(该记录必须存在;我们刚刚写入了它)
检查批量清理是否完成(残留记录为零)数组(你要统计记录数,而不是断言只有一条)
写入(POST / PATCH / DELETE)

成功的 POST 或 PATCH 会返回插入/更新的记录 (如果设置了 Prefer: return=minimal,则返回 [],但平台 默认不会设置该选项)。DELETE 会返回已删除的记录。因此, 对于未匹配任何记录的写入操作,同样适用“退出码为 0 且 [] 表示未执行任何操作”的规则:带有过滤条件且未匹配任何记录的 PATCH 会静默成功。单条记录写入也适用 --single (必须恰好影响一条记录的 POST/PATCH),这是断言更改已生效的最简洁方式。如果操作本应更改状态,务必读取数据进行验证。

批量写入的响应始终是数组,绝不能使用 --single。 带有数组 data 的 create_*、带有数组 id(或 table_name)的 update_* / delete_*,或带有数组 body 的 postgrestRequest,始终返回受影响记录的数组——每条成功写入的记录对应一个元素。 CLI 会在发送请求前拒绝此类调用中的 --single(退出码为 1,错误码为 SINGLE_ARRAY_INPUT)。数组调用也绝不要显式传入 "accept": "application/vnd.pgrst.object+json"。通过计数断言批量写入结果(jq 'length' 等于发送的记录数),或通过后续带有 in.(...) 过滤条件的 read_* 调用进行验证。批量调用是一个事务:如果失败,其中的任何记录都不会写入——修复原因后重新发起这一次调用;不要退而采用循环逐条调用的方式。

评论

支持 Markdown