pipefy-portal-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Portal setup

门户设置

Configure an organization's Pipefy portal: bootstrap the main hub, add pages and widgets, wire and publish sub-portals. 20 MCP tools (Interfaces GraphQL + internal_api for sub-portal wiring).
Deep reference:
docs/mcp/tools/portal.md
. Parity matrix:
docs/parity.md
. Env vars:
docs/config.md
.

配置组织的Pipefy门户:初始化主枢纽、添加页面和小部件、连接并发布子门户。20个MCP工具(使用Interfaces GraphQL + internal_api进行子门户连接)。
深度参考:
docs/mcp/tools/portal.md
。Parity矩阵:
docs/parity.md
。环境变量:
docs/config.md

When to use

适用场景

  • "Create our company portal", "list portals for org X", "publish a sub-portal".
  • Add or change portal pages, layout, or page elements (
    forms
    ,
    link
    , etc.).
  • Attach, publish, unpublish, or delete sub-portals on the main portal.
Do not use for:
  • Pipes, phases, cards, or automations — see
    skills/pipes-and-cards/
    ,
    skills/automations/
    .
  • Raw GraphQL when a portal tool exists — prefer the tools below.
  • Bootstrapping a portal via undocumented
    createInterface
    GraphQL — always use
    create_portal
    /
    pipefy portal create
    .

  • "创建我们公司的门户"、"列出组织X的门户"、"发布子门户"。
  • 添加或修改门户页面、布局或页面元素(
    forms
    link
    等)。
  • 在主门户上附加、发布、取消发布或删除子门户。
请勿用于:
  • 管道、阶段、卡片或自动化操作 — 请查看
    skills/pipes-and-cards/
    skills/automations/
  • 当已有门户工具时使用原生GraphQL — 优先使用下方的工具。
  • 通过未公开的
    createInterface
    GraphQL初始化门户 — 务必使用**
    create_portal
    ** /
    pipefy portal create

Prerequisites

前提条件

  • Organization id: UUID or numeric org id from
    pipefy org get
    / the Pipefy URL (examples below use fictional
    123456789
    per
    fixture_ids.py
    ). SDK resolves numeric ids before Interfaces calls. The org you pass to
    list_portals
    /
    create_portal
    must be the same org your token can write on.
  • Portal writes: token needs
    create_portal
    and/or
    manage_portals
    on that org. Many service accounts only have pipe/card scope on their default org →
    PERMISSION_DENIED
    on portal mutations even when reads succeed elsewhere.
  • One main portal per org
    create_portal
    is idempotent (second call returns the same portal UUID).
  • Cursor MCP: after changing
    PIPEFY_*
    in
    .env
    , restart the MCP server so tools pick up the new credentials.
  • 组织ID:UUID或从
    pipefy org get
    / Pipefy URL获取的数字组织ID(以下示例使用虚构的
    123456789
    ,来自
    fixture_ids.py
    )。SDK会在调用Interfaces前解析数字ID。传递给**
    list_portals
    ** / **
    create_portal
    **的组织必须与你的令牌具有写入权限的组织一致。
  • 门户写入权限:令牌需要在该组织拥有**
    create_portal
    和/或
    manage_portals
    **权限。许多服务帐户在默认组织仅拥有管道/卡片范围的权限 → 即使在其他地方读取成功,门户变更操作仍会返回
    PERMISSION_DENIED
  • 每个组织最多一个主门户
    create_portal
    是幂等的(第二次调用会返回相同的门户UUID)。
  • Cursor MCP:在
    .env
    中修改
    PIPEFY_*
    后,重启MCP服务器以使工具加载新的凭据。

Confirm access before writes

写入前确认权限

Reads on the wrong org can succeed while Interfaces writes fail. Before page/element/sub-portal mutations:
  1. Call
    list_portals
    with the intended
    organization_uuid
    .
  2. Ensure the token is meant for that org (service account email vs human user on a different org is a common mismatch).
  3. Prefer an org where the account has
    manage_portals
    and portal admin in Pipefy (not only
    canManagePortals
    on a read query from another org).
