Expose workflows as tools
Every self-service workflow in Port is automatically available as an invokable tool through the Port MCP server. AI agents - whether Port's built-in agents, custom agents you've built, or external agents connecting via MCP - can discover your workflows, read their descriptions, and trigger them with the appropriate inputs.
This is the bridge between workflows and agents in the AEP model: agents provide the intent, Port supplies the context, and the workflow enforces the logic, validations, and approvals. Workflows become the governed execution layer for autonomous action.
How it works
The Port MCP server exposes two tools that make workflows available to any connected agent:
| Tool | What it does |
|---|---|
list_workflows | Returns all self-service workflows with their trigger configuration, title, description, and input schema. |
trigger_run | Executes a workflow by identifier, accepting inputs that match the workflow's trigger schema. |
When an agent receives a task, it calls list_workflows to discover what operations are available. It reads the workflow's title and description to determine which workflow matches the task, then calls trigger_run with the appropriate inputs. The workflow runs exactly as it would if a human had submitted the form.
Both self-service actions (legacy) and self-service workflows are discoverable by agents. Actions are exposed through the run_action tool; workflows through trigger_run. For new work, prefer workflows - they offer multi-step logic, conditional branching, and richer tool support.
What the agent sees
The agent reads three pieces of information from your workflow definition:
| Field | Where it lives | What the agent uses it for |
|---|---|---|
| Title | title on the workflow | The display name of the tool. |
| Description | description on the workflow | Determines when to invoke this tool - the agent picks the right workflow by matching its task against descriptions. |
| Input schema | userInputs.properties on the trigger node | Each input's title and description guide the agent on what value to provide. |
Configure the tool definition
Workflow title and description
The workflow title and description are defined at the top level of the workflow object:
{
"identifier": "deploy-service",
"title": "Deploy service",
"description": "Deploy a service to a target environment. Use this tool when a user asks to deploy, release, or promote a service to staging or production. Requires a service identifier and target environment.",
"icon": "Deploy",
"nodes": [ ... ],
"connections": [ ... ]
}
Write the description as instructions to the agent:
- State what the workflow does in one sentence.
- State when to use it - include synonyms and related intents the agent might encounter.
- List required context so the agent knows what inputs to gather before invoking.
Input descriptions
Each user input in the trigger node should have a description that tells the agent what value is expected:
{
"identifier": "trigger",
"title": "Deploy service trigger",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"service": {
"type": "string",
"format": "entity",
"blueprint": "service",
"title": "Service",
"description": "The service to deploy. Use the service's identifier from the catalog."
},
"environment": {
"type": "string",
"title": "Environment",
"description": "Target deployment environment. Accepted values: staging, production.",
"enum": ["staging", "production"]
},
"version": {
"type": "string",
"title": "Version",
"description": "The image tag or semantic version to deploy. Leave empty to deploy the latest artifact."
}
},
"required": ["service", "environment"]
}
}
}
Imagine the agent has no context beyond what you write. Describe the expected format, valid values, and where to find the value. For entity inputs, tell the agent how to resolve the identifier (for example, "use the service's identifier from the catalog").
Permissions
Workflow permissions apply equally to human users and agents. The same permissions configuration on the trigger node controls both.
For the full permissions reference, see dynamic permissions & approvals.
Agents and machine tokens
Agents that connect to the Port MCP server using a machine token (client credentials) bypass static role, user, and team checks by default - the token itself carries the authorization. To restrict agent access:
- Allow only named agents: add the agent's user identifier to the
usersarray. - Restrict by policy: add a
policyrule that limits invocation to specific conditions. Machine tokens do not bypasspolicychecks.
{
"permissions": {
"users": ["agent-user-id"],
"policy": {
"combinator": "and",
"rules": [
{
"property": { "context": "user", "property": "type" },
"operator": "=",
"value": "machine"
}
]
}
}
}
Admins can always invoke all workflows regardless of the permissions configuration. Use the policy field for enforceable restrictions.
End-to-end example
This example shows a "Deploy service" workflow configured as a well-described tool, an agent that discovers it, and the invocation that follows.
The workflow
{
"identifier": "deploy-service",
"title": "Deploy service",
"description": "Deploy a service to a target environment. Use this tool when a user asks to deploy, release, promote, or roll out a service. Accepts a service identifier, a target environment (staging or production), and an optional version tag.",
"icon": "Deploy",
"nodes": [
{
"identifier": "trigger",
"title": "Deploy service trigger",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"service": {
"type": "string",
"format": "entity",
"blueprint": "service",
"title": "Service",
"description": "The service to deploy. Use the service's catalog identifier (for example, 'payment-service')."
},
"environment": {
"type": "string",
"title": "Environment",
"description": "Target deployment environment. Use 'staging' for pre-production validation and 'production' for live traffic.",
"enum": ["staging", "production"]
},
"version": {
"type": "string",
"title": "Version",
"description": "Semantic version or image tag to deploy (for example, 'v2.4.1'). Omit to use the latest artifact."
}
},
"required": ["service", "environment"]
},
"permissions": {
"roles": ["Member"]
}
}
},
{
"identifier": "send-webhook",
"title": "Trigger deployment pipeline",
"config": {
"type": "WEBHOOK",
"url": "https://ci.example.com/api/deploy",
"method": "POST",
"body": {
"service": "{{ .outputs.trigger.service }}",
"environment": "{{ .outputs.trigger.environment }}",
"version": "{{ .outputs.trigger.version }}"
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "send-webhook"
}
]
}
The agent interaction
A developer asks their Port AI agent: "Deploy payment-service to staging."
The agent's reasoning:
-
Discovery - calls
list_workflowsand receives the workflow list. It reads thedeploy-servicedescription: "Use this tool when a user asks to deploy, release, promote, or roll out a service." The task matches. -
Input resolution - the agent checks the input schema:
service- description says "use the service's catalog identifier". The agent querieslist_entitieson theserviceblueprint and findspayment-service.environment- the user said "staging". Enum values confirmstagingis valid.version- not specified, and the description says "omit to use the latest artifact". Agent leaves it empty.
-
Invocation - calls
trigger_run:
{
"workflowIdentifier": "deploy-service",
"inputs": {
"service": "payment-service",
"environment": "staging"
}
}
- Result - the workflow triggers the CI pipeline. The agent reports back with the run link.
The developer never left the chat. No custom agent code was required. The same deployment logic that platform engineers configured and governed is what the agent executed.
Best practices
| Practice | Why it matters |
|---|---|
| Write descriptions for the agent, not for humans | Humans can read documentation; agents only have what you write in the description field. Include intent keywords, synonyms, and expected input formats. |
| Include trigger conditions in the description | Help the agent decide when to call the workflow vs. a different one. For example: "Use this tool only for production deployments. For staging use deploy-to-staging." |
| Describe enums and formats in input descriptions | Even if an input has an enum, describe valid values in description. The agent uses both. |
Set explicit required fields | Inputs not listed in required are treated as optional. If the agent can proceed without a value, make it optional - the agent won't ask the user unnecessarily. |
| Use a consistent naming convention for identifiers | Predictable identifiers (for example, deploy-<service>, scale-<resource>) make it easier to define permissions policies that scope agent access to specific workflows. |