diff --git a/src/frontend/src/content/docs/dashboard/explore.mdx b/src/frontend/src/content/docs/dashboard/explore.mdx
index e008f263a..3d0dcf648 100644
--- a/src/frontend/src/content/docs/dashboard/explore.mdx
+++ b/src/frontend/src/content/docs/dashboard/explore.mdx
@@ -579,13 +579,15 @@ Selecting **View response** opens the text visualizer with the command's result
+Markdown command results render as formatted Markdown in the text visualizer (for example, headings and tables), not as raw markdown source.
+
The unread count resets when you open the notification center. To clear all notifications, select the **Dismiss all** button in the dialog.
-For information on returning messages from custom commands, see [Custom resource commands](/fundamentals/custom-resource-commands/).
+For information on returning command result payloads from custom commands, see [Custom resource commands](/fundamentals/custom-resource-commands/).
## Settings dialog
diff --git a/src/frontend/src/content/docs/fundamentals/custom-resource-commands.mdx b/src/frontend/src/content/docs/fundamentals/custom-resource-commands.mdx
index cbd95af11..628490680 100644
--- a/src/frontend/src/content/docs/fundamentals/custom-resource-commands.mdx
+++ b/src/frontend/src/content/docs/fundamentals/custom-resource-commands.mdx
@@ -676,7 +676,7 @@ return { success: false, message: err instanceof Error ? err.message : String(er
-## Return structured output from a command
+## Returning a result from a command
Resource commands can return a structured payload — plain text, JSON, or Markdown — alongside the success/failure signal. The payload flows automatically through the entire Aspire pipeline:
@@ -826,6 +826,47 @@ await builder.build().run();
+### Return Markdown
+
+When a command needs rich output (for example headings, tables, and lists), return `CommandResultData` with `Format = CommandResultFormat.Markdown`:
+
+```csharp title="C# — AppHost.cs"
+builder
+ .AddProject("myservice")
+ .WithCommand(
+ name: "migrate-database",
+ displayName: "Migrate Database",
+ executeCommand: _ =>
+ {
+ var markdown = """
+ # ⚙️ Database Migration Summary
+
+ | Table | Result |
+ |------------|----------------------------|
+ | Customers | ✅ 1,200 rows |
+ | Products | ✅ 850 rows |
+ | Orders | ✅ 3,400 rows |
+ | OrderItems | ✅ 8,750 rows |
+ | Categories | ✅ 45 rows |
+ | Reviews | ❌ FK constraint violation |
+ | Inventory | ✅ 850 rows |
+ | Shipping | ✅ 3,400 rows |
+ | Payments | ❌ Timeout after 30s |
+ | Coupons | ✅ 120 rows |
+
+ **Summary:** 8 of 10 tables migrated successfully. 2 tables failed.
+ """;
+
+ return Task.FromResult(CommandResults.Success(
+ "Database migrated.",
+ new CommandResultData
+ {
+ Value = markdown,
+ Format = CommandResultFormat.Markdown,
+ }));
+ });
+```
+
### Choose a result format
`CommandResultFormat` has three values:
diff --git a/src/frontend/src/content/docs/whats-new/aspire-13-3.mdx b/src/frontend/src/content/docs/whats-new/aspire-13-3.mdx
index 74ceb4594..a767d314d 100644
--- a/src/frontend/src/content/docs/whats-new/aspire-13-3.mdx
+++ b/src/frontend/src/content/docs/whats-new/aspire-13-3.mdx
@@ -521,7 +521,7 @@ await builder.build().run();
### Resource commands return structured results
-Custom resource commands can now return an `ExecuteCommandResult` with a structured `Message` payload that the dashboard renders in the notification center. The new `Logger` property on `ExecuteCommandContext` lets command implementations log directly to the resource's log stream.
+Custom resource commands can now return an `ExecuteCommandResult` with structured `Data` payloads (`Text`, `Json`, or `Markdown`) that the dashboard renders from the notification center's **View response** action. The `CommandResults.Success(string, CommandResultData)` overload also makes it easy to return markdown tables and other rich output from a command. The new `Logger` property on `ExecuteCommandContext` lets command implementations log directly to the resource's log stream.