AI
The AI action node invokes Port AI directly from your workflow. It supports two modes of operation: invoking an AI agent by identifier, or invoking Port AI with custom configuration.
The workflow pauses execution after sending the AI request and automatically resumes once the AI invocation completes (or fails).
Modes
- Invoke AI Agent
- Invoke AI
Use the AI_AGENT type to invoke a pre-configured AI agent by its identifier. The agent's tools, system prompt, and domain configuration are defined on the agent itself. You only need to provide the prompt.
Configuration
| Field | Type | Description |
|---|---|---|
type | "AI_AGENT" | Required. Must be "AI_AGENT" |
agentIdentifier | string | Required. The identifier of the AI agent to invoke |
userPrompt | string | Required. The prompt or query to send to the agent |
outputSchema | object | JSON Schema that defines the expected structure of the AI response. When provided, the AI will generate a structured JSON object matching the schema instead of free-form text |
Example
Invoke an incident response agent to analyze a service's health:
{
"identifier": "analyze-health",
"title": "Analyze Service Health",
"config": {
"type": "AI_AGENT",
"agentIdentifier": "incident-response-agent",
"userPrompt": "Analyze the health of service {{ .outputs.trigger.service }} and provide a summary of any issues"
}
}
Use the AI type for general-purpose AI invocations where you configure the tools, system prompt, and other parameters directly in the node.
Configuration
| Field | Type | Description |
|---|---|---|
type | "AI" | Required. Must be "AI" |
userPrompt | string | Required. The prompt or query to send to Port AI |
systemPrompt | string | Instructions that guide the AI's behavior, role, and operational rules |
tools | string[] | Optional. List of tool names to allow (for example list_entities). Use regex patterns to match multiple tools (for example sentry_.* for an MCP connector). Defaults to [], which allows all Port native tools and all tools from mcpServers. Prefer an explicit list in workflows. See available tools |
mcpServers | object[] | Optional. Up to five MCP connectors. Each item requires identifier (the _mcp_server entity identifier). See external MCP connectors in workflows. |
provider | string | The AI provider to use. If not specified, the default provider is used |
model | string | The AI model to use. Must be specified together with provider |
outputSchema | object | JSON Schema that defines the expected structure of the AI response. When provided, the AI will generate a structured JSON object matching the schema instead of free-form text |
The provider and model fields must both be specified together, or both omitted. When omitted, the organization's default AI provider and model are used. For more information, see LLM providers management.
Example
Invoke Port AI with a custom system prompt and specific tools to generate a deployment summary:
{
"identifier": "generate-summary",
"title": "Generate Deployment Summary",
"config": {
"type": "AI",
"userPrompt": "Generate a deployment summary for service {{ .outputs.trigger.service }} in the {{ .outputs.trigger.environment }} environment",
"systemPrompt": "You are a deployment analyst. Provide concise, actionable summaries of deployment status and any risks.",
"tools": ["list_blueprints", "list_entities"]
}
}
If your prompt uses list_entities with include, add list_blueprints to tools.
The include parameter requires exact property key names from the schema, not display names.
If the schema is already in context from this session, the AI can skip the call.
External MCP connectors in workflows
Workflow type: "AI" nodes accept mcpServers with the same shape as /v1/ai/invoke.
Workflow AI nodes run with an organization automation token, not the triggering user's session. Per-user OAuth MCP connectors are not supported. Use connectors with shared header authentication.
See MCP servers in API requests for request shape, tool names, patterns, and examples.
Example
The mcpServers field accepts any MCP server that exists in Port. You can reference a connector by its identifier - the same identifier used when the MCP server was registered in Port. The node then passes your prompt to that server's tools.
The example below uses the newrelic MCP connector for incident discovery. The node calls a specific New Relic tool (new_relic_get_newrelic_entity) to fetch entity details and golden signals, and uses outputSchema to force the AI to return a structured JSON response that downstream nodes can parse.New Relic MCP node example (click to expand)
A few things worth noting in this example:
mcpServers- thenewrelicidentifier maps to the_mcp_serverentity registered in Port for your New Relic MCP connector. This is the only field required to connect to the server.tools- scoped tonew_relic_get_newrelic_entityonly, which prevents the AI from calling unintended tools on the MCP server. Use explicit tool lists in workflows rather than relying on defaults.systemPrompt- limits the AI to at most two tool calls and instructs it to return immediately after a successful response. In automated workflows, strict system prompts prevent runaway tool-call loops.outputSchema- forces the response into a structured JSON object. Downstream nodes can then reference individual fields directly, for example{{ .outputs.nr_entity_and_metrics.response | fromjson | .golden_signals }}.
Structured output
Both AI modes support structured output through the outputSchema field. When you provide a JSON Schema, the AI generates a structured JSON object that conforms to the schema instead of free-form text. This is useful when you need to parse the AI response programmatically in subsequent workflow nodes.
Schema format
The outputSchema must be a valid JSON Schema with type: "object":
{
"outputSchema": {
"type": "object",
"properties": {
"summary": { "type": "string" },
"severity": { "type": "string" },
"recommendations": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["summary", "severity"]
}
}
When outputSchema is provided, the response output contains the JSON object as a string. You can parse specific fields using JQ in subsequent nodes.
Example with structured output
{
"identifier": "analyze-service",
"title": "Analyze Service Health",
"config": {
"type": "AI_AGENT",
"agentIdentifier": "service-analyzer",
"userPrompt": "Analyze the health of service {{ .outputs.trigger.service }}",
"outputSchema": {
"type": "object",
"properties": {
"status": { "type": "string" },
"issues": {
"type": "array",
"items": { "type": "string" }
},
"score": { "type": "number" }
},
"required": ["status", "score"]
}
}
}
When structured output is requested, the AI must generate a valid JSON object matching the schema. If the AI fails to generate valid output, the node will fail with an error.
Using skills in workflows
You can load skills in AI workflow nodes to provide domain-specific guidance for specialized tasks. To use skills:
-
Include the
load_skilltool in thetoolsarray. You can add it explicitly or use a regex pattern like"^(list|get|load|track|describe)_.*". -
In the
userPromptorsystemPrompt, instruct the AI to load the skill by name.
Example
{
"identifier": "troubleshoot-integration",
"title": "Troubleshoot Integration",
"config": {
"type": "AI",
"userPrompt": "Load skill 'troubleshoot-integration' and use it to diagnose issues with the {{ .outputs.trigger.integration }} integration",
"tools": ["^(list|get|load|track|describe)_.*"]
}
}
When using the AI_AGENT mode, the agent's tool configuration determines whether skills are available. Ensure the agent has access to the load_skill tool if you want to use skills in your prompts.
Outputs
When the AI invocation completes, the node produces the following outputs:
| Field | Description |
|---|---|
response | The AI response. When outputSchema is provided, this contains the structured JSON object as a string. Otherwise, it contains free-form text |
invocationIdentifier | The identifier of the AI invocation entity |
error | Error message (only present if the invocation failed) |
Reference these outputs in subsequent nodes:
{{ .outputs.analyze_health.response }}
{{ .outputs.analyze_health.invocationIdentifier }}
When using structured output, you can parse specific fields from the JSON response using JQ:
{{ .outputs.analyze_health.response | fromjson | .status }}
{{ .outputs.analyze_health.response | fromjson | .score }}
Examples
Invoke an AI agent and notify Slack with the result
This workflow invokes an AI agent to analyze a service and sends the AI response to Slack:
Workflow example (click to expand)
{
"identifier": "ai-analyze-and-notify",
"title": "AI Analysis with Notification",
"nodes": [
{
"identifier": "trigger",
"title": "Select Service",
"config": {
"type": "SELF_SERVE_TRIGGER",
"userInputs": {
"properties": {
"service": {
"type": "string",
"format": "entity",
"blueprint": "service",
"title": "Service"
}
},
"required": ["service"]
}
}
},
{
"identifier": "ai-analyze",
"title": "Analyze with AI Agent",
"config": {
"type": "AI_AGENT",
"agentIdentifier": "service-analyzer",
"userPrompt": "Analyze the health and status of service {{ .outputs.trigger.service }}. Include any recent incidents and scorecard results."
}
},
{
"identifier": "notify-slack",
"title": "Send Analysis to Slack",
"config": {
"type": "WEBHOOK",
"url": "https://hooks.slack.com/services/xxx",
"method": "POST",
"body": {
"text": "AI Analysis for {{ .outputs.trigger.service }}:\n{{ .outputs[\"ai-analyze\"].response }}"
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "ai-analyze"
},
{
"sourceIdentifier": "ai-analyze",
"targetIdentifier": "notify-slack"
}
]
}
Generate an incident summary on service degradation
This event-driven workflow detects service degradation and uses AI to generate an incident summary:
Workflow example (click to expand)
{
"identifier": "ai-incident-summary",
"title": "Generate Incident Summary on Degradation",
"nodes": [
{
"identifier": "trigger",
"title": "On Service Degraded",
"config": {
"type": "EVENT_TRIGGER",
"event": {
"type": "ENTITY_UPDATED",
"blueprintIdentifier": "service"
},
"condition": {
"type": "JQ",
"expressions": [
".diff.before.properties.healthStatus == \"healthy\"",
".diff.after.properties.healthStatus != \"healthy\""
],
"combinator": "and"
}
}
},
{
"identifier": "ai-summarize",
"title": "Generate Incident Summary",
"config": {
"type": "AI",
"userPrompt": "Service {{ .outputs.trigger.diff.after.title }} has degraded from {{ .outputs.trigger.diff.before.properties.healthStatus }} to {{ .outputs.trigger.diff.after.properties.healthStatus }}. Analyze the service and its dependencies to generate a concise incident summary with potential root causes.",
"systemPrompt": "You are an incident response analyst. Provide structured incident summaries with severity assessment, affected components, and recommended next steps.",
"tools": ["list_blueprints", "list_entities"]
}
},
{
"identifier": "create-incident-entity",
"title": "Create Incident Record",
"config": {
"type": "UPSERT_ENTITY",
"blueprintIdentifier": "incident",
"mapping": {
"identifier": "incident-{{ .outputs.trigger.diff.after.identifier }}-{{ now | todateiso8601 }}",
"title": "Degradation: {{ .outputs.trigger.diff.after.title }}",
"properties": {
"summary": "{{ .outputs[\"ai-summarize\"].response }}",
"status": "open",
"detectedAt": "{{ now | todateiso8601 }}"
},
"relations": {
"service": "{{ .outputs.trigger.diff.after.identifier }}"
}
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "ai-summarize"
},
{
"sourceIdentifier": "ai-summarize",
"targetIdentifier": "create-incident-entity"
}
]
}