← Port Agent Skills (EU)CONTENT HISTORY

Update to Port Agent Skills (EU)

Snapshot Oct 28, 2026 · 13:15 UTC · version 1.0.8

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Port Agent Skills (EU) and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Build Port workflows: node-based automations made of triggers (self-service forms, context lake events), action nodes (webhook, upsert entity, GitHub/GitLab/Azure DevOps/Claude managed agents integration actions, Kafka, Cursor Agent, AI), condition and input nodes, JQ templating between nodes, and self-service trigger permissions, authored as workflow JSON against the Port API. Use when asked to create a Port workflow, add a trigger to a workflow, add an action node, wire up a self-service workflow, add branching with a condition node, add an approval step to a workflow, build an event-driven automation in Port, or write workflow JSON. Port workflows are Port's own nodes-and-edges automation graph, not a CI/CD pipeline file like GitHub Actions.",
  "included_files": [
    {
      "relative_path": "assets/approval-workflow.json",
      "size_in_bytes": 3084
    },
    {
      "relative_path": "assets/event-driven-ai-incident-response.json",
      "size_in_bytes": 3335
    },
    {
      "relative_path": "assets/self-service-deploy-workflow.json",
      "size_in_bytes": 3849
    },
    {
      "relative_path": "references/data-flow.md",
      "size_in_bytes": 5562
    },
    {
      "relative_path": "references/node-types.md",
      "size_in_bytes": 34952
    },
    {
      "relative_path": "references/permissions.md",
      "size_in_bytes": 6004
    }
  ],
  "name": "port-workflows",
  "skill_md_contents": "---\nname: port-workflows\ndescription: \"Build Port workflows: node-based automations made of triggers (self-service forms, context lake events), action nodes (webhook, upsert entity, GitHub/GitLab/Azure DevOps/Claude managed agents integration actions, Kafka, Cursor Agent, AI), condition and input nodes, JQ templating between nodes, and self-service trigger permissions, authored as workflow JSON against the Port API. Use when asked to create a Port workflow, add a trigger to a workflow, add an action node, wire up a self-service workflow, add branching with a condition node, add an approval step to a workflow, build an event-driven automation in Port, or write workflow JSON. Port workflows are Port's own nodes-and-edges automation graph, not a CI/CD pipeline file like GitHub Actions.\"\nlicense: MIT\ncompatibility: \"Claude Code, Cursor, Codex CLI, GitHub Copilot\"\nmetadata:\n  version: \"1.0.0\"\n  author: port-labs\n  repository: https://github.com/port-labs/port-skills\n  tags: port,workflows,automation,reference\n  summary: Build Port workflows with triggers, action nodes, and conditions\n---\n\n# Port workflows\n\nA workflow is Port's visual, node-based automation layer. Nodes (triggers,\nactions, conditions, inputs) connect into a graph; running the workflow walks\nthat graph, passing each node's output to the next as JQ-templated data.\n\n## Use this skill when\n\nUse this skill to author or edit workflow JSON: adding a self-service or\nevent trigger, adding an action node (webhook, upsert entity, an integration\naction, Kafka, Cursor Agent, or AI), branching with a condition node, gating\non human approval with an input node, or wiring the connections and JQ\ntemplates between them. This skill is reference-only: the JSON it produces is\nvalid without a live Port account, though applying it needs API credentials\n(see [Prerequisites](#prerequisites)).\n\nOut of scope: Port's older, single-step Actions & Automations model (not\ncovered by a skill in this repo yet; see the\n[comparison table](https://docs.port.io/workflows/overview#comparison-with-actions--automations)\nfor when to use which), blueprint schema design (`port-blueprints`), and\nCI/CD pipeline files such as `.github/workflows/*.yml`, GitHub Actions is a\nseparate product that a workflow can *trigger* (via `INTEGRATION_ACTION`)\nbut does not replace.\n\n## Prerequisites\n\n- Go over the `port-getting-started` skill first if this is your first time\n  working with Port.\n- To create or update workflows without MCP: a Port `CLIENT_ID` and\n  `CLIENT_SECRET` (**...** menu > **Credentials** in the Port app),\n  exchanged for a bearer token at `POST https://api.port.io/v1/auth/access_token`.\n- If Port's MCP server is connected, this skill can use its workflow tools\n  (`list_workflows`, `get_workflow`, `upsert_workflow`) to read or apply a\n  workflow directly instead of you copying JSON in by hand, but the raw API\n  calls in [Step 6](#step-6---create-or-update-via-the-port-api) always\n  work as a fallback. Search `search_port_knowledge_sources` for anything\n  this skill doesn't cover.\n- Workflows are in open beta: cross-check unfamiliar fields against\n  [docs.port.io/workflows](https://docs.port.io/workflows/overview) before\n  shipping.\n\n## Step 1 - Sketch the graph and pick trigger type(s)\n\nPrecondition: you know what should start the automation and what it should do.\nAction: decide `SELF_SERVE_TRIGGER` (a user submits a form on demand),\n`EVENT_TRIGGER` (an entity is created, updated, deleted, or a timer property\nexpires), or both, a workflow can define multiple trigger nodes feeding the\nsame downstream graph. Then list the actions in order: webhook calls, entity\nupserts, integration dispatches, AI steps, with any branching (condition) or\nhuman approval (input) points.\nFallback: if the trigger is unclear, default to a self-service trigger, it is\nthe safer, opt-in default and easiest to test.\n\n## Step 2 - Configure the trigger node(s)\n\nPrecondition: trigger type chosen.\nAction: for `SELF_SERVE_TRIGGER`, define `userInputs.properties` (and\n`required`); for `EVENT_TRIGGER`, define `event.type` and\n`blueprintIdentifier`, plus an optional JQ `condition` to filter which events\nfire the workflow. Full field reference, including `contexts` (bolt-menu and\ncreate-entity surfacing) and `variant`, is in\n[references/node-types.md](references/node-types.md#trigger-nodes).\nFallback: never add `title`, `icon`, or `description` to a trigger node,\nthose fields are ignored there and belong on action nodes instead.\n\n## Step 3 - Add action and flow nodes\n\nPrecondition: trigger is defined.\nAction: add one node per step. See\n[references/node-types.md](references/node-types.md) for the full field\nreference and JSON shape of every node type: `WEBHOOK`, `UPSERT_ENTITY`,\n`INTEGRATION_ACTION` (GitHub, Claude managed agents, and others), `KAFKA`,\n`CURSOR_AGENT`, `AI_AGENT`, `AI`, `CONDITION`, `INPUT`. Reference upstream\ndata with JQ templates, see\n[references/data-flow.md](references/data-flow.md).\nFallback: if a step just needs to call an HTTP API, prefer `WEBHOOK` over\nbuilding a custom integration, and prefer `UPSERT_ENTITY` over a raw\n`WEBHOOK` call to Port's entity API, it is simpler and less error-prone.\n\n## Step 4 - Wire connections\n\nPrecondition: nodes exist.\nAction: add a `connections` entry (`sourceIdentifier`, `targetIdentifier`)\nper edge. `CONDITION` and `INPUT` nodes need `sourceOutletIdentifier` (or\n`fallback: true`) on every outgoing connection, matching one of the node's\n`outlets`. Trigger nodes can only be sources, never targets. Each node (and\neach outlet) can have at most one outgoing connection, fan-out is not\nsupported, chain nodes sequentially instead.\nFallback: got a fan-out requirement (one node feeding two independent next\nsteps)? Split it into two workflows, or serialize the two branches behind a\nsingle downstream node instead of trying to fan out directly.\n\n## Step 5 - Set self-service permissions\n\nPrecondition: workflow has a `SELF_SERVE_TRIGGER` node.\nAction: set `permissions` on the trigger node's `config`. Omitted or `{}`\nmeans Admin only. See\n[references/permissions.md](references/permissions.md) for static\n(`roles`/`users`/`teams`) and dynamic `policy` rules (based on user, team, or\nform-input properties).\nFallback: event triggers have no `permissions` field, event-driven workflows\nrun under the organization's automation identity, not a specific user.\n\n## Step 6 - Create or update via the Port API\n\nPrecondition: you have a bearer token and a complete workflow JSON body\n(`identifier`, `nodes`, `connections`, at minimum).\n\nAction: use the endpoints below (`workflow_identifier` is the workflow's\n`identifier`).\n\n| Operation | Method | Path |\n|---|---|---|\n| Create | `POST` | `/v1/workflows` |\n| List | `GET` | `/v1/workflows` |\n| Get | `GET` | `/v1/workflows/{workflow_identifier}` |\n| Update (creates a new version) | `PUT` | `/v1/workflows/{workflow_identifier}` |\n| Delete | `DELETE` | `/v1/workflows/{workflow_identifier}` |\n| Trigger a run | `POST` | `/v1/workflows/{workflow_identifier}/runs` |\n\n```bash\ncurl -L -X POST 'https://api.port.io/v1/workflows' \\\n  -H \"Authorization: Bearer ${ACCESS_TOKEN}\" \\\n  -H 'Content-Type: application/json' \\\n  --data @workflow.json\n ```\n\nFallback: a `409` on create means the `identifier` is taken, `PUT` an update\ninstead. A `422` usually means a `connections` entry references a node\nidentifier that doesn't exist, or a `CONDITION`/`INPUT` connection is missing\n`sourceOutletIdentifier`, check [Common pitfalls](#common-pitfalls) below.\n\n## Complete examples\n\n[assets/self-service-deploy-workflow.json](assets/self-service-deploy-workflow.json) -\nself-service trigger, environment branching with a `CONDITION` node, and a\nSlack notification.\n\n[assets/event-driven-ai-incident-response.json](assets/event-driven-ai-incident-response.json) -\nevent trigger with a JQ filter, an `AI` node with `outputSchema` for\nstructured output, and an entity upsert.\n\n[assets/approval-workflow.json](assets/approval-workflow.json) - self-service\ntrigger gated by an `INPUT` approval step before a production deploy.\n\n## Common pitfalls\n\n| Symptom | Cause | Fix |\n|---|---|---|\n| `.outputs.my-node.field` silently returns nothing | Hyphens in a node identifier break JQ dot notation (`-` reads as subtraction) | Use bracket notation `.outputs[\"my-node\"].field`, or keep node identifiers snake_case so dot notation works |\n| Adding `variables` makes existing output references break | `variables` **replaces** a node's entire default output, `response` and friends disappear | Re-declare anything downstream still needs inside `variables`, e.g. `\"response\": \"{{ .result.response }}\"` |\n| `CONDITION`/`INPUT` connection has no effect, or workflow rejects it | Missing `sourceOutletIdentifier` (or `fallback: true`) on the connection | Every outgoing connection from a `CONDITION` or `INPUT` node must set `sourceOutletIdentifier` matching one of the node's `outlets`, or `fallback: true` |\n| `UPSERT_ENTITY` (or another structured node) after an `AI` node gets nothing | The AI node emitted free-form text, not JSON | Set `outputSchema` (JSON Schema, `type: \"object\"`) on the AI node, then parse with `{{ .outputs.node_id.response \\| fromjson \\| .field }}` |\n| Event trigger fires but `.outputs.trigger.diff.before` is unexpectedly `null` | `ENTITY_CREATED` has no `before`, `ENTITY_DELETED` has no `after` | Branch on `.outputs.trigger.action` (`CREATE`/`UPDATE`/`DELETE`) before reading `diff.before`/`diff.after` |\n| Workflow silently does nothing when a node fails mid-graph | Default `onFailure` is `\"terminate\"`, the whole run stops | Set `\"onFailure\": \"continue\"` on `WEBHOOK`, `UPSERT_ENTITY`, `KAFKA`, or `INTEGRATION_ACTION` nodes that shouldn't block the rest of the run |\n| GitHub Actions workflow never fires | Used `WEBHOOK` to call the GitHub API by hand, or used the wrong field name for status reporting | Use `INTEGRATION_ACTION` with `integrationProvider: \"github-ocean\"`, and `reportWorkflowStatus` (not `reportStatus`) to get status back in Port |\n\n## Quick reference\n\n- Node types: `SELF_SERVE_TRIGGER`, `EVENT_TRIGGER` (triggers); `WEBHOOK`,\n  `UPSERT_ENTITY`, `INTEGRATION_ACTION`, `KAFKA`, `CURSOR_AGENT`, `AI_AGENT`,\n  `AI` (actions); `CONDITION`, `INPUT` (flow control). Full reference:\n  [references/node-types.md](references/node-types.md).\n- Data access: `{{ .outputs[\"node_id\"].field }}` (previous node output),\n  `{{ .outputs.trigger.field }}` (always aliases the trigger that fired),\n  `{{ .secrets[\"name\"] }}`, `{{ .workflowRun.trigger.by.email }}`. Full\n  reference: [references/data-flow.md](references/data-flow.md).\n- Permissions: `{}`/omitted = Admin only; `roles`/`users`/`teams` = static OR\n  match; `policy` = dynamic rules over `user`, `userTeams`, or `form`\n  context. Full reference: [references/permissions.md](references/permissions.md).\n- Auth: `POST /v1/auth/access_token` with `clientId`/`clientSecret` for a\n  bearer token; no `Authorization` header needed when a workflow node itself\n  calls `https://api.port.io`.\n- Workflow top-level fields: `identifier` (required, ≤60 chars,\n  `^[A-Za-z0-9@_:-]+$`), `title`, `icon`, `description`, `category` (groups\n  it in the UI), `allowAnyoneToViewRuns` (default `true`), `nodes`,\n  `connections`.\n"
}

SHA-256 of public snapshot: d380a6920ae4ae241fcbdd0bfb5b20618baa73d581664ce49613c0414fe3656f