Skip to content

Commit 53c461d

Browse files
committed
Added new FiggoTool to MCP Server. Created a new MCP Client Demo project MCPClientDemo
1 parent adb2098 commit 53c461d

File tree

7 files changed

+281
-10
lines changed

7 files changed

+281
-10
lines changed

Directory.Packages.props

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,37 @@
44
<System10Version>10.0.0-preview.3.25171.5</System10Version>
55
<MicrosoftExtensionsAIVersion>9.5.0</MicrosoftExtensionsAIVersion>
66
</PropertyGroup>
7-
87
<!-- Product dependencies netstandard -->
98
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
9+
<PackageVersion Include="McpDotNet.Extensions.AI" />
1010
<PackageVersion Include="Microsoft.Bcl.Memory" Version="9.0.4" />
1111
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
1212
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.3" />
1313
<PackageVersion Include="System.IO.Pipelines" Version="8.0.0" />
1414
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
1515
<PackageVersion Include="System.Threading.Channels" Version="8.0.0" />
1616
</ItemGroup>
17-
1817
<!-- Product dependencies LTS -->
1918
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
2019
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
2120
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.3" />
2221
<PackageVersion Include="System.IO.Pipelines" Version="8.0.0" />
2322
</ItemGroup>
24-
2523
<!-- Product dependencies .NET 9 -->
2624
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
2725
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.4" />
2826
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.4" />
2927
<PackageVersion Include="System.IO.Pipelines" Version="9.0.4" />
3028
</ItemGroup>
31-
3229
<!-- Product dependencies shared -->
3330
<ItemGroup>
3431
<PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="$(MicrosoftExtensionsAIVersion)" />
35-
<PackageVersion Include="Microsoft.Extensions.AI" Version="$(MicrosoftExtensionsAIVersion)" />
32+
<PackageVersion Include="Microsoft.Extensions.AI" Version="9.5.0" />
3633
<PackageVersion Include="System.Net.ServerSentEvents" Version="$(System10Version)" />
3734
</ItemGroup>
38-
3935
<ItemGroup>
40-
4136
<!-- Build Infra & Packaging -->
4237
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
43-
4438
<!-- Testing dependencies -->
4539
<PackageVersion Include="Anthropic.SDK" Version="5.2.3" />
4640
<PackageVersion Include="coverlet.collector" Version="6.0.4">
@@ -61,8 +55,8 @@
6155
<PackageVersion Include="OpenTelemetry.Exporter.InMemory" Version="1.11.2" />
6256
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.11.2" />
6357
<PackageVersion Include="OpenTelemetry.Instrumentation.Http " Version="1.11.0" />
64-
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.11.2" />
65-
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.11.1" />
58+
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.11.2" />
59+
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.11.1" />
6660
<PackageVersion Include="Serilog.Extensions.Hosting" Version="9.0.0" />
6761
<PackageVersion Include="Serilog.Extensions.Logging" Version="9.0.0" />
6862
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />

MCPClientDemo/MCPClientDemo.csproj

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.Extensions.AI" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<ProjectReference Include="..\src\ModelContextProtocol\ModelContextProtocol.csproj" />
16+
</ItemGroup>
17+
18+
</Project>

