microsoft/aspire · error · InvalidOperationException
MCP tool ' ' must resolve to a Foundry-reachable absolute…
Error message
MCP tool '{Name}' must resolve to a Foundry-reachable absolute HTTPS endpoint. What it means
After resolving to a non-empty string, the endpoint must be an absolute URI that IsFoundryReachableHttpsEndpoint accepts: https scheme, no user info, non-loopback, and not localhost/.localhost. Microsoft Foundry cannot reach a developer-local server, so the integration rejects such endpoints with this InvalidOperationException before building the MCP wire JSON.
Solutions
- Deploy or host the MCP server at a publicly reachable HTTPS URL and use that as the endpoint.
- Change the scheme to https and remove any user info from the URL.
- Verify the string is a full absolute URI (e.g. https://host/mcp), not a relative path or bare hostname.
- For local testing, use a tunnel (dev tunnels/ngrok) that exposes a public HTTPS URL.
Example fix
// before ReferenceExpression.Create($"http://localhost:8080/mcp") // after ReferenceExpression.Create($"https://my-mcp.example.com/mcp")
Defensive patterns
Strategy: validation
Validate before calling
if (Uri.TryCreate(endpoint, UriKind.Absolute, out var uri)
&& uri.Scheme == Uri.UriSchemeHttps
&& string.IsNullOrEmpty(uri.UserInfo)
&& !uri.IsLoopback
&& !uri.Host.EndsWith("localhost", StringComparison.OrdinalIgnoreCase))
{ /* endpoint is Foundry-reachable */ } Type guard
static bool IsFoundryReachable(Uri u) =>
u.Scheme == Uri.UriSchemeHttps && string.IsNullOrEmpty(u.UserInfo) &&
!u.IsLoopback && !u.Host.TrimEnd('.').EndsWith("localhost", StringComparison.OrdinalIgnoreCase); Try / catch
try { await definition.ResolveAsync(ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Foundry-reachable absolute HTTPS endpoint"))
{ logger.LogError("Endpoint '{Endpoint}' must be a public absolute HTTPS URL.", endpoint); } Prevention
- Always use https:// and full absolute URLs for MCP servers
- Never point Foundry tools at localhost — use a public tunnel for local dev
- Strip credentials from URLs; Foundry does not accept user info in the endpoint
When it happens
Trigger: Passing an http:// URL, a relative or malformed URI, a URL with embedded user:password, or a http://localhost / 127.0.0.1 / *.localhost endpoint to FoundryToolboxMcpToolDefinition.
Common situations: Pointing the MCP tool at a locally running MCP server during development; forgetting the 's' in https; supplying a path-only string like 'myserver/mcp' instead of a full absolute URL; credentials embedded in the URL.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- A global MCP approval policy cannot be combined with custom…
- An MCP approval filter must specify at least one tool name…
- An MCP approval policy must specify a global mode or at…
- MCP tool ' ' does not have a resolvable endpoint URI.
- MCP tool ' ' cannot both always and never require approval.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/8ef8f73bf45f1f7f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Foundry/Toolbox/FoundryToolboxToolDefinition.cs:156
public string ServerLabel { get; }
public string? ServerDescription { get; }
internal ResolvedFoundryToolboxMcpApprovalPolicy? ApprovalPolicy { get; }
internal override async ValueTask<ResolvedFoundryToolboxTool> ResolveAsync(CancellationToken cancellationToken)
{
var endpoint = await EndpointExpression.GetValueAsync(cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(endpoint))
{
throw new InvalidOperationException(
$"MCP tool '{Name}' does not have a resolvable endpoint URI.");
}
if (!Uri.TryCreate(endpoint, UriKind.Absolute, out var endpointUri) ||
!IsFoundryReachableHttpsEndpoint(endpointUri))
{
throw new InvalidOperationException(
$"MCP tool '{Name}' must resolve to a Foundry-reachable absolute HTTPS endpoint.");
}
// Build the OpenAI Responses "mcp" tool wire JSON by hand and read it back as a
// ProjectsAgentTool. See the comment on FoundryToolboxWebSearchToolDefinition for the
// underlying cross-ALC System.ClientModel version mismatch that makes the natural
// `ResponseTool.CreateMcpTool(...).AsAgentTool()` round-trip throw in the polyglot
// (e.g. JavaScript/TypeScript) AppHostServer host process. Constructing the JSON
// ourselves keeps everything inside types that are consistent across the integration's
// ALC (BCL + Azure.AI.Projects.Agents + that ALC's copy of System.ClientModel).
//
// OpenAI Responses "mcp" tool wire shape:
// {
// "type": "mcp",
// "server_label": "<required>",
// "server_url": "<absolute uri>" // required for hosted MCP
// }
// See https://platform.openai.com/docs/api-reference/responses/create#responses-create-toolsView on GitHub (pinned to 25830f84bd)