Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ dotnet add package ModelContextProtocol --prerelease

## Getting Started (Client)

To get started writing a client, the `McpClientFactory.CreateAsync` method is used to instantiate and connect an `IMcpClient`
to a server. Once you have an `IMcpClient`, you can interact with it, such as to enumerate all available tools and invoke tools.
To get started writing a client, the `McpClient.CreateAsync` method is used to instantiate and connect an `McpClient`
to a server. Once you have an `McpClient`, you can interact with it, such as to enumerate all available tools and invoke tools.

```csharp
var clientTransport = new StdioClientTransport(new StdioClientTransportOptions
Expand All @@ -48,7 +48,7 @@ var clientTransport = new StdioClientTransport(new StdioClientTransportOptions
Arguments = ["-y", "@modelcontextprotocol/server-everything"],
});

var client = await McpClientFactory.CreateAsync(clientTransport);
var client = await McpClient.CreateAsync(clientTransport);

// Print the list of tools available from the server.
foreach (var tool in await client.ListToolsAsync())
Expand Down Expand Up @@ -224,7 +224,7 @@ McpServerOptions options = new()
},
};

await using IMcpServer server = McpServerFactory.Create(new StdioServerTransport("MyServer"), options);
await using IMcpServer server = McpServer.Create(new StdioServerTransport("MyServer"), options);
await server.RunAsync();
```

Expand Down
6 changes: 3 additions & 3 deletions docs/concepts/elicitation/elicitation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ The **elicitation** feature allows servers to request additional information fro

### Server Support for Elicitation

Servers request structured data from users with the [ElicitAsync] extension method on [IMcpServer].
The C# SDK registers an instance of [IMcpServer] with the dependency injection container,
so tools can simply add a parameter of type [IMcpServer] to their method signature to access it.
Servers request structured data from users with the [ElicitAsync] extension method on [McpServer].
The C# SDK registers an instance of [McpServer] with the dependency injection container,
so tools can simply add a parameter of type [McpServer] to their method signature to access it.

[ElicitAsync]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.McpServerExtensions.html#ModelContextProtocol_Server_McpServerExtensions_ElicitAsync_ModelContextProtocol_Server_IMcpServer_ModelContextProtocol_Protocol_ElicitRequestParams_System_Threading_CancellationToken_
[IMcpServer]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html
Expand Down
4 changes: 2 additions & 2 deletions docs/concepts/elicitation/samples/client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

var endpoint = Environment.GetEnvironmentVariable("ENDPOINT") ?? "http://localhost:3001";

var clientTransport = new SseClientTransport(new()
var clientTransport = new HttpClientTransport(new()
{
Endpoint = new Uri(endpoint),
TransportMode = HttpTransportMode.StreamableHttp,
Expand All @@ -27,7 +27,7 @@
}
};

await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport, options);
await using var mcpClient = await McpClient.CreateAsync(clientTransport, options);
// </snippet_McpInitialize>

var tools = await mcpClient.ListToolsAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public sealed class InteractiveTools
// <snippet_GuessTheNumber>
[McpServerTool, Description("A simple game where the user has to guess a number between 1 and 10.")]
public async Task<string> GuessTheNumber(
IMcpServer server, // Get the McpServer from DI container
McpServer server, // Get the McpServer from DI container
CancellationToken token
)
{
Expand Down
10 changes: 5 additions & 5 deletions docs/concepts/logging/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ messages as there may not be an open connection to the client on which the log m

The C# SDK provides an extension method [WithSetLoggingLevelHandler] on [IMcpServerBuilder] to allow the
server to perform any special logic it wants to perform when a client sets the logging level. However, the
SDK already takes care of setting the [LoggingLevel] in the [IMcpServer], so most servers will not need to
SDK already takes care of setting the [LoggingLevel] in the [McpServer], so most servers will not need to
implement this.

[IMcpServer]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html
[McpServer]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html
[IMcpServerBuilder]: https://modelcontextprotocol.github.io/csharp-sdk/api/Microsoft.Extensions.DependencyInjection.IMcpServerBuilder.html
[WithSetLoggingLevelHandler]: https://modelcontextprotocol.github.io/csharp-sdk/api/Microsoft.Extensions.DependencyInjection.McpServerBuilderExtensions.html#Microsoft_Extensions_DependencyInjection_McpServerBuilderExtensions_WithSetLoggingLevelHandler_Microsoft_Extensions_DependencyInjection_IMcpServerBuilder_System_Func_ModelContextProtocol_Server_RequestContext_ModelContextProtocol_Protocol_SetLevelRequestParams__System_Threading_CancellationToken_System_Threading_Tasks_ValueTask_ModelContextProtocol_Protocol_EmptyResult___
[LoggingLevel]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html#ModelContextProtocol_Server_IMcpServer_LoggingLevel

MCP Servers using the MCP C# SDK can obtain an [ILoggerProvider] from the IMcpServer [AsClientLoggerProvider] extension method,
MCP Servers using the MCP C# SDK can obtain an [ILoggerProvider] from the McpServer [AsClientLoggerProvider] extension method,
and from that can create an [ILogger] instance for logging messages that should be sent to the MCP client.

[!code-csharp[](samples/server/Tools/LoggingTools.cs?name=snippet_LoggingConfiguration)]
Expand All @@ -75,14 +75,14 @@ the logging level to specify which messages the server should send to the client

Clients should check if the server supports logging by checking the [Logging] property of the [ServerCapabilities] field of [IMcpClient].

[IMcpClient]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.IMcpClient.html
[McpClient]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.IMcpClient.html
[ServerCapabilities]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.IMcpClient.html#ModelContextProtocol_Client_IMcpClient_ServerCapabilities
[Logging]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Protocol.ServerCapabilities.html#ModelContextProtocol_Protocol_ServerCapabilities_Logging

[!code-csharp[](samples/client/Program.cs?name=snippet_LoggingCapabilities)]

If the server supports logging, the client should set the level of log messages it wishes to receive with
the [SetLoggingLevel] method on [IMcpClient]. If the client does not set a logging level, the server might choose
the [SetLoggingLevel] method on [McpClient]. If the client does not set a logging level, the server might choose
to send all log messages or none -- this is not specified in the protocol -- so it is important that the client
sets a logging level to ensure it receives the desired log messages and only those messages.

Expand Down
4 changes: 2 additions & 2 deletions docs/concepts/logging/samples/client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

var endpoint = Environment.GetEnvironmentVariable("ENDPOINT") ?? "http://localhost:3001";

var clientTransport = new SseClientTransport(new()
var clientTransport = new HttpClientTransport(new()
{
Endpoint = new Uri(endpoint),
TransportMode = HttpTransportMode.StreamableHttp,
});

await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport);
await using var mcpClient = await McpClient.CreateAsync(clientTransport);

// <snippet_LoggingCapabilities>
// Verify that the server supports logging
Expand Down
12 changes: 6 additions & 6 deletions docs/concepts/progress/progress.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ This project illustrates the common case of a server tool that performs a long-r

### Server Implementation

When processing a request, the server can use the [sendNotificationAsync] extension method of [IMcpServer] to send progress updates,
When processing a request, the server can use the [sendNotificationAsync] extension method of [McpServer] to send progress updates,
specifying `"notifications/progress"` as the notification method name.
The C# SDK registers an instance of [IMcpServer] with the dependency injection container,
so tools can simply add a parameter of type [IMcpServer] to their method signature to access it.
The C# SDK registers an instance of [McpServer] with the dependency injection container,
so tools can simply add a parameter of type [McpServer] to their method signature to access it.
The parameters passed to [sendNotificationAsync] should be an instance of [ProgressNotificationParams], which includes the current progress, total steps, and an optional message.

[sendNotificationAsync]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.McpEndpointExtensions.html#ModelContextProtocol_McpEndpointExtensions_SendNotificationAsync_ModelContextProtocol_IMcpEndpoint_System_String_System_Threading_CancellationToken_
[IMcpServer]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html
[McpServer]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html
[ProgressNotificationParams]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Protocol.ProgressNotificationParams.html

The server must verify that the caller provided a `progressToken` in the request and include it in the call to [sendNotificationAsync]. The following example demonstrates how a server can send a progress notification:
Expand All @@ -38,9 +38,9 @@ Note that servers are not required to support progress tracking, so clients shou

In the MCP C# SDK, clients can specify a `progressToken` in the request parameters when calling a tool method.
The client should also provide a notification handler to process "notifications/progress" notifications.
There are two way to do this. The first is to register a notification handler using the [RegisterNotificationHandler] method on the [IMcpClient] instance. A handler registered this way will receive all progress notifications sent by the server.
There are two way to do this. The first is to register a notification handler using the [RegisterNotificationHandler] method on the [McpClient] instance. A handler registered this way will receive all progress notifications sent by the server.

[IMcpClient]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.IMcpClient.html
[McpClient]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.IMcpClient.html
[RegisterNotificationHandler]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.IMcpEndpoint.html#ModelContextProtocol_IMcpEndpoint_RegisterNotificationHandler_System_String_System_Func_ModelContextProtocol_Protocol_JsonRpcNotification_System_Threading_CancellationToken_System_Threading_Tasks_ValueTask__

```csharp
Expand Down
4 changes: 2 additions & 2 deletions docs/concepts/progress/samples/client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

var endpoint = Environment.GetEnvironmentVariable("ENDPOINT") ?? "http://localhost:3001";

var clientTransport = new SseClientTransport(new()
var clientTransport = new HttpClientTransport(new()
{
Endpoint = new Uri(endpoint),
TransportMode = HttpTransportMode.StreamableHttp,
Expand All @@ -20,7 +20,7 @@
}
};

await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport, options);
await using var mcpClient = await McpClient.CreateAsync(clientTransport, options);

var tools = await mcpClient.ListToolsAsync();
foreach (var tool in tools)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class LongRunningTools
{
[McpServerTool, Description("Demonstrates a long running tool with progress updates")]
public static async Task<string> LongRunningTool(
IMcpServer server,
McpServer server,
RequestContext<CallToolRequestParams> context,
int duration = 10,
int steps = 5)
Expand Down
2 changes: 1 addition & 1 deletion samples/AspNetCoreMcpServer/Tools/SampleLlmTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public sealed class SampleLlmTool
{
[McpServerTool(Name = "sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
public static async Task<string> SampleLLM(
IMcpServer thisServer,
McpServer thisServer,
[Description("The prompt to send to the LLM")] string prompt,
[Description("Maximum number of tokens to generate")] int maxTokens,
CancellationToken cancellationToken)
Expand Down
2 changes: 1 addition & 1 deletion samples/ChatWithTools/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
.UseOpenTelemetry(loggerFactory: loggerFactory, configure: o => o.EnableSensitiveData = true)
.Build();

var mcpClient = await McpClientFactory.CreateAsync(
var mcpClient = await McpClient.CreateAsync(
new StdioClientTransport(new()
{
Command = "npx",
Expand Down
2 changes: 1 addition & 1 deletion samples/EverythingServer/LoggingUpdateMessageSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace EverythingServer;

public class LoggingUpdateMessageSender(IMcpServer server, Func<LoggingLevel> getMinLevel) : BackgroundService
public class LoggingUpdateMessageSender(McpServer server, Func<LoggingLevel> getMinLevel) : BackgroundService
{
readonly Dictionary<LoggingLevel, string> _loggingLevelMap = new()
{
Expand Down
2 changes: 1 addition & 1 deletion samples/EverythingServer/SubscriptionMessageSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using ModelContextProtocol;
using ModelContextProtocol.Server;

internal class SubscriptionMessageSender(IMcpServer server, HashSet<string> subscriptions) : BackgroundService
internal class SubscriptionMessageSender(McpServer server, HashSet<string> subscriptions) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
Expand Down
2 changes: 1 addition & 1 deletion samples/EverythingServer/Tools/LongRunningTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class LongRunningTool
{
[McpServerTool(Name = "longRunningOperation"), Description("Demonstrates a long running operation with progress updates")]
public static async Task<string> LongRunningOperation(
IMcpServer server,
McpServer server,
RequestContext<CallToolRequestParams> context,
int duration = 10,
int steps = 5)
Expand Down
2 changes: 1 addition & 1 deletion samples/EverythingServer/Tools/SampleLlmTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class SampleLlmTool
{
[McpServerTool(Name = "sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
public static async Task<string> SampleLLM(
IMcpServer server,
McpServer server,
[Description("The prompt to send to the LLM")] string prompt,
[Description("Maximum number of tokens to generate")] int maxTokens,
CancellationToken cancellationToken)
Expand Down
4 changes: 2 additions & 2 deletions samples/InMemoryTransport/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Pipe clientToServerPipe = new(), serverToClientPipe = new();

// Create a server using a stream-based transport over an in-memory pipe.
await using IMcpServer server = McpServerFactory.Create(
await using McpServer server = McpServer.Create(
new StreamServerTransport(clientToServerPipe.Reader.AsStream(), serverToClientPipe.Writer.AsStream()),
new McpServerOptions()
{
Expand All @@ -21,7 +21,7 @@
_ = server.RunAsync();

// Connect a client using a stream-based transport over the same in-memory pipe.
await using IMcpClient client = await McpClientFactory.CreateAsync(
await using McpClient client = await McpClient.CreateAsync(
new StreamClientTransport(clientToServerPipe.Writer.AsStream(), serverToClientPipe.Reader.AsStream()));

// List all tools.
Expand Down
4 changes: 2 additions & 2 deletions samples/ProtectedMcpClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
builder.AddConsole();
});

var transport = new SseClientTransport(new()
var transport = new HttpClientTransport(new()
{
Endpoint = new Uri(serverUrl),
Name = "Secure Weather Client",
Expand All @@ -40,7 +40,7 @@
}
}, httpClient, consoleLoggerFactory);

var client = await McpClientFactory.CreateAsync(transport, loggerFactory: consoleLoggerFactory);
var client = await McpClient.CreateAsync(transport, loggerFactory: consoleLoggerFactory);

var tools = await client.ListToolsAsync();
if (tools.Count == 0)
Expand Down
6 changes: 3 additions & 3 deletions samples/QuickstartClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
if (command == "http")
{
// make sure AspNetCoreMcpServer is running
clientTransport = new SseClientTransport(new()
clientTransport = new HttpClientTransport(new()
{
Endpoint = new Uri("http://localhost:3001")
});
Expand All @@ -33,7 +33,7 @@
Arguments = arguments,
});
}
await using var mcpClient = await McpClientFactory.CreateAsync(clientTransport!);
await using var mcpClient = await McpClient.CreateAsync(clientTransport!);

var tools = await mcpClient.ListToolsAsync();
foreach (var tool in tools)
Expand Down Expand Up @@ -62,7 +62,7 @@
var sb = new StringBuilder();

PromptForInput();
while(Console.ReadLine() is string query && !"exit".Equals(query, StringComparison.OrdinalIgnoreCase))
while (Console.ReadLine() is string query && !"exit".Equals(query, StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrWhiteSpace(query))
{
Expand Down
2 changes: 1 addition & 1 deletion samples/TestServerWithHosting/Tools/SampleLlmTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public sealed class SampleLlmTool
{
[McpServerTool(Name = "sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
public static async Task<string> SampleLLM(
IMcpServer thisServer,
McpServer thisServer,
[Description("The prompt to send to the LLM")] string prompt,
[Description("Maximum number of tokens to generate")] int maxTokens,
CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class HttpServerTransportOptions
/// Gets or sets an optional asynchronous callback for running new MCP sessions manually.
/// This is useful for running logic before a sessions starts and after it completes.
/// </summary>
public Func<HttpContext, IMcpServer, CancellationToken, Task>? RunSessionHandler { get; set; }
public Func<HttpContext, McpServer, CancellationToken, Task>? RunSessionHandler { get; set; }

/// <summary>
/// Gets or sets whether the server should run in a stateless mode that does not require all requests for a given session
Expand Down
2 changes: 1 addition & 1 deletion src/ModelContextProtocol.AspNetCore/SseHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public async Task HandleSseRequestAsync(HttpContext context)

try
{
await using var mcpServer = McpServerFactory.Create(transport, mcpServerOptions, loggerFactory, context.RequestServices);
await using var mcpServer = McpServer.Create(transport, mcpServerOptions, loggerFactory, context.RequestServices);
context.Features.Set(mcpServer);

var runSessionAsync = httpMcpServerOptions.Value.RunSessionHandler ?? StreamableHttpHandler.RunSessionAsync;
Expand Down
4 changes: 2 additions & 2 deletions src/ModelContextProtocol.AspNetCore/StreamableHttpHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ private async ValueTask<StreamableHttpSession> CreateSessionAsync(
}
}

var server = McpServerFactory.Create(transport, mcpServerOptions, loggerFactory, mcpServerServices);
var server = McpServer.Create(transport, mcpServerOptions, loggerFactory, mcpServerServices);
context.Features.Set(server);

var userIdClaim = statelessId?.UserIdClaim ?? GetUserIdClaim(context.User);
Expand Down Expand Up @@ -307,7 +307,7 @@ private void ScheduleStatelessSessionIdWrite(HttpContext context, StreamableHttp
};
}

internal static Task RunSessionAsync(HttpContext httpContext, IMcpServer session, CancellationToken requestAborted)
internal static Task RunSessionAsync(HttpContext httpContext, McpServer session, CancellationToken requestAborted)
=> session.RunAsync(requestAborted);

// SignalR only checks for ClaimTypes.NameIdentifier in HttpConnectionDispatcher, but AspNetCore.Antiforgery checks that plus the sub and UPN claims.
Expand Down
4 changes: 2 additions & 2 deletions src/ModelContextProtocol.AspNetCore/StreamableHttpSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace ModelContextProtocol.AspNetCore;
internal sealed class StreamableHttpSession(
string sessionId,
StreamableHttpServerTransport transport,
IMcpServer server,
McpServer server,
UserIdClaim? userId,
StatefulSessionManager sessionManager) : IAsyncDisposable
{
Expand All @@ -20,7 +20,7 @@ internal sealed class StreamableHttpSession(

public string Id => sessionId;
public StreamableHttpServerTransport Transport => transport;
public IMcpServer Server => server;
public McpServer Server => server;
private StatefulSessionManager SessionManager => sessionManager;

public CancellationToken SessionClosed => _disposeCts.Token;
Expand Down
9 changes: 9 additions & 0 deletions src/ModelContextProtocol.Core/AssemblyNameHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Reflection;

namespace ModelContextProtocol;

internal static class AssemblyNameHelper
{
/// <summary>Cached naming information used for MCP session name/version when none is specified.</summary>
public static AssemblyName DefaultAssemblyName { get; } = (Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly()).GetName();
}
Loading
Loading