MCPClientDemo/Program.cs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using System;
2+
using System.Net.Http;
3+
using System.Net.Sockets;
4+
using System.Text;
5+
using System.Text.Json;
6+
using System.Threading.Tasks;
7+
using Microsoft.Extensions.AI;
8+
using Microsoft.Extensions.Logging;
9+
using ModelContextProtocol;
10+
using ModelContextProtocol.Client;
11+
12+
class Program
13+
{
14+
static async Task Main(string[] args)
15+
{
16+
await NpxDemo(args);
17+
}
18+
19+
static async Task NpxDemo(string[] args)
20+
{
21+
// Uncomment the following line to run the NpxDemo method
22+
// NpxDemo().GetAwaiter().GetResult();
23+
// To install npx, run the following command in a terminal after install node.js NPM:
24+
// <cmd> npm i -g npx </cmd>
25+
var clientTransport = new StdioClientTransport(new StdioClientTransportOptions
26+
{
27+
Name = "Everything",
28+
Command = "npx",
29+
Arguments = ["-y", "@modelcontextprotocol/server-everything"],
30+
});
31+
32+
var client = await McpClientFactory.CreateAsync(clientTransport);
33+
34+
// Print the list of tools available from the server.
35+
foreach (var tool in await client.ListToolsAsync())
36+
{
37+
Console.WriteLine($"{tool.Name} ({tool.Description})");
38+
}
39+
40+
// Execute a tool (this would normally be driven by LLM tool invocations).
41+
var result = await client.CallToolAsync(
42+
"echo",
43+
new Dictionary<string, object?>() { ["message"] = "Hello MCP!" },
44+
cancellationToken: CancellationToken.None);
45+
46+
// echo always returns one and only one text content object
47+
Console.WriteLine(result.Content.First(c => c.Type == "text").Text);
48+
}
49+
50+
51+
static async Task DockerDemo(string[] args)
52+
{
53+
//Console.WriteLine("Hello, Microsoft.Extensions.AI with Ollama & MCP Server !");
54+
//var message = "What is the current (CET) time in Illzach, France?";
55+
//Console.WriteLine(message);
56+
57+
//// 👇🏼 Configure the Model Context Protocol server to use
58+
//var config = new McpServerConfig
59+
//{
60+
// Id = "time",
61+
// Name = "Time MCP Server",
62+
// TransportType = TransportTypes.StdIo,
63+
// TransportOptions = new Dictionary<string, string>
64+
// {
65+
// // 👇🏼 The command executed to start the MCP server
66+
// ["command"] = "docker",
67+
// ["arguments"] = "run -i --rm mcp/time"
68+
// }
69+
//};
70+
71+
//// 👇🏼 Get an MCP session scope used to get the MCP tools
72+
//await using var sessionScope = await McpSessionScope.CreateAsync(config);
73+
//using var factory =
74+
// LoggerFactory.Create(builder => builder.AddConsole().SetMinimumLevel(LogLevel.Trace));
75+
76+
//// 👇🏼 Use Ollama as the chat client
77+
//var ollamaChatClient =
78+
// new OllamaChatClient(new Uri("http://localhost:11434/"), "llama3.2:3b");
79+
//var client = new ChatClientBuilder(ollamaChatClient)
80+
// // 👇🏼 Add logging to the chat client, wrapping the function invocation client
81+
// .UseLogging(factory)
82+
// // 👇🏼 Add function invocation to the chat client, wrapping the Ollama client
83+
// .UseFunctionInvocation()
84+
// .Build();
85+
86+
//IList<ChatMessage> messages =
87+
//[
88+
// new(ChatRole.System, """
89+
// You are a helpful assistant delivering time in one sentence
90+
// in a short format, like 'It is 10:08 in Paris, France.'
91+
// """),
92+
// new(ChatRole.User, message)
93+
//];
94+
95+
//// 👇🏼 Pass the MCP tools to the chat client
96+
//var response =
97+
// await client.GetResponseAsync(
98+
// messages,
99+
// new ChatOptions { Tools = sessionScope.Tools });
100+
101+
//Console.WriteLine(response);
102+
}
103+
}

