pipefy-portal-setup について
pipefy-portal-setupは、組織のPipefyポータルを設定するスキルです。ページ、ウィジェット、レイアウト、サブポータルを扱い、メインポータルの構築からサブポータルの紐付け・公開までを案内します。
主な機能
- 01組織ポータルの一覧表示と作成
- 02ページと要素の作成・編集
- 03ページレイアウトと配置の調整
- 04サブポータルの作成・紐付け・公開
- 05アクセス権と公開状態の確認
活用シーン
- 01組織のメインポータルの初期設定
- 02ページ、フォーム、リンク、ウィジェットの追加
- 03メインハブでのサブポータル公開
- 04ポータルページ要素の並べ替え
MCP 対応
MCPクライアント向けの参照先を示し、ポータル構造、ページ、要素、サブポータルを読み取り・変更するMCPツールを説明します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pipefy/ ai-toolkit --skill pipefy-portal-setupインストール後、Claude Code で/pipefy-portal-setupを入力して読み込まれたか確認します。
同梱ファイルreferences/cli.mdreferences/mcp.md
詳細
ポータルのセットアップ
MCP クライアントは references/mcp.md をお読みください。CLI のユーザーは references/cli.md をお読みください。以下の例では、共通の操作引数について説明します。
組織の Pipefy ポータルを設定します。メインハブを初期設定し、ページとウィジェットを追加し、サブポータルを接続して公開します(サブポータルの接続には Interfaces GraphQL と internal_api を使用します)。
詳細なリファレンス: docs/mcp/tools/portal.md。対応状況の一覧: docs/parity.md。環境変数: docs/config.md。
使用する場面
- 「会社のポータルを作成する」「組織 X のポータルを一覧表示する」「サブポータルを公開する」。
- ポータルのページ、レイアウト、ページ要素(
forms、linkなど)を追加または変更する。 - メインポータルでサブポータルを接続、公開、非公開化、または削除する。
次の用途には使用しないでください。
- パイプ、フェーズ、カード、自動化 —
pipefy-pipes-and-cards、pipefy-automationsを参照してください。 - HTML インターフェース(単一の HTML ドキュメントとして記述され、
customCode要素に格納されたスタンドアロンページ)—pipefy-html-interfacesを参照してください。以下の要素ツールはcustomCode要素を受け付けますが、その要素には使用しないでください。 - ポータルツールがある場合の生の GraphQL — 以下のツールを優先してください。
- ドキュメントに記載されていない
createInterfaceGraphQL によるポータルの初期設定 — 必ずcreate_portalを使用してください。
前提条件
- 組織 ID: 組織の検索結果または Pipefy URL から取得した UUID または数値の組織 ID(以下の例では
fixture_ids.pyにある架空の123456789を使用しています)。SDK は Interfaces の呼び出し前に数値 ID を解決します。list_portals/create_portalに渡す組織は、トークンが書き込み権限を持つ組織と同じでなければなりません。 - ポータルへの書き込み: トークンには、その組織で
create_portalおよび/またはmanage_portalsの権限が必要です。多くのサービスアカウントは、デフォルトの組織でパイプ/カードの権限しか持たないため、他の組織で読み取りに成功しても、ポータルの変更操作ではPERMISSION_DENIEDになることがあります。 - 組織ごとにメインポータルは 1 つ —
create_portalは冪等です(2 回目の呼び出しでは同じポータル UUID が返されます)。
書き込み前にアクセスを確認する
誤った組織への読み取りは成功しても、Interfaces の書き込みは失敗する場合があります。ページ、要素、サブポータルを変更する前に、次の手順を行ってください。
- 意図する
organization_uuidを指定してlist_portalsを呼び出します。 - トークンがその組織向けであることを確認します(別の組織に属するサービスアカウントのメールアドレスと人間ユーザーとの取り違えはよくあります)。
- Pipefy でそのアカウントが
manage_portalsとポータル管理者の権限を持つ組織を優先します(別の組織への読み取りクエリでcanManagePortalsが確認できるだけでは不十分です)。
update_portal または delete_portal が PERMISSION_DENIED を返し、ユーザーが組織のロールは正しいと主張する場合:サービスアカウントに対して、Pipefy がそのポータルインターフェースで joinAsAdmin を必要としている可能性があります(Interfaces の変更操作であり、MCP/CLI では提供されていません)。SA による書き込みを成功させるには、ユーザーがポータル UUID ごとに一度、UI または GraphQL からポータル管理者として参加する必要があります。
ポータルの構成
| 概念 | 内容 |
|---|---|
| メインポータル | 組織ごとに最大 1 つです(subType: portal)。create_portal(findOrCreateInterfaceByTemplate)で作成します。 |
list_portals | 通常は 1 行のみで、メインポータルだけが表示されます(フィルター 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 フラグではありません。 |
メインポータルのライフサイクル
- テストに再利用する組織では、既存のメインポータルに対して
update_portalを使用し、削除してからcreate_portalする方法は避けてください。 - メインポータルに対する
delete_portalはインターフェースの UUID を 1 つ削除しますが、先に削除しないと孤立したサブポータルが残ることがあります。 - メインポータルを削除した後、
create_portalがMenu already createdで失敗することがあります(mainPortalが null でも、組織のメニュー状態は保持されます)。復旧するには、孤立したサブポータルを削除する、Pipefy の管理者/サポートに問い合わせる、または残存する UUID 上にコンテンツを構築してください。生のcreateInterfaceには切り替えないでください。スケルトン状態のメインページ("Page"、0 個の要素)が作成され、ビルダーも壊れます。また、冪等なcreate_portalはその UUID を返し続けます。
空のメインページ
get_portal で要素のないメインページが表示される場合は、title のみを指定して create_portal_page を呼び出してください(リクエストに elements は含めません)。通常、API はテンプレート化されたウィジェット(テキスト、フォーム、リンクなど)が 約 14 個含まれるページを返します。そのページを公開スロットと要素のテストに使用してください。create_portal_page 内で type: subPortal を指定しないでください。作成時に検証エラーになります。
スキーマに関する注意事項
| トピック | ルール |
|---|---|
リスト上のpublished | list_portalsはpublishedを返しません — **get_portal**を呼び出してください。 |
| レイアウト内のサブポータル | トップレベルのsubPortals[]が空でも、type: subPortalを持つタイルが**pages[].elements[]**の下に表示されることがあります。 |
| 公開の仕組み | 既存の**forms要素に対してpublish_sub_portal/update_sub_portal_element(internal_apiではupdateSubPortalElement)を使用してください。type: subPortalを指定したcreate_portal_element**は、公開の代わりにはなりません。 |
| 要素のメタデータ | **update_portal_element**は全置換です。毎回、metadata JSON全体を送信してください。 |
| 要素のデータソース | すべての**update_portal_element**では、要素の種類にかかわらず、data_sourcesまたはportal_uuidのいずれかを渡してください。両方を省略すると拒否されます。data_sourcesは全置換です。[]を指定すると、要素とそのパイプまたはテーブルとのリンクが解除されます。バインディングのない要素(link、text)には、これを1回の呼び出しで指定できます。バインディングを維持するには、data_sourcesを省略し、portal_uuid(get_portalに渡したuuid。これによりpages[]にpage_idが含まれます)を渡してください。要素のdataSourcesとeditableフラグが返送されます。 |
| メタデータのキー | forms → name(formIdではありません)。link → linkName/linkUrl(url/labelではありません)。 |
| レイアウトJSON | update_portal_page_layoutには、行オブジェクトの配列が必要です。各行には空でないid、type: "row"、空でない文字列を含むchildrenが必要です。**get_portalから対象のpages[].layout**をコピーしてください。metadata.gridMapが示すのは要素の寸法であり、配置ではありません。APIはこの値に任意のJSONをそのまま保存するため、ラッパーや不完全な行を渡すとグリッドが置き換えられます。ツールキットは配列以外の値や不完全な行をローカルで拒否しますが、空のページを表す[]は引き続き受け付けます。生のGraphQLでこの検証を回避してはいけません。 |
| ページのグリッドと要素 | **create_portal_elementは、element_idとlayout(既存の行に新しいIDを含む行を加えたもの)を渡さない限り、レイアウトグリッドを変更しません。duplicate_portal_elementはレイアウト行を追加します。delete_portal_element**は、layout(要素を取り除いた既存の行)を渡さない限り、レイアウト内の参照を残します。孤立した参照があると、ポータルビューアーで問題が発生することがあります(HTTP 500)。 |
必要なツール
| 操作 | 読み取り専用 |
|---|---|
list_portals | はい |
get_portal | はい |
create_portal | いいえ |
update_portal | いいえ |
delete_portal | いいえ |
create_portal_page | いいえ |
update_portal_page | いいえ |
delete_portal_page | いいえ |
sort_portal_pages | いいえ |
update_portal_page_layout | いいえ |
create_portal_element | いいえ |
update_portal_element | いいえ |
delete_portal_element | いいえ |
duplicate_portal_element | いいえ |
create_sub_portal | いいえ |
update_sub_portal_element | いいえ |
publish_sub_portal | いいえ |
unpublish_sub_portal | いいえ |
delete_sub_portal_element | いいえ |
delete_sub_portal | いいえ |
要素のtypeの値(15種類):text、table、field、embedLink、embedVideo、embedImage、button、divider、link、forms、pages、subPortal、automationButton、contentBlock、document。
手順 — 正常系(メインポータルとサブポータルの公開)
-
メインポータルを一覧表示するか、初期設定する
操作の引数:
list_portals(organization_uuid="123456789")メインポータルの行は最大 1 つであることを確認します。存在しない場合:
操作の引数:
create_portal(organization_uuid="123456789")メインポータルの
subTypeを持つuuidを記録します。 -
構造を確認する
操作の引数:
get_portal(portal_uuid="<MAIN_PORTAL_UUID>")pages[]、elements[]、およびforms要素の ID を確認します。メインページに要素が1 つもない場合は、ウィジェットを追加する前に、そのポータルでcreate_portal_page(タイトルのみ)を実行します。 -
任意 —
forms要素を追加する(テンプレートのformsスロットがない場合)操作の引数:
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を実行します。 -
サブポータルを作成する
操作の引数:
create_sub_portal(main_portal_uuid="<MAIN_PORTAL_UUID>", name="Partner hub")サブポータルの
uuidを記録します。get_portalでは、published: falseの状態でsubPortals[]に表示されます。手順 5 までは、メインハブの UI は変わりません。 -
forms要素で公開する操作の引数:
publish_sub_portal(portal_uuid="<MAIN_PORTAL_UUID>", element_id="<FORMS_ELEMENT_ID>", sub_portal_uuid="<SUB_PORTAL_UUID>") -
公開状態を確認する
操作の引数:
get_portal(portal_uuid="<MAIN_PORTAL_UUID>")成功の条件:対象の
subPortals[].publishedがtrueであること。この操作の完了後(およびハブの表示ルールが適用された後)にのみ、エンドユーザーにサブポータルが表示されます。 -
任意 — メインハブを公開する
update_portalを通じて、visibility="public"を指定し、<MAIN_PORTAL_UUID>を更新します(SDK の引数:interface_uuid、MCP の引数:portal_uuid)。
手順 — ページ、レイアウト、安全な編集
共有組織のメインポータルで要素やレイアウトを試す場合は、使い捨てページを使用します。
create_portal_pageで一意のタイトル(例:Agent smoke 2026-06-01)を指定します。- そのページだけで
create_portal_element、update_portal_element、duplicate_portal_element、update_portal_page_layoutを実行します。 - 使い捨てページの削除を確認して承認した後、
delete_portal_pageを使用します。
duplicate_portal_element: element_id、portal_uuid、page_id は、ソース要素がすでに存在する同じページを参照する必要があります(ページをまたがず、同じページ内で複製します)。
update_portal_page_layout: get_portal から対象の pages[].layout を読み取り、行 ID、子要素 UUID、および変更対象外の行を維持します。意図した並べ替えやグループ化の変更だけを加えた完全な配列を送信し、その後、再度読み取って比較します。elements[].metadata.gridMap(height、columns、minColumns)は寸法を示すもので、行の順序やグループ化を復元することはできません。要素のサイズ変更時はメタデータ全体を維持します。レイアウトを取得できない場合は、推測で位置を編集せず、中止してください。配列を { "rows": [ ... ] } で囲まないでください。
MCP:
get_portal portal_uuid="<portal_uuid>"
update_portal_page_layout page_id="<page_uuid>" layout=[<complete edited rows from that page>]
get_portal portal_uuid="<portal_uuid>"
CLI:
pipefy portal get <portal_uuid> --json
pipefy portal page layout update --page-id <page_uuid> --layout '[<complete edited rows from that page>]' --json
pipefy portal get <portal_uuid> --json
配置を指定する create_portal_element: pages[].layout を読み取り、element_id の UUID を生成し、{ "id": "<new row uuid>", "type": "row", "children": ["<element_id>"] } という行を追加または挿入して、element_id と完全な layout の両方を渡します。layout を指定しない場合、要素は作成されますが、グリッドには配置されません。再度読み取って比較します。
MCP:
create_portal_element page_id="<page_uuid>" type="link" metadata={...} element_id="<element_id>" layout=[<existing rows>, {"id": "<row uuid>", "type": "row", "children": ["<element_id>"]}]
CLI:
pipefy portal element create --page-id <page_uuid> --type link --metadata '{...}' --element-id <element_id> --layout '[<existing rows>, {"id": "<row uuid>", "type": "row", "children": ["<element_id>"]}]' --json
整理を伴う delete_portal_element: pages[].layout を読み取り、すべての行の children から element_id を削除して、完全な配列を layout として渡します。グリッドと要素は 1 回の呼び出しで変更されるため、削除済み要素を参照する行は残りません。element_id が残っているレイアウトは拒否されます。再度読み取って比較します。MCP と CLI のリファレンスには、layout を指定した削除呼び出しが記載されています。
sort_portal_pages: 重複のない空ではない page_ids リストを渡します。レスポンスにネストされた success: false が含まれている場合は、操作は失敗したものとして扱います。
リンク要素のメタデータ(作成/更新、全置換):
{
"gridMap": { "height": 64, "columns": 4, "minColumns": 4 },
"linkUrl": "https://example.com",
"linkName": "Example link"
}
link にはバインディングがないため、更新時にも data_sources: [] を渡します(CLI では --data-sources '[]')。
手順 — サブポータルの非公開化または削除
非公開化(サブポータルのエンティティは保持されます。訪問者はアクセスできなくなります):
操作の引数:
unpublish_sub_portal(portal_uuid="<MAIN_PORTAL_UUID>", element_id="<FORMS_ELEMENT_ID>")
影響を確認し、承認を得た後、delete_sub_portal_element で要素の接続を解除します。
delete_sub_portal でサブポータルのインターフェースを削除します(元に戻せません)。削除する前に確認し、承認を得てください。
成功基準
list_portalsが組織のメインポータル(通常は1行)を返し、create_portalは繰り返し実行しても同じ UUID を返します。get_portalに、書き込み後の想定どおりのpages/elementsが表示されます。create_sub_portalの後、サブポータルは API に存在しますが、公開するまではpublished: falseです。- 公開後:
subPortals[].publishedがtrueになり、メインページに接続されたformsスロットが表示されます。 - 非公開化後:サブポータルのエンティティを削除せずに(
delete_sub_portalを呼び出した場合を除く)、publishedがfalseになります。 - 使い捨てページでレイアウトや要素を編集した後も、本番環境で使用されているメインポータルのページがビルダーで開きます(HTTP 500 が発生しません)。
障害モード
| 症状 | 原因として考えられること | 復旧方法 |
|---|---|---|
書き込み時に PERMISSION_DENIED が発生する | 組織が間違っている、manage_portals がない、または SA がインターフェースに参加していない | 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 スロットに公開されていません | 各サブポータルに publish_sub_portal を実行し、forms の element_id を指定します |
| 公開しても変化がない | 要素の種類が違うか、内部 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 を確認します。トップレベルの成功を前提にしないでください |
| 要素の検証エラー | メタデータのキーが間違っているか、部分更新です | メタデータ全体を指定します。種類に応じて linkName / name を使います |
関連項目
docs/mcp/tools/portal.md— エンドポイント、接続の命名、メンテナー向けのイントロスペクションpipefy-introspection— ツールを変更する前に Interfaces / internal_api の変更を検証します