Skip to content

Commit 65a9f2e

Browse files
stephentoubeiriktsarpalis
authored andcommitted
Change type of Tool.InputSchema to be JsonElement
1 parent 27ba8b1 commit 65a9f2e

File tree

10 files changed

+70
-117
lines changed

10 files changed

+70
-117
lines changed

samples/anthropic/tools/ToolsConsole/McpToolExtensions.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ public static class McpToolExtensions
1616
List<Anthropic.SDK.Common.Tool> result = [];
1717
foreach (var tool in tools)
1818
{
19-
var function = tool.InputSchema == null
20-
? new Function(tool.Name, tool.Description)
21-
: new Function(tool.Name, tool.Description, JsonSerializer.Serialize(tool.InputSchema));
19+
var function = new Function(tool.Name, tool.Description, JsonSerializer.SerializeToNode(tool.InputSchema));
2220
result.Add(function);
2321
}
2422
return result;

src/ModelContextProtocol/Client/McpClientExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ private static JsonRpcRequest CreateRequest(string method, Dictionary<string, ob
466466
/// <summary>Provides an AI function that calls a tool through <see cref="IMcpClient"/>.</summary>
467467
private sealed class McpAIFunction(IMcpClient client, Tool tool) : AIFunction
468468
{
469-
private JsonElement? _jsonSchema;
469+
private JsonElement? _jsonSchema = tool.InputSchema;
470470

471471
/// <inheritdoc/>
472472
public override string Name => tool.Name;
@@ -481,8 +481,8 @@ private sealed class McpAIFunction(IMcpClient client, Tool tool) : AIFunction
481481
["type"] = "object",
482482
["title"] = tool.Name,
483483
["description"] = tool.Description ?? string.Empty,
484-
["properties"] = tool.InputSchema?.Properties ?? [],
485-
["required"] = tool.InputSchema?.Required ?? []
484+
["properties"] = new Dictionary<string, object?>(),
485+
["required"] = Array.Empty<object>(),
486486
}, McpJsonUtilities.JsonContext.Default.DictionaryStringObject);
487487

488488
/// <inheritdoc/>

src/ModelContextProtocol/Configuration/McpServerBuilderExtensions.Tools.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, params
9696
{
9797
Name = function.Name,
9898
Description = function.Description,
99-
InputSchema = JsonSerializer.Deserialize(function.JsonSchema, McpJsonUtilities.JsonContext.Default.JsonSchema),
99+
InputSchema = function.JsonSchema,
100100
});
101101

102102
callbacks.Add(function.Name, async (request, cancellationToken) =>

src/ModelContextProtocol/Protocol/Types/JsonSchema.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/ModelContextProtocol/Protocol/Types/JsonSchemaProperty.cs

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/ModelContextProtocol/Protocol/Types/Tool.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Text.Json.Serialization;
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
23

34
namespace ModelContextProtocol.Protocol.Types;
45

@@ -24,5 +25,5 @@ public class Tool
2425
/// A JSON Schema object defining the expected parameters for the tool.
2526
/// </summary>
2627
[JsonPropertyName("inputSchema")]
27-
public JsonSchema? InputSchema { get; set; }
28+
public JsonElement InputSchema { get; set; }
2829
}

src/ModelContextProtocol/Utils/Json/McpJsonUtilities.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ internal static JsonTypeInfo<T> GetTypeInfo<T>(this JsonSerializerOptions option
9696
[JsonSerializable(typeof(CreateMessageResult))]
9797
[JsonSerializable(typeof(ListRootsResult))]
9898
[JsonSerializable(typeof(InitializeResult))]
99-
[JsonSerializable(typeof(JsonSchema))]
10099
[JsonSerializable(typeof(CallToolResponse))]
101100
internal sealed partial class JsonContext : JsonSerializerContext;
102101
}