ModelContextProtocol.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelContextProtocol.AspNet
5656
EndProject
5757
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelContextProtocol.AspNetCore.Tests", "tests\ModelContextProtocol.AspNetCore.Tests\ModelContextProtocol.AspNetCore.Tests.csproj", "{85557BA6-3D29-4C95-A646-2A972B1C2F25}"
5858
EndProject
59+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MCPClientDemo", "MCPClientDemo\MCPClientDemo.csproj", "{46553E45-FA74-4379-83AD-2D5946C90313}"
60+
EndProject
5961
Global
6062
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6163
Debug|Any CPU = Debug|Any CPU
@@ -110,6 +112,10 @@ Global
110112
{85557BA6-3D29-4C95-A646-2A972B1C2F25}.Debug|Any CPU.Build.0 = Debug|Any CPU
111113
{85557BA6-3D29-4C95-A646-2A972B1C2F25}.Release|Any CPU.ActiveCfg = Release|Any CPU
112114
{85557BA6-3D29-4C95-A646-2A972B1C2F25}.Release|Any CPU.Build.0 = Release|Any CPU
115+
{46553E45-FA74-4379-83AD-2D5946C90313}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
116+
{46553E45-FA74-4379-83AD-2D5946C90313}.Debug|Any CPU.Build.0 = Debug|Any CPU
117+
{46553E45-FA74-4379-83AD-2D5946C90313}.Release|Any CPU.ActiveCfg = Release|Any CPU
118+
{46553E45-FA74-4379-83AD-2D5946C90313}.Release|Any CPU.Build.0 = Release|Any CPU
113119
EndGlobalSection
114120
GlobalSection(SolutionProperties) = preSolution
115121
HideSolutionNode = FALSE
@@ -128,6 +134,7 @@ Global
128134
{17B8453F-AB72-99C5-E5EA-D0B065A6AE65} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
129135
{37B6A5E0-9995-497D-8B43-3BC6870CC716} = {A2F1F52A-9107-4BF8-8C3F-2F6670E7D0AD}
130136
{85557BA6-3D29-4C95-A646-2A972B1C2F25} = {2A77AF5C-138A-4EBB-9A13-9205DCD67928}
137+
{46553E45-FA74-4379-83AD-2D5946C90313} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
131138
EndGlobalSection
132139
GlobalSection(ExtensibilityGlobals) = postSolution
133140
SolutionGuid = {384A3888-751F-4D75-9AE5-587330582D89}

