Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions Web/Resgrid.Web.Mcp/Controllers/HealthController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Resgrid.Config;
using Resgrid.Web.Mcp.Infrastructure;
using Resgrid.Web.Mcp.Models;

namespace Resgrid.Web.Mcp.Controllers
{
/// <summary>
/// Health Check system to get information and health status of the MCP Server
/// </summary>
[AllowAnonymous]
[Route("health")]
public sealed class HealthController : Controller
{
private readonly McpToolRegistry _toolRegistry;
private readonly IResponseCache _responseCache;

public HealthController(
McpToolRegistry toolRegistry,
IResponseCache responseCache)
{
_toolRegistry = toolRegistry;
_responseCache = responseCache;
}

/// <summary>
/// Gets the current health status of the MCP Server
/// </summary>
/// <returns>HealthResult object with the server health status</returns>
[HttpGet("current")]
public IActionResult GetCurrent()
{
var result = new HealthResult
{
ServerVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "Unknown",
ServerName = McpConfig.ServerName ?? "Resgrid MCP Server",
SiteId = "0",
ToolCount = _toolRegistry.GetToolCount(),
ServerRunning = true
};

// Check cache connectivity
try
{
result.CacheOnline = _responseCache != null;
}
catch
{
result.CacheOnline = false;
}

// Check API connectivity
try
{
// Simple ping to the API to check connectivity
var apiBaseUrl = SystemBehaviorConfig.ResgridApiBaseUrl;
result.ApiOnline = !string.IsNullOrWhiteSpace(apiBaseUrl);
}
catch
{
result.ApiOnline = false;
}

return Json(result);
}
}
}


6 changes: 6 additions & 0 deletions Web/Resgrid.Web.Mcp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ FROM mcr.microsoft.com/dotnet/aspnet:9.0.3-noble-amd64 AS base
ARG BUILD_VERSION
WORKDIR /app
EXPOSE 80
EXPOSE 5050

FROM mcr.microsoft.com/dotnet/sdk:9.0.202-noble-amd64 AS build
ARG BUILD_VERSION
Expand Down Expand Up @@ -43,4 +44,9 @@ RUN chmod +x wait

WORKDIR /app
COPY --from=publish /app/publish .

# Health check configuration
HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=10s \
CMD curl -f http://localhost:5050/health/current || exit 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify if curl or wget is present in the aspnet base image
echo "Checking for curl..."
docker run --rm mcr.microsoft.com/dotnet/aspnet:9.0.3-noble-amd64 which curl 2>&1 || true
echo "---"
echo "Checking for wget..."
docker run --rm mcr.microsoft.com/dotnet/aspnet:9.0.3-noble-amd64 which wget 2>&1 || true

Repository: Resgrid/Core

Length of output: 191


🏁 Script executed:

#!/bin/bash
# First, locate and examine the Dockerfile
find . -name "Dockerfile" -path "*/Resgrid.Web.Mcp/*" | head -5

Repository: Resgrid/Core

Length of output: 88


🌐 Web query:

mcr.microsoft.com/dotnet/aspnet:9.0.3-noble-amd64 curl wget available

💡 Result:

mcr.microsoft.com/dotnet/aspnet:9.0.3-noble-amd64 does not include curl or wget by default (this is consistent with the standard dotnet/aspnet images, where both tools are often absent unless you add them). [1]

If you need them, install via apt in your Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:9.0.3-noble-amd64

