Skip to content

Commit b9a802e

Browse files
authored
Update instructions for the C# Client Quickstart (modelcontextprotocol#379)
1 parent 3afdc13 commit b9a802e

File tree

1 file changed

+52
-42
lines changed

1 file changed

+52
-42
lines changed

docs/quickstart/client.mdx

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -560,13 +560,13 @@ async connectToServer(serverScriptPath: string) {
560560
? "python"
561561
: "python3"
562562
: process.execPath;
563-
563+
564564
this.transport = new StdioClientTransport({
565565
command,
566566
args: [serverScriptPath],
567567
});
568568
this.mcp.connect(this.transport);
569-
569+
570570
const toolsResult = await this.mcp.listTools();
571571
this.tools = toolsResult.tools.map((tool) => {
572572
return {
@@ -1370,7 +1370,7 @@ If you see:
13701370
</Tab>
13711371

13721372
<Tab title="C#">
1373-
[You can find the complete code for this tutorial here.](https://github.io/modelcontextprotocol/csharp-sdk/tree/main/samples/QuickstartClient)
1373+
[You can find the complete code for this tutorial here.](https://github.com/modelcontextprotocol/csharp-sdk/tree/main/samples/QuickstartClient)
13741374

13751375
## System Requirements
13761376
Before starting, ensure your system meets these requirements:
@@ -1403,14 +1403,19 @@ dotnet user-secrets set "ANTHROPIC_API_KEY" "<your key here>"
14031403

14041404
## Creating the Client
14051405
### Basic Client Structure
1406-
First, let's setup the basic client class:
1406+
First, let's setup the basic client class in the file `Program.cs`:
14071407
```csharp
1408+
using Anthropic.SDK;
1409+
using Microsoft.Extensions.AI;
14081410
using Microsoft.Extensions.Configuration;
14091411
using Microsoft.Extensions.Hosting;
1412+
using ModelContextProtocol.Client;
1413+
using ModelContextProtocol.Protocol.Transport;
14101414
1411-
var builder = Host.CreateEmptyApplicationBuilder(settings: null);
1415+
var builder = Host.CreateApplicationBuilder(args);
14121416
14131417
builder.Configuration
1418+
.AddEnvironmentVariables()
14141419
.AddUserSecrets<Program>();
14151420
```
14161421

@@ -1419,47 +1424,46 @@ This creates the beginnings of a .NET console application that can read the API
14191424
Next, we'll setup the MCP Client:
14201425

14211426
```csharp
1422-
var (command, arguments) = args switch
1423-
{
1424-
[var script] when script.EndsWith(".py") => ("python", script),
1425-
[var script] when script.EndsWith(".js") => ("node", script),
1426-
[var script] when Directory.Exists(script) || (File.Exists(script) && script.EndsWith(".csproj")) => ("dotnet", $"run --project {script} --no-build"),
1427-
_ => throw new NotSupportedException("An unsupported server script was provided. Supported scripts are .py, .js, or .csproj")
1428-
};
1427+
var (command, arguments) = GetCommandAndArguments(args);
14291428
1430-
await using var mcpClient = await McpClientFactory.CreateAsync(new()
1429+
var clientTransport = new StdioClientTransport(new()
14311430
{
1432-
Id = "demo-server",
14331431
Name = "Demo Server",
1434-
TransportType = TransportTypes.StdIo,
1435-
TransportOptions = new()
1436-
{
1437-
["command"] = command,
1438-
["arguments"] = arguments,
1439-
}
1432+
Command = command,
1433+
Arguments = arguments,
14401434
});
14411435
1436+
await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport);
1437+
14421438
var tools = await mcpClient.ListToolsAsync();
14431439
foreach (var tool in tools)
14441440
{
14451441
Console.WriteLine($"Connected to server with tools: {tool.Name}");
14461442
}
14471443
```
1448-
<Note>
1449-
Be sure to add the `using` statements for the namespaces:
1444+
1445+
Add this function at the end of the `Program.cs` file:
1446+
14501447
```csharp
1451-
using ModelContextProtocol.Client;
1452-
using ModelContextProtocol.Protocol.Transport;
1448+
static (string command, string[] arguments) GetCommandAndArguments(string[] args)
1449+
{
1450+
return args switch
1451+
{
1452+
[var script] when script.EndsWith(".py") => ("python", args),
1453+
[var script] when script.EndsWith(".js") => ("node", args),
1454+
[var script] when Directory.Exists(script) || (File.Exists(script) && script.EndsWith(".csproj")) => ("dotnet", ["run", "--project", script, "--no-build"]),
1455+
_ => throw new NotSupportedException("An unsupported server script was provided. Supported scripts are .py, .js, or .csproj")
1456+
};
1457+
}
14531458
```
1454-
</Note>
14551459

1456-
This configures a MCP client that will connect to a server that is provided as a command line argument. It then lists the available tools from the connected server.
1460+
This creates a MCP client that will connect to a server that is provided as a command line argument. It then lists the available tools from the connected server.
14571461

14581462
### Query processing logic
14591463
Now let's add the core functionality for processing queries and handling tool calls:
14601464

14611465
```csharp
1462-
using IChatClient anthropicClient = new AnthropicClient(new APIAuthentication(builder.Configuration["ANTHROPIC_API_KEY"]))
1466+
using var anthropicClient = new AnthropicClient(new APIAuthentication(builder.Configuration["ANTHROPIC_API_KEY"]))
14631467
.Messages
14641468
.AsBuilder()
14651469
.UseFunctionInvocation()
@@ -1472,29 +1476,34 @@ var options = new ChatOptions
14721476
Tools = [.. tools]
14731477
};
14741478
1475-
while (true)
1476-
{
1477-
Console.WriteLine("MCP Client Started!");
1478-
Console.WriteLine("Type your queries or 'quit' to exit.");
1479-
1480-
string? query = Console.ReadLine();
1479+
Console.ForegroundColor = ConsoleColor.Green;
1480+
Console.WriteLine("MCP Client Started!");
1481+
Console.ResetColor();
14811482
1483+
PromptForInput();
1484+
while(Console.ReadLine() is string query && !"exit".Equals(query, StringComparison.OrdinalIgnoreCase))
1485+
{
14821486
if (string.IsNullOrWhiteSpace(query))
14831487
{
1488+
PromptForInput();
14841489
continue;
14851490
}
1486-
if (string.Equals(query, "quit", StringComparison.OrdinalIgnoreCase))
1487-
{
1488-
break;
1489-
}
14901491
1491-
var response = anthropicClient.GetStreamingResponseAsync(query, options);
1492-
1493-
await foreach (var message in response)
1492+
await foreach (var message in anthropicClient.GetStreamingResponseAsync(query, options))
14941493
{
1495-
Console.Write(message.Text);
1494+
Console.Write(message);
14961495
}
14971496
Console.WriteLine();
1497+
1498+
PromptForInput();
1499+
}
1500+
1501+
static void PromptForInput()
1502+
{
1503+
Console.WriteLine("Enter a command (or 'exit' to quit):");
1504+
Console.ForegroundColor = ConsoleColor.Cyan;
1505+
Console.Write("> ");
1506+
Console.ResetColor();
14981507
}
14991508
```
15001509

@@ -1516,7 +1525,8 @@ while (true)
15161525
* The server processes the query and returns a response.
15171526
* The response is displayed to the user.
15181527

1519-
### Running the Client
1528+
## Running the Client
1529+
15201530
To run your client with any MCP server:
15211531
```bash
15221532
dotnet run -- path/to/server.csproj # dotnet server

0 commit comments

Comments
 (0)