If
update_portal
or
delete_portal
returns
PERMISSION_DENIED
but the user insists the org role is correct: Pipefy may require
joinAsAdmin
on that portal interface for service accounts (Interfaces mutation, not shipped as MCP/CLI). The user must join as portal admin once in the UI (or via GraphQL) per portal UUID before SA writes succeed.

在错误的组织上读取可能成功,但Interfaces写入可能失败。在进行页面/元素/子门户变更前:
  1. 使用目标
    organization_uuid
    调用**
    list_portals
    **。
  2. 确保令牌适用于该组织(服务帐户邮箱与其他组织的人类用户不匹配是常见问题)。
  3. 优先选择帐户拥有**
    manage_portals
    **权限且在Pipefy中是门户管理员的组织(不仅仅是在其他组织的读取查询中拥有
    canManagePortals
    权限)。
如果**
update_portal
delete_portal
返回
PERMISSION_DENIED
但用户坚持组织角色正确:Pipefy可能要求服务帐户在该门户接口上执行
joinAsAdmin
**(Interfaces变更操作,未作为MCP/CLI工具提供)。用户必须在UI中(或通过GraphQL)以门户管理员身份加入一次该门户UUID,服务帐户才能成功写入。

How portals are organized

门户组织结构

ConceptWhat to expect
Main portalAt most one per org (
subType: portal
). Created with
create_portal
(
findOrCreateInterfaceByTemplate
).
list_portals
Usually one row — the main portal only (filter
portal
). Sub-portals do not appear here.
Sub-portalsSeparate entities (
create_sub_portal
). Listed under
get_portal
subPortals[]
.
UI on the main hubCreating sub-portals does not add tiles to the main page. You must publish (or attach) on a
forms
element via
publish_sub_portal
/
update_sub_portal_element
.
End-user visibilitySub-portals with
published: false
exist in the API but are invisible to portal visitors until published.
Public main hubMain portal
published
is always
true
on
get_portal
. Public access =
update_portal(visibility="public")
, not the
published
flag.
概念说明
主门户每个组织最多一个
subType: portal
)。通过**
create_portal
**(
findOrCreateInterfaceByTemplate
)创建。
list_portals
通常返回一行 — 仅主门户(过滤条件
portal
)。子门户不会在此处显示。
子门户独立实体(通过
create_sub_portal
创建)。在**
get_portal
subPortals[]
**下列出。
主枢纽UI创建子门户不会在主页面添加磁贴。你必须通过**
publish_sub_portal
** /
update_sub_portal_element
forms
元素上进行发布
(或附加)。
终端用户可见性
published: false
的子门户存在于API中,但在发布前对门户访客不可见
公开主枢纽
get_portal
中,主门户的**
published
**始终为
true
公开访问 =
update_portal(visibility="public")
,而非
published
标志。

Main portal lifecycle

主门户生命周期

  • Prefer
    update_portal
    on an existing main portal over delete +
    create_portal
    on orgs you reuse for testing.
  • delete_portal
    on the main removes one interface UUID; orphan sub-portals can remain unless deleted first.
  • After deleting the main,
    create_portal
    may fail with
    Menu already created
    (org menu state persists while
    mainPortal
    is null). Recovery: delete orphan sub-portals, use Pipefy admin/support, or bootstrap content on the surviving UUID — do not switch to raw
    createInterface
    , which leaves a skeleton main page (
    "Page"
    , 0 elements) and a broken builder; idempotent
    create_portal
    will keep returning that UUID.
  • 优先使用
    update_portal
    更新现有主门户,而非在重复用于测试的组织上执行删除 +
    create_portal
  • 删除主门户的**
    delete_portal
    **操作会移除一个接口UUID;孤立子门户可能会保留,除非先删除它们。
  • 删除主门户后,
    create_portal
    可能会因
    Menu already created
    失败(当
    mainPortal
    为null时,组织菜单状态仍会保留)。恢复方法:删除孤立子门户、联系Pipefy管理员/支持、或在剩余的UUID上初始化内容 — 请勿切换到原生
    createInterface
    ,这会留下一个骨架主页面("Page",0个元素)和损坏的构建器;幂等的**
    create_portal
    **会持续返回该UUID。

