CLI Workflows¶
Use the generated command reference for arguments and options. This page covers operational behavior that the command manifest cannot express. For installation, use Install the SAIF CLI; for the difference between resource lookups, services, and cross-domain search, see the CLI command model.
Commands that accept --format default to human-readable table output; pass --format json when a script needs to parse the result.
Tokens for API testing¶
saif auth generate¶
Follow JWT Test Tokens for the token-generation workflow, provider-specific scopes, and pipeline alternative. Entra ID is the default provider; Okta requires an explicit --identity-provider okta.
--plain prints only the token on success, but it does not make authentication non-interactive. Supply --name because plain mode cannot prompt for the application name; for Entra, that name must also identify a single application. Okta still opens a browser and never reuses a cached token. The Okta browser and loopback troubleshooting covers the two-minute wait, registered ports 8406-8408, and headless limitations.
Use Request Specific Scopes for scope qualification and the --no-default-scopes negative-test case. Use the API pipeline's auth-server output rather than guessing an issuer; a full issuer URL must use HTTPS. These checks live in AuthGenerateCommand.
saif auth clear¶
Clear the Entra ID MSAL cache when you need the next Entra token request to sign in again. This does not clear an Okta session or token cache: the CLI's Okta flow is interactive-only and stores no token cache. The command asks for confirmation unless you explicitly bypass it; see the command options.
saif auth validate¶
Use this command to decode claims, inspect expiration, and resolve the audience to an Entra application registration. It is an inspection tool, not proof that an API will accept the token. Run without a token argument and paste when prompted to avoid leaving the token in shell history. For long or wrapped tokens, use the word-wrapping troubleshooting guidance.
Create and publish an application¶
saif new¶
Create projects with Forge templates owns template discovery and generation. saif new normally publishes after scaffolding; use --no-publish when you want only local generation. That leaves repository creation and pipeline registration for a later saif publish, not for the local AppHost run.
saif publish¶
Run from the directory containing the project's SAIF manifest, or select that directory with --directory. Publishing applies the manifest to create or reuse the remote repository, push the project, and register its pipelines. It does not itself deploy the application: the main pipeline still needs to run, whether triggered by the push or started manually.
After a partial failure, correct the reported error and retry. ApplicationService.PublishAsync() reuses an existing repository rather than duplicating it; review the returned pipeline errors and warnings rather than treating repository creation alone as success.
Use Aspire Publish to generate pipeline YAML and infrastructure configuration from an AppHost. That generation step and saif publish registration are different operations. For registration failures, see saif publish does not create pipelines.
Check and repair the developer environment¶
saif doctor¶
Run diagnostics before repairing an installation. Doctor reports health and whether it can fix a problem automatically. Version-based checks show installed and latest versions separately; after a fix, the row reports the installed or updated version. A healthy row with no latest-version information is not evidence that an online update check succeeded.
saif doctor fix¶
Updating the SAIF CLI owns the update commands, opt-in CLI self-update, and Aspire compatibility fallback. With no group filters, doctor repairs tools, templates, and plugins but excludes the SAIF CLI binary; use --self deliberately for that binary. --tools covers dotnet global tools, npm global tools, and the Aspire CLI. Use the global --dry-run flag to inspect proposed changes.
If doctor reports that Aspire requires a package-manager update, follow the remedy in that warning rather than repeatedly retrying the same repair. Forge's AspireCliCheck attempts the current self-update form first and retries without --yes only when the installed CLI rejects that argument, not for every update failure. See the Aspire update reference for upstream installation-method behavior.
Plugin registration, refresh, and recovery have one home in Forge Agent Plugins.
Find a service and interpret the result¶
saif app search¶
Use app for an individual Entra registration, especially when investigating a JWT audience or a vendor application that does not follow Forge's service naming convention, and service for the consolidated, repository-aware view; the command model explains the layering.
Choose one lookup mode: audience, application ID, or listing. The generated app-search options list the accepted aliases. A GUID audience can identify an application ID; --appid makes that intent explicit.
saif service search¶
Service search matches application registration display names by case-insensitive substring, then groups recognized environment suffixes under one service key. For example, payments-test and payments-prod become payments.
saif service search policyportal
saif service search payments --verbose
saif service search payments --format json
Interpret these results with the catalog's limits:
- Queries need at least two characters.
- Only registrations ending in
platformdev,test,qa,uat, orprodqualify as service facets. Useapp searchfor registrations without one of those suffixes. - The Entra provider scans at most 2,000 registrations for a filtered query, then applies the name filter. A truncation notice means the result is incomplete; narrowing the term does not remove that scan cap. Do not treat an empty truncated result as proof that a service does not exist.
- Repository correlation probes exact names in order: the full service name, a name assembled from its first and last hyphen-separated tokens (normally
{domain}-{app name}), then its last token (normally the app name). The first candidate with an exact match wins. Aweborfunccomponent whose code lives in a sibling repository can therefore show no repository. Correlation is a naming lookup, not a scan of repository contents.
ServiceCatalog, ServiceGrouper, and the Entra catalog provider own this behavior. The search_services MCP tool and the service portion of saif search use the same consolidation.
saif service describe¶
Use the full service key from search when you want a single topology view:
Describe strips a recognized environment suffix before requiring an exact, case-insensitive service-key match. payments-prod selects the payments service, not only its production environment; use --environment prod to narrow the view. It errors when the requested service or environment does not resolve.
Permissions describe what each registration requests through Graph requiredResourceAccess, not a proof of effective access. The command resolves scope and role IDs against target service principals on a best-effort basis. A failed environment lookup renders permissions as unavailable (null in JSON) without discarding the rest of the topology; unresolved targets or permission IDs retain their raw IDs. Use --verbose when you need pipeline identifiers and low-level permission identifiers: with --format json, it populates the pipelines array (otherwise null) alongside pipelineCount and sets resourceAppId and id on each permission entry. Without --verbose, JSON output still sets id for a permission whose value did not resolve.
For deployed resource naming and runtime lookups, use the Service and Azure Resource Model. ServiceDescribeCommand owns exact matching and partial-result handling.
Find and read documentation¶
saif docs list¶
Use this as a sample of available pages, not a complete inventory: it returns at most 25 results. The MkDocs fallback configuration owns how wildcard listings are built, capped, and interleaved across sites.
saif docs search¶
Search first when you do not know the location, then pass the returned location unchanged to docs get. Non-default sites carry a site prefix; removing it can select the wrong page. Search defaults to 10 results, and the shared service clamps requested limits to 1–25. A search hit does not guarantee that the page is still available or matches the indexed revision; see Documentation Retrieval.
saif docs search "documentation retrieval" --limit 5
saif docs get reference/documentation-retrieval --section "Search result locations"
saif docs get¶
--section matches the exact heading text case-insensitively and returns that heading through the next heading of equal or higher level. Use the heading text, not its URL fragment. Human output prints Markdown directly, without Spectre markup parsing or width-wrapping.
For scripts, use --format json and handle not_found and section_not_found error records as well as successful content. The retrieval contract owns path normalization, cross-site ambiguity, and freshness limitations; DocsGetCommand owns section extraction and output behavior.
Agent integration¶
saif agent init¶
Use Forge Agent Plugins for package selection, installation, scope, permission opt-in, verification, and recovery. Do not maintain a second host configuration from command-reference examples.
saif agent mcp¶
The forge plugin launches this stdio MCP entrypoint. Use the plugin setup guide to verify the tools, the generated options for command syntax, and Smithy for Smithy's separate MCP contract.