Skip to content

Commit e7a6efb

Browse files
Fix some issues from the code review
1 parent 75b443b commit e7a6efb

18 files changed

+215
-266
lines changed

mcp_nexus/Controllers/McpController.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
using mcp_nexus.Infrastructure;
88
using mcp_nexus.Session;
99
using mcp_nexus.Models;
10+
using AspNetCoreRateLimit;
1011

1112
namespace mcp_nexus.Controllers
1213
{
1314
[ApiController]
1415
[Route("mcp")]
15-
public class McpController(McpProtocolService mcpProtocolService, ILogger<McpController> logger)
16+
public class McpController(IMcpProtocolService mcpProtocolService, ILogger<McpController> logger)
1617
: ControllerBase
1718
{
1819
// PERFORMANCE: Reuse JSON options to avoid repeated allocations

mcp_nexus/Program.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Text.Json;
33
using Microsoft.AspNetCore.Server.Kestrel.Core;
44
using NLog.Web;
5+
using AspNetCoreRateLimit;
56

67
using mcp_nexus.Constants;
78
using mcp_nexus.Debugger;
@@ -551,7 +552,7 @@ private static async Task RunHttpServer(string[] args, CommandLineArguments comm
551552

552553
ConfigureLogging(webBuilder.Logging, commandLineArgs.ServiceMode);
553554
RegisterServices(webBuilder.Services, webBuilder.Configuration, commandLineArgs.CustomCdbPath);
554-
ConfigureHttpServices(webBuilder.Services);
555+
ConfigureHttpServices(webBuilder.Services, webBuilder.Configuration);
555556

556557
var app = webBuilder.Build();
557558
ConfigureHttpPipeline(app);
@@ -703,14 +704,14 @@ private static void RegisterServices(IServiceCollection services, IConfiguration
703704
Console.Error.WriteLine("Registered McpResourceService for MCP resources support");
704705
}
705706

706-
private static void ConfigureHttpServices(IServiceCollection services)
707+
private static void ConfigureHttpServices(IServiceCollection services, IConfiguration configuration)
707708
{
708709
Console.WriteLine("Configuring MCP server for HTTP...");
709710

710711
services.AddControllers()
711712
.AddJsonOptions(options =>
712713
{
713-
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
714+
options.JsonSerializerOptions.PropertyNamingPolicy = null; // Don't change property names - MCP protocol requires exact field names
714715
options.JsonSerializerOptions.WriteIndented = true;
715716
});
716717

@@ -738,14 +739,22 @@ private static void ConfigureHttpServices(IServiceCollection services)
738739
});
739740
});
740741

742+
// Configure rate limiting
743+
services.AddMemoryCache();
744+
services.Configure<IpRateLimitOptions>(configuration.GetSection("IpRateLimiting"));
745+
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
746+
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
747+
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
748+
services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>();
749+
741750
// MIGRATION: Register tool discovery without stdio transport for HTTP mode
742751
// Note: Tools are discovered automatically via [McpServerToolType] attribute
743752
// HTTP mode uses controllers instead of stdio transport
744753

745754
// Register MCP services for HTTP endpoint compatibility
746-
services.AddSingleton<McpToolDefinitionService>();
747-
services.AddSingleton<McpToolExecutionService>();
748-
services.AddSingleton<McpProtocolService>();
755+
services.AddSingleton<IMcpToolDefinitionService, McpToolDefinitionService>();
756+
services.AddSingleton<IMcpToolExecutionService, McpToolExecutionService>();
757+
services.AddSingleton<IMcpProtocolService, McpProtocolService>();
749758
// Note: IMcpNotificationService now registered in shared RegisterServices() method
750759

751760
Console.WriteLine("MCP server configured for HTTP with controllers, CORS, and tool discovery");
@@ -756,7 +765,7 @@ private static void ConfigureStdioServices(IServiceCollection services)
756765
Console.Error.WriteLine("Configuring MCP server for stdio...");
757766

758767
// Add the MCP protocol service for logging comparison
759-
services.AddSingleton<McpProtocolService>();
768+
services.AddSingleton<IMcpProtocolService, McpProtocolService>();
760769

761770
// Note: IMcpNotificationService is now registered in shared RegisterServices() method
762771

@@ -774,6 +783,7 @@ private static void ConfigureHttpPipeline(WebApplication app)
774783
{
775784
Console.WriteLine("Configuring HTTP request pipeline...");
776785

786+
app.UseIpRateLimiting();
777787
app.UseCors();
778788
app.UseRouting();
779789
app.MapControllers();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Text.Json;
2+
3+
namespace mcp_nexus.Protocol
4+
{
5+
/// <summary>
6+
/// Interface for MCP protocol service to enable better testability
7+
/// </summary>
8+
public interface IMcpProtocolService
9+
{
10+
/// <summary>
11+
/// Process an incoming MCP request
12+
/// </summary>
13+
/// <param name="requestElement">The JSON request element</param>
14+
/// <returns>Response object or null for notifications</returns>
15+
Task<object?> ProcessRequest(JsonElement requestElement);
16+
}
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using mcp_nexus.Models;
2+
3+
namespace mcp_nexus.Protocol
4+
{
5+
/// <summary>
6+
/// Interface for MCP tool definition service to enable better testability
7+
/// </summary>
8+
public interface IMcpToolDefinitionService
9+
{
10+
/// <summary>
11+
/// Get all available MCP tools
12+
/// </summary>
13+
/// <returns>Array of tool definitions</returns>
14+
McpToolSchema[] GetAllTools();
15+
}
16+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Text.Json;
2+
3+
namespace mcp_nexus.Protocol
4+
{
5+
/// <summary>
6+
/// Interface for MCP tool execution service to enable better testability
7+
/// </summary>
8+
public interface IMcpToolExecutionService
9+
{
10+
/// <summary>
11+
/// Execute a specific MCP tool
12+
/// </summary>
13+
/// <param name="toolName">Name of the tool to execute</param>
14+
/// <param name="arguments">Tool arguments</param>
15+
/// <returns>Tool execution result</returns>
16+
Task<object> ExecuteTool(string toolName, JsonElement arguments);
17+
}
18+
}

mcp_nexus/Protocol/McpProtocolService.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
namespace mcp_nexus.Protocol
77
{
88
public class McpProtocolService(
9-
McpToolDefinitionService m_toolDefinitionService,
10-
McpToolExecutionService m_toolExecutionService,
9+
IMcpToolDefinitionService m_toolDefinitionService,
10+
IMcpToolExecutionService m_toolExecutionService,
1111
McpResourceService m_resourceService,
12-
ILogger<McpProtocolService> m_logger)
12+
ILogger<McpProtocolService> m_logger) : IMcpProtocolService
1313
{
1414
public async Task<object?> ProcessRequest(JsonElement requestElement)
1515
{
@@ -19,7 +19,11 @@ public class McpProtocolService(
1919
var request = ParseRequest(requestElement);
2020
if (request == null)
2121
{
22-
return CreateErrorResponse(null, -32600, "Invalid Request - malformed JSON-RPC");
22+
return CreateErrorResponse(null, -32600, "Invalid Request: The request is not a valid JSON-RPC 2.0 request. Please ensure the request contains a 'method' field and follows the JSON-RPC 2.0 specification.", new {
23+
errorType = "InvalidRequest",
24+
requiredFields = new[] { "jsonrpc", "method" },
25+
specification = "JSON-RPC 2.0"
26+
});
2327
}
2428

2529
requestId = request.Id;
@@ -42,8 +46,12 @@ public class McpProtocolService(
4246
}
4347
catch (Exception ex)
4448
{
45-
m_logger.LogError(ex, "Error processing MCP request");
46-
return CreateErrorResponse(requestId, -32603, "Internal error", ex.Message);
49+
m_logger.LogError(ex, "Unexpected error processing MCP request: {RequestId}", requestId);
50+
return CreateErrorResponse(requestId, -32603, "Internal server error occurred while processing your request. Please try again or contact support if the issue persists.", new {
51+
errorType = "InternalError",
52+
timestamp = DateTime.UtcNow,
53+
requestId = requestId?.ToString() ?? "unknown"
54+
});
4755
}
4856
}
4957

mcp_nexus/Protocol/McpToolDefinitionService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace mcp_nexus.Protocol
66
{
7-
public class McpToolDefinitionService
7+
public class McpToolDefinitionService : IMcpToolDefinitionService
88
{
99
private readonly IMcpNotificationService? m_notificationService;
1010

mcp_nexus/Protocol/McpToolExecutionService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace mcp_nexus.Protocol
77
{
88
public class McpToolExecutionService(
99
SessionAwareWindbgTool sessionAwareWindbgTool,
10-
ILogger<McpToolExecutionService> logger)
10+
ILogger<McpToolExecutionService> logger) : IMcpToolExecutionService
1111
{
1212
// PERFORMANCE: Cache JsonSerializerOptions to avoid repeated allocation
1313
private static readonly JsonSerializerOptions s_jsonOptions = new()

mcp_nexus/appsettings.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,18 @@
4242
"DefaultCommandTimeoutMinutes": 10,
4343
"MemoryCleanupThresholdMB": 1024
4444
}
45+
},
46+
"IpRateLimiting": {
47+
"EnableEndpointRateLimiting": true,
48+
"StackBlockedRequests": false,
49+
"RealIpHeader": "X-Real-IP",
50+
"ClientIdHeader": "X-ClientId",
51+
"GeneralRules": [
52+
{
53+
"Endpoint": "*:/mcp",
54+
"Period": "1m",
55+
"Limit": 100
56+
}
57+
]
4558
}
4659
}

mcp_nexus/mcp_nexus.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
</ItemGroup>
2121

2222
<ItemGroup>
23+
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
2324
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
2425
<PackageReference Include="ModelContextProtocol" Version="0.3.0-preview.4" />
2526
<PackageReference Include="NLog.Extensions.Logging" Version="6.0.4" />

0 commit comments

Comments
 (0)