Skip to content

MCP Inspector integration #625

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 8, 2025
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
Hosting.Java.Tests,
Hosting.LavinMQ.Tests,
Hosting.MailPit.Tests,
Hosting.McpInspector.Tests,
Hosting.Meilisearch.Tests,
Hosting.MongoDB.Extensions.Tests,
Hosting.MySql.Extensions.Tests,
Expand Down Expand Up @@ -124,4 +125,3 @@ jobs:
with:
name: testresults-${{ matrix.name }}-${{ matrix.os }}
path: testresults/**

6 changes: 6 additions & 0 deletions CommunityToolkit.Aspire.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
<Project Path="examples/masstransit-rabbitmq/CommunityToolkit.Aspire.MassTransit.RabbitMQ.MessageTypes/CommunityToolkit.Aspire.MassTransit.RabbitMQ.MessageTypes.csproj" />
<Project Path="examples/masstransit-rabbitmq/CommunityToolkit.Aspire.MassTransit.RabbitMQ.Publisher/CommunityToolkit.Aspire.MassTransit.RabbitMQ.Publisher.csproj" />
</Folder>
<Folder Name="/examples/mcp-inspector/">
<Project Path="examples/mcp-inspector/CommunityToolkit.Aspire.Hosting.McpInspector.AppHost/CommunityToolkit.Aspire.Hosting.McpInspector.AppHost.csproj" />
<Project Path="examples/mcp-inspector/CommunityToolkit.Aspire.Hosting.McpInspector.McpServer/CommunityToolkit.Aspire.Hosting.McpInspector.McpServer.csproj" />
</Folder>
<Folder Name="/examples/meilisearch/">
<Project Path="examples/meilisearch/CommunityToolkit.Aspire.Hosting.Meilisearch.ApiService/CommunityToolkit.Aspire.Hosting.Meilisearch.ApiService.csproj" />
<Project Path="examples/meilisearch/CommunityToolkit.Aspire.Hosting.Meilisearch.AppHost/CommunityToolkit.Aspire.Hosting.Meilisearch.AppHost.csproj" />
Expand Down Expand Up @@ -150,6 +154,7 @@
<Project Path="src/CommunityToolkit.Aspire.Hosting.k6/CommunityToolkit.Aspire.Hosting.k6.csproj" />
<Project Path="src/CommunityToolkit.Aspire.Hosting.LavinMQ/CommunityToolkit.Aspire.Hosting.LavinMQ.csproj" />
<Project Path="src/CommunityToolkit.Aspire.Hosting.MailPit/CommunityToolkit.Aspire.Hosting.MailPit.csproj" />
<Project Path="src/CommunityToolkit.Aspire.Hosting.McpInspector/CommunityToolkit.Aspire.Hosting.McpInspector.csproj" />
<Project Path="src/CommunityToolkit.Aspire.Hosting.Meilisearch/CommunityToolkit.Aspire.Hosting.Meilisearch.csproj" />
<Project Path="src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.csproj" />
<Project Path="src/CommunityToolkit.Aspire.Hosting.MySql.Extensions/CommunityToolkit.Aspire.Hosting.MySql.Extensions.csproj" />
Expand Down Expand Up @@ -194,6 +199,7 @@
<Project Path="tests/CommunityToolkit.Aspire.Hosting.k6.Tests/CommunityToolkit.Aspire.Hosting.k6.Tests.csproj" />
<Project Path="tests/CommunityToolkit.Aspire.Hosting.LavinMQ.Tests/CommunityToolkit.Aspire.Hosting.LavinMQ.Tests.csproj" />
<Project Path="tests/CommunityToolkit.Aspire.Hosting.MailPit.Tests/CommunityToolkit.Aspire.Hosting.MailPit.Tests.csproj" />
<Project Path="tests/CommunityToolkit.Aspire.Hosting.McpInspector.Tests/CommunityToolkit.Aspire.Hosting.McpInspector.Tests.csproj" />
<Project Path="tests/CommunityToolkit.Aspire.Hosting.Meilisearch.Tests/CommunityToolkit.Aspire.Hosting.Meilisearch.Tests.csproj" />
<Project Path="tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests.csproj" />
<Project Path="tests/CommunityToolkit.Aspire.Hosting.MySql.Extensions.Tests/CommunityToolkit.Aspire.Hosting.MySql.Extensions.Tests.csproj" />
Expand Down
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="7.3.1" />
<PackageVersion Include="Microsoft.PowerShell.SDK" Version="7.4.10" />
<PackageVersion Include="ModelContextProtocol" Version="0.3.0-preview.1" />
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="0.3.0-preview.1" />
</ItemGroup>
<ItemGroup Label="Testing">
<!-- Testing packages -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<Sdk Name="Aspire.AppHost.Sdk" Version="$(AspireAppHostSdkVersion)" />

<PropertyGroup>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>985811f2-fd0c-480a-885b-bc6cc0574b62</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../../../src/CommunityToolkit.Aspire.Hosting.McpInspector/CommunityToolkit.Aspire.Hosting.McpInspector.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="../CommunityToolkit.Aspire.Hosting.McpInspector.McpServer/CommunityToolkit.Aspire.Hosting.McpInspector.McpServer.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var builder = DistributedApplication.CreateBuilder(args);

var server = builder.AddProject<Projects.CommunityToolkit_Aspire_Hosting_McpInspector_McpServer>("mcp-server");

builder.AddMcpInspector("mcp-inspector")
.WithMcpServer(server)
;

builder.Build().Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:17118;http://localhost:15207",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21173",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22290"
}
},
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15207",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19133",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20023"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<ItemGroup>
<PackageReference Include="ModelContextProtocol" />
<PackageReference Include="ModelContextProtocol.AspNetCore" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using ModelContextProtocol.Server;
using System.ComponentModel;

var builder = WebApplication.CreateBuilder(args);

builder.Services
.AddMcpServer()
.WithHttpTransport()
.WithTools<McpServerTools>();

var app = builder.Build();

app.MapMcp();

app.Run();

[McpServerToolType]
class McpServerTools
{
[McpServerTool, Description("An echo tool")]
public static string Echo(string message) => $"Echo: {message}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5230",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7295;http://localhost:5230",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>An Aspire to run the MCP Inspector against a MCP server.</Description>
<AdditionalPackageTags>ai mcp debugging hosting</AdditionalPackageTags>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.Diagnostics.CodeAnalysis;

namespace Aspire.Hosting.ApplicationModel;

/// <summary>
/// Resource for the MCP Inspector server.
/// </summary>
/// <param name="name">The name of the resource.</param>
public class McpInspectorResource(string name) : ExecutableResource(name, "npx", "")
{
internal readonly string ConfigPath = Path.GetTempFileName();

/// <summary>
/// The name of the client endpoint.
/// </summary>
public const string ClientEndpointName = "client";

private EndpointReference? _clientEndpoint;

/// <summary>
/// Gets the client endpoint reference for the MCP Inspector.
/// </summary>
public EndpointReference ClientEndpoint => _clientEndpoint ??= new(this, ClientEndpointName);

/// <summary>
/// The name of the server proxy endpoint.
/// </summary>
public const string ServerProxyEndpointName = "server-proxy";

private EndpointReference? _serverProxyEndpoint;

/// <summary>
/// Gets the server proxy endpoint reference for the MCP Inspector.
/// </summary>
public EndpointReference ServerProxyEndpoint => _serverProxyEndpoint ??= new(this, ServerProxyEndpointName);

/// <summary>
/// Gets the version of the MCP Inspector.
/// </summary>
public const string InspectorVersion = "0.15.0";

private readonly List<McpServerMetadata> _mcpServers = [];

private McpServerMetadata? _defaultMcpServer;

/// <summary>
/// List of MCP server resources that this inspector is aware of.
/// </summary>
public IReadOnlyList<McpServerMetadata> McpServers => _mcpServers;

/// <summary>
/// Gets the default MCP server resource.
/// </summary>
public McpServerMetadata? DefaultMcpServer => _defaultMcpServer;

internal void AddMcpServer(IResourceWithEndpoints mcpServer, bool isDefault, McpTransportType transportType)
{
if (_mcpServers.Any(s => s.Name == mcpServer.Name))
{
throw new InvalidOperationException($"The MCP server {mcpServer.Name} is already added to the MCP Inspector resource.");
}

McpServerMetadata item = new(
mcpServer.Name,
mcpServer.GetEndpoint("http") ?? throw new InvalidOperationException($"The MCP server {mcpServer.Name} must have a 'http' endpoint defined."),
transportType);

_mcpServers.Add(item);

if (isDefault)
{
_defaultMcpServer = item;
}
}
}
Loading
Loading