tests/ModelContextProtocol.TestServer/Program.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,28 +91,39 @@ private static ToolsCapability ConfigureTools()
9191
{
9292
Name = "echo",
9393
Description = "Echoes the input back to the client.",
94-
InputSchema = new JsonSchema()
95-
{
96-
Type = "object",
97-
Properties = new Dictionary<string, JsonSchemaProperty>()
94+
InputSchema = JsonSerializer.SerializeToElement("""
9895
{
99-
["message"] = new JsonSchemaProperty() { Type = "string", Description = "The input to echo back." }
96+
"type": "object",
97+
"properties": {
98+
"message": {
99+
"type": "string",
100+
"description": "The input to echo back."
101+
}
102+
},
103+
"required": ["message"]
100104
}
101-
},
105+
"""),
102106
},
103107
new Tool()
104108
{
105109
Name = "sampleLLM",
106110
Description = "Samples from an LLM using MCP's sampling feature.",
107-
InputSchema = new JsonSchema()
108-
{
109-
Type = "object",
110-
Properties = new Dictionary<string, JsonSchemaProperty>()
111+
InputSchema = JsonSerializer.SerializeToElement("""
111112
{
112-
["prompt"] = new JsonSchemaProperty() { Type = "string", Description = "The prompt to send to the LLM" },
113-
["maxTokens"] = new JsonSchemaProperty() { Type = "number", Description = "Maximum number of tokens to generate" }
113+
"type": "object",
114+
"properties": {
115+
"prompt": {
116+
"type": "string",
117+
"description": "The prompt to send to the LLM"
118+
},
119+
"maxTokens": {
120+
"type": "number",
121+
"description": "Maximum number of tokens to generate"
122+
}
123+
},
124+
"required": ["prompt", "maxTokens"]
114125
}
115-
},
126+
"""),
116127
}
117128
]
118129
});

tests/ModelContextProtocol.TestSseServer/Program.cs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Microsoft.Extensions.Logging;
55
using Serilog;
66
using System.Text;
7+
using System.Text.Json;
78