samples/ChatWithTools/Class1.cs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//using Microsoft.Extensions.AI;
2+
//using Microsoft.Extensions.Logging;
3+
//using ModelContextProtocol.Client;
4+
//using OpenTelemetry;
5+
//using OpenTelemetry.Logs;
6+
//using OpenTelemetry.Metrics;
7+
//using OpenTelemetry.Trace;
8+
//using System.Net.Http.Json;
9+
//using System.Text.Json;
10+
11+
//using var tracerProvider = Sdk.CreateTracerProviderBuilder()
12+
// .AddHttpClientInstrumentation()
13+
// .AddSource("*")
14+
// .AddOtlpExporter()
15+
// .Build();
16+
17+
//using var metricsProvider = Sdk.CreateMeterProviderBuilder()
18+
// .AddHttpClientInstrumentation()
19+
// .AddMeter("*")
20+
// .AddOtlpExporter()
21+
// .Build();
22+
23+
//using var loggerFactory = LoggerFactory.Create(builder => builder.AddOpenTelemetry(opt => opt.AddOtlpExporter()));
24+
//var logger = loggerFactory.CreateLogger<Program>();
25+
26+
//Console.WriteLine("Starting local LLaMA 3.2 client via Ollama...");
27+
28+
//// IChatClient backed by Ollama via local HTTP
29+
//var chatClient = new OllamaChatClient("llama3");
30+
31+
//// Hook up telemetry and tool invocation
32+
//using var samplingClient = chatClient.AsIChatClient()
33+
// .AsBuilder()
34+
// .UseOpenTelemetry(loggerFactory: loggerFactory, configure: o => o.EnableSensitiveData = true)
35+
// .Build();
36+
37+
//// Start MCP with tool access
38+
//var mcpClient = await McpClientFactory.CreateAsync(
39+
// new StdioClientTransport(new()
40+
// {
41+
// Command = "npx",
42+
// Arguments = ["-y", "--verbose", "@modelcontextprotocol/server-everything"],
43+
// Name = "Everything",
44+
// }),
45+
// clientOptions: new()
46+
// {
47+
// Capabilities = new()
48+
// {
49+
// Sampling = new()
50+
// {
51+
// SamplingHandler = samplingClient.CreateSamplingHandler()
52+
// }
53+
// },
54+
// },
55+
// loggerFactory: loggerFactory);
56+
57+
//Console.WriteLine("Tools available:");
58+
//var tools = await mcpClient.ListToolsAsync();
59+
//foreach (var tool in tools)
60+
//{
61+
// Console.WriteLine($" {tool}");
62+
//}
63+
64+
//Console.WriteLine();
65+
66+
//// Set up chat loop
67+
//using var interactiveClient = chatClient.AsIChatClient()
68+
// .AsBuilder()
69+
// .UseFunctionInvocation()
70+
// .UseOpenTelemetry(loggerFactory: loggerFactory, configure: o => o.EnableSensitiveData = true)
71+
// .Build();
72+
73+
//List<ChatMessage> messages = [];
74+
//while (true)
75+
//{
76+
// Console.Write("Q: ");
77+
// var userInput = Console.ReadLine();
78+
// if (string.IsNullOrWhiteSpace(userInput))
79+
// break;
80+
81+
// messages.Add(new(ChatRole.User, userInput));
82+
83+
// List<ChatResponseUpdate> updates = [];
84+
// await foreach (var update in interactiveClient.GetStreamingResponseAsync(messages, new() { Tools = [.. tools] }))
85+
// {
86+
// Console.Write(update);
87+
// updates.Add(update);
88+
// }
89+
90+
// Console.WriteLine();
91+
// messages.AddMessages(updates);
92+
//}
93+
94+
//public class OllamaChatClient : IChatClient
95+
//{
96+
// private readonly HttpClient _client = new() { BaseAddress = new Uri("http://localhost:11434") };
97+
// private readonly string _model;
98+
99+
// public OllamaChatClient(string model)
100+
// {
101+
// _model = model;
102+
// }
103+
104+
// public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
105+
// IReadOnlyList<ChatMessage> messages, ChatRequestOptions? options = null)
106+
// {
107+
// var requestBody = new
108+
// {
109+
// model = _model,
110+
// messages = messages.Select(m => new { role = m.Role.ToString().ToLower(), content = m.Content })
111+
// };
112+
113+
// var response = await _client.PostAsJsonAsync("/api/chat", requestBody);
114+
// response.EnsureSuccessStatusCode();
115+
116+
// var json = await response.Content.ReadFromJsonAsync<JsonElement>();
117+
// var content = json.GetProperty("message").GetProperty("content").GetString();
118+
119+
// yield return new ChatResponseUpdate(ChatRole.Assistant, content ?? "");
120+
// }
121+
//}

samples/EverythingServer/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
.WithTools<PrintEnvTool>()
3636
.WithTools<SampleLlmTool>()
3737
.WithTools<TinyImageTool>()
38+
.WithTools<FiggoTool>()
3839
.WithPrompts<ComplexPromptType>()
3940
.WithPrompts<SimplePromptType>()
4041
.WithResources<SimpleResourceType>()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using ModelContextProtocol.Server;
8+
9+
namespace EverythingServer.Tools
10+
{
11+
[McpServerToolType]
12+
public class FiggoTool
13+
{
14+
[McpServerTool(Name = "FiggoAge"), Description("Answer how old Figgo is")]
15+
public static int howOldIsFiggo() => DateTime.Now.Year - 1976;
16+
17+
[McpServerTool(Name = "FiggoInfo"),Description("Describe who Figgo is")]
18+
public static string whoIsFiggo() => $"Figgo is Chief Technology Officer and Senior Vice President at Home Partners. " +
19+
"Figgo develops enterprise software solutions that enable the company to better engage with residents and manage its portfolio of homes." +
20+
" He works with cross-functional teams to establish and implement data and technology strategies while driving innovation. Prior to " +
21+
"joining us in 2015, Figgo held a variety of software development and systems integration roles at Morningstar in the United States and China. " +
22+
"Based in Chicago, Figgo earned a B.S. in Engineering from South China University of Technology. Here is the linkedin https://www.linkedin.com/in/figgo/";
23+
24+
25+
26+
}
27+
}

0 commit comments

Comments
 (0)