RUN apt-get update \
  && apt-get install -y --no-install-recommends curl wget ca-certificates \
  && rm -rf /var/lib/apt/lists/*

This same approach is commonly required on dotnet/aspnet images when curl isn’t present. [2]

Notes:

  • Alpine-based variants typically rely on the (usually present) wget instead of curl. [3]
  • If you use a chiseled/distroless variant, you generally can’t apt-get install tools at all (no package manager), so you’d need a different strategy. [4]

Sources: [1] [2] [3] [4]


🏁 Script executed:

#!/bin/bash
cat -n ./Web/Resgrid.Web.Mcp/Dockerfile

Repository: Resgrid/Core

Length of output: 3432


curl is not available in the dotnet/aspnet:9.0.3-noble-amd64 base image.

This HEALTHCHECK will fail with "exec: curl: not found", permanently marking the container as unhealthy. The base image is not installing curl anywhere in the build stages.

Either install curl in the final stage via apt-get, use wget (if available), or implement a .NET-based health check:

Proposed fix
 HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=10s \
-  CMD curl -f http://localhost:5050/health/current || exit 1
+  CMD wget --no-verbose --tries=1 --spider http://localhost:5050/health/current || exit 1

Or install curl in the final stage before the HEALTHCHECK.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=10s \
CMD curl -f http://localhost:5050/health/current || exit 1
HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=10s \
CMD wget --no-verbose --tries=1 --spider http://localhost:5050/health/current || exit 1
🤖 Prompt for AI Agents
In `@Web/Resgrid.Web.Mcp/Dockerfile` around lines 49 - 50, The HEALTHCHECK uses
curl which is not present in the dotnet/aspnet:9.0.3-noble-amd64 base image so
the probe will always fail; fix by either installing a HTTP client in the final
image (e.g., add apt-get update && apt-get install -y curl or wget in the final
stage before the HEALTHCHECK) or replace the HEALTHCHECK command with a
.NET-based health probe callable from the container; update the Dockerfile
HEALTHCHECK line accordingly and ensure the package install happens in the same
final stage that defines HEALTHCHECK (reference: the Dockerfile HEALTHCHECK and
the base image dotnet/aspnet:9.0.3-noble-amd64).


ENTRYPOINT ["sh", "-c", "./wait && dotnet Resgrid.Web.Mcp.dll"]
44 changes: 44 additions & 0 deletions Web/Resgrid.Web.Mcp/Models/HealthResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
namespace Resgrid.Web.Mcp.Models
{
/// <summary>
/// Response for getting the health of the Resgrid MCP Server.
/// </summary>
public sealed class HealthResult
{
/// <summary>
/// Site\Location of this MCP Server
/// </summary>
public string SiteId { get; set; }

/// <summary>
/// The Version of the MCP Server
/// </summary>
public string ServerVersion { get; set; }

/// <summary>
/// The name of the MCP Server
/// </summary>
public string ServerName { get; set; }

/// <summary>
/// Number of registered tools
/// </summary>
public int ToolCount { get; set; }

/// <summary>
/// Can the MCP Server talk to the Resgrid API
/// </summary>
public bool ApiOnline { get; set; }

/// <summary>
/// Can the MCP Server talk to the cache
/// </summary>
public bool CacheOnline { get; set; }

/// <summary>
/// Is the MCP Server running
/// </summary>
public bool ServerRunning { get; set; }
}
}

26 changes: 23 additions & 3 deletions Web/Resgrid.Web.Mcp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Multiple BOM characters — same root cause as the build failure.

Line 1 contains four BOM characters. Strip them so the file starts with using.

-using System;
+using System;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
using System;
using System;
🤖 Prompt for AI Agents
In `@Web/Resgrid.Web.Mcp/Program.cs` at line 1, The file starts with stray BOM
characters before the initial directive; remove the leading BOM bytes so the
first token is "using System;" (i.e., ensure the top of Program.cs begins
exactly with the "using System;" line and no invisible characters precede it) to
resolve the build error.

using System.IO;
using System.Threading.Tasks;
using Autofac.Extensions.DependencyInjection;
Expand Down Expand Up @@ -31,14 +31,30 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel(serverOptions =>
{
// Configure Kestrel to listen on a specific port for health checks
serverOptions.ListenAnyIP(5050); // Health check port
});
webBuilder.Configure((context, app) =>
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
});
})
.ConfigureAppConfiguration((_, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddEnvironmentVariables()
.AddCommandLine(args);
})
.ConfigureLogging((hostingContext, logging) =>
.ConfigureLogging((_, logging) =>
{
logging.ClearProviders();
logging.AddConsole();
Expand Down Expand Up @@ -71,6 +87,10 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
// Register MCP server
services.AddHostedService<McpServerHost>();

// Add MVC controllers for health check endpoint
services.AddControllers()
.AddNewtonsoftJson();

// Register infrastructure services
services.AddMemoryCache();
services.AddSingleton<Infrastructure.IResponseCache, Infrastructure.ResponseCache>();
Expand Down
3 changes: 2 additions & 1 deletion Web/Resgrid.Web.Mcp/Resgrid.Web.Mcp.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.Web">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Double BOM causing build failure — this is the pipeline error.

The file begins with two UTF-8 BOM characters (), which causes MSBuild error MSB4025: "Data at the root level is invalid. Line 1, position 1." Remove the extra BOM so the file starts cleanly with <Project.

The same double-BOM issue also appears in Program.cs (line 1: using). Fix both files.

-<Project Sdk="Microsoft.NET.Sdk.Web">
+<Project Sdk="Microsoft.NET.Sdk.Web">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
🧰 Tools
🪛 GitHub Actions: .NET

[error] 1-1: MSB4025: The project file could not be loaded. Data at the root level is invalid. Line 1, position 1.

🤖 Prompt for AI Agents
In `@Web/Resgrid.Web.Mcp/Resgrid.Web.Mcp.csproj` at line 1, Remove the stray
double UTF-8 BOM at the start of the csproj and Program.cs so the files begin
exactly with "<Project" and "using" respectively; open Resgrid.Web.Mcp.csproj
and Program.cs, delete any invisible BOM characters at the very start, and save
both files as UTF-8 without BOM (or re-encode using your editor/CLI) so MSBuild
sees valid XML/CS source.

<PropertyGroup>
<Description>Model Context Protocol (MCP) Server for Resgrid CAD System</Description>
<VersionPrefix>1.0.0</VersionPrefix>
Expand Down Expand Up @@ -32,6 +32,7 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.3" />
<!-- MCP SDK from https://github.com/modelcontextprotocol/csharp-sdk -->
<!-- TODO: Add as project reference or wait for NuGet package -->
Expand Down
Loading