89
internal class Program
910
{
@@ -121,28 +122,39 @@ static CreateMessageRequestParams CreateRequestSamplingParams(string context, st
121122
{
122123
Name = "echo",
123124
Description = "Echoes the input back to the client.",
124-
InputSchema = new JsonSchema()
125-
{
126-
Type = "object",
127-
Properties = new Dictionary<string, JsonSchemaProperty>()
125+
InputSchema = JsonSerializer.SerializeToElement("""
128126
{
129-
["message"] = new JsonSchemaProperty() { Type = "string", Description = "The input to echo back." }
127+
"type": "object",
128+
"properties": {
129+
"message": {
130+
"type": "string",
131+
"description": "The input to echo back."
132+
}
133+
},
134+
"required": ["message"]
130135
}
131-
},
136+
"""),
132137
},
133138
new Tool()
134139
{
135140
Name = "sampleLLM",
136141
Description = "Samples from an LLM using MCP's sampling feature.",
137-
InputSchema = new JsonSchema()
138-
{
139-
Type = "object",
140-
Properties = new Dictionary<string, JsonSchemaProperty>()
142+
InputSchema = JsonSerializer.SerializeToElement("""
141143
{
142-
["prompt"] = new JsonSchemaProperty() { Type = "string", Description = "The prompt to send to the LLM" },
143-
["maxTokens"] = new JsonSchemaProperty() { Type = "number", Description = "Maximum number of tokens to generate" }
144+
"type": "object",
145+
"properties": {
146+
"prompt": {
147+
"type": "string",
148+
"description": "The prompt to send to the LLM"
149+
},
150+
"maxTokens": {
151+
"type": "number",
152+
"description": "Maximum number of tokens to generate"
153+
}
154+
},
155+
"required": ["prompt", "maxTokens"]
144156
}
145-
},
157+
"""),
146158
}
147159
]
148160
});

tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,10 @@ public async Task Can_List_Registered_Tool()
4848
var tool = result.Tools[0];
4949
Assert.Equal("Echo", tool.Name);
5050
Assert.Equal("Echoes the input back to the client.", tool.Description);
51-
Assert.NotNull(tool.InputSchema);
52-
Assert.Equal("object", tool.InputSchema.Type);
53-
Assert.NotNull(tool.InputSchema.Properties);
54-
Assert.NotEmpty(tool.InputSchema.Properties);
55-
Assert.Contains("message", tool.InputSchema.Properties);
56-
Assert.Equal("string", tool.InputSchema.Properties["message"].Type);
57-
Assert.Equal("the echoes message", tool.InputSchema.Properties["message"].Description);
58-
Assert.NotNull(tool.InputSchema.Required);
59-
Assert.NotEmpty(tool.InputSchema.Required);
60-
Assert.Contains("message", tool.InputSchema.Required);
51+
Assert.Equal("object", tool.InputSchema.GetProperty("type").GetString());
52+
Assert.Equal(JsonValueKind.Object, tool.InputSchema.GetProperty("properties").GetProperty("message").ValueKind);
53+
Assert.Equal("the echoes message", tool.InputSchema.GetProperty("properties").GetProperty("message").GetProperty("description").GetString());
54+
Assert.Equal(1, tool.InputSchema.GetProperty("required").GetArrayLength());
6155

6256
tool = result.Tools[1];
6357
Assert.Equal("double_echo", tool.Name);
@@ -288,31 +282,15 @@ public async Task Recognizes_Parameter_Types()
288282
var tool = result.Tools.First(t => t.Name == "TestTool");
289283
Assert.Equal("TestTool", tool.Name);
290284
Assert.Empty(tool.Description!);
291-
Assert.NotNull(tool.InputSchema);
292-
Assert.Equal("object", tool.InputSchema.Type);
293-
Assert.NotNull(tool.InputSchema.Properties);
294-
Assert.NotEmpty(tool.InputSchema.Properties);
295-
296-
Assert.Contains("number", tool.InputSchema.Properties);
297-
Assert.Equal("integer", tool.InputSchema.Properties["number"].Type);
298-
299-
Assert.Contains("otherNumber", tool.InputSchema.Properties);
300-
Assert.Equal("number", tool.InputSchema.Properties["otherNumber"].Type);
301-
302-
Assert.Contains("someCheck", tool.InputSchema.Properties);
303-
Assert.Equal("boolean", tool.InputSchema.Properties["someCheck"].Type);
304-
305-
Assert.Contains("someDate", tool.InputSchema.Properties);
306-
Assert.Equal("string", tool.InputSchema.Properties["someDate"].Type);
307-
308-
Assert.Contains("someOtherDate", tool.InputSchema.Properties);
309-
Assert.Equal("string", tool.InputSchema.Properties["someOtherDate"].Type);
310-
311-
Assert.Contains("data", tool.InputSchema.Properties);
312-
Assert.Equal("array", tool.InputSchema.Properties["data"].Type);
313-
314-
Assert.Contains("complexObject", tool.InputSchema.Properties);
315-
Assert.Equal("object", tool.InputSchema.Properties["complexObject"].Type);
285+
Assert.Equal("object", tool.InputSchema.GetProperty("type").GetString());
286+
287+
Assert.Contains("integer", tool.InputSchema.GetProperty("properties").GetProperty("number").GetProperty("type").GetString());
288+
Assert.Contains("number", tool.InputSchema.GetProperty("properties").GetProperty("otherNumber").GetProperty("type").GetString());
289+
Assert.Contains("boolean", tool.InputSchema.GetProperty("properties").GetProperty("someCheck").GetProperty("type").GetString());
290+
Assert.Contains("string", tool.InputSchema.GetProperty("properties").GetProperty("someDate").GetProperty("type").GetString());
291+
Assert.Contains("string", tool.InputSchema.GetProperty("properties").GetProperty("someOtherDate").GetProperty("type").GetString());
292+
Assert.Contains("array", tool.InputSchema.GetProperty("properties").GetProperty("data").GetProperty("type").GetString());
293+
Assert.Contains("object", tool.InputSchema.GetProperty("properties").GetProperty("complexObject").GetProperty("type").GetString());
316294
}
317295

318296
[McpToolType]

0 commit comments

Comments
 (0)