Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 25, 2025

Closes #1008

MCP Inspector hardcodes npx for running the inspector. This PR adds support for pnpm dlx and yarn dlx via .WithYarn() and .WithPnpm() extension methods, consistent with how other JavaScript integrations in Aspire handle package manager selection.

Changes

  • McpInspectorResource: Updated to store package name for runtime argument configuration
  • McpInspectorResourceBuilderExtensions:
    • Added WithInspectorArgs to dynamically set args based on package manager annotation (dlx for yarn/pnpm, -y for npm)
    • Added custom WithYarn() and WithPnpm() extension methods that configure the package manager and command
  • README: Updated documentation with new API usage examples

Usage

// Using yarn
var inspector = builder.AddMcpInspector("inspector")
    .WithYarn()
    .WithMcpServer(mcpServer);

// Using pnpm
var inspector = builder.AddMcpInspector("inspector")
    .WithPnpm()
    .WithMcpServer(mcpServer);

PR Checklist

  • Created a feature/dev branch in your fork (vs. submitting directly from a commit on main)
  • Based off latest main branch of toolkit
  • PR doesn't include merge commits (always rebase on top of our main, if needed)
  • Tests for the changes have been added (for bug fixes / features) (if applicable)
  • Contains NO breaking changes
  • Every new API (including internal ones) has full XML docs
  • Code follows all style conventions

Other information

  • 6 new unit tests added covering package manager annotation setup and argument generation
  • README updated with documentation for the new .WithYarn() and .WithPnpm() methods
  • Backward compatible: defaults to npm/npx behavior
  • Follows Aspire API design pattern where users chain .WithYarn() or .WithPnpm() after creating the resource, consistent with how other JavaScript resources work in Aspire
Original prompt

This section details on the original issue you should resolve

<issue_title>Support alternative package managers in MCP Inspector integration</issue_title>
<issue_description>### Related to an existing integration?

Yes

Existing integration

McpInspector

Overview

Currently, the Aspire MCP Inspector integration defaults to using npx for Node.js tooling invocation. However, developers who prefer or require alternative package managers like pnpm or yarn (using their respective pnpm dlx or yarn dlx commands) are unable to leverage their tool of choice directly when working with this integration. The Node.js Aspire extension, as documented at https://aspire.dev/integrations/frameworks/nodejs-extensions/, already provides the ability to specify which package manager should be used, falling back to npx if none is supplied. Ensuring consistent extensibility between the MCP Inspector and the Node.js Aspire framework will improve usability and flexibility for projects leveraging different JS package managers.

Usage example

Add an option or configuration property to the MCP Inspector integration, such as PackageManager, allowing the user to select their preferred Node.js package manager. For instance:

  • If PackageManager is set to pnpm, run commands using pnpm dlx.
  • If set to yarn, use yarn dlx.
  • If not specified, default to using npx for compatibility with current behavior.

Example API usage:

{
.WithPnpm()
}

This would translate command invocations to use pnpm dlx under the hood when the MCP Inspector runs Node.js-based tools.

Breaking change?

No

Alternatives

Currently, the only approach is to use the default NPX-based invocation, or roll your own model context protocol inspector integration into Aspire.

Additional context

Reference for Node.js Aspire extension's implementation: https://aspire.dev/integrations/frameworks/nodejs-extensions/

Help us help you

Yes, I'd like to be assigned to work on this item</issue_description>

<agent_instructions>The MCP inspector resource uses the base JavaScriptAppResource (from memory), so the methods should be usable, but it might not be respecting what is set.

It'd be worth reviewing how the Turbo Repo and Nx resources also work as that might help with the plan</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>
Copilot AI changed the title [WIP] Support alternative package managers in MCP Inspector integration Support alternative package managers in MCP Inspector integration Nov 25, 2025
Copilot AI requested a review from aaronpowell November 25, 2025 23:56
@aaronpowell
Copy link
Member

@copilot this doesn't really fit with the API design of Aspire, instead refer to https://aspire.dev/whats-new/aspire-13/#package-manager-flexibility on how JavaScript apps can work with different package managers and adapt to that

…thYarn() and .WithPnpm() methods

Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 26, 2025

@copilot this doesn't really fit with the API design of Aspire, instead refer to https://aspire.dev/whats-new/aspire-13/#package-manager-flexibility on how JavaScript apps can work with different pack...

Refactored in commit 3915676 to follow the Aspire API design pattern. Users can now chain .WithYarn() or .WithPnpm() after creating the inspector:

var inspector = builder.AddMcpInspector("inspector")
    .WithYarn()
    .WithMcpServer(mcpServer);

This is consistent with how other JavaScript resources work in Aspire. The implementation uses the SDK's JavaScriptHostingExtensions.WithYarn/WithPnpm to set up the package manager annotation, and dynamically sets the correct arguments (dlx for yarn/pnpm, -y for npm) at runtime.

