using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
namespace Sozsoft.Mcp;
///
/// Model metin parametresine tirnaksiz deger (section: 4.2) ya da JSON metni yerine dogrudan
/// dizi/nesne (filter: ["Status","=","Open"]) gonderebilir. SDK her parametreyi ayri ayri
/// string olarak bagladigi icin bu deger ("Cannot get the value of a
/// token type 'Number' / 'StartArray' as a string") ile duser. Deger cagri araca ulasmadan, aracin kendi
/// semasina bakilarak ham JSON metnine cevrilir — JSON bekleyen parametre ayni metni alir; string icin
/// ozel converter kullanilmaz, cunku arac semasindaki "type": "string" bilgisini siler.
///
internal static class McpToolArgumentNormalizer
{
public static void Normalize(CallToolRequestParams? parameters, McpServerTool? tool)
{
if (parameters?.Arguments is not { Count: > 0 } arguments
|| tool is null
|| !tool.ProtocolTool.InputSchema.TryGetProperty("properties", out var properties)
|| properties.ValueKind != JsonValueKind.Object)
{
return;
}
Dictionary? normalized = null;
foreach (var (name, value) in arguments)
{
if (value.ValueKind is JsonValueKind.String or JsonValueKind.Null or JsonValueKind.Undefined
|| !properties.TryGetProperty(name, out var schema)
|| !IsStringOnly(schema))
{
continue;
}
normalized ??= new Dictionary(arguments);
normalized[name] = JsonSerializer.SerializeToElement(value.GetRawText());
}
if (normalized is not null)
{
parameters.Arguments = normalized;
}
}
// Nullable metin parametresi semada ["string", "null"] olarak gelir; baska tip de kabul eden bir
// birlesim tipi donusturulmez, degeri SDK oldugu gibi baglar.
private static bool IsStringOnly(JsonElement schema)
{
if (!schema.TryGetProperty("type", out var type))
{
return false;
}
return type.ValueKind switch
{
JsonValueKind.String => type.GetString() == "string",
JsonValueKind.Array => type.EnumerateArray()
.Select(item => item.GetString())
.Where(item => item != "null")
.SequenceEqual(["string"]),
_ => false
};
}
}