Skip to content

Commit d371818

Browse files
Copilotstephentoub
andcommitted
Add tests and sample usage for McpMetaAttribute
Co-authored-by: stephentoub <[email protected]>
1 parent 9fb01c5 commit d371818

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

samples/AspNetCoreMcpServer/Tools/WeatherTools.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public WeatherTools(IHttpClientFactory httpClientFactory)
1717
}
1818

1919
[McpServerTool, Description("Get weather alerts for a US state.")]
20+
[McpMeta(Name = "category", Value = "weather")]
21+
[McpMeta(Name = "dataSource", Value = "weather.gov")]
2022
public async Task<string> GetAlerts(
2123
[Description("The US state to get alerts for. Use the 2 letter abbreviation for the state (e.g. NY).")] string state)
2224
{
@@ -46,6 +48,8 @@ public async Task<string> GetAlerts(
4648
}
4749

4850
[McpServerTool, Description("Get weather forecast for a location.")]
51+
[McpMeta(Name = "category", Value = "weather")]
52+
[McpMeta(Name = "recommendedModel", Value = "gpt-4")]
4953
public async Task<string> GetForecast(
5054
[Description("Latitude of the location.")] double latitude,
5155
[Description("Longitude of the location.")] double longitude)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
using ModelContextProtocol.Protocol;
2+
using ModelContextProtocol.Server;
3+
using System.Reflection;
4+
using System.Text.Json.Nodes;
5+
6+
namespace ModelContextProtocol.Tests.Server;
7+
8+
public class McpMetaAttributeTests
9+
{
10+
[Fact]
11+
public void McpMetaAttribute_OnTool_PopulatesMeta()
12+
{
13+
// Arrange
14+
var method = typeof(TestToolClass).GetMethod(nameof(TestToolClass.ToolWithMeta))!;
15+
16+
// Act
17+
var tool = McpServerTool.Create(method, null);
18+
19+
// Assert
20+
Assert.NotNull(tool.ProtocolTool.Meta);
21+
Assert.Equal("gpt-4o", tool.ProtocolTool.Meta["model"]?.ToString());
22+
Assert.Equal("1.0", tool.ProtocolTool.Meta["version"]?.ToString());
23+
}
24+
25+
[Fact]
26+
public void McpMetaAttribute_OnPrompt_PopulatesMeta()
27+
{
28+
// Arrange
29+
var method = typeof(TestPromptClass).GetMethod(nameof(TestPromptClass.PromptWithMeta))!;
30+
31+
// Act
32+
var prompt = McpServerPrompt.Create(method, null);
33+
34+
// Assert
35+
Assert.NotNull(prompt.ProtocolPrompt.Meta);
36+
Assert.Equal("reasoning", prompt.ProtocolPrompt.Meta["type"]?.ToString());
37+
Assert.Equal("claude-3", prompt.ProtocolPrompt.Meta["model"]?.ToString());
38+
}
39+
40+
[Fact]
41+
public void McpMetaAttribute_OnResource_PopulatesMeta()
42+
{
43+
// Arrange
44+
var method = typeof(TestResourceClass).GetMethod(nameof(TestResourceClass.ResourceWithMeta))!;
45+
46+
// Act
47+
var resource = McpServerResource.Create(method, null);
48+
49+
// Assert
50+
Assert.NotNull(resource.ProtocolResource.Meta);
51+
Assert.Equal("text/plain", resource.ProtocolResource.Meta["encoding"]?.ToString());
52+
Assert.Equal("cached", resource.ProtocolResource.Meta["caching"]?.ToString());
53+
}
54+
55+
[Fact]
56+
public void McpMetaAttribute_WithoutAttributes_ReturnsNull()
57+
{
58+
// Arrange
59+
var method = typeof(TestToolClass).GetMethod(nameof(TestToolClass.ToolWithoutMeta))!;
60+
61+
// Act
62+
var tool = McpServerTool.Create(method, null);
63+
64+
// Assert
65+
Assert.Null(tool.ProtocolTool.Meta);
66+
}
67+
68+
[Fact]
69+
public void McpMetaAttribute_SingleAttribute_PopulatesMeta()
70+
{
71+
// Arrange
72+
var method = typeof(TestToolClass).GetMethod(nameof(TestToolClass.ToolWithSingleMeta))!;
73+
74+
// Act
75+
var tool = McpServerTool.Create(method, null);
76+
77+
// Assert
78+
Assert.NotNull(tool.ProtocolTool.Meta);
79+
Assert.Equal("test-value", tool.ProtocolTool.Meta["test-key"]?.ToString());
80+
Assert.Single(tool.ProtocolTool.Meta);
81+
}
82+
83+
private class TestToolClass
84+
{
85+
[McpServerTool]
86+
[McpMeta(Name = "model", Value = "gpt-4o")]
87+
[McpMeta(Name = "version", Value = "1.0")]
88+
public static string ToolWithMeta(string input)
89+
{
90+
return input;
91+
}
92+
93+
[McpServerTool]
94+
public static string ToolWithoutMeta(string input)
95+
{
96+
return input;
97+
}
98+
99+
[McpServerTool]
100+
[McpMeta(Name = "test-key", Value = "test-value")]
101+
public static string ToolWithSingleMeta(string input)
102+
{
103+
return input;
104+
}
105+
}
106+
107+
private class TestPromptClass
108+
{
109+
[McpServerPrompt]
110+
[McpMeta(Name = "type", Value = "reasoning")]
111+
[McpMeta(Name = "model", Value = "claude-3")]
112+
public static string PromptWithMeta(string input)
113+
{
114+
return input;
115+
}
116+
}
117+
118+
private class TestResourceClass
119+
{
120+
[McpServerResource(UriTemplate = "resource://test/{id}")]
121+
[McpMeta(Name = "encoding", Value = "text/plain")]
122+
[McpMeta(Name = "caching", Value = "cached")]
123+
public static string ResourceWithMeta(string id)
124+
{
125+
return $"Resource content for {id}";
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)