Files
EugeneTes b30c71d30a feat(mcp): server launch plumbing and tool naming
Spec: the complete environment goes to the SDK with InheritEnvironmentVariables=false instead of nulls; the cache key also covers cwd and prefix.
2026-09-26 20:17:37 +02:00

41 lines
1.5 KiB
C#

using System.Text.RegularExpressions;
namespace Volcanic.AgenticCore.Extensions.Mcp;
/// <summary>
/// Exposed tool names: <c>prefix + mcpName</c>, characters outside <c>[A-Za-z0-9_-]</c> replaced by <c>_</c>, at most 48
/// characters so the Claude Code provider's <c>ToolCatalog</c> keeps them readable, duplicates suffixed <c>_2</c>, <c>_3</c>.
/// </summary>
internal static partial class ToolNaming
{
public const int MaxLength = 48;
public static string Sanitize(string? prefix, string mcpName)
{
var name = InvalidCharacters().Replace((prefix ?? "") + mcpName, "_");
if (name.Length == 0) name = "tool";
return name.Length > MaxLength ? name[..MaxLength] : name;
}
public static IReadOnlyList<string> Expose(IReadOnlyList<string> mcpNames, string? prefix)
{
var used = new HashSet<string>(StringComparer.Ordinal);
var result = new List<string>(mcpNames.Count);
foreach (var mcpName in mcpNames)
{
var baseName = Sanitize(prefix, mcpName);
var name = baseName;
for (var n = 2; !used.Add(name); n++)
{
var suffix = $"_{n}";
name = (baseName.Length + suffix.Length > MaxLength ? baseName[..(MaxLength - suffix.Length)] : baseName) + suffix;
}
result.Add(name);
}
return result;
}
[GeneratedRegex("[^A-Za-z0-9_-]")]
private static partial Regex InvalidCharacters();
}