Trigger Claude Code from Port
This guide demonstrates how to trigger Claude Code from Port, enabling AI-powered coding assistance in your development workflow. By leveraging Claude Code, you can significantly reduce manual coding tasks and enhance productivity, allowing developers to focus on more complex problem-solving. You will learn how to create self-service actions that can trigger Claude Code and configure the necessary GitHub workflows to handle the execution process with comprehensive usage tracking.

Common use casesโ
- Central access โ let developers run Claude Code from Port without extra tools.
- Usage tracking โ monitor cost, activity, and results across the org.
- Workflow automation โ trigger Claude Code on events like bugs or PRs.
- Faster onboarding โ help new devs generate code and docs quickly.

Prerequisitesโ
This guide assumes the following:
- You have a Port account and have completed the onboarding process.
- Port's GitHub app is installed in your account.
- You have access to create and configure AI agents in Port.
- You have completed the setup in the Track AI-driven pull requests guide to enable AI agent tracking and visualization.
- You have an Anthropic API key for Claude Code access.
Set up data modelโ
We need to create blueprints to support our Claude Code workflow. These blueprints will be used to track Claude Code executions and their usage metrics.
Create Claude Code execution blueprintโ
This blueprint will track Claude Code executions, including token usage, costs, and execution details.
-
Go to the builder page of your portal.
-
Click on
+ Blueprint
. -
Click on the
{...} Edit JSON
button. -
Copy and paste the following JSON configuration:
Claude Code Execution blueprint (Click to expand)
{
"identifier": "claudeCodeExecution",
"title": "Claude Code Execution",
"icon": "Code",
"schema": {
"properties": {
"prompt": {
"title": "Prompt",
"type": "string",
"format": "markdown",
"description": "The prompt that was sent to Claude Code"
},
"status": {
"title": "Status",
"type": "string",
"enum": [
"pending",
"running",
"success",
"failed"
],
"enumColors": {
"pending": "blue",
"running": "yellow",
"success": "green",
"failed": "red"
}
},
"executionTime": {
"title": "Execution Time (ms)",
"type": "number",
"description": "Total execution time in milliseconds"
},
"inputTokens": {
"title": "Input Tokens",
"type": "number",
"description": "Number of input tokens consumed"
},
"outputTokens": {
"title": "Output Tokens",
"type": "number",
"description": "Number of output tokens generated"
},
"totalCost": {
"title": "Total Cost (USD)",
"type": "number",
"description": "Total cost of the Claude Code execution"
},
"repository": {
"title": "Repository",
"type": "string",
"description": "The repository where Claude Code was executed"
},
"claudeResponse": {
"type": "string",
"title": "Response",
"format": "markdown"
}
},
"required": [
"prompt",
"status"
]
},
"mirrorProperties": {},
"calculationProperties": {},
"aggregationProperties": {},
"relations": {
"repository": {
"title": "Repository",
"target": "service",
"required": false,
"many": false
},
"ai_coding_agent": {
"title": "AI Coding Agent",
"target": "ai_coding_agent",
"required": false,
"many": false
}
}
} -
Click
Create
to save the blueprint.
Set up self-service actionsโ
We will create self-service actions that can trigger Claude Code executions. First, we need to add the necessary secrets to Port.
Add GitHub secretsโ
In your GitHub repository, go to Settings > Secrets and add the following secrets:
PORT_CLIENT_ID
- Port Client ID learn more.PORT_CLIENT_SECRET
- Port Client Secret learn more.PORT_GITHUB_TOKEN
: A GitHub fine-grained personal access token is required. This token must have read and write permissions for the "Contents", "Issues", "Metadata" and "Pull request" section of your repositories.ANTHROPIC_API_KEY
: Your Anthropic API key for Claude Code access.
Create Claude Code actionโ
-
Go to the self-service page of your portal.
-
Click on
+ New Action
. -
Click on the
{...} Edit JSON
button. -
Copy and paste the following JSON configuration:
Run Claude Code action (Click to expand)
Modification RequiredMake sure to replace
<GITHUB_ORG>
and<GITHUB_REPO>
with your GitHub organization and repository names respectively.{
"identifier": "run_claude_code",
"title": "Run Claude Code",
"icon": "Code",
"description": "Open a Claude Code PR on any given repository",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"prompt": {
"type": "string",
"title": "Prompt",
"description": "The prompt to pass to Claude Code (AI Coding Agent)",
"format": "multi-line"
},
"service": {
"type": "string",
"description": "The service associated with the Claude's Code implementation",
"blueprint": "service",
"title": "Service",
"format": "entity"
}
},
"required": [
"prompt",
"service"
],
"order": [
"prompt",
"service"
]
}
},
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB_ORG>",
"repo": "<GITHUB_REPO>",
"workflow": "claude-backend.yaml",
"workflowInputs": {
"command": "{{ .inputs.prompt }}",
"repo_name": "{{ .inputs.service.identifier }}",
"run_id": "{{ .run.id }}"
},
"reportWorkflowStatus": false
},
"requiredApproval": false
} -
Click
Save
to create the action.
Set up GitHub workflowโ
We recommend creating a dedicated repository for the workflows that are used by Port actions. Create the file .github/workflows/claude-backend.yaml
in this repository to allow Claude Code to be triggered from all associated repositories.
This workflow will execute Claude Code with the provided prompt, track execution progress, and report back to Port with usage metrics including token consumption, costs, and execution details.
GitHub workflow for Claude Code execution (Click to expand)
We recommend creating a GitHub machine user for automated tasks. Update the <GIT USERNAME>
and <GIT USER EMAIL>
fields with the machine user's credentials to ensure proper commit attribution.
name: Trigger Claude Code
on:
workflow_dispatch:
inputs:
repo_name:
required: true
description: "The name of the repo to pull code from"
command:
required: true
description: "The command to run"
run_id:
required: false
description: "Port action run ID to update"
permissions:
contents: read
packages: write
jobs:
claude-generic:
env:
GITHUB_TOKEN: ${{ secrets.PORT_GITHUB_TOKEN }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.PORT_GITHUB_TOKEN }}
repository: ${{ inputs.repo_name }}
ref: main
- name: Configure Git
run: |
git config --global user.name "<GIT USERNAME>"
git config --global user.email "<GIT USER EMAIL>"
- name: Execute Claude Code
id: claude_execution
uses: anthropics/claude-code-base-action@beta
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
allowed_tools: "Bash(git:*),Bash(gh:*),Bash(jq:*),Edit,GlobTool,GrepTool,BatchTool"
system_prompt: |
You are a senior backend engineer. Focus on security, performance, and maintainability.
You will receive repository and a command. You will follow the commands, and open a PR if relevant.
Do NOT make any changes directly to main EVER, only through a PR via a new branch.
prompt: ${{ inputs.command }}
- name: Parse Claude Code Execution Results
id: parse_results
run: |
# Get the execution file path from the claude_execution step
EXECUTION_FILE="${{ steps.claude_execution.outputs.execution_file }}"
if [ -f "$EXECUTION_FILE" ]; then
# Parse the execution results
RESULT=$(cat "$EXECUTION_FILE" | jq -r '.[] | select(.type == "result") | .')
if [ "$RESULT" != "" ]; then
# Extract key metrics
CONCLUSION=$(echo "$RESULT" | jq -r '.subtype // "unknown"')
DURATION_MS=$(echo "$RESULT" | jq -r '.duration_ms // 0')
INPUT_TOKENS=$(echo "$RESULT" | jq -r '.usage.input_tokens // 0')
OUTPUT_TOKENS=$(echo "$RESULT" | jq -r '.usage.output_tokens // 0')
TOTAL_COST=$(echo "$RESULT" | jq -r '.total_cost_usd // 0')
SESSION_ID=$(echo "$RESULT" | jq -r '.session_id // ""')
CLAUDE_RESPONSE=$(echo "$RESULT" | jq -r '.result // ""')
# Set outputs for next steps
{
echo "claude_response<<EOF"
echo "$CLAUDE_RESPONSE"
echo "EOF"
} >> $GITHUB_OUTPUT
echo "conclusion=$CONCLUSION" >> $GITHUB_OUTPUT
echo "duration_ms=$DURATION_MS" >> $GITHUB_OUTPUT
echo "input_tokens=$INPUT_TOKENS" >> $GITHUB_OUTPUT
echo "output_tokens=$OUTPUT_TOKENS" >> $GITHUB_OUTPUT
echo "total_cost=$TOTAL_COST" >> $GITHUB_OUTPUT
echo "session_id=$SESSION_ID" >> $GITHUB_OUTPUT
echo "โ
Parsed Claude Code execution results:"
else
echo "โ No result found in execution file"
echo "conclusion=failure" >> $GITHUB_OUTPUT
echo "duration_ms=0" >> $GITHUB_OUTPUT
echo "input_tokens=0" >> $GITHUB_OUTPUT
echo "output_tokens=0" >> $GITHUB_OUTPUT
echo "total_cost=0" >> $GITHUB_OUTPUT
fi
else
echo "โ Execution file not found: $EXECUTION_FILE"
echo "conclusion=failure" >> $GITHUB_OUTPUT
echo "duration_ms=0" >> $GITHUB_OUTPUT
echo "input_tokens=0" >> $GITHUB_OUTPUT
echo "output_tokens=0" >> $GITHUB_OUTPUT
echo "total_cost=0" >> $GITHUB_OUTPUT
fi
- name: Create Claude Code Execution Entity in Port
if: ${{ inputs.run_id != '' }}
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.port.io
operation: UPSERT
identifier: "claude-exec-${{ inputs.run_id }}"
title: "claude-exec-${{ inputs.run_id }}"
icon: "Code"
blueprint: "claudeCodeExecution"
properties: |-
{
"prompt": "${{ inputs.command }}",
"status": "${{ steps.parse_results.outputs.conclusion == 'success' && 'success' || 'failed' }}",
"executionTime": ${{ steps.parse_results.outputs.duration_ms }},
"claudeResponse": ${{ toJSON(steps.parse_results.outputs.claude_response) }},
"inputTokens": ${{ steps.parse_results.outputs.input_tokens }},
"outputTokens": ${{ steps.parse_results.outputs.output_tokens }},
"totalCost": ${{ steps.parse_results.outputs.total_cost }},
"repository": "${{ inputs.repo_name }}"
}
relations: |
{
"ai_coding_agent": "Claude",
"repository": "${{ inputs.repo_name }}"
}
- name: Update Port Action Run Status to Success
if: ${{ inputs.run_id != '' && steps.parse_results.outputs.conclusion == 'success' }}
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.port.io
operation: PATCH_RUN
runId: ${{ inputs.run_id }}
status: "SUCCESS"
logMessage: |
โ
Claude Code execution completed successfully!
**Execution Summary:**
- Duration: ${{ steps.parse_results.outputs.duration_ms }}ms
- Input tokens: ${{ steps.parse_results.outputs.input_tokens }}
- Output tokens: ${{ steps.parse_results.outputs.output_tokens }}
- Total cost: ${{ steps.parse_results.outputs.total_cost }}
- Session ID: ${{ steps.parse_results.outputs.session_id }}
- name: Update Port Action Run Status to Failed
if: ${{ inputs.run_id != '' && steps.parse_results.outputs.conclusion != 'success' }}
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.port.io
operation: PATCH_RUN
runId: ${{ inputs.run_id }}
status: "FAILURE"
logMessage: |
โ Claude Code execution failed. Check GitHub Actions logs for details!
**Execution Summary:**
- Duration: ${{ steps.parse_results.outputs.duration_ms }}ms
- Input tokens: ${{ steps.parse_results.outputs.input_tokens }}
- Output tokens: ${{ steps.parse_results.outputs.output_tokens }}
- Total cost: ${{ steps.parse_results.outputs.total_cost }}
- Session ID: ${{ steps.parse_results.outputs.session_id }}
Test the workflowโ
Now let us test the complete workflow to ensure everything works correctly.
Run the self-service action
- Go to Self-Service.
- Run the
Run Claude Code
action. - Fill in the fields:
- Prompt โ what you want Claude Code to do (e.g., "Generate Terraform modules for creating an AWS S3 bucket")
- Service โ the related service
- Click Execute and confirm a PR is created in your repo.
Verify execution tracking
- Open the Software Catalog.
- Check the Claude Code Execution entity for the new record.


Related guidesโ
- Set up the Task Manager AI agent - Create an AI agent to manage and prioritize development tasks
- Trigger GitHub Copilot from Port - Set up GitHub Copilot integration with Port