Skip to main content
Version: Cloud (SaaS)

sem-ai Command Line

sem-ai is an agent-first CLI for Semaphore CI/CD. It's designed for AI agents and automation, with structured JSON output, self-discovery, and composable commands. It can also run as an MCP server for direct tool integration.

Overview​

sem-ai provides full control over your Semaphore CI/CD from the terminal or from AI agents. Every command returns structured JSON by default. Key capabilities:

  • Diagnose CI failures with parsed test results
  • Pipeline topology analysis (critical path, blast radius)
  • Test intelligence (flaky detection, test summaries)
  • Testbox: run commands in real CI environments before pushing
  • MCP server mode for native AI agent integration

Installation​

curl -fsSL https://raw.githubusercontent.com/semaphoreio/sem-ai/main/install.sh | sh

Installs the latest release for macOS / Linux on amd64 / arm64. The binary lands at $HOME/.local/bin/sem-ai (or $HOME/.semaphore-ai/bin/sem-ai if that's not on your $PATH). Re-run the same command to upgrade.

From source​

Requires Go 1.25+.

git clone https://github.com/semaphoreio/sem-ai.git
cd sem-ai
make install

Setup​

sem-ai connect​

Connect to your Semaphore organization. You need an API token.

sem-ai connect <organization>.semaphoreci.com <API_TOKEN>

For example:

sem-ai connect myorg.semaphoreci.com NeUFkim46BCdpqCAyWXN

The token is stored in ~/.sem.yaml, shared with the Semaphore CLI. If you already have sem configured, sem-ai uses the same credentials automatically.

sem-ai signin​

Sign in without pasting a token. signin runs a device flow: it shows a one-time code and a verification URL, opening a browser when one is available.

sem-ai signin

Enter the code in the browser, sign in — or create an account there, if you do not have one — and approve. The terminal finishes on its own. signup and login are aliases for the same flow. The resulting token is stored in ~/.sem.yaml the same way connect stores one.

Defaults to Semaphore Cloud. For another deployment, pass the host, and --id-host when the CLI-auth endpoints live elsewhere:

sem-ai signin my-onprem.example.com --id-host id.my-onprem.example.com
FlagDescription
--headless or --deviceNever try to open a browser; print the code and URL
--browserOpen the verification page even when the terminal looks non-interactive
--id-hostHost serving the CLI-auth endpoints (defaults to <host>)
--orgAlso create a first organization with this name (new accounts only)
--org-hostHost for the --org organization's context

An account has a single API token. If yours already has one, approving the sign-in resets it, after an explicit confirmation in the browser. The previous token then stops working everywhere it is used — CI secrets, scripts, other machines. To authenticate with a token you already hold, use connect instead.

sem-ai context​

Each organization you connect to is stored in ~/.sem.yaml as a named context.

List configured organizations:

sem-ai context list

Show the organization this invocation resolves to — the pin, if one is set, otherwise the active context:

sem-ai context show

Under a pin, show and list report different things by design: show names what this invocation will actually talk to, while list reports the file, marking the stored default active and the pinned entry pinned.

Change the default organization used by unpinned commands:

sem-ai context switch myorg_semaphoreci_com

context switch rewrites the shared active-context key in ~/.sem.yaml. Unpinned invocations that set no credential environment variables read that key — including invocations of the legacy sem CLI — so switching affects sessions other than your own. It is meant for a person changing their own default, not for scoping a command, a script, or an agent. To target an organization for one command without changing what anyone else sees, pin it instead.

Pinning an organization​

--context selects a named context for one invocation, without writing to the config file. It takes a context name, not a host: connect names each context after its host with the dots replaced by underscores, so myorg.semaphoreci.com is stored as myorg_semaphoreci_com. Run sem-ai context list to see the exact names.

sem-ai --context myorg_semaphoreci_com project list

SEM_CONTEXT does the same for a whole shell session:

export SEM_CONTEXT=myorg_semaphoreci_com
sem-ai project list

A name that is not in ~/.sem.yaml fails immediately and lists the contexts that are, instead of quietly falling back to another organization.

Pinning isolates the read path: a pinned invocation neither reads nor writes active-context, so pinned sessions cannot flip each other's organization. It does not make every operation concurrency-safe. connect, signin, and context switch still write ~/.sem.yaml; each write replaces the whole file, and two overlapping writes are last-writer-wins, so a context one session adds can disappear when another lands. Pinning also covers sem-ai only — the legacy sem CLI reads neither --context nor SEM_CONTEXT and still follows active-context. When several agents run at once, sequence the commands that write, or give each agent its own HOME.

signin, context switch, and context list ignore the pin entirely, so a pin naming a context that does not exist yet cannot block the command that is about to create it. connect ignores it when resolving credentials, but refuses outright when the pin resolves to a different host than its <host> argument, since that names two organizations at once. connect names the context it creates after its host, so re-pin to that name once onboarding finishes.

Credential resolution order​

sem-ai resolves a host and a token from these sources, in order:

PrioritySourceScopeBehavior
1--context <name>A single invocationReplaces everything below
2SEM_CONTEXT=<name>A shell sessionReplaces everything below
3SEMAPHORE_HOST and/or SEMAPHORE_API_TOKENThe process environmentMerged — each variable overrides only its own field
4active-context in ~/.sem.yamlShared by every session on the machineThe starting point when nothing above applies

The two halves of that table behave differently, and the difference matters.

A context named by --context or SEM_CONTEXT supplies the host and the token together and fully replaces the sources below it, so its credentials are never mixed with the environment variables.

Without a selector, rows 3 and 4 merge field by field. SEMAPHORE_HOST and SEMAPHORE_API_TOKEN are independent, so setting only one leaves the other coming from the active context. Exporting SEMAPHORE_API_TOKEN on its own — which the hosted MCP server setup instructs you to do — means every later sem-ai command in that shell sends that token to whichever host active-context currently names. Set both variables together, or pin a context, whenever the host and the token have to belong to the same organization.

General syntax​

sem-ai <command> [subcommand] [flags]

Global flags:

FlagDescription
--contextRun against a named context from ~/.sem.yaml without changing the active one. See pinning an organization
--format or -fOutput format: json (default), table, yaml
--verbose or -vShow HTTP requests for debugging
--examplesShow usage examples for any command
--help or -hHelp for any command

Self-discovery​

sem-ai discover​

Returns a structured map of every command, its flags, and examples. Designed for AI agents to self-orient without documentation.

sem-ai discover
sem-ai discover --format table

sem-ai <command> --examples​

Every command supports --examples to show usage examples:

sem-ai diagnose --examples
sem-ai pipeline promote --examples

Working with projects​

sem-ai project list​

List all projects in the organization:

sem-ai project list

sem-ai project show​

Show project details:

sem-ai project show <project-name>

sem-ai project create​

Create a project from a git repository. With no flags it uses the origin remote of the current directory and derives the name from the repo URL, then bootstraps an initial .semaphore/semaphore.yml (unless --skip-yaml). If a project with the same name already exists it returns the existing one, unless --fail-on-exists is set.

sem-ai project create
sem-ai project create --repo-url git@github.com:org/repo.git
sem-ai project create --name my-project --github-integration github_app
FlagDefaultDescription
--repo-urlorigin of cwdgit repository URL
--namederived from repo URLproject name
--github-integrationgithub_tokenGitHub integration: github_token or github_app
--remoteorigingit remote to detect when --repo-url is not set
--skip-yamlfalsedon't generate .semaphore/semaphore.yml in cwd
--fail-on-existsfalseexit non-zero if a project with the same name already exists

sem-ai project update​

Update project settings:

sem-ai project update <project-name> --visibility public
sem-ai project update <project-name> --description "My app"

sem-ai project delete​

Delete a project:

sem-ai project delete <project-name>

Working with workflows​

sem-ai workflow list​

List workflows for a project:

sem-ai workflow list --project <project-name>
sem-ai workflow list --project <project-name> --branch main

sem-ai workflow show​

Show workflow details:

sem-ai workflow show <workflow-id>

sem-ai workflow run​

Trigger a new workflow run (reruns the latest workflow):

sem-ai workflow run --project <project-name>
sem-ai workflow run --project <project-name> --branch feature-x

sem-ai workflow rerun​

Rerun a specific workflow:

sem-ai workflow rerun <workflow-id>

sem-ai workflow stop​

Stop a running workflow:

sem-ai workflow stop <workflow-id>

Working with pipelines​

sem-ai pipeline show​

Show pipeline with blocks and jobs tree:

sem-ai pipeline show <pipeline-id>

sem-ai pipeline list​

List pipelines for a project:

sem-ai pipeline list --project <project-name>

sem-ai pipeline stop​

Stop a running pipeline:

sem-ai pipeline stop <pipeline-id>

sem-ai pipeline rebuild​

Rebuild only failed blocks (partial rebuild):

sem-ai pipeline rebuild <pipeline-id>

sem-ai pipeline promote​

Trigger a promotion (deployment). This is a safety-gated operation:

  • Without --confirm: dry run showing what would happen
  • With --confirm: actually executes the promotion
# Dry run
sem-ai pipeline promote <pipeline-id> --target "Deploy to Staging"

# Execute
sem-ai pipeline promote <pipeline-id> --target "Deploy to Staging" --confirm

# Override conditions (promote despite failures)
sem-ai pipeline promote <pipeline-id> --target "Deploy to Staging" --confirm --override

# With parameters
sem-ai pipeline promote <pipeline-id> --target "Production" --confirm --param version=1.2.3

sem-ai pipeline topology​

Show the block dependency graph:

sem-ai pipeline topology <pipeline-id>

Working with jobs​

sem-ai job list​

List jobs, optionally filtered by state:

sem-ai job list --states RUNNING --states QUEUED
sem-ai job list --states FINISHED

sem-ai job show​

Show job details:

sem-ai job show <job-id>

sem-ai job log​

Fetch structured job logs:

sem-ai job log <job-id>
sem-ai job log <job-id> --format table

sem-ai job stop​

Stop a running job:

sem-ai job stop <job-id>

Managing organization members and roles​

sem-ai org member list​

List organization members, optionally filtered by member type:

sem-ai org member list
sem-ai org member list --type service_account
sem-ai org member list --type group
FlagDefaultDescription
--typeuserfilter by member type: user, service_account, or group

sem-ai org member add​

Invite a person to the organization by their SCM handle:

sem-ai org member add --provider github --handle octocat
sem-ai org member add --provider github --handle octocat --role <role-id> --name "Octo Cat" --email octo@example.com
sem-ai org member add --provider bitbucket --handle jdoe --uid 557058:1a2b3c
FlagDefaultDescription
--handle—SCM login/handle of the person to invite (required)
--provider—SCM provider: github, bitbucket, or gitlab (required)
--uid—SCM user ID (required for bitbucket)
--role—org role ID to assign
--name—display name
--email—email address

sem-ai org member set-role​

Assign or change a member's org-level role. This is an upsert — the same command creates the initial role assignment and changes it later.

sem-ai org member set-role <user-id> <role-id>
sem-ai org member set-role <service-account-id> <role-id>

sem-ai org member remove​

Remove a member or service account from the organization:

sem-ai org member remove <user-id>

sem-ai org role list​

List organization roles, including built-in and custom roles:

sem-ai org role list

sem-ai org role show​

Show role details, including its permission set:

sem-ai org role show <role-id>

sem-ai org role create​

Create a custom role:

sem-ai org role create deployer --permissions "project.view,project.job.rerun"
sem-ai org role create viewer --scope project --permissions "project.view"
FlagDefaultDescription
--description—role description
--scopeorgrole scope: org or project
--permissions—comma-separated permission names, e.g. organization.people.view,organization.people.manage

sem-ai org role update​

Update a custom role:

sem-ai org role update <role-id> --permissions "project.view,project.job.rerun"
FlagDefaultDescription
--name—new role name
--description—new role description
--permissions—comma-separated permission names (replaces the existing set)

sem-ai org role delete​

Delete a custom role:

sem-ai org role delete <role-id>

sem-ai permission list​

List available permissions, optionally filtered by scope:

sem-ai permission list
sem-ai permission list --scope project
FlagDefaultDescription
--scope—filter by scope: org or project

Managing groups​

sem-ai group list​

List groups in the organization:

sem-ai group list

sem-ai group create​

Create a group:

sem-ai group create backend-team
sem-ai group create backend-team --description "Backend engineers" --members "id1,id2"
FlagDefaultDescription
--description—group description
--members—comma-separated member IDs to add on creation

sem-ai group update​

Update a group's name, description, or membership:

sem-ai group update <group-id> --add "id1,id2" --remove "id3"
sem-ai group update <group-id> --name "new-name"
FlagDefaultDescription
--name—new group name
--description—new group description
--add—comma-separated member IDs to add
--remove—comma-separated member IDs to remove

sem-ai group delete​

Delete a group:

sem-ai group delete <group-id>

Managing service accounts​

sem-ai service-account list​

List service accounts in the organization:

sem-ai service-account list

sem-ai service-account create​

Create a service account. The API token is only ever returned in this create response — save it now, since service-account show never returns it again (use regenerate-token if it's lost).

sem-ai service-account create ci-bot
sem-ai service-account create ci-bot --description "Bot for CI pipelines"
FlagDefaultDescription
--description—service account description

sem-ai service-account show​

Show service account details:

sem-ai service-account show <service-account-id>

sem-ai service-account update​

Update a service account's name or description. The API replaces the whole record on update, so if --name is omitted, sem-ai first fetches the current name and resends it unchanged to avoid clearing it.

sem-ai service-account update <service-account-id> --name "new-name"
sem-ai service-account update <service-account-id> --description "new description"
FlagDefaultDescription
--name—new service account name
--description—new service account description

sem-ai service-account delete​

Delete a service account:

sem-ai service-account delete <service-account-id>

sem-ai service-account deactivate​

Deactivate a service account, disabling its token without deleting the account:

sem-ai service-account deactivate <service-account-id>

sem-ai service-account reactivate​

Reactivate a previously deactivated service account:

sem-ai service-account reactivate <service-account-id>

sem-ai service-account regenerate-token​

Regenerate a service account's API token. The old token is invalidated and the new one is printed once in the response — save it immediately.

sem-ai service-account regenerate-token <service-account-id>

Managing project members​

sem-ai project member list​

List project members:

sem-ai project member list my-project

sem-ai project member set-role​

Set a project-level role for a member:

sem-ai project member set-role my-project <user-id> <role-id>

sem-ai project member remove​

Remove a member's project-level role:

sem-ai project member remove my-project <user-id>

Managing pre-flight checks​

Pre-flight checks are commands Semaphore runs during pipeline initialization, before any block starts. There is one organization-wide check and one check per project; both run, and either can stop a pipeline. Scope follows --project: pass it for a project's check, omit it for the organization-wide one.

sem-ai pfc show​

Show the commands, secrets, and agent of a pre-flight check:

# the organization-wide check
sem-ai pfc show

# one project's check
sem-ai pfc show --project my-project

sem-ai pfc apply​

Create or replace a pre-flight check. This is a privileged change — the commands run at the start of every workflow in the scope, and a non-zero exit stops the pipeline before any block runs. Apply replaces the whole check rather than merging into it.

# organization-wide gate, two commands and one secret
sem-ai pfc apply --command checkout --command 'make security-scan' --secret scanner-token

# project-level gate on a specific agent
sem-ai pfc apply --project my-project \
--command './scripts/gate.sh' \
--machine-type e2-standard-2 --os-image ubuntu2204

The spec can come from a YAML or JSON file instead of flags, but not both:

sem-ai pfc apply --project my-project --from-file pfc.yml
commands:
- checkout
- make security-scan
secrets:
- scanner-token
agent:
machine_type: e2-standard-2
os_image: ubuntu2204

Requires organization.pre_flight_checks.manage or project.pre_flight_checks.manage.

sem-ai pfc delete​

Remove a pre-flight check:

sem-ai pfc delete --project my-project

Compound commands​

These commands compose multiple API calls into a single operation.

sem-ai status​

Quick CI status for the current branch, a pull request, or a project. When run inside a git checkout, project and branch are auto-detected from the remote and HEAD, and status prefers the workflow for the exact HEAD commit, falling back to the latest run on the branch.

sem-ai status                                    # current repo, branch, commit
sem-ai status --branch main
sem-ai status --pr 422 # match a pull request's workflow (overrides --branch)
sem-ai status --project <project-name> --branch feature-x

If the git remote maps to several Semaphore projects that each ran the commit, status returns all of them rather than guessing — pass --project to disambiguate.

With --exit-code, status sets a poll-friendly process exit code instead of requiring output parsing — useful for shell wait-loops:

ExitMeaning
0passed
1failed
2ambiguous (multiple matching projects)
3no workflow found / project not detected
8pending / running
until sem-ai status --exit-code; do sleep 20; done   # wait until green

sem-ai diagnose​

One-command failure diagnosis. Composes workflow lookup, pipeline details, failed jobs, log tails, and parsed test results into a single structured response.

sem-ai diagnose
sem-ai diagnose <workflow-id>
sem-ai diagnose --project <project-name> --branch main

Returns structured output with:

  • Pipeline state and result
  • Failed blocks and jobs
  • Log tails with failed commands highlighted
  • Parsed test results with file, line, and error message
  • stop_reason when a job was stopped by a signal rather than a test failure — exit 130 (SIGINT), 137 (SIGKILL / OOM), or 143 (SIGTERM). This is most useful for exit 130, where the job shows up as STOPPED and failure notifications are suppressed, so the cause is otherwise easy to miss.

sem-ai health​

Project health summary with pass rates, failure trends, and deployment status:

sem-ai health --project <project-name>

sem-ai watch​

Poll a workflow until it completes, streaming status updates:

sem-ai watch <workflow-id>
sem-ai watch <workflow-id> --interval 10s

sem-ai promote-and-wait​

Promote a pipeline and block until the promoted pipeline finishes:

# Dry run
sem-ai promote-and-wait <pipeline-id> --target "Deploy to Staging"

# Execute and wait
sem-ai promote-and-wait <pipeline-id> --target "Deploy to Staging" --confirm

sem-ai open​

Open the latest workflow for the current branch in the browser:

sem-ai open
sem-ai open --project my-app
sem-ai open --workflow <workflow-id>

sem-ai version​

Print version information as JSON:

sem-ai version
sem-ai version --check # also check GitHub for a newer release

When sem-ai is installed via the Claude Code / Codex plugin, a SessionStart hook surfaces a one-line upgrade notice at most once every few hours. Opt out with export SEM_AI_NO_UPDATE_CHECK=1.

sem-ai rerun-failed​

Rebuild only failed blocks in a pipeline:

sem-ai rerun-failed <pipeline-id>

sem-ai critical-path​

Show the longest dependency chain (bottleneck) in a pipeline:

sem-ai critical-path <pipeline-id>

sem-ai blast-radius​

Show which blocks failed as root causes vs which were canceled due to upstream failures:

sem-ai blast-radius <pipeline-id>
sem-ai blast-radius <pipeline-id> --block "Build"

Analytics​

Historical pipeline and workflow analytics. All analytics commands share a common set of flags:

FlagDefaultDescription
--projectauto-detectedProject name
--branchall branchesFilter by branch
--days7Time window in days
--limit100Max workflows to analyze

sem-ai analytics summary​

All-in-one analytics overview: pass rate, duration stats (avg/p50/p95), phase breakdown (compile, queue, execution), failing blocks, deploy count, and trigger distribution.

sem-ai analytics summary --project my-app
sem-ai analytics summary --project my-app --days 30 --branch main

sem-ai analytics duration​

Pipeline duration trends with avg, p50, p95, min, and max, plus a phase breakdown showing where time is spent (compile, queue, execution).

sem-ai analytics duration --project my-app --days 30

sem-ai analytics failures​

Block-level failure rates across analyzed pipelines, ranked by failure count. Also reports overall pass rate and failure reasons (test failure, stuck, canceled, etc.).

sem-ai analytics failures --project my-app --days 14

sem-ai analytics queue​

Queue wait time analysis (avg, p50, p95, min, max) — measures time between a job being queued and starting execution.

sem-ai analytics queue --project my-app --days 7

sem-ai analytics deploys​

Deploy frequency and promotion stats: total deploys, deploys per day, and deploys per week.

sem-ai analytics deploys --project my-app --days 30

sem-ai analytics trend​

Week-over-week trends for pass rate, duration, queue time, failure reasons, and trigger distribution. Uses --weeks instead of --days.

FlagDefaultDescription
--weeks4Number of weeks to analyze
--limit200Max workflows to analyze
sem-ai analytics trend --project my-app --weeks 4
sem-ai analytics trend --project my-app --weeks 8 --branch main

Returns an array of weekly buckets plus an overall trend field: improving, degrading, or stable.

Pipeline insights​

Server-side pipeline insights, keyed by a specific pipeline YAML file. This is distinct from analytics, which sem-ai computes client-side from recent workflows: insights reads pre-aggregated metrics from Semaphore for one pipeline file.

All insights subcommands share these flags:

FlagDefaultDescription
--projectauto-detectedproject name or ID
--pipeline-file—pipeline YAML path, e.g. .semaphore/semaphore.yml (required)
--branchall branchesbranch name
--from—start date YYYY-MM-DD
--to—end date YYYY-MM-DD
--aggregatedailyaggregation: daily or range

sem-ai insights performance​

Pipeline duration metrics over time.

sem-ai insights performance --project my-app --pipeline-file .semaphore/semaphore.yml --branch main

sem-ai insights reliability​

Pipeline pass/fail rate over time.

sem-ai insights reliability --project my-app --pipeline-file .semaphore/semaphore.yml --branch main

sem-ai insights frequency​

Pipeline run frequency over time.

sem-ai insights frequency --project my-app --pipeline-file .semaphore/semaphore.yml --branch main

Test intelligence​

sem-ai test summary​

AI-friendly test summary for a pipeline. Parses test results from job logs and artifacts.

sem-ai test summary --pipeline <pipeline-id>

sem-ai test report​

Detailed test results with individual test cases:

sem-ai test report --pipeline <pipeline-id>

sem-ai test flaky​

Detect flaky tests by analyzing recent workflow runs:

sem-ai test flaky --project <project-name>
sem-ai test flaky --project <project-name> --branch main --count 10

Flaky tests​

History-backed flaky-test signals for a project, sourced from Semaphore's flaky-test history (per-context pass rate, p95, disruption counts). This is distinct from test flaky, which is a quick single-pipeline snapshot computed from JUnit artifacts; the flaky command group reads the accumulated history instead.

All flaky subcommands require --project (name or ID).

sem-ai flaky list​

List a project's flaky tests. The heavy per-test disruption_history histogram is omitted by default for compact output; pass --full to include it.

sem-ai flaky list --project my-app
sem-ai flaky list --project my-app --sort-field pass_rate --sort-dir asc
sem-ai flaky list --project my-app --full
FlagDefaultDescription
--page1page number
--page-size20results per page
--sort-field—sort field, e.g. total_disruptions_count, pass_rate
--sort-dir—sort direction (asc or desc)
--fullfalseinclude full disruption_history per test

sem-ai flaky show​

Show details for a single flaky test (per-context pass rate, p95, disruptions). test_id is positional.

sem-ai flaky show <test_id> --project my-app

sem-ai flaky disruptions​

List the individual disruption occurrences for a flaky test.

sem-ai flaky disruptions <test_id> --project my-app --page-size 50
FlagDefaultDescription
--page1page number
--page-size10results per page

sem-ai flaky failure​

Show the real failure behind a flaky test: resolves its latest disruption's job, fetches that job's log, and extracts the failing assertion / message. Use --run-id to point at a specific job directly instead of resolving the latest disruption.

sem-ai flaky failure <test_id> --project my-app
sem-ai flaky failure <test_id> --project my-app --run-id <job-id>

Project-level flaky / disruption count time series.

sem-ai flaky trends --project my-app
sem-ai flaky trends --project my-app --metric disruptions
FlagDefaultDescription
--metricflakyseries: flaky or disruptions

Testbox​

Testbox lets you run commands in a real Semaphore CI environment before pushing. It creates a warm VM with your project's machine type and syncs your local code.

sem-ai testbox warmup​

Start a testbox:

sem-ai testbox warmup --project <project-name>
sem-ai testbox warmup --project <project-name> --machine f1-standard-4 --duration 30m
sem-ai testbox warmup --project <project-name> --os-image ubuntu2404

Defaults: --machine f1-standard-2, --os-image ubuntu2204, --duration 30m.

sem-ai testbox run​

Sync local changes and run a command:

sem-ai testbox run --id <testbox-id> "go test ./..."
sem-ai testbox run --id <testbox-id> "make build"

sem-ai testbox ssh​

Open an interactive SSH session:

sem-ai testbox ssh --id <testbox-id>

sem-ai testbox stop​

Stop a running testbox:

sem-ai testbox stop --id <testbox-id>

Secrets​

sem-ai secret list​

List organization-level secrets, or project-level with --project:

sem-ai secret list
sem-ai secret list --project <project-name>

sem-ai secret show​

Show secret details:

sem-ai secret show <secret-name>
sem-ai secret show <secret-name> --project <project-name>

sem-ai secret create​

Create a secret with environment variables:

sem-ai secret create <secret-name> --env KEY=VALUE --env DB_URL=postgres://...
sem-ai secret create <secret-name> --project <project-name> --env API_KEY=abc123

sem-ai secret update​

Update a secret (replaces env vars):

sem-ai secret update <secret-name> --env KEY=NEW_VALUE

sem-ai secret delete​

Delete a secret:

sem-ai secret delete <secret-name>

Deployment targets​

sem-ai deploy targets​

List deployment targets:

sem-ai deploy targets --project <project-name>

sem-ai deploy show​

Show deployment target details:

sem-ai deploy show <target-id>

sem-ai deploy history​

Show deployment history:

sem-ai deploy history <target-id>

sem-ai deploy create​

Create a deployment target:

sem-ai deploy create <name> --project <project-name> --url https://staging.example.com

sem-ai deploy activate / deactivate​

Activate or deactivate a deployment target:

sem-ai deploy activate <target-id>
sem-ai deploy deactivate <target-id>

sem-ai deploy delete​

Delete a deployment target:

sem-ai deploy delete <target-id>

Notifications​

sem-ai notification list​

List notification rules:

sem-ai notification list

sem-ai notification show​

Show notification details:

sem-ai notification show <name>

sem-ai notification delete​

Delete a notification rule:

sem-ai notification delete <name>

Scheduled tasks​

sem-ai task list​

List scheduled tasks:

sem-ai task list --project <project-name>

sem-ai task show​

Show task details:

sem-ai task show <task-id>

sem-ai task create​

Create a scheduled task:

sem-ai task create <name> --project <project-name> --branch main --file .semaphore/nightly.yml --cron "0 2 * * *"

sem-ai task run​

Trigger a task to run now:

sem-ai task run <task-id>

sem-ai task delete​

Delete a task:

sem-ai task delete <task-id>

Self-hosted agents​

sem-ai agent types​

List self-hosted agent types:

sem-ai agent types

sem-ai agent show​

Show agent type details:

sem-ai agent show <type-name>

sem-ai agent list​

List agents for a given type:

sem-ai agent list --type <type-name>

sem-ai agent delete​

Delete an agent type:

sem-ai agent delete <type-name>

Artifacts​

sem-ai artifact list​

List artifacts for a job, workflow, or project:

sem-ai artifact list --scope jobs --id <job-id>
sem-ai artifact list --scope workflows --id <workflow-id>

sem-ai artifact get​

Download an artifact:

sem-ai artifact get --scope jobs --id <job-id> --path test-results/junit.json --output ./results.json

Troubleshooting​

Server-side diagnostics for workflows, pipelines, and jobs:

sem-ai troubleshoot workflow <id>
sem-ai troubleshoot pipeline <id>
sem-ai troubleshoot job <id>

YAML validation​

Validate a pipeline YAML file against the Semaphore API:

sem-ai yaml validate --file .semaphore/semaphore.yml

MCP server​

sem-ai can run as an MCP (Model Context Protocol) server, exposing all commands as native tools for AI agents.

Starting the server​

sem-ai mcp

Claude Code configuration​

Add to your project's .mcp.json:

{
"mcpServers": {
"sem-ai": {
"command": "sem-ai",
"args": ["mcp"]
}
}
}

Most commands become available as MCP tools (e.g., project_list, diagnose, status, blast-radius). The long-running commands watch and promote-and-wait are excluded, since they would block the single in-memory command tree; use status --exit-code in a poll loop instead. The onboarding commands signin and connect are excluded too — the device flow holds the server lock and hides the one-time code it prints, and connect's two positional arguments cannot be expressed as tool arguments — so run those in a shell. The server starts once and handles all tool calls in-process — no new process per call.

To tie a server to one organization, pass --context in its args, as described under pinning an organization. One tool is worth knowing about: context_switch remains available and rewrites the shared active-context key for every session on the machine. It ignores both the server pin and a per-call context argument, so never call it to scope a request — pass context on the call instead.

Agent skills​

sem-ai ships its skills as a plugin for Claude Code and Codex. The plugin bundles the skills, the MCP server, and a SessionStart hook (release-update check + Semaphore-repo awareness).

Claude Code / Codex plugin​

Claude Code:

/plugin marketplace add semaphoreio/sem-ai
/plugin install sem-ai@semaphoreio

Codex CLI:

codex plugin marketplace add semaphoreio/sem-ai
codex plugin add sem-ai@semaphoreio

The bundle includes these skills: debug-pipeline, deploy, fix-flaky, gha-to-semaphore, init, manage-infra, probe-agent-environment, project-health, sem-ai-bootstrap, semaphore-blocks, semaphore-ci, semaphore-promotions, semaphore-test-results, semaphore-toolbox, test-intelligence, testbox, and watch-after-push. They give agents context on when and how to use each sem-ai command without reading this reference.

npx skills​

You can also install the skill bundle with the cross-agent skills tool, which supports Claude Code, Cursor, Codex, OpenCode, and many other agents. It discovers sem-ai's skills from the plugin manifest, so no clone is required:

npx skills add semaphoreio/sem-ai --list             # list available skills
npx skills add semaphoreio/sem-ai --all # install all skills
npx skills add semaphoreio/sem-ai --skill semaphore-ci --skill watch-after-push
npx skills add semaphoreio/sem-ai --all -g # user level (all repos)
npx skills add semaphoreio/sem-ai --all --agent cursor opencode

This installs the skill instructions only — not the MCP server. The sem-ai binary must be installed and connected first, since every skill calls it.

Differences from sem CLI​

Featuresemsem-ai
Output formatHuman textJSON (default), table, yaml
Self-discovery--help onlydiscover + --examples on every command
Failure diagnosisManual (multiple commands)diagnose (one command, full root cause)
Test intelligenceNonetest summary, test flaky, flaky history, insights
Pipeline topologyNonetopology, critical-path, blast-radius
Testboxsem debug (limited)testbox warmup/run/ssh/stop with file sync
MCP serverNonesem-ai mcp
Health reportsNonehealth (pass rates, trends, verdict)
Deploy safetyFire-and-forgetDry run by default, --confirm required
Configuration~/.sem.yaml~/.sem.yaml (shared, compatible)