Files
Playa/tests/Volcanic.AgenticCore.Telegram.Tests/McpConfigurationTests.cs
EugeneTes 2a201f7d95 fix(mcp): address review findings
- redact /mcp output, and stderr lines as they arrive (log, errors, tail)
- take host servers by name: configuration binding sorts keys anyway
- dispose kills the tree only without an exit code and only if the pid's
  start time matches the spawn (no kill of a reused pid)
- idle timer generation guards stale callbacks; catalogue check runs in
  the background with a 10 s cap; shutdown stops servers concurrently
- stop resets a failed status; /mcp shows an exited process; ordinal names
- spec: ${workspace} in command, ordering, dispose and /mcp wording
2026-09-26 21:18:12 +02:00

71 lines
3.1 KiB
C#

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Volcanic.AgenticCore.Extensions.Mcp;
namespace Volcanic.AgenticCore.Telegram.Tests;
public class McpConfigurationTests
{
[Fact]
public void Mcp_section_binds_servers_and_the_playwright_preset()
{
var config = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>
{
["Mcp:Servers:github:Command"] = "npx",
["Mcp:Servers:github:Args:0"] = "-y",
["Mcp:Servers:github:Args:1"] = "@modelcontextprotocol/server-github@2025.9.1",
["Mcp:Servers:github:Env:GITHUB_TOKEN"] = "${env:GITHUB_TOKEN}",
["Mcp:Servers:github:ToolPrefix"] = "gh_",
["Mcp:Servers:github:IdleTimeoutSeconds"] = "0",
["Mcp:Servers:github:StderrLevel"] = "Information",
["Mcp:Playwright:Enabled"] = "true",
["Mcp:Playwright:Headless"] = "false",
["Mcp:Playwright:ExtraArgs:0"] = "--isolated",
}).Build();
var mcp = config.GetSection(McpOptions.SectionName).Get<McpOptions>()!;
var github = mcp.Servers["github"];
Assert.Equal("npx", github.Command);
Assert.Equal(["-y", "@modelcontextprotocol/server-github@2025.9.1"], github.Args);
Assert.Equal("${env:GITHUB_TOKEN}", github.Env["GITHUB_TOKEN"]);
Assert.Equal("gh_", github.ToolPrefix);
Assert.Equal(0, github.IdleTimeoutSeconds);
Assert.Equal(LogLevel.Information, github.StderrLevel);
Assert.Equal(120, github.CallTimeoutSeconds);
Assert.True(mcp.Playwright.IsEnabled);
Assert.False(mcp.Playwright.IsHeadless);
Assert.Equal(["--isolated"], mcp.Playwright.ExtraArgs!);
Assert.Empty(mcp.Validate());
Assert.Equal("MCP: playwright enabled (headed, chromium)", mcp.DescribePlaywright());
}
[Fact]
public void Bound_servers_arrive_in_name_order_whatever_the_file_order()
{
// Microsoft.Extensions.Configuration sorts child keys, so the file order is lost; McpServerSet.Resolve then
// takes host servers by name and the first by name wins a tool name.
var config = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>
{
["Mcp:Servers:zeta:Command"] = "zeta-mcp",
["Mcp:Servers:alpha:Command"] = "alpha-mcp",
}).Build();
var mcp = config.GetSection(McpOptions.SectionName).Get<McpOptions>()!;
Assert.Equal(["alpha", "zeta"], mcp.Servers.Keys);
}
[Fact]
public void Configured_values_win_over_PLAYWRIGHT_variables()
{
var config = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?> { ["Mcp:Playwright:Enabled"] = "false" }).Build();
var mcp = config.GetSection(McpOptions.SectionName).Get<McpOptions>()!;
mcp.ApplyEnvironment(name => name == "PLAYWRIGHT_ENABLED" ? "true" : null);
Assert.False(mcp.Playwright.IsEnabled);
Assert.Equal("MCP: playwright disabled (set PLAYWRIGHT_ENABLED=true)", mcp.DescribePlaywright());
}
}