@aaronpowell aaronpowell marked this pull request as ready for review December 1, 2025 00:30
Copilot AI review requested due to automatic review settings December 1, 2025 00:30
@github-actions
Copy link
Contributor

github-actions bot commented Dec 1, 2025

Code Coverage

Package Line Rate Branch Rate Complexity Health
CommunityToolkit.Aspire.GoFeatureFlag 100% 97% 74
CommunityToolkit.Aspire.Hosting.ActiveMQ 78% 40% 108
CommunityToolkit.Aspire.Hosting.ActiveMQ.MassTransit 1% 0% 14
CommunityToolkit.Aspire.Hosting.Adminer 74% 50% 20
CommunityToolkit.Aspire.Hosting.Azure.Dapr 29% 7% 124
CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis 61% 34% 76
CommunityToolkit.Aspire.Hosting.Azure.DataApiBuilder 100% 100% 22
CommunityToolkit.Aspire.Hosting.Bun 96% 83% 28
CommunityToolkit.Aspire.Hosting.Dapr 60% 37% 840
CommunityToolkit.Aspire.Hosting.DbGate 94% 50% 18
CommunityToolkit.Aspire.Hosting.Deno 98% 85% 44
CommunityToolkit.Aspire.Hosting.Flagd 79% 100% 32
CommunityToolkit.Aspire.Hosting.GoFeatureFlag 88% 73% 36
CommunityToolkit.Aspire.Hosting.Golang 51% 40% 88
CommunityToolkit.Aspire.Hosting.Java 70% 75% 130
CommunityToolkit.Aspire.Hosting.JavaScript.Extensions 97% 85% 200
CommunityToolkit.Aspire.Hosting.k6 58% 12% 20
CommunityToolkit.Aspire.Hosting.Keycloak.Extensions 100% 100% 22
CommunityToolkit.Aspire.Hosting.KurrentDB 71% 75% 34
CommunityToolkit.Aspire.Hosting.LavinMQ 74% 50% 26
CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit 1% 0% 14
CommunityToolkit.Aspire.Hosting.MailPit 85% 50% 22
CommunityToolkit.Aspire.Hosting.McpInspector 79% 50% 168
CommunityToolkit.Aspire.Hosting.Meilisearch 71% 57% 58
CommunityToolkit.Aspire.Hosting.Minio 88% 75% 56
CommunityToolkit.Aspire.Hosting.MongoDB.Extensions 96% 83% 36
CommunityToolkit.Aspire.Hosting.MySql.Extensions 100% 88% 78
CommunityToolkit.Aspire.Hosting.Ngrok 52% 35% 82
CommunityToolkit.Aspire.Hosting.Ollama 65% 69% 260
CommunityToolkit.Aspire.Hosting.OpenTelemetryCollector 78% 61% 77
CommunityToolkit.Aspire.Hosting.PapercutSmtp 81% 50% 18
CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions 99% 89% 84
CommunityToolkit.Aspire.Hosting.Python.Extensions 45% 29% 100
CommunityToolkit.Aspire.Hosting.RavenDB 62% 48% 148
CommunityToolkit.Aspire.Hosting.Redis.Extensions 100% 71% 48
CommunityToolkit.Aspire.Hosting.Rust 94% 83% 16
CommunityToolkit.Aspire.Hosting.Solr 72% 100% 22
CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects 51% 48% 192
CommunityToolkit.Aspire.Hosting.Sqlite 89% 89% 52
CommunityToolkit.Aspire.Hosting.SqlServer.Extensions 100% 87% 78
CommunityToolkit.Aspire.Hosting.SurrealDb 55% 40% 256
CommunityToolkit.Aspire.KurrentDB 94% 92% 54
CommunityToolkit.Aspire.MassTransit.RabbitMQ 100% 100% 30
CommunityToolkit.Aspire.Meilisearch 97% 92% 68
CommunityToolkit.Aspire.Microsoft.Data.Sqlite 89% 85% 52
CommunityToolkit.Aspire.Microsoft.EntityFrameworkCore.Sqlite 61% 58% 114
CommunityToolkit.Aspire.Minio.Client 90% 85% 112
CommunityToolkit.Aspire.OllamaSharp 77% 71% 132
CommunityToolkit.Aspire.RavenDB.Client 60% 53% 237
CommunityToolkit.Aspire.SurrealDb 79% 63% 78
Summary 68% (7270 / 10690) 56% (2074 / 3698) 4698

Minimum allowed line rate is 60%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for alternative JavaScript package managers (yarn and pnpm) to the MCP Inspector integration, addressing issue #1008. The implementation follows a simpler approach than the Nx/Turborepo pattern by directly manipulating the command and arguments rather than using package manager annotations, which is appropriate given that MCP Inspector is a leaf resource without child apps.

