Hub Nodes
Applies to: ChengOS v0.2.0+ | Last verified: 2026-09-25 | Source: crates/cheng-nodes/src/nodes/builtin/tools
A hub is one node that stands for many callable operations, which is how an agent gets a toolbox
without the canvas growing a node per tool. tools/tool_hub exposes tools either as declared by the
active Skill or as configured by the workflow author. tools/mcp_hub does the same for tools served
by an MCP server, and tools/skills_hub discovers and manages Skills themselves. The preset nodes are
the smaller pair: list what is available, and request a switch.
Tool Hub — tools/tool_hub
Unified policy-controlled gateway for executing registered tools. The workflow author configures each Tool Hub instance in one of two modes: - skill: tools are authorized by a selected Skill's canonical Tool Hub declaration. Global list_tools discovery is unavailable. Use Skills Hub list or search to select a Skill, call Skills Hub describe, then execute with the returned skill_name, tool identifier or unique short name, allowed operation, and arguments matching the returned schema. - user: tools are explicitly enabled by the workflow author. Use list_tools to discover this instance's executable tools, then call execute within that configured scope. For execute, provide action="execute", tool, operation when required, and arguments. Skill mode also requires skill_name. Do not guess tool identifiers, operations, or argument schemas. All calls are revalidated against the current trusted scope and runtime policy.
Inputs
| Field | Type | Required | Default | Description |
action | enum | ✅ | — | Tool Hub action: list_tools or execute (required). Options: list_tools (List the executable tools of this node instance (user mode only).), execute (Execute one concrete tool command inside the trusted scope.) |
skill_name | string | — | null | Skill whose Tool Hub declaration authorizes this command (skill mode execute) |
tool | string | — | null | Tool type id or unique short name to execute (execute) |
operation | string | — | null | Tool operation/action (execute) |
arguments | any | — | null | Tool arguments object for execute. Pass a JSON object directly, never a JSON-encoded string. Use the selected tool's input schema to fill fields inside arguments. |
mode | enum | — | user | Tool source mode: skill (Skill-defined) or user (author-configured). Options: skill (The selected Skill's canonical tool_hub.tools declaration defines the executable scope; list_tools is unavailable (use Skills Hub describe).), user (The workflow author's enabled_tools rows define the scope. The default: with no rows enabled the scope is empty (deny-all).) |
enabled_tools | array<object> | — | [] | Author-enabled tool rows (user mode) |
Outputs
| Field | Type | Description |
status | string | Tool Hub status (closed enum; see node docs) |
mode | string | Tool source mode of this node |
tools | array<object> | Executable tool descriptors |
unavailable_tools | array<object> | Configured but currently unavailable tools (diagnostics) |
result | object | Runtime tool result (execute) |
approval | object | Stable approval continuation token and action summary |
errors | array<string> | Blocking errors |
warnings | array<string> | Non-blocking warnings |
error_details | any | Structured failure details such as received arguments and expected schema |
MCP Hub — tools/mcp_hub
Connect one or more MCP servers in one place. Discover tools, manage visibility, and call tools with unified output.
Inputs
| Field | Type | Required | Default | Description |
server_registry | array<object> | — | [] | 结构化 MCP 服务器列表。前端可渲染为“列表 + 独立弹窗编辑器”。 Control: mcp-server-manager |
action | enum | — | null | LLM 调用模式:list(只列名字)/ describe(查描述与参数)/ call(执行)。 留空时按兼容规则推导:discover_only 为 true → list; 填了 tool_name/arguments → call;都没有 → 配置态(只返回服务器状态)。 Control: select. Options: list (List Tool Names), describe (Describe Tools), call (Call Tool) |
tool_name | string | — | "" | 要调用(或查询描述)的工具名。格式 "server_name:tool_name"(多服务器时明确指定) 或直接 "tool_name"(单服务器时自动选择)。 |
tool_names | array<string> | — | [] | describe 模式下要查询的多个工具名。与 tool_name 合并去重。 |
arguments | object | array | string | number | integer | boolean | — | null | 工具参数(JSON 对象,由用户或 LLM 提供). Control: code-editor |
tool_visibility | string | — | null | 工具可见性配置(JSON 字符串,可选) 格式:{"server:tool": {"visible": true, "callable": true}, "*": {...}}. Control: textarea |
visibility_config | object | — | null | 结构化工具可见性配置(推荐) 格式: { "servers": {"server-a": {"visible": true, "callable": true}, "": {...}}, "tools": {"server-a:search": {"visible": true, "callable": true}, "": {...}} }. Control: mcp-visibility-editor |
discover_only | boolean | — | false | 发现模式开关:开启后只列出所有服务器的可用工具,不执行工具调用. Control: switch |
timeout_ms | integer | — | null | 请求超时(毫秒,0 或留空表示不限时). Control: number |
env_vars | object | — | null | Env vars from the credential node. These values are used for ${env:KEY} placeholders in URL, authorization, headers, arguments, and env fields. |
Outputs
| Field | Type | Description |
result | any | Unified result with summary, server status, discovered tools, and optional tool call output. |
Skills Hub — tools/skills_hub
Unified gateway for workspace Skill integration. Operations: - list: list discoverable Skills in the current workspace. - search: find Skills by capability, name, description, or tags. - describe: return a Skill's complete descriptor, required inputs, execution requirements, and declared Tool Hub tools. - credential_status: check whether required credentials are available. - approval_status: check whether execution requires human approval. - execute: execute a Skill with input_data. The Skill catalog is dynamic. Use list or search to discover Skills instead of assuming which Skills exist. Before invoking a tool declared by a Skill, call describe and use the returned tool identifiers, allowed operations, and argument schemas with Tool Hub. Do not guess Skill or tool contracts.
Inputs
| Field | Type | Required | Default | Description |
operation | enum | ✅ | — | Which Hub operation to run. Required: a missing operation is rejected at deserialization rather than defaulting to execute, so a caller that supplies only skill_name can never accidentally trigger a skill execution. Options: list (List discoverable skills in the workspace (paginated, with optional filters).), search (Free-text search across discoverable skills.), describe (Full secret-free descriptor for one skill, including its Tool Hub tool declarations with filtered input schemas.), credential_status (Check whether the required credentials for a skill are bound and resolvable.), approval_status (Check whether a high-risk skill still needs human approval before execute.), execute (Execute a skill by slug (forwards to the shared execute pipeline).) |
skill_name | string | — | null | Target skill slug |
query | string | — | null | Search query (name/description) |
category | string | — | null | Category filter |
tags | array<string> | — | [] | Tag filters |
backend_type | string | — | null | Backend type filter |
input_data | any | — | null | Execute input data |
timeout_seconds | integer | — | 3600 | Execute timeout, default 3600 |
async_execution | boolean | — | false | Return after starting the workflow |
env_vars | object | — | null | Transient credential env vars |
limit | integer | — | 50 | Discovery page size, default 50 |
cursor | string | — | null | Discovery pagination cursor |
audience | enum | — | llm | Discovery visibility audience: llm (default) or human. Options: llm (Model-facing: excludes both hidden and llm_hidden. The default.), human (Human-facing: shows llm_hidden (still hides hidden).) |
Outputs
| Field | Type | Description |
status | string | Skill execution status (see SkillOutput::status docs for the closed enum and frontend mapping) |
skill_id | string | Matched skill ID |
skill_name | string | Matched skill name |
execution_id | string | Workflow execution ID (if started) |
outputs | any | Workflow output data |
instructions | string | Skill usage instructions (returned when no associated workflow) |
next_action | string | Suggested next action (for LLM reference) |
error | string | Error message |
missing_binaries | array | Required binaries that were not found on PATH; install them or run the skill on a host that has them. |
missing_credentials | array | List of credential bindings that could not be resolved; rendered into the credential-setup UI. |
approval_outcome | string | Approval gate outcome for high-risk skills |
normalization_status | string | Canonical spec normalization status |
policy_warnings | array<string> | Runtime policy warnings |
operation | string | Hub operation that produced this output |
data | any | Operation-specific payload (discovery page or status report) |
List Available Presets — tools/list_available_presets
Scoped introspection: lists node presets an LLM may request a switch to, limited to the current workflow, the tools connected alongside the calling agent, and presets marked visible to LLMs.
Inputs
| Field | Type | Required | Default | Description |
target_node_id | string | — | null | Optional target tool node id to scope the preset list to. |
Outputs
| Field | Type | Description |
presets | array<object> | List of available presets visible to the requesting agent |
count | integer | Number of presets returned |
error | string | Error message when the operation failed |
Request Preset Switch — tools/request_preset_switch
Requests an approval-gated preset switch for a tool node connected alongside the calling agent. The preset is applied only after the user approves; the LLM can never apply it directly.
Inputs
| Field | Type | Required | Default | Description |
target_node_id | string | — | null | Target tool node id. Optional if only one node of the preset's type exists. |
preset_id | string | — | "" | Preset id to switch to. Discover valid ids via list_available_presets. |
reason | string | — | null | Optional reason for the switch, shown to the approver. |
Outputs
| Field | Type | Description |
status | string | Outcome status: applied, rejected, out_of_scope, or error |
applied | boolean | Whether the preset was applied |
request_id | string | Approval request identifier |
message | string | Human-readable result message |
change_summary | any | Key-by-key diff ({key: {from, to}}) presented for approval |
Next steps