Browse Source

Refactor tool input schema handling and JSON serialization

Set default 'Type' property in McpToolInputSchema and pass the schema object directly instead of building a dictionary. Use camelCase JSON serialization for input schemas in McpServerService to ensure correct property naming.
pull/24677/head
Mansur Besleney 2 weeks ago
parent
commit
b63a13a3b0
  1. 1
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Models/McpToolDefinition.cs
  2. 36
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/McpServerService.cs

1
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Models/McpToolDefinition.cs

@ -13,6 +13,7 @@ public class McpToolDefinition
public class McpToolInputSchema
{
public string Type { get; set; } = "object";
public Dictionary<string, McpToolProperty> Properties { get; set; }
public List<string> Required { get; set; }
}

36
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/McpServerService.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@ -18,6 +17,11 @@ public class McpServerService : ITransientDependency
private const string LogSource = nameof(McpServerService);
private const int MaxLogResponseLength = 500;
private static readonly JsonSerializerOptions JsonCamelCaseOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
private static class ToolErrorMessages
{
public const string InvalidResponseFormat = "The tool execution completed but returned an invalid response format. Please try again.";
@ -74,32 +78,8 @@ public class McpServerService : ITransientDependency
private void RegisterToolFromDefinition(McpServerOptions options, McpToolDefinition toolDef)
{
// Build input schema with lowercase keys as required by MCP JSON Schema format
var inputSchemaObject = new Dictionary<string, object>
{
["type"] = "object",
["properties"] = ConvertProperties(toolDef.InputSchema?.Properties),
["required"] = toolDef.InputSchema?.Required ?? new List<string>()
};
RegisterTool(options, toolDef.Name, toolDef.Description, inputSchemaObject, toolDef.OutputSchema);
}
private static Dictionary<string, object> ConvertProperties(Dictionary<string, McpToolProperty> properties)
{
if (properties == null)
{
return new Dictionary<string, object>();
}
return properties.ToDictionary(
kvp => kvp.Key,
kvp => (object)new Dictionary<string, object>
{
["type"] = kvp.Value.Type,
["description"] = kvp.Value.Description
}
);
var inputSchema = toolDef.InputSchema ?? new McpToolInputSchema();
RegisterTool(options, toolDef.Name, toolDef.Description, inputSchema, toolDef.OutputSchema);
}
private static CallToolResult CreateErrorResult(string errorMessage)
@ -132,7 +112,7 @@ public class McpServerService : ITransientDependency
var tool = new AbpMcpServerTool(
name,
description,
JsonSerializer.SerializeToElement(inputSchema),
JsonSerializer.SerializeToElement(inputSchema, JsonCamelCaseOptions),
outputSchema,
(context, cancellationToken) => HandleToolInvocationAsync(name, context, cancellationToken)
);

Loading…
Cancel
Save