Skip to content

Commit 0368fe1

Browse files
Pin built-in MCP clients to the current protocol
1 parent 0de593f commit 0368fe1

3 files changed

Lines changed: 37 additions & 20 deletions

File tree

‎src/AI.Tools/DefaultToolSessionFactory.cs‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public sealed class DefaultToolSessionFactory(
1515
IChatTemporaryDirectory temporaryDirectory,
1616
IToolEnvironment toolEnvironment) : IMcpServerConnection
1717
{
18+
private const string ProtocolVersion = "2026-07-28";
19+
1820
public Guid ServerId => DefaultMcpServer.Id;
1921

2022
/// <summary>Name of the environment variable through which the built-in server receives its directory grants.</summary>
@@ -30,7 +32,12 @@ public async Task<IToolSession> OpenAsync(IReadOnlyList<ToolDirectoryGrant> dire
3032
// replaced. Every call has returned by then, so there is nothing left to wait for.
3133
var transport = toolEnvironment.Launch(new ToolProcessLaunch("Default tools", executable, [], null, environment,
3234
InheritEnvironment: false, ShutdownTimeout: TimeSpan.FromMilliseconds(500)));
33-
var client = await McpClient.CreateAsync(transport, cancellationToken: cancellationToken);
35+
// This is our own current server, so do not let a slow discovery response make the SDK
36+
// fall back to the legacy initialize handshake on the same connection.
37+
var client = await McpClient.CreateAsync(transport, new McpClientOptions
38+
{
39+
ProtocolVersion = ProtocolVersion
40+
}, cancellationToken: cancellationToken);
3441
try
3542
{
3643
var tools = await client.ListToolsAsync(cancellationToken: cancellationToken);

‎tests/AI.Mcp.BuiltIn.Tests/SandboxedToolTests.cs‎

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ namespace AI.Mcp.BuiltIn.Tests;
1414
[Trait("Category", "Integration")]
1515
public sealed class SandboxedToolTests : IAsyncLifetime
1616
{
17+
private const string ProtocolVersion = "2026-07-28";
18+
1719
private static readonly string[] ReadOnly = ["read"];
1820
private static readonly string[] Everything = ["read", "write", "edit", "delete"];
1921

@@ -41,17 +43,20 @@ public async ValueTask InitializeAsync()
4143
new { root = _writable, recursive = true, capabilities = Everything, purpose = "project" },
4244
new { root = _temporary, recursive = true, capabilities = Everything, purpose = "chatTemporary" }
4345
});
44-
_client = await McpClient.CreateAsync(new StdioClientTransport(new StdioClientTransportOptions
45-
{
46-
Name = "Default tools",
47-
Command = "dotnet",
48-
Arguments = [Path.Combine(AppContext.BaseDirectory, "AI.Mcp.BuiltIn.dll")],
49-
EnvironmentVariables = new Dictionary<string, string?>
46+
_client = await McpClient.CreateAsync(
47+
new StdioClientTransport(new StdioClientTransportOptions
5048
{
51-
["AI_CLIENT_DIRECTORY_GRANTS"] = grants
52-
},
53-
ShutdownTimeout = TimeSpan.FromMilliseconds(500)
54-
}), cancellationToken: Token);
49+
Name = "Default tools",
50+
Command = "dotnet",
51+
Arguments = [Path.Combine(AppContext.BaseDirectory, "AI.Mcp.BuiltIn.dll")],
52+
EnvironmentVariables = new Dictionary<string, string?>
53+
{
54+
["AI_CLIENT_DIRECTORY_GRANTS"] = grants
55+
},
56+
ShutdownTimeout = TimeSpan.FromMilliseconds(500)
57+
}),
58+
new McpClientOptions { ProtocolVersion = ProtocolVersion },
59+
cancellationToken: Token);
5560
}
5661

5762
public async ValueTask DisposeAsync()

‎tests/AI.Mcp.BuiltIn.Tests/ScriptRunToolTests.cs‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ namespace AI.Mcp.BuiltIn.Tests;
1414
[Trait("Category", "Integration")]
1515
public sealed class ScriptRunToolTests : IAsyncLifetime
1616
{
17+
private const string ProtocolVersion = "2026-07-28";
18+
1719
private static readonly string[] TwoArguments = ["hello", "world"];
1820
private static readonly string[] XmlImports = ["System.Xml.Linq"];
1921
private static readonly string[] XmlReferences = ["System.Xml.Linq"];
@@ -27,15 +29,18 @@ public async ValueTask InitializeAsync()
2729
{
2830
var assembly = Path.Combine(AppContext.BaseDirectory, "AI.Mcp.BuiltIn.dll");
2931
File.Exists(assembly).ShouldBeTrue($"The server assembly must be next to the tests: {assembly}");
30-
_client = await McpClient.CreateAsync(new StdioClientTransport(new StdioClientTransportOptions
31-
{
32-
Name = "Default tools",
33-
// Started through the muxer rather than the apphost so the test does not depend on
34-
// which runtime the test host resolved.
35-
Command = "dotnet",
36-
Arguments = [assembly],
37-
ShutdownTimeout = TimeSpan.FromMilliseconds(500)
38-
}), cancellationToken: Token);
32+
_client = await McpClient.CreateAsync(
33+
new StdioClientTransport(new StdioClientTransportOptions
34+
{
35+
Name = "Default tools",
36+
// Started through the muxer rather than the apphost so the test does not depend on
37+
// which runtime the test host resolved.
38+
Command = "dotnet",
39+
Arguments = [assembly],
40+
ShutdownTimeout = TimeSpan.FromMilliseconds(500)
41+
}),
42+
new McpClientOptions { ProtocolVersion = ProtocolVersion },
43+
cancellationToken: Token);
3944
}
4045

4146
public async ValueTask DisposeAsync() => await _client.DisposeAsync();

0 commit comments

Comments
 (0)