summaryrefslogtreecommitdiff
path: root/tests/Agent.Mcp.TestHost/ConformanceTools.cs
blob: 3d8879dc5e82200858d49d5621d056a6c494a52a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System.ComponentModel;
using ModelContextProtocol;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;

#pragma warning disable MCP9005 // The frozen alpha conformance fixture deliberately probes the legacy sampling capability.

namespace Agent.Mcp.TestHost;

[McpServerToolType]
public sealed class ConformanceTools
{
    [McpServerTool(Name = "test_missing_capability")]
    [Description("Conformance-only sampling capability probe.")]
    public async Task<string> TestMissingCapability(McpServer server, CancellationToken cancellationToken)
    {
        await server.SampleAsync(new CreateMessageRequestParams
        {
            MaxTokens = 1,
            Messages = [new SamplingMessage { Role = Role.User, Content = [new TextContentBlock { Text = "probe" }] }]
        }, cancellationToken).ConfigureAwait(false);
        return "sampled";
    }

    [McpServerTool(Name = "test_streaming_elicitation")]
    [Description("Conformance-only response-stream framing probe.")]
    public string TestStreamingElicitation() => "stream complete";

    [McpServerTool(Name = "test_logging_tool")]
    [Description("Conformance-only request log-level probe.")]
    public string TestLoggingTool() => "no request-scoped log emitted";

    [McpServerTool(Name = "confirm_delete")]
    [Description("Conformance-only elicitation task fixture.")]
    public string ConfirmDelete(RequestContext<CallToolRequestParams> context, string filename)
    {
        if (context.Params?.InputResponses?.Count > 0) return $"delete {filename}: accepted";
        throw new InputRequiredException(new Dictionary<string, InputRequest>
        {
            ["confirm-delete"] = Elicitation($"Confirm deletion of {filename}", "confirm", new ElicitRequestParams.BooleanSchema())
        }, "confirm-delete");
    }

    [McpServerTool(Name = "multi_input")]
    [Description("Conformance-only multiple elicitation task fixture.")]
    public string MultiInput(RequestContext<CallToolRequestParams> context)
    {
        if (context.Params?.InputResponses?.Count >= 2) return "both inputs received";
        throw new InputRequiredException(new Dictionary<string, InputRequest>
        {
            ["first"] = Elicitation("First confirmation", "confirm", new ElicitRequestParams.BooleanSchema()),
            ["second"] = Elicitation("Second confirmation", "confirm", new ElicitRequestParams.BooleanSchema())
        }, "multi-input");
    }

    [McpServerTool(Name = "test_tool_with_task")]
    [Description("Conformance-only MRTR and Tasks composition fixture.")]
    public string TestToolWithTask(RequestContext<CallToolRequestParams> context)
    {
        if (context.Params?.InputResponses is { Count: > 0 } responses)
        {
            string response = System.Text.Json.JsonSerializer.Serialize(responses);
            return response.Contains("Alice", StringComparison.Ordinal) ? "Hello, Alice" : "Hello, user";
        }
        throw new InputRequiredException(new Dictionary<string, InputRequest>
        {
            ["user-name"] = Elicitation("Provide a user name", "name", new ElicitRequestParams.StringSchema())
        }, "user-name");
    }

    private static InputRequest Elicitation(string message, string propertyName, ElicitRequestParams.PrimitiveSchemaDefinition schema) =>
        InputRequest.ForElicitation(new ElicitRequestParams
        {
            Mode = "form",
            Message = message,
            RequestedSchema = new ElicitRequestParams.RequestSchema
            {
                Properties = new Dictionary<string, ElicitRequestParams.PrimitiveSchemaDefinition> { [propertyName] = schema },
                Required = [propertyName]
            }
        });

    public sealed class Confirmation
    {
        public bool Confirm { get; set; }
    }

    public sealed class UserName
    {
        public string? Name { get; set; }
    }
}