A setup tool to finalize .NET Aspire configuration after initial project scaffolding.

Install

mkdir -p .claude/skills/aspireify && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10799" && unzip -o skill.zip -d .claude/skills/aspireify && rm skill.zip

Installs to .claude/skills/aspireify

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

One-time skill for completing Aspire initialization in an existing app after `aspire init` has dropped the skeleton AppHost. Use this skill when an `aspire.config.json` exists but the AppHost has not yet been wired up.
218 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Wire up AppHost
  • Map environment variables
  • Configure project ports
  • Integrate OTel

How it works

It completes the initialization of Aspire by mapping existing service configurations to the AppHost without restructuring the project.

Inputs & outputs

You give it
existing application configuration
You get back
integrated Aspire AppHost

When to use aspireify

  • Complete Aspire initialization
  • Configure AppHost for services
  • Map existing docker-compose settings

About this skill

Aspireify

This is a one-time setup skill. It completes the Aspire initialization that aspire init started. After this skill finishes successfully, the evergreen aspire skill handles ongoing AppHost work. Do not delete this skill unless the user explicitly asks.

Keep this as one skill with context-specific references. Load the reference files that match the repo you discover instead of trying to keep every edge case in the main document.

Guiding principles

Minimize changes to the user's code

The default stance is adapt the AppHost to fit the app, not the other way around. The user's services already work — the goal is to model them in Aspire without breaking anything.

  • Prefer WithEnvironment() to match existing env var names over asking users to rename vars in their code
  • Prefer Aspire-managed ports (WithHttpsEndpoint(env: "PORT"), WithHttpEndpoint(env: "PORT"), or no explicit port when supported) over fixed ports
  • Only preserve a specific port when the user confirms it is actually significant (for example: external callbacks, OAuth redirect URIs, browser extensions, webhooks, or a repo-documented hard requirement)
  • Map existing docker-compose.yml config 1:1 before optimizing
  • Don't restructure project directories, rename files, or change build scripts

Surface tradeoffs, don't decide silently

Sometimes a small code change unlocks significantly better Aspire integration. When this happens, present the tradeoff to the user and let them decide. Examples:

  • Connection strings: A service reads DATABASE_URL but Aspire injects ConnectionStrings__mydb. You can use WithEnvironment("DATABASE_URL", db.Resource.ConnectionStringExpression) (zero code change) or suggest the service reads from config so WithReference(db) just works (enables service discovery, health checks, auto-retry). → Ask: "Your API reads DATABASE_URL. I can map that with WithEnvironment (no code change) or you could switch to reading ConnectionStrings:mydb which unlocks WithReference and automatic service discovery. Which do you prefer?"

  • Port binding: A service hardcodes PORT=3000. You can preserve that with WithHttpsEndpoint(port: 3000) (zero code change) or switch the service to read PORT from env so Aspire can manage ports dynamically and avoid conflicts. → Ask: "Your frontend is currently fixed to port 3000. Unless that exact port is important for something external, I recommend switching it to read PORT from env so Aspire can manage the port and avoid conflicts. If you need 3000 to stay stable, I can preserve it. Which do you want?"

  • OTel setup: Service has its own tracing config pointing to Jaeger. You can leave it (Aspire won't show its traces) or suggest switching the exporter to read OTEL_EXPORTER_OTLP_ENDPOINT (which Aspire injects). → Ask: "Your API exports traces to Jaeger directly. I can leave that, or switch it to use the OTEL_EXPORTER_OTLP_ENDPOINT env var so traces show up in the Aspire dashboard. The Jaeger endpoint would still work in non-Aspire environments. Want me to update it?"

Format for presenting tradeoffs:

  1. Explain what the current code does
  2. Show the zero-change option and what it gives you
  3. Show the small-change option and the extra benefits
  4. Ask which they prefer
  5. If they decline the change, implement the zero-change option without complaint

When in doubt, ask

If you're unsure whether something is a service, whether two services depend on each other, whether a port is truly significant, or whether a Docker Compose service should be modeled — ask. Don't guess at architectural intent.

Always use latest Aspire APIs — verify before you write

Do not assume APIs exist. Before writing any AppHost code, look up the correct API using aspire docs search and aspire docs get. Follow the tiered preference: Tier 1 (first-party Aspire.Hosting.*) → Tier 2 (community CommunityToolkit.Aspire.Hosting.*) → Tier 3 (raw AddExecutable/AddDockerfile/AddContainer). See the "Looking up APIs and integrations" section below for full discovery workflow, tier details, and auto-managed values.

Don't invent APIs — if docs search and integration list don't return it, it doesn't exist. Fall back to Tier 3. API shapes differ between C# and TypeScript — always check the correct language docs.

Choosing the right JavaScript resource type

For JavaScript/TypeScript apps, pick the right resource type (AddViteApp, AddNodeApp, or AddJavaScriptApp) and configure dev scripts and port binding. See references/javascript-apps.md for the selection table, dev script patterns, framework-specific port binding, and browser suppression.

Never call it ".NET Aspire"

Always refer to the product as just Aspire, never ".NET Aspire". This applies to all comments in generated AppHost code, messages to the user, and any documentation you produce.

Dashboard URL must include auth token

When printing or displaying the Aspire dashboard URL to the user, always include the full login token query parameter. The dashboard requires authentication — a bare URL like http://localhost:18888 won't work. Use the full URL as printed by aspire start (e.g., http://localhost:18888/login?t=<token>).

Redis and auto-TLS

Aspire's infrastructure automatically provisions TLS certificates for container resources that register WithHttpsCertificateConfiguration callbacks. AddRedis() registers one by default, which means Redis will get TLS automatically when the Aspire dev cert infrastructure is active. This is usually fine, but some apps expect plain (non-TLS) Redis.

If Redis health checks fail with SslStream / RedisConnectionException errors about SSL/TLS handshake failures, the cause is this auto-TLS behavior. Do not fall back to AddContainer(). Instead, disable the certificate on the Redis resource:

var redis = builder.AddRedis("redis")
    .WithoutHttpsCertificate();  // plain Redis, no TLS

WithoutHttpsCertificate() suppresses the auto-TLS cert injection so Redis stays on plain TCP. Use this when the consuming services don't support TLS Redis connections.

Prefer HTTPS over HTTP

Always set up HTTPS endpoints by default. Use WithHttpsEndpoint() instead of WithHttpEndpoint() unless HTTPS doesn't work for a specific integration. For JavaScript and Python apps, call WithHttpsDeveloperCertificate() to configure the dev cert. If HTTPS causes issues for a specific resource, fall back to HTTP and leave a comment explaining why. See the "Endpoints and ports" section in the AppHost wiring reference below for detailed patterns and examples.

Never hardcode URLs — use endpoint references

When a service needs another service's URL as an environment variable, always pass an endpoint reference — never a hardcoded string. Hardcoded URLs break whenever Aspire assigns different ports. See the "Cross-service environment variable wiring" section in the AppHost wiring reference below for examples.

Similarly, never use withUrlForEndpoint / WithUrlForEndpoint to set dev.localhost URLs. That API is ONLY for setting display labels in the dashboard (e.g., url.DisplayText = "Web UI"). dev.localhost configuration belongs in aspire.config.json profiles — see Step 9.

Optimize for local dev, not deployment

This skill is about getting a great local development experience. Don't worry about production deployment manifests, cloud provisioning, or publish configuration — that's a separate concern for later.

This means:

  • Prefer ContainerLifetime.Persistent for databases and caches so data survives AppHost restarts
  • Use WithDataVolume() to persist data across container recreations
  • Cookie and session isolation with *.dev.localhost subdomains is encouraged
  • Don't add production health check probes, scaling config, or cloud resource definitions
  • If services reference external third-party APIs/services (e.g., a hardcoded Stripe URL, an external database host, a SaaS webhook endpoint), consider modeling those as parameters or connection strings in the AppHost so they're visible and configurable from one place:
// Instead of the service hardcoding "https://api.stripe.com"
var stripeUrl = builder.AddParameter("stripe-url", secret: false);
var api = builder.AddCSharpApp("api", "../src/Api")
    .WithEnvironment("STRIPE_API_URL", stripeUrl);

This makes the external dependency visible in the dashboard and lets developers easily swap endpoints (e.g., to a Stripe test endpoint) without digging through service code. Present this as an option to the user — don't silently refactor their external service calls.

Migrate .env files into AppHost parameters

Many projects use .env files for configuration. These should be migrated into the AppHost so that all config is centralized and visible in the dashboard. Scan for .env, .env.local, .env.development, etc. and propose migrating their contents:

  • Secrets (API keys, tokens, passwords, connection strings): use AddParameter(name, secret: true). Aspire stores these securely via user secrets and prompts the developer to set them.
  • Non-secret config (feature flags, URLs, mode settings): use AddParameter(name, secret: false) with a default value, or WithEnvironment() directly.
  • Values that map to Aspire resources (e.g., DATABASE_URL=postgres://..., REDIS_URL=redis://...): replace with actual Aspire resources (AddPostgres, AddRedis) and WithReference() — the connection string is then managed by Aspire.
// Before: .env file with DATABASE_URL=postgres://user:pass@localhost:5432/mydb
//         STRIPE_KEY=sk_test_abc123
//         DEBUG=true

// After: modeled in AppHost
var db = builder.AddPostgres("pg").AddDatabase("mydb");
var stripeKey = builder.AddParameter("stripe-key", secret: true);

var api = builder.AddCSharpApp("api", "../

---

*Content truncated.*

When not to use it

  • New projects without existing AppHost skeleton

Prerequisites

aspire.config.json

Limitations

  • One-time setup skill

How it compares

It adapts the AppHost to existing application logic rather than requiring the user to refactor their code to fit Aspire.

Compared to similar skills

aspireify side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
aspireify (this skill)02moCautionIntermediate
aspire03moReviewAdvanced
csharp-developer432moNo flagsAdvanced
csharp-pro94moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

aspire

davidortinau

**WORKFLOW SKILL** - Orchestrates Aspire applications using the Aspire CLI and MCP tools for running, debugging, deploying, and managing distributed apps. USE FOR: aspire run, aspire stop, aspire deploy, start aspire app, aspire describe, list aspire integrations, debug aspire issues, view aspire lo

00

csharp-developer

zenobi-us

Expert C# developer specializing in modern .NET development, ASP.NET Core, and cloud-native applications. Masters C# 12 features, Blazor, and cross-platform development with emphasis on performance and clean architecture.

43151

csharp-pro

sickn33

Write modern C# code with advanced features like records, pattern matching, and async/await. Optimizes .NET applications, implements enterprise patterns, and ensures comprehensive testing. Use PROACTIVELY for C# refactoring, performance optimization, or complex .NET solutions.

953

dotnet-architect

sickn33

Expert .NET backend architect specializing in C#, ASP.NET Core, Entity Framework, Dapper, and enterprise application patterns. Masters async/await, dependency injection, caching strategies, and performance optimization. Use PROACTIVELY for .NET API development, code review, or architecture decisions.

1241

nuget-manager

github

Manage NuGet packages in .NET projects/solutions. Use this skill when adding, removing, or updating NuGet package versions. It enforces using `dotnet` CLI for package management and provides strict procedures for direct file edits only when updating versions.

540

dotnet-backend-patterns

wshobson

Master C#/.NET backend development patterns for building robust APIs, MCP servers, and enterprise applications. Covers async/await, dependency injection, Entity Framework Core, Dapper, configuration, caching, and testing with xUnit. Use when developing .NET backends, reviewing C# code, or designing API architectures.

722

Search skills

Search the agent skills registry