69 lines
2.6 KiB
C#
69 lines
2.6 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using ModelContextProtocol.Protocol;
|
|
using ModelContextProtocol.Server;
|
|
|
|
namespace Sozsoft.Mcp;
|
|
|
|
/// <summary>
|
|
/// Model metin parametresine tirnaksiz deger (<c>section: 4.2</c>) ya da JSON metni yerine dogrudan
|
|
/// dizi/nesne (<c>filter: ["Status","=","Open"]</c>) gonderebilir. SDK her parametreyi ayri ayri
|
|
/// <c>string</c> olarak bagladigi icin bu deger <see cref="JsonException"/> ("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 <c>"type": "string"</c> bilgisini siler.
|
|
/// </summary>
|
|
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<string, JsonElement>? 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<string, JsonElement>(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
|
|
};
|
|
}
|
|
}
|