{"id":337,"date":"2026-04-02T10:00:00","date_gmt":"2026-04-02T17:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/aspire\/?p=337"},"modified":"2026-04-01T14:51:06","modified_gmt":"2026-04-01T21:51:06","slug":"aspire-docs-in-your-terminal","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/aspire\/aspire-docs-in-your-terminal\/","title":{"rendered":"Aspire Docs in Your Terminal (and Your AI&#8217;s Brain)"},"content":{"rendered":"<p>You&#8217;re three files deep in your Aspire AppHost, and you need to remember exactly which parameters the Redis integration expects. You could alt-tab to your browser, hunt through <a href=\"https:\/\/aspire.dev\">aspire.dev<\/a>, squint at the API docs, then come back. Or you could just run a command. Or\u2014better yet\u2014let your AI agent look it up for you without you even thinking about it.<\/p>\n<p>Aspire 13.2 ships with <code>aspire docs<\/code>\u2014a set of CLI commands for browsing, searching, and reading official Aspire documentation without leaving your terminal. And because the CLI is just a thin layer over Aspire&#8217;s documentation services, the same source of truth is available to humans, AI skills, and automation. This isn&#8217;t a fragmented snapshot or a crudely scraped copy. It&#8217;s the real documentation from aspire.dev, exposed in a way both people and tools can use.<\/p>\n<h2>\ud83e\udd16 Skill-friendly, human-friendly<\/h2>\n<p>Let&#8217;s be real about what&#8217;s happening here. Modern AI tooling works best when it can stop improvising and start looking things up. That might mean a repo skill, a local agent workflow, a custom automation step, or just you running a CLI command yourself. Different wrappers, same goal: get the model to read the docs instead of guessing.<\/p>\n<p>AI agents were <em>terrible<\/em> at helping developers build Aspire apps. They&#8217;d recommend <code>dotnet run<\/code> instead of <code>aspire run<\/code>, reference learn.microsoft.com for docs that live on aspire.dev, suggest outdated NuGet packages, and\u2014my personal favorite\u2014hallucinate APIs that don&#8217;t exist. Why? Because Aspire was .NET specific far longer than polyglot and LLMs are working off training data that predates our latest features. The AI was confidently wrong, which is arguably worse than being obviously wrong. (At least when it&#8217;s obviously wrong, you know to ignore it.)<\/p>\n<p>The documentation tooling fixes that. When your assistant can call <code>list_docs<\/code>, <code>search_docs<\/code>, and <code>get_doc<\/code>\u2014whether through a skill, a local tool integration, or a simple CLI wrapper\u2014it stops guessing and starts referencing actual, current documentation from aspire.dev. The important part isn&#8217;t the transport. It&#8217;s that every workflow can reach the same current docs instead of relying on stale training data. It&#8217;s like giving every AI in your stack a cheat sheet\u2014 except it&#8217;s not cheating, it&#8217;s just&#8230; reading the docs. (Revolutionary concept, I know \ud83e\udd23.)<\/p>\n<p>For the full backstory on how the docs tooling came together\u2014the conversation with David Fowler, the <code>plan-spec-spike-it<\/code> branch, the weighted lexical search architecture, and the <code>llms.txt<\/code> foundation\u2014check out my post on <a href=\"https:\/\/davidpine.dev\/posts\/aspire-docs-mcp-tools\/\">how I taught AI to read Aspire docs<\/a>. It&#8217;s a fun read, I promise.<\/p>\n<p>But the architecture had a happy side effect: because we built reusable services (<code>IDocsIndexService<\/code>, <code>IDocsSearchService<\/code>, <code>IDocsFetcher<\/code>, <code>IDocsCache<\/code>) rather than a one-off integration, we could expose the same search engine through a CLI and make it easy for skills and automation to build on top of it. And that&#8217;s what this post is about.<\/p>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>Tip<\/strong><\/p> If your editor or agent platform supports repo skills or local tool integrations, wrap <code>aspire docs list<\/code>, <code>aspire docs search<\/code>, and <code>aspire docs get<\/code> in a small skill so your assistant can pull official Aspire guidance on demand. The key idea is simple: point your AI tooling at the CLI instead of hoping the model memorized the latest docs. <\/div><\/p>\n<h2>\ud83d\udcbb The <code>aspire docs<\/code> CLI: because humans deserve nice things too<\/h2>\n<p>The <code>aspire docs<\/code> command gives you\u2014the actual human developer\u2014direct access to the same documentation index that powers your AI agent. No browser, no context-switching, just docs in your terminal. Think of it as the human-friendly interface to the same search engine. Same source, same results, different consumer.<\/p>\n<h3>\ud83d\udccb List all documentation pages<\/h3>\n<pre><code class=\"language-bash\">aspire docs list<\/code><\/pre>\n<p>Returns every documentation page available on aspire.dev. Human-readable by default:<\/p>\n<pre><code class=\"language-text\">\u2714\ufe0f Found 264 documentation pages.\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Title                            \u2502 Slug                             \u2502 Summary                          \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Certificate configuration        \u2502 certificate-configuration        \u2502 Learn how to configure HTTPS     \u2502\n\u2502                                  \u2502                                  \u2502 endpoints and certificate trust  \u2502\n\u2502                                  \u2502                                  \u2502 for resources in Aspire.         \u2502\n\u2502 AppHost configuration            \u2502 apphost-configuration            \u2502 Learn about the Aspire AppHost   \u2502\n\u2502                                  \u2502                                  \u2502 configuration options.           \u2502\n\u2502 Docker Compose to Aspire AppHost \u2502 docker-compose-to-aspire-apphost \u2502 Quick reference for converting   \u2502\n\u2502                                  \u2502                                  \u2502 Docker Compose YAML to Aspire.   \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n  ... remaining 261 pages omitted for brevity.<\/code><\/pre>\n<p>Need structured output for scripting? (Or feeding into other tools?)<\/p>\n<pre><code class=\"language-bash\">aspire docs list --format Json<\/code><\/pre>\n<p>JSON array with slug, title, and summary for each page. Useful if you&#8217;re building a local docs indexer or piping results to <code>jq<\/code> for filtering.<\/p>\n<h3>\ud83d\udd0d Search for a topic<\/h3>\n<pre><code class=\"language-bash\">aspire docs search \"redis\"<\/code><\/pre>\n<p>This searches both page titles and content. Results are ranked by relevance using the same weighted scoring that powers Aspire&#8217;s documentation tooling:<\/p>\n<pre><code class=\"language-text\">\u2714\ufe0f Found 5 results for 'redis'.\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Title                             \u2502 Slug                              \u2502 Section                                     \u2502 Score  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 Redis integration                 \u2502 redis-integration                 \u2502 Hosting integration                         \u2502 351.75 \u2502\n\u2502 Azure Cache for Redis integration \u2502 azure-cache-for-redis-integration \u2502 Hosting integration                         \u2502 319.25 \u2502\n\u2502 Redis Distributed Caching         \u2502 redis-distributed-caching         \u2502 Hosting integration                         \u2502 186.25 \u2502\n\u2502 Redis Output Caching              \u2502 redis-output-caching              \u2502 Hosting integration                         \u2502 186.25 \u2502\n\u2502 Examples                          \u2502 examples                          \u2502 Example: Derived Container Resource (Redis) \u2502 128.75 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/code><\/pre>\n<p>Control result count with <code>--limit<\/code>:<\/p>\n<pre><code class=\"language-bash\">aspire docs search \"integration\" --limit 5<\/code><\/pre>\n<p>And yes, <code>--format Json<\/code> gives you structured output with relevance scoring. Perfect for scripting or feeding results into downstream tools.<\/p>\n<h3>\ud83d\udcd6 Read a full page<\/h3>\n<pre><code class=\"language-bash\">aspire docs get redis-integration<\/code><\/pre>\n<p>Streams the full page content to your terminal\u2014markdown-formatted, ready to read. No browser, no rendering overhead. Just text. (Remember text? It&#8217;s what we used before everything needed a JavaScript framework to render.)<\/p>\n<h3>\ud83d\udcd1 Read a specific section<\/h3>\n<p>Not all documentation pages are short. Sometimes you only need one section:<\/p>\n<pre><code class=\"language-bash\">aspire docs get redis-integration --section \"Add Redis resource\"<\/code><\/pre>\n<p>Returns just that section. Invaluable when you&#8217;re looking for a quick API example without scrolling through 500 lines of documentation. Surgical precision.<\/p>\n<h2>\ud83d\udd27 Real scenarios: when you&#8217;d actually use this<\/h2>\n<h3>Scenario 1: Skill-assisted Aspire development<\/h3>\n<p>You&#8217;re building an Aspire app in VS Code with a repo skill or local tool integration configured. You ask your AI assistant: &#8220;Add a PostgreSQL database to my AppHost.&#8221; Instead of hallucinating an API, the assistant runs <code>aspire docs search \"postgres\"<\/code>, finds the official integration docs, then reads the right page and gives you the documented approach.<\/p>\n<p>No alt-tabbing. No second-guessing. No &#8220;wait, is that a real API?&#8221; The AI agent does the doc lookup for you, transparently, in real-time. That&#8217;s the whole point. You didn&#8217;t even have to think about it\u2014the agent just <em>knew<\/em> where to look. (Because we told it. You&#8217;re welcome.)<\/p>\n<h3>Scenario 2: Quick terminal lookups (for the humans)<\/h3>\n<p>You&#8217;re three files deep in your AppHost and need to remember which parameters the Redis integration expects. You <em>could<\/em> alt-tab to your browser, hunt through aspire.dev, squint at the docs, then come back. Or:<\/p>\n<pre><code class=\"language-bash\">aspire docs search \"redis\" --limit 1\naspire docs get redis-integration --section \"Configuration\"<\/code><\/pre>\n<p>Ninety seconds, you have the answer. You never left your terminal. Context preserved. Flow maintained. Chef&#8217;s kiss \ud83e\udd0c.<\/p>\n<h3>Scenario 3: Feeding docs to custom skills and AI pipelines<\/h3>\n<p>Building your own AI tooling on top of Aspire? Maybe a repo skill, an Agent Framework agent, or a custom workflow? Pipe the structured output directly:<\/p>\n<pre><code class=\"language-bash\">aspire docs get redis-integration --format Json | jq '.content' | xclip<\/code><\/pre>\n<p>Full Redis documentation in your clipboard, ready to paste into an AI chat or add to a prompt context. Or build a custom tool that indexes Aspire docs into your own knowledge base:<\/p>\n<pre><code class=\"language-bash\">aspire docs search \"monitoring\" --format Json | jq '[.[] | {slug, title, summary}]'<\/code><\/pre>\n<p>Structured, machine-readable doc metadata in seconds. No web scraping, no API keys, no nonsense. The JSON output is the same structured data the docs tooling uses internally\u2014same source, different plumbing.<\/p>\n<h3>Scenario 4: CI\/CD documentation validation<\/h3>\n<p>Your CI pipeline runs checks on your Aspire AppHosts. You could add a step that validates integrations against the official documentation:<\/p>\n<pre><code class=\"language-bash\">#!\/bin\/bash\nREDIS_DOCS=$(aspire docs get redis-integration --format Json)\n\n# Extract configuration requirements from docs\nREQUIRED_CONFIG=$(echo \"$REDIS_DOCS\" | jq -r '.required_fields[]')\n\n# Validate your AppHost defines them\nfor field in $REQUIRED_CONFIG; do\n  grep -q \"\\\"$field\\\"\" apphost.csproj || echo \"Missing: $field\"\ndone<\/code><\/pre>\n<p>Trivial example, but the pattern is powerful. Your CI now has access to the source of truth for Aspire integrations, programmatically. No stale documentation snapshots. No &#8220;but the wiki said&#8230;&#8221; excuses.<\/p>\n<h2>\ud83d\udcca Output formats: human and machine<\/h2>\n<p>Every command supports two output formats, because not all consumers have eyeballs:<\/p>\n<p><strong>Default (human-readable):<\/strong> Clean markdown, formatted for terminal reading. Colors and wrapping controlled by your terminal.<\/p>\n<pre><code class=\"language-bash\">aspire docs get redis-integration<\/code><\/pre>\n<p><strong>JSON (machine-readable):<\/strong> Structured JSON with metadata\u2014full page content, section structure, and related links.<\/p>\n<pre><code class=\"language-bash\">aspire docs get redis-integration --format Json<\/code><\/pre>\n<p>The JSON output makes it trivial to build custom documentation tools, indexers, or knowledge bases on top of Aspire&#8217;s official docs. Same data, different interface.<\/p>\n<p><div class=\"alert alert-success\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Lightbulb\"><\/i><strong>Tip<\/strong><\/p> The documentation is always live. The moment aspire.dev updates, the CLI and any skill or automation built on top of it can reflect that. You&#8217;re not downloading a snapshot\u2014you&#8217;re querying the real documentation source with ETag-based caching for performance. <\/div><\/p>\n<h2>\ud83c\udf89 The bottom line<\/h2>\n<p>The documentation tooling in Aspire 13.2 fixes a real, painful problem: humans and AI assistants both need current, official guidance, and browser tabs plus stale model memory are a lousy way to get it. By putting Aspire docs behind a simple CLI and reusable tools, we turned the docs into something you can use directly in your terminal or plug into skills and automation. Same index, same search, same source of truth.<\/p>\n<p>Like I mentioned earlier, if you want the deep dive on the architecture go read <a href=\"https:\/\/davidpine.dev\/posts\/aspire-docs-mcp-tools\/\">how I taught AI to read Aspire docs<\/a>. It covers the full story.<\/p>\n<p>Get started by trying the CLI directly, then wire it into whatever skill or automation setup you already use:<\/p>\n<pre><code class=\"language-bash\">aspire docs search \"your-topic-here\"<\/code><\/pre>\n<p>That&#8217;s all it takes. Now go build something cool\u2014and give your tools the docs while you&#8217;re at it. \ud83d\ude80<\/p>\n<h2>Get involved<\/h2>\n<ul>\n<li><strong>\ud83d\udcd6 Learn more:<\/strong> Read the full documentation on <a href=\"https:\/\/aspire.dev\/reference\/cli\/commands\/aspire-docs\/\">Aspire CLI documentation commands<\/a> at aspire.dev.<\/li>\n<li><strong>\ud83d\udcac Give us feedback:<\/strong> We&#8217;d love to hear what you think\u2014file issues or join discussions on the <a href=\"https:\/\/github.com\/dotnet\/aspire\">Aspire GitHub repo<\/a>.<\/li>\n<li><strong>\ud83c\udf10 Join the community:<\/strong> Follow us and connect with other Aspire developers at <a href=\"https:\/\/aspire.dev\/community\/\">aspire.dev\/community<\/a>.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Aspire 13.2 ships aspire docs, a CLI for browsing, searching, and reading official aspire.dev docs from your terminal, with the same source of truth available to AI skills and automation.<\/p>\n","protected":false},"author":24662,"featured_media":338,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[20,1,17],"tags":[8,9,10,58],"class_list":["post-337","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-aspire-category","category-deep-dives","tag-ai","tag-aspire","tag-cli","tag-skills"],"acf":[],"blog_post_summary":"<p>Aspire 13.2 ships aspire docs, a CLI for browsing, searching, and reading official aspire.dev docs from your terminal, with the same source of truth available to AI skills and automation.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts\/337","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/users\/24662"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/comments?post=337"}],"version-history":[{"count":2,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts\/337\/revisions"}],"predecessor-version":[{"id":340,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts\/337\/revisions\/340"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/media\/338"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/media?parent=337"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/categories?post=337"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/tags?post=337"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}