Skip to content

CLI automation parity with Dashboard/MCP #14138

@davidfowl

Description

@davidfowl

Summary

The CLI lacks several commands available in MCP/Dashboard that are essential for end-to-end automation, diagnostics, and scripting - including AI agent-led workflows.

Community POC

See #13727 for a community proof-of-concept implementing some of these features.

Current Commands (aspire 13.2 daily)

Command Description Status
aspire new Create a new Aspire project.
aspire init Initialize Aspire support in an existing solution or create a single-file AppHost.
aspire run Run an Aspire apphost in development mode.
aspire stop [<resource>] Stop a running apphost or the specified resource.
aspire start <resource> Start a stopped resource. ✅ New
aspire restart <resource> Restart a running resource. ✅ New
aspire command <resource> <command> Execute a command on a resource. ✅ New
aspire ps List running Aspire apphosts.
aspire resources [<resource>] Display resource snapshots from a running Aspire apphost.
aspire logs [<resource>] Display logs from resources in a running Aspire apphost.
aspire add <integration> Add a hosting integration to the Aspire AppHost.
aspire publish Generates deployment artifacts for an Aspire apphost. (Preview)
aspire config Manage configuration settings.
aspire cache Manage disk cache for CLI operations.
aspire doctor Diagnose Aspire environment issues and verify setup.
aspire deploy Deploy the contents of an Aspire apphost to its defined deployment targets. (Preview)
aspire do <step> Execute a specific pipeline step and its dependencies. (Preview)
aspire update Update integrations in the Aspire project. (Preview)
aspire agent Manage AI agent integrations.
aspire telemetry View telemetry data (logs, spans, traces) from a running Aspire application.
aspire docs Browse and search Aspire documentation from aspire.dev. ✅ New

Config Subcommands

Command Description Status
aspire config get <key> Get a configuration value.
aspire config set <key> <value> Set a configuration value.
aspire config list List all configuration values.
aspire config delete <key> Delete a configuration value.

Telemetry Subcommands

Command Description Status
aspire telemetry logs [resource] View structured logs from the Dashboard telemetry API.
aspire telemetry spans [resource] View spans from the Dashboard telemetry API.
aspire telemetry traces [resource] View traces from the Dashboard telemetry API.

Telemetry Options:

  • --format <format> - Output format
  • -n, --limit <n> - Maximum number of items to return
  • --trace-id <id> - Filter by trace ID
  • -f, --follow - Stream telemetry in real-time (logs, spans only)
  • --severity <level> - Filter logs by minimum severity (logs only)
  • --has-error - Filter by error status (spans, traces only)

Docs Subcommands

Command Description Status
aspire docs list List all available Aspire documentation pages. ✅ New
aspire docs search <query> Search Aspire documentation by keywords. ✅ New
aspire docs get <slug> Get the full content of a documentation page by its slug. ✅ New

Remaining Proposed Commands

Command Description Status
aspire wait Wait for resource state (e.g. aspire wait api --state Running --timeout 60) ❌ Proposed
aspire secret Set/get/list parameter values for dev (like dotnet user-secrets but Aspire-aware) ❌ Proposed

aspire secret — Motivation

Today, managing Azure provisioning config (location, subscription, resource group) requires knowing the internal user-secrets ID and using dotnet user-secrets directly:

# Current painful workflow when Azure provisioning fails:
# 1. Find the secrets file manually
find ~/.microsoft/usersecrets -name "*.json" -newer apphost.cs
# 2. Read it to find what's wrong
cat ~/.microsoft/usersecrets/apphost-<hash>/secrets.json
# 3. Fix it with dotnet user-secrets and the full ID
dotnet user-secrets set "Azure:Location" "eastus2" --id apphost-<hash>
# 4. Clear stale state
dotnet user-secrets remove "Azure:ResourceGroup" --id apphost-<hash>
# 5. Restart
aspire stop && aspire run --detach

This should be:

aspire secret set Azure:Location eastus2
aspire secret delete Azure:ResourceGroup
aspire restart openai

Or even simpler with aspire config if it could write to the apphost user-secrets store:

aspire config set Azure:Location eastus2
aspire config delete Azure:ResourceGroup

Proposed Global Flag

--format json for machine-readable output on:

  • aspire ps
  • aspire resources
  • aspire logs
  • aspire telemetry logs ✅ (13.2)
  • aspire telemetry spans ✅ (13.2)
  • aspire telemetry traces ✅ (13.2)
  • aspire doctor
  • aspire command (proposed)
  • aspire docs (proposed)
  • aspire wait (proposed)

Automation Scenarios

Lifecycle & Discovery

Scenario Command
Find where the apphost is running aspire ps --format json
Start the apphost in background aspire run --detach
Stop the apphost aspire stop
Restart a specific resource aspire restart api
Stop a specific resource aspire stop redis

Waiting & Health

Scenario Command
Wait for all resources to be running aspire wait --all --state Running --timeout 120
Wait for specific resource to be healthy aspire wait api --state Healthy --timeout 60
Check if any resources failed aspire resources --format json | jq ".[] | select(.state == \"Failed\")"

Documentation & Learning

Scenario Command
Find docs about a topic aspire docs search "connection strings"
Get full integration guide aspire docs get postgres-integration
List all available docs aspire docs list --format json

Debugging & Tracing

Scenario Command
View distributed traces aspire telemetry traces --format json
Find traces with errors aspire telemetry traces --has-error --format json
Get structured logs correlated to slow trace aspire telemetry logs --trace-id <id> --format json
View structured logs for a resource aspire telemetry logs api --format json
Filter structured logs by level aspire telemetry logs api --severity Error
Stream logs in real-time aspire telemetry logs --follow
Stream spans in real-time aspire telemetry spans --follow
View raw console logs aspire logs api

Parameters & Secrets

Scenario Command
Set a parameter value aspire secret set postgres-password "mysecret"
List configured parameters aspire secret list
Get a parameter value aspire secret get postgres-password

Endpoint Discovery

Scenario Command
Get endpoint URL for a resource aspire resources --format json | jq -r ".[] | select(.name == \"api\") | .endpoints[0].url"
List all running resources aspire resources --format json

Environment Validation

Scenario Command
Validate environment before deploy aspire doctor --format json
Check for doctor failures aspire doctor --format json | jq ".[] | select(.status == \"fail\")"

AI Agent-Led Automation Scenarios

These scenarios enable AI coding agents (Copilot, Claude, etc.) to autonomously diagnose, debug, and fix issues.

Agent: Diagnose Why a Resource Failed

# Agent checks resource state
aspire resources --format json

# Agent sees "api" is in Failed state, gets structured logs
aspire telemetry logs api --severity Error --format json

# Agent analyzes error, identifies missing connection string
# Agent fixes appsettings.json and restarts
aspire restart api
aspire wait api --state Running --timeout 30

Agent: Learn About Aspire Features

# Agent needs to understand health checks
aspire docs search "health checks"

# Agent reads the full documentation
aspire docs get health-checks

# Agent implements health checks based on documentation

Agent: Investigate Slow Endpoint

# Agent finds slow traces
aspire telemetry traces --format json | jq ".[] | select(.durationMs > 1000)"

# Agent gets structured logs correlated to slow trace
aspire telemetry logs --trace-id <id> --format json

# Agent identifies slow database query in logs
# Agent optimizes query and restarts service
aspire restart api

Agent: Validate Fix After Code Change

# Agent made a code change, rebuilds and waits
aspire wait api --state Running --timeout 60

# Agent verifies no errors in structured logs since restart
aspire telemetry logs api --severity Error --format json

# Agent checks endpoint works
curl $(aspire resources --format json | jq -r ".[] | select(.name == \"api\") | .endpoints[0].url")/health

Agent: Root Cause Analysis Across Services

# User reports: "checkout is broken"
# Agent finds traces with errors in checkout flow
aspire telemetry traces --has-error --format json | jq ".[] | select(.resources | contains([\"checkout\"]))"

# Agent gets structured logs for the trace
aspire telemetry logs --trace-id <id> --format json

# Agent sees: checkout -> inventory -> postgres (connection refused)
# Agent checks postgres status
aspire resources --format json | jq ".[] | select(.name == \"postgres\")"

# Agent restarts postgres
aspire restart postgres
aspire wait postgres --state Healthy --timeout 30

Development Scenarios

Debug Why Endpoint Returns 500

# Dev: "GET /orders returns 500, no idea why"

# Agent hits endpoint
curl http://localhost:5000/orders

# Agent finds the trace
aspire telemetry traces --has-error --format json | jq ".[-1]"

# Agent gets correlated logs
aspire telemetry logs --trace-id abc123 --format json
# → NullReferenceException at OrderService.cs:42 - _repository was null

# Agent sees: missing DI registration
# Agent adds services.AddScoped() to Program.cs
aspire restart api

# Agent verifies
curl http://localhost:5000/orders
# → 200 OK

Auto-Fix Database Migration Error

# Agent sees migration failure
aspire telemetry logs api --severity Error --format json
# → "Invalid column name CustomerId"

# Agent checks the model, sees missing migration
# Agent generates migration
dotnet ef migrations add AddCustomerId --project src/Api

# Agent restarts to apply
aspire restart api
aspire wait api --state Healthy

# Agent verifies
aspire telemetry logs api --severity Error --format json  # empty
git add . && git commit -m "Add missing CustomerId migration"

CI Scenarios

Integration Test Gate

# GitHub Actions / Azure Pipelines
- name: Run Aspire App
  run: |
    aspire run --detach --project ./AppHost
    aspire wait --all --state Running --timeout 180

- name: Run Integration Tests
  run: dotnet test ./tests/IntegrationTests

- name: Collect Failure Logs
  if: failure()
  run: |
    aspire telemetry logs --severity Error --format json > error-logs.json
    aspire telemetry traces --has-error --format json > failed-traces.json

- name: Cleanup
  if: always()
  run: aspire stop

Smoke Test on PR

- name: Start App
  run: |
    aspire run --detach
    aspire wait --all --state Running --timeout 120

- name: Smoke Test All Endpoints
  run: |
    aspire resources --format json | jq -r ".[].endpoints[]?.url" | while read url; do
      echo "Testing $url/health"
      curl -sf "$url/health" || exit 1
    done

- name: Check No Startup Errors
  run: |
    ERRORS=$(aspire telemetry logs --severity Error --format json | jq length)
    if [ "$ERRORS" -gt 0 ]; then
      echo "❌ Found $ERRORS startup errors"
      aspire telemetry logs --severity Error --format json
      exit 1
    fi

- name: Cleanup
  if: always()
  run: aspire stop

Impact

These additions enable:

  1. CI/CD automation - Script resource lifecycle, wait for health, gate on failures
  2. CLI-based debugging - Trace requests across services without Dashboard
  3. Headless operation - Full control in SSH/container/remote environments
  4. AI agent workflows - Agents can diagnose, debug, and fix issues autonomously
  5. Integration with tools - Pipe JSON to jq, forward to logging systems, build custom dashboards
  6. Development inner loop - Stay in terminal/editor, no context switching to Dashboard
  7. Documentation access - Query Aspire docs directly from CLI for learning and reference

Metadata

Metadata

Assignees

Labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions