Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
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 @@ -54,7 +54,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 @@ -222,7 +222,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 @@ -281,7 +281,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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ namespace ModelContextProtocol.Client;
/// </summary>
internal sealed partial class AutoDetectingClientSessionTransport : ITransport
{
private readonly SseClientTransportOptions _options;
private readonly HttpClientTransportOptions _options;
private readonly McpHttpClient _httpClient;
private readonly ILoggerFactory? _loggerFactory;
private readonly ILogger _logger;
private readonly string _name;
private readonly Channel<JsonRpcMessage> _messageChannel;

public AutoDetectingClientSessionTransport(string endpointName, SseClientTransportOptions transportOptions, McpHttpClient httpClient, ILoggerFactory? loggerFactory)
public AutoDetectingClientSessionTransport(string endpointName, HttpClientTransportOptions transportOptions, McpHttpClient httpClient, ILoggerFactory? loggerFactory)
{
Throw.IfNull(transportOptions);
Throw.IfNull(httpClient);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,26 @@ namespace ModelContextProtocol.Client;
/// Unlike the <see cref="StdioClientTransport"/>, this transport connects to an existing server
/// rather than launching a new process.
/// </remarks>
public sealed class SseClientTransport : IClientTransport, IAsyncDisposable
public sealed class HttpClientTransport : IClientTransport, IAsyncDisposable
{
private readonly SseClientTransportOptions _options;
private readonly HttpClientTransportOptions _options;
private readonly McpHttpClient _mcpHttpClient;
private readonly ILoggerFactory? _loggerFactory;

private readonly HttpClient? _ownedHttpClient;

/// <summary>
/// Initializes a new instance of the <see cref="SseClientTransport"/> class.
/// Initializes a new instance of the <see cref="HttpClientTransport"/> class.
/// </summary>
/// <param name="transportOptions">Configuration options for the transport.</param>
/// <param name="loggerFactory">Logger factory for creating loggers used for diagnostic output during transport operations.</param>
public SseClientTransport(SseClientTransportOptions transportOptions, ILoggerFactory? loggerFactory = null)
public HttpClientTransport(HttpClientTransportOptions transportOptions, ILoggerFactory? loggerFactory = null)
: this(transportOptions, new HttpClient(), loggerFactory, ownsHttpClient: true)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="SseClientTransport"/> class with a provided HTTP client.
/// Initializes a new instance of the <see cref="HttpClientTransport"/> class with a provided HTTP client.
/// </summary>
/// <param name="transportOptions">Configuration options for the transport.</param>
/// <param name="httpClient">The HTTP client instance used for requests.</param>
Expand All @@ -41,7 +41,7 @@ public SseClientTransport(SseClientTransportOptions transportOptions, ILoggerFac
/// <see langword="true"/> to dispose of <paramref name="httpClient"/> when the transport is disposed;
/// <see langword="false"/> if the caller is retaining ownership of the <paramref name="httpClient"/>'s lifetime.
/// </param>
public SseClientTransport(SseClientTransportOptions transportOptions, HttpClient httpClient, ILoggerFactory? loggerFactory = null, bool ownsHttpClient = false)
public HttpClientTransport(HttpClientTransportOptions transportOptions, HttpClient httpClient, ILoggerFactory? loggerFactory = null, bool ownsHttpClient = false)
{
Throw.IfNull(transportOptions);
Throw.IfNull(httpClient);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
namespace ModelContextProtocol.Client;

/// <summary>
/// Provides options for configuring <see cref="SseClientTransport"/> instances.
/// Provides options for configuring <see cref="HttpClientTransport"/> instances.
/// </summary>
public sealed class SseClientTransportOptions
public sealed class HttpClientTransportOptions
{
/// <summary>
/// Gets or sets the base address of the server for SSE connections.
Expand Down
4 changes: 2 additions & 2 deletions src/ModelContextProtocol.Core/Client/IClientTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace ModelContextProtocol.Client;
/// and servers, allowing different transport protocols to be used interchangeably.
/// </para>
/// <para>
/// When creating an <see cref="IMcpClient"/>, <see cref="McpClientFactory"/> is typically used, and is
/// When creating an <see cref="McpClient"/>, <see cref="McpClient"/> is typically used, and is
/// provided with the <see cref="IClientTransport"/> based on expected server configuration.
/// </para>
/// </remarks>
Expand Down Expand Up @@ -39,7 +39,7 @@ public interface IClientTransport
/// the transport session as well.
/// </para>
/// <para>
/// This method is used by <see cref="McpClientFactory"/> to initialize the connection.
/// This method is used by <see cref="McpClient"/> to initialize the connection.
/// </para>
/// </remarks>
/// <exception cref="InvalidOperationException">The transport connection could not be established.</exception>
Expand Down
5 changes: 3 additions & 2 deletions src/ModelContextProtocol.Core/Client/IMcpClient.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Protocol;

namespace ModelContextProtocol.Client;

/// <summary>
/// Represents an instance of a Model Context Protocol (MCP) client that connects to and communicates with an MCP server.
/// </summary>
[Obsolete($"Use {nameof(McpClient)} instead.")]
public interface IMcpClient : IMcpEndpoint
{
/// <summary>
Expand Down Expand Up @@ -44,4 +45,4 @@ public interface IMcpClient : IMcpEndpoint
/// </para>
/// </remarks>
string? ServerInstructions { get; }
}
}
Loading
Loading