Key Changes:

  • Added WithYarn() and WithPnpm() extension methods for configuring package manager
  • Modified McpInspectorResource to store package name for dynamic argument configuration
  • Updated argument generation logic to use dlx for yarn/pnpm and -y for npm/npx
  • Added comprehensive test coverage for new package manager functionality

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
src/CommunityToolkit.Aspire.Hosting.McpInspector/McpInspectorResource.cs Added packageName constructor parameter to support dynamic command configuration; property stores npm package name
src/CommunityToolkit.Aspire.Hosting.McpInspector/McpInspectorResourceBuilderExtensions.cs Added WithYarn() and WithPnpm() methods; refactored to use WithInspectorArgs for dynamic argument generation based on package manager
tests/CommunityToolkit.Aspire.Hosting.McpInspector.Tests/McpInspectorResourceBuilderExtensionsTests.cs Added 6 new tests covering package manager command setup and argument generation for npm, yarn, and pnpm
src/CommunityToolkit.Aspire.Hosting.McpInspector/README.md Added documentation section explaining alternative package manager usage with code examples; fixed typo in ClientPort default value
.devcontainer/devcontainer.json Configured node feature to disable yarn installation via apt

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/node:latest": {},
"ghcr.io/devcontainers/features/node:latest": {
"installYarnUsingApt": false,
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing comma after false should be removed. JSON doesn't allow trailing commas in object properties.

Suggested change
"installYarnUsingApt": false,
"installYarnUsingApt": false

Copilot uses AI. Check for mistakes.
/// <param name="name">The name of the resource.</param>
public class McpInspectorResource(string name) : JavaScriptAppResource(name, "npx", "")
/// <param name="packageName">The npm package name for the MCP Inspector.</param>
public class McpInspectorResource(string name, string packageName) : JavaScriptAppResource(name, "npx", "")
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a required packageName parameter to the constructor is a breaking change for anyone directly instantiating McpInspectorResource. Consider making the parameter optional with a default value (e.g., string packageName = "@modelcontextprotocol/inspector@" + InspectorVersion) or providing a constructor overload to maintain backward compatibility.

Suggested change
public class McpInspectorResource(string name, string packageName) : JavaScriptAppResource(name, "npx", "")
public class McpInspectorResource(string name, string packageName = "@modelcontextprotocol/inspector@" + InspectorVersion) : JavaScriptAppResource(name, "npx", "")

Copilot uses AI. Check for mistakes.
var appBuilder = DistributedApplication.CreateBuilder();

// Act
var inspector = appBuilder.AddMcpInspector("inspector");
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call to obsolete method AddMcpInspector.

Suggested change
var inspector = appBuilder.AddMcpInspector("inspector");
var inspector = appBuilder.AddMcpInspectorResource("inspector");

Copilot uses AI. Check for mistakes.
var appBuilder = DistributedApplication.CreateBuilder();

// Act
var inspector = appBuilder.AddMcpInspector("inspector")
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call to obsolete method AddMcpInspector.

Copilot uses AI. Check for mistakes.
var appBuilder = DistributedApplication.CreateBuilder();

// Act
var inspector = appBuilder.AddMcpInspector("inspector")
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call to obsolete method AddMcpInspector.

Copilot uses AI. Check for mistakes.
var appBuilder = DistributedApplication.CreateBuilder();

// Act
var inspector = appBuilder.AddMcpInspector("inspector")
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment to inspector is useless, since its value is never read.

Suggested change
var inspector = appBuilder.AddMcpInspector("inspector")
appBuilder.AddMcpInspector("inspector")

Copilot uses AI. Check for mistakes.
var appBuilder = DistributedApplication.CreateBuilder();

// Act
var inspector = appBuilder.AddMcpInspector("inspector")
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment to inspector is useless, since its value is never read.

Suggested change
var inspector = appBuilder.AddMcpInspector("inspector")
appBuilder.AddMcpInspector("inspector")

Copilot uses AI. Check for mistakes.
Comment on lines +560 to +564
var inspector = appBuilder.AddMcpInspector("inspector", options =>
{
options.InspectorVersion = "0.15.0";
})
.WithYarn();
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment to inspector is useless, since its value is never read.

Copilot uses AI. Check for mistakes.
Comment on lines +587 to +591
var inspector = appBuilder.AddMcpInspector("inspector", options =>
{
options.InspectorVersion = "0.15.0";
})
.WithPnpm();
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment to inspector is useless, since its value is never read.

Copilot uses AI. Check for mistakes.
Comment on lines +614 to +617
var inspector = appBuilder.AddMcpInspector("inspector", options =>
{
options.InspectorVersion = "0.15.0";
});
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment to inspector is useless, since its value is never read.

Copilot uses AI. Check for mistakes.
@aaronpowell aaronpowell merged commit 4ef7859 into main Dec 3, 2025
106 of 107 checks passed
@aaronpowell aaronpowell deleted the copilot/support-alternative-package-managers branch December 3, 2025 00:30
@aaronpowell aaronpowell added this to the 13.1 milestone Dec 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support alternative package managers in MCP Inspector integration

2 participants