Empty main page

空主页面

If
get_portal
shows a main page with no elements, call
create_portal_page
with
title
only
(no
elements
in the request). The API typically returns a page with ~14 templated widgets (text, forms, links, etc.). Use that page for publish slots and element tests. Do not pass
type: subPortal
inside
create_portal_page
— validation fails at create time.

如果**
get_portal
显示主页面无元素**,仅传递**
title
(请求中不包含
elements
)调用
create_portal_page
。API通常会返回一个包含约14个模板化小部件**(文本、表单、链接等)的页面。使用该页面进行发布槽和元素测试。请勿在**
create_portal_page
**中传递
type: subPortal
— 创建时会验证失败。

Schema notes

架构说明

TopicRule
Response idsGraphQL field is
id
; MCP/CLI expose
uuid
(same value).
published
on list
list_portals
does not return
published
— call
get_portal
.
Sub-portal in layoutTiles may appear under
pages[].elements[]
with
type: subPortal
even when top-level
subPortals[]
is empty.
Publish wireUse
publish_sub_portal
/
update_sub_portal_element
on an existing
forms
element (
updateSubPortalElement
on internal_api).
create_portal_element
with
type: subPortal
is not a substitute for publish.
Element metadata
update_portal_element
is replace-all — send the full
metadata
JSON every time.
Metadata keys
forms
name
(not
formId
);
link
linkName
/
linkUrl
(not
url
/
label
).
Layout JSON
update_portal_page_layout
expects an array of row objects (
id
,
type: "row"
,
children: [elementUuid, ...]
). Copy from
get_portal
. A wrapper like
{ "rows": [...] }
fails API validation.
Page grid vs elements
create_portal_element
does not update the layout grid;
duplicate_portal_element
appends layout rows;
delete_portal_element
does not remove layout refs unless you update layout — orphan refs can break the portal viewer (HTTP 500).

主题规则
响应IDGraphQL字段为
id
;MCP/CLI暴露**
uuid
**(值相同)。
列表中的
published
字段
list_portals
不返回
published
— 调用**
get_portal
**获取。
布局中的子门户磁贴可能出现在**
pages[].elements[]
**下,类型为
subPortal
,即使顶级
subPortals[]
为空。
发布连接在现有**
forms
元素上使用
publish_sub_portal
** /
update_sub_portal_element
(internal_api上的
updateSubPortalElement
)。**
create_portal_element
指定
type: subPortal
**不能替代发布操作。
元素元数据
update_portal_element
全量替换
— 每次都要发送完整的
metadata
JSON。
元数据键
forms
name
(而非
formId
);
link
linkName
/
linkUrl
(而非
url
/
label
)。
布局JSON
update_portal_page_layout
期望一个行对象数组
id
type: "row"
children: [elementUuid, ...]
)。从**
get_portal
**复制。像
{ "rows": [...] }
这样的包装器会导致API验证失败。
页面网格与元素**
create_portal_element
不会更新布局网格;
duplicate_portal_element
会追加布局行;
delete_portal_element
**不会移除布局引用,除非你更新布局 — 孤立引用会破坏门户查看器(HTTP 500)。

Tools needed

所需工具

