microsoft/aspire · error · McpProtocolException

-32603

-32603

Error message

No Aspire AppHost is currently running. To use Aspire MCP tools, you must first start an Aspire application by running 'aspire start' in your AppHost project directory. Once the application is running, the MCP tools will be able to connect to the dashboard and execute commands.

What it means

Thrown by McpToolHelpers.GetDashboardInfoAsync when no live AppHost connection is available (GetSelectedConnectionAsync returned null); the shared McpErrorMessages.NoAppHostRunning message is thrown as McpProtocolException with McpErrorCode.InternalError (-32603). This helper backs the telemetry tools' dashboard API discovery.

Solutions

  1. Run 'aspire start' in the AppHost project directory, then retry the tool call.
  2. Confirm the AppHost process is alive and restart it if needed.
  3. Reconnect the CLI session so the auxiliary backchannel monitor selects a connection.
  4. Ensure the MCP client and AppHost share the same environment/session.

Example fix

// before: assume dashboard info always available
var (token, baseUrl, _) = await McpToolHelpers.GetDashboardInfoAsync(monitor, logger, ct);
// after: pre-check connection and start app if missing
if (await AppHostConnectionHelper.GetSelectedConnectionAsync(monitor, logger, ct) is null)
{
    throw new InvalidOperationException("Start the AppHost with 'aspire start' before calling telemetry tools.");
}
var (token, baseUrl, _) = await McpToolHelpers.GetDashboardInfoAsync(monitor, logger, ct);
Defensive patterns

Strategy: try-catch

Validate before calling

var connection = await AppHostConnectionHelper.GetSelectedConnectionAsync(monitor, logger, ct);
if (connection is null)
{
    // AppHost not running: require 'aspire start' before dashboard info can be resolved
}

Try / catch

try
{
    var (token, baseUrl, dashboardUrl) = await McpToolHelpers.GetDashboardInfoAsync(monitor, logger, ct);
}
catch (McpProtocolException ex) when (ex.Message.Contains("No Aspire AppHost is currently running"))
{
    // Guide the user to run 'aspire start' in the AppHost project directory
}

Prevention

When it happens

Trigger: Any telemetry MCP tool that calls GetDashboardInfoAsync running without an active 'aspire start' session, after the AppHost exited, or with no backchannel connection selected in the monitor.

Common situations: MCP client started before the app; AppHost crashed or was stopped; session/environment mismatch (different directory, user, or machine); connection dropped and never re-established.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/b27770badbb7c15c. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Cli/Mcp/Tools/McpToolHelpers.cs:24

using System.Web;
using Aspire.Cli.Backchannel;
using Aspire.Dashboard.Model;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using ModelContextProtocol;
using ModelContextProtocol.Protocol;

namespace Aspire.Cli.Mcp.Tools;

internal static class McpToolHelpers
{
    public static async Task<(string apiToken, string apiBaseUrl, string? dashboardBaseUrl)> GetDashboardInfoAsync(IAuxiliaryBackchannelMonitor auxiliaryBackchannelMonitor, ILogger logger, CancellationToken cancellationToken)
    {
        var connection = await AppHostConnectionHelper.GetSelectedConnectionAsync(auxiliaryBackchannelMonitor, logger, cancellationToken).ConfigureAwait(false);
        if (connection is null)
        {
            logger.LogWarning("No Aspire AppHost is currently running");
            throw new McpProtocolException(McpErrorMessages.NoAppHostRunning, McpErrorCode.InternalError);
        }

        var dashboardInfo = await connection.GetDashboardInfoV2Async(cancellationToken).ConfigureAwait(false);
        if (dashboardInfo?.ApiBaseUrl is null || dashboardInfo.ApiToken is null)
        {
            logger.LogWarning("Dashboard API is not available");
            throw new McpProtocolException(McpErrorMessages.DashboardNotAvailable, McpErrorCode.InternalError);
        }

        var apiBaseUrl = NormalizeDashboardUrl(dashboardInfo.ApiBaseUrl);
        var dashboardBaseUrl = StripLoginPath(dashboardInfo.DashboardUrls.FirstOrDefault());

        return (dashboardInfo.ApiToken, apiBaseUrl, dashboardBaseUrl);
    }

    /// <summary>
    /// Strips the <c>/login</c> path segment (and any query string) from a dashboard URL
    /// returned by the AppHost. Other path segments are preserved.

View on GitHub (pinned to 25830f84bd)