Tool (MCP)CLI equivalentRead-only
list_portals
pipefy portal list
Yes
get_portal
pipefy portal get
Yes
create_portal
pipefy portal create
No
update_portal
pipefy portal update
No
delete_portal
pipefy portal delete
No
create_portal_page
pipefy portal page create
No
update_portal_page
pipefy portal page update
No
delete_portal_page
pipefy portal page delete
No
sort_portal_pages
pipefy portal page sort
No
update_portal_page_layout
pipefy portal page layout update
No
create_portal_element
pipefy portal element create
No
update_portal_element
pipefy portal element update
No
delete_portal_element
pipefy portal element delete
No
duplicate_portal_element
pipefy portal element duplicate
No
create_sub_portal
pipefy portal sub-portal create
No
update_sub_portal_element
pipefy portal sub-portal attach
No
publish_sub_portal
pipefy portal sub-portal publish
No
unpublish_sub_portal
pipefy portal sub-portal unpublish
No
delete_sub_portal_element
pipefy portal sub-portal detach
No
delete_sub_portal
pipefy portal sub-portal delete
No
Element
type
values (15):
text
,
table
,
field
,
embedLink
,
embedVideo
,
embedImage
,
button
,
divider
,
link
,
forms
,
pages
,
subPortal
,
automationButton
,
contentBlock
,
document
.

工具(MCP)CLI等效命令只读
list_portals
pipefy portal list
get_portal
pipefy portal get
create_portal
pipefy portal create
update_portal
pipefy portal update
delete_portal
pipefy portal delete
create_portal_page
pipefy portal page create
update_portal_page
pipefy portal page update
delete_portal_page
pipefy portal page delete
sort_portal_pages
pipefy portal page sort
update_portal_page_layout
pipefy portal page layout update
create_portal_element
pipefy portal element create
update_portal_element
pipefy portal element update
delete_portal_element
pipefy portal element delete
duplicate_portal_element
pipefy portal element duplicate
create_sub_portal
pipefy portal sub-portal create
update_sub_portal_element
pipefy portal sub-portal attach
publish_sub_portal
pipefy portal sub-portal publish
unpublish_sub_portal
pipefy portal sub-portal unpublish
delete_sub_portal_element
pipefy portal sub-portal detach
delete_sub_portal
pipefy portal sub-portal delete
元素
type
值(15种):
text
table
field
embedLink
embedVideo
embedImage
button
divider
link
forms
pages
subPortal
automationButton
contentBlock
document

Steps — happy path (main portal + sub-portal publish)

步骤 — 常规流程(主门户 + 子门户发布)

  1. List or bootstrap the main portal
    MCP:
    list_portals organization_uuid="123456789"
    Expect at most one main portal row. If none:
    MCP:
    create_portal organization_uuid="123456789"
    CLI:
    bash
    pipefy portal list --organization-uuid 123456789
    pipefy portal create --organization-uuid 123456789
    Capture
    uuid
    where
    subType
    is the main portal.
  2. Inspect structure
    MCP:
    get_portal portal_uuid="<MAIN_PORTAL_UUID>"
    CLI:
    bash
    pipefy portal get <MAIN_PORTAL_UUID>
    Note
    pages[]
    ,
    elements[]
    , and
    forms
    element ids. If the main page has zero elements, run
    create_portal_page
    (title only) on that portal before adding widgets.
  3. Optional — add a
    forms
    element
    (if no templated
    forms
    slot exists)
    MCP:
    create_portal_element page_id="<PAGE_ID>" type="forms" metadata={"name": "Request access", "gridMap": {"height": 66, "columns": 4, "minColumns": 4}}
    If
    create_portal_element
    returns an opaque or
    INTERNAL_SERVER_ERROR
    from Interfaces,
    duplicate_portal_element
    from an existing link on the same
    portal_uuid
    and
    page_id
    instead of retrying create blindly.
    CLI:
    bash
    pipefy portal element create --page-id <PAGE_ID> --type forms \
      --metadata '{"name":"Request access","gridMap":{"height":66,"columns":4,"minColumns":4}}'
  4. Create a sub-portal
    MCP:
    create_sub_portal main_portal_uuid="<MAIN_PORTAL_UUID>" name="Partner hub"
    CLI:
    bash
    pipefy portal sub-portal create --main-portal-uuid <MAIN_PORTAL_UUID> --name "Partner hub"
    Capture the sub-portal
    uuid
    .
    get_portal
    will list it under
    subPortals[]
    with
    published: false
    — the main hub UI is unchanged until step 5.
  5. Publish on a
    forms
    element
    MCP:
    publish_sub_portal portal_uuid="<MAIN_PORTAL_UUID>" element_id="<FORMS_ELEMENT_ID>" sub_portal_uuid="<SUB_PORTAL_UUID>"
    CLI:
    bash
    pipefy portal sub-portal publish <MAIN_PORTAL_UUID> <FORMS_ELEMENT_ID> <SUB_PORTAL_UUID>
  6. Verify publish state
    MCP:
    get_portal portal_uuid="<MAIN_PORTAL_UUID>"
    Success: target
    subPortals[].published
    is
    true
    . End users can see the sub-portal only after this (and hub visibility rules).
  7. Optional — make the main hub public
    MCP:
    update_portal portal_uuid="<MAIN_PORTAL_UUID>" visibility="public"
    CLI:
    bash
    pipefy portal update <MAIN_PORTAL_UUID> --visibility public

  1. 列出或初始化主门户
    MCP命令:
    list_portals organization_uuid="123456789"
    预期返回最多一个主门户行。如果没有:
    MCP命令:
    create_portal organization_uuid="123456789"
    CLI命令:
    bash
    pipefy portal list --organization-uuid 123456789
    pipefy portal create --organization-uuid 123456789
    记录
    subType
    为主门户的
    uuid
  2. 检查结构
    MCP命令:
    get_portal portal_uuid="<MAIN_PORTAL_UUID>"
    CLI命令:
    bash
    pipefy portal get <MAIN_PORTAL_UUID>
    记录
    pages[]
    elements[]
    以及**
    forms
    元素ID。如果主页面无元素**,在添加小部件前对该门户运行**
    create_portal_page
    **(仅传递标题)。
  3. 可选 — 添加
    forms
    元素
    (如果没有模板化的
    forms
    槽)
    MCP命令:
    create_portal_element page_id="<PAGE_ID>" type="forms" metadata={"name": "Request access", "gridMap": {"height": 66, "columns": 4, "minColumns": 4}}
    如果**
    create_portal_element
    返回模糊错误或来自Interfaces的
    INTERNAL_SERVER_ERROR
    ,从
    同一**
    portal_uuid
    page_id
    上的现有链接执行**
    duplicate_portal_element
    **,而非盲目重试创建。
    CLI命令:
    bash
    pipefy portal element create --page-id <PAGE_ID> --type forms \
      --metadata '{"name":"Request access","gridMap":{"height":66,"columns":4,"minColumns":4}}'
  4. 创建子门户
    MCP命令:
    create_sub_portal main_portal_uuid="<MAIN_PORTAL_UUID>" name="Partner hub"
    CLI命令:
    bash
    pipefy portal sub-portal create --main-portal-uuid <MAIN_PORTAL_UUID> --name "Partner hub"
    记录子门户的
    uuid
    get_portal
    会在
    subPortals[]
    下列出它,且
    published: false
    — 直到步骤5,主枢纽UI才会变化。
  5. forms
    元素上发布
    MCP命令:
    publish_sub_portal portal_uuid="<MAIN_PORTAL_UUID>" element_id="<FORMS_ELEMENT_ID>" sub_portal_uuid="<SUB_PORTAL_UUID>"
    CLI命令:
    bash
    pipefy portal sub-portal publish <MAIN_PORTAL_UUID> <FORMS_ELEMENT_ID> <SUB_PORTAL_UUID>
  6. 验证发布状态
    MCP命令:
    get_portal portal_uuid="<MAIN_PORTAL_UUID>"
    成功标志:目标**
    subPortals[].published
    true
    **。终端用户只有在此之后(且符合枢纽可见性规则)才能看到子门户。
  7. 可选 — 将主枢纽设为公开
    MCP命令:
    update_portal portal_uuid="<MAIN_PORTAL_UUID>" visibility="public"
    CLI命令:
    bash
    pipefy portal update <MAIN_PORTAL_UUID> --visibility public

Steps — pages, layout, and safe edits

步骤 — 页面、布局与安全编辑

Use a disposable page for element/layout experiments on a shared org main portal:
  1. create_portal_page
    with a unique title (e.g.
    Agent smoke 2026-06-01
    ).
  2. Run
    create_portal_element
    ,
    update_portal_element
    ,
    duplicate_portal_element
    ,
    update_portal_page_layout
    on that page only.
  3. delete_portal_page
    with MCP preview then
    confirm=true
    , or CLI
    --yes
    .
duplicate_portal_element
:
element_id
,
portal_uuid
, and
page_id
must refer to the same page that already contains the source element (duplicate on the same page, not cross-page).
update_portal_page_layout
:
read
layout
from
get_portal
for that page and send the full array back with intentional edits. Never invent
{ "rows": [ ... ] }
stubs.
sort_portal_pages
:
pass a non-empty
page_ids
list with no duplicates. If the raw response exposes nested
success: false
, treat the operation as failed even when the MCP envelope looks ambiguous.
Link element metadata (create/update, full replace):
json
{
  "gridMap": { "height": 64, "columns": 4, "minColumns": 4 },
  "linkUrl": "https://example.com",
  "linkName": "Example link"
}

在共享组织主门户上使用一次性页面进行元素/布局实验:
  1. **
    create_portal_page
    **创建一个唯一标题的页面(例如
    Agent smoke 2026-06-01
    )。
  2. 仅在该页面上执行**
    create_portal_element
    update_portal_element
    duplicate_portal_element
    update_portal_page_layout
    **操作。
  3. 使用MCP预览后执行**
    delete_portal_page
    并设置
    confirm=true
    ,或使用CLI的
    --yes
    **参数。
duplicate_portal_element
element_id
portal_uuid
page_id
必须指向同一页面,且该页面已包含源元素(在同一页面复制,而非跨页面)。
update_portal_page_layout
:从**
get_portal
**获取该页面的
layout
,并在进行有意编辑后发送完整数组。切勿自行编写
{ "rows": [ ... ] }
存根。
sort_portal_pages
:传递非空且无重复的
page_ids
列表。如果原始响应显示嵌套的
success: false
,即使MCP包装看起来模糊,也要视为操作失败。
链接元素元数据(创建/更新,全量替换)
json
{
  "gridMap": { "height": 64, "columns": 4, "minColumns": 4 },
  "linkUrl": "https://example.com",
  "linkName": "Example link"
}

Steps — unpublish or remove sub-portal

步骤 — 取消发布或移除子门户

Unpublish (keeps sub-portal entity; visitors lose access):
MCP:
unpublish_sub_portal portal_uuid="<MAIN_PORTAL_UUID>" element_id="<FORMS_ELEMENT_ID>"
CLI:
bash
pipefy portal sub-portal unpublish <MAIN_PORTAL_UUID> <FORMS_ELEMENT_ID>
Detach element wiring (destructive — preview/confirm on MCP,
--yes
on CLI):
MCP:
delete_sub_portal_element portal_uuid="<MAIN_PORTAL_UUID>" element_id="<FORMS_ELEMENT_ID>" confirm=false
Then after approval:
confirm=true
.
CLI:
bash
pipefy portal sub-portal detach <MAIN_PORTAL_UUID> <FORMS_ELEMENT_ID> --yes
Delete sub-portal interface (irreversible):
MCP two-step
delete_sub_portal
/ CLI:
bash
pipefy portal sub-portal delete <SUB_PORTAL_UUID> --yes

取消发布(保留子门户实体;访客失去访问权限):
MCP命令:
unpublish_sub_portal portal_uuid="<MAIN_PORTAL_UUID>" element_id="<FORMS_ELEMENT_ID>"
CLI命令:
bash
pipefy portal sub-portal unpublish <MAIN_PORTAL_UUID> <FORMS_ELEMENT_ID>
断开元素连接(破坏性操作;在MCP上预览/确认,在CLI上使用
--yes
):
MCP命令:
delete_sub_portal_element portal_uuid="<MAIN_PORTAL_UUID>" element_id="<FORMS_ELEMENT_ID>" confirm=false
然后在确认后执行:
confirm=true
CLI命令:
bash
pipefy portal sub-portal detach <MAIN_PORTAL_UUID> <FORMS_ELEMENT_ID> --yes
删除子门户接口(不可逆):
MCP两步操作
delete_sub_portal
/ CLI命令:
bash
pipefy portal sub-portal delete <SUB_PORTAL_UUID> --yes

MCP response shape

MCP响应格式

  • Read tools return
    { success: true, data: { ... } }
    when
    PIPEFY_MCP_UNIFIED_ENVELOPE
    is enabled (default). Parse
    data
    for
    portals
    ,
    pages
    ,
    subPortals
    , etc.
  • GraphQL/transport failures →
    { success: false, error: { message: "..." } }
    — do not treat transport errors as success.
  • PERMISSION_DENIED
    on portal tools usually names
    create_portal
    or
    manage_portals
    . Re-check org id, token, and SA
    joinAsAdmin
    (see Confirm access).
  • Only
    PERMISSION_DENIED
    is rewritten to the portal permission hint; other GraphQL codes surface as generic errors with the API message.
  • Destructive deletes: default
    confirm=false
    returns a preview (
    requires_confirmation: true
    ); call again with
    confirm=true
    only after explicit human approval.
CLI
--json
prints the raw SDK payload (no
success
wrapper).

  • PIPEFY_MCP_UNIFIED_ENVELOPE
    启用(默认)时,只读工具返回
    { success: true, data: { ... } }
    。解析**
    data
    **获取
    portals
    pages
    subPortals
    等内容。
  • GraphQL/传输失败 →
    { success: false, error: { message: "..." } }
    — 不要将传输错误视为成功。
  • 门户工具上的**
    PERMISSION_DENIED
    通常会指定
    create_portal
    manage_portals
    权限。重新检查组织ID、令牌和服务帐户的
    joinAsAdmin
    **状态(查看写入前确认权限)。
  • 只有**
    PERMISSION_DENIED
    **会重写为门户权限提示;其他GraphQL代码会以包含API消息的通用错误形式显示。
  • 破坏性删除操作:默认**
    confirm=false
    会返回预览(
    requires_confirmation: true
    );仅在获得明确人工批准后再次调用并设置
    confirm=true
    **。
CLI的
--json
参数会打印原始SDK负载(无
success
包装)。

Success criteria

成功标准

  • list_portals
    returns the org main portal (typically one row);
    create_portal
    returns the same UUID on repeat.
  • get_portal
    shows expected
    pages
    /
    elements
    after writes.
  • After
    create_sub_portal
    , sub-portal exists in API but
    published: false
    until publish.
  • After publish:
    subPortals[].published
    is
    true
    and the main page shows the wired
    forms
    slot.
  • After unpublish:
    published
    is
    false
    without deleting the sub-portal entity (unless you called
    delete_sub_portal
    ).
  • After layout/element edits on a disposable page, main portal pages used in production still open in the builder (no HTTP 500).

  • list_portals
    返回组织的主门户(通常一行);重复调用
    create_portal
    返回相同的UUID。
  • 写入后,
    get_portal
    显示预期的
    pages
    /
    elements
  • create_sub_portal
    后,子门户存在于API中但
    published: false
    ,直到发布。
  • 发布后:**
    subPortals[].published
    true
    ,且主页面显示已连接的
    forms
    **槽。
  • 取消发布后:**
    published
    **为
    false
    ,且未删除子门户实体(除非调用了
    delete_sub_portal
    )。
  • 在一次性页面上进行布局/元素编辑后,生产环境中使用的主门户页面仍能在构建器中打开(无HTTP 500错误)。

Failure modes

故障模式

SymptomLikely causeRecovery
PERMISSION_DENIED
on writes
Wrong org, missing
manage_portals
, or SA not joined on interface
Same org as
list_portals
; user runs portal admin join; try human admin token
Reads OK, writes fail on
admin
org
Token is human on org A, numeric id is org BAlign
organization_uuid
with token membership
Menu already created
on
create_portal
Main deleted but org menu state remainsDelete orphan sub-portals; avoid raw
createInterface
; bootstrap with
create_portal_page
on existing UUID
Main page empty in builderPortal created outside
create_portal
template path
create_portal_page
(title only) for templated elements
published
missing on list
Expected
get_portal
Many subs in
get_portal
, empty main UI
Sub-portals not published to
forms
slots
publish_sub_portal
per sub +
forms
element_id
Publish no effectWrong element type or skipped internal_api wire
get_portal
forms
element →
publish_sub_portal
subPortals[]
empty but UI shows tile
Linked under
pages[].elements
Inspect
type: subPortal
in
elements[]
create_portal_element
opaque / 500
Interfaces instability on some orgs
duplicate_portal_element
from existing widget on same page
Portal viewer HTTP 500Orphan
layout
children or wrong layout shape
Copy/fix layout from
get_portal
; delete disposable smoke page
Nested
success: false
API rejected mutationRead
error.message
; do not assume top-level success
Validation on elementWrong metadata keys or partial updateFull metadata blob;
linkName
/
name
per type

症状可能原因恢复方法
写入时返回
PERMISSION_DENIED
错误的组织、缺少
manage_portals
权限、或服务帐户未加入接口
使用与
list_portals
相同的组织;用户以门户管理员身份加入;尝试使用人类管理员令牌
读取正常,但在
admin
组织写入失败
令牌属于组织A的人类用户,数字ID是组织B的
organization_uuid
与令牌所属组织对齐
create_portal
时返回
Menu already created
主门户已删除但组织菜单状态仍保留删除孤立子门户;避免使用原生
createInterface
;在现有UUID上使用
create_portal_page
初始化内容
构建器中主页面为空通过
create_portal
模板路径之外的方式创建了门户
使用
create_portal_page
(仅传递标题)获取模板化元素
列表中缺少
published
字段
预期行为调用
get_portal
获取
get_portal
中有许多子门户,但主UI为空
子门户未发布到
forms
为每个子门户 +
forms
element_id
执行
publish_sub_portal
发布操作无效果错误的元素类型或跳过了internal_api连接调用
get_portal
→ 找到
forms
元素 → 执行
publish_sub_portal
subPortals[]
为空但UI显示磁贴
pages[].elements
下链接
检查
elements[]
中的
type: subPortal
create_portal_element
返回模糊错误 / 500
部分组织的Interfaces不稳定从同一页面的现有小部件执行
duplicate_portal_element
门户查看器返回HTTP 500孤立的
layout
子项或错误的布局格式
get_portal
复制/修复布局;删除一次性测试页面
嵌套的
success: false
API拒绝了变更操作读取
error.message
;不要假设顶级成功
元素验证失败错误的元数据键或部分更新发送完整的元数据Blob;根据类型使用
linkName
/
name

See also

另请参阅

  • docs/mcp/tools/portal.md
    — endpoints, wire naming, maintainer introspection
  • skills/introspection/pipefy-introspection/SKILL.md
    — verify Interfaces / internal_api mutations before changing tools
  • docs/mcp/tools/portal.md
    — 端点、连接命名、维护者自省
  • skills/introspection/pipefy-introspection/SKILL.md
    — 在修改工具前验证Interfaces / internal_api变更操作