Skip to content

Commit eaab1bf

Browse files
authored
Initial MCP Server implementation (microsoft#5610)
Discussion on further MCP work: microsoft#5609 ## Change This change adds an MCP server that provides two tools: - Find packages - Searches for packages based on a single input value, returning information about each one found. - Install package - Installs a package given a single input value, which is expected to be an identifier, name or moniker (same rules as `winget` CLI) The package response looks like: ```JSON { "identifier":"Microsoft.VisualStudioCode", "name":"Microsoft Visual Studio Code", "catalog":"winget", "isInstalled":true, "installedVersion":"1.102.1", "installedLocation":"%LOCALAPPDATA%\\Programs\\Microsoft VS Code\\", <- Is actually real path, not tokenized "isUpdateAvailable":false } ``` Also includes: - A group policy that determines whether the MCP server is allowed to operate - An `mcp` command that helps with manually configuring an MCP client - A change to the default COM caller behavior that makes it only use the file name - Also changes to not use the package family name if it is the same as the current process (so we can better differentiate our own callers) - A `Version` property on the `PackageManager` COM object that returns the version string as `1.2.3` or `1.2.3-preview`. - Start preferentially using this in the PowerShell module to get the version rather than running the CLI
1 parent b50a974 commit eaab1bf

File tree

63 files changed

+1256
-80
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1256
-80
lines changed

.github/actions/spelling/allow.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ MAKEINTRESOURCE
167167
makemsix
168168
MANIFESTSCHEMA
169169
MANIFESTVERSION
170+
mcp
170171
Memberwise
171172
meme
172173
metadatas

.github/actions/spelling/excludes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,5 @@
104104
^src/SfsClient/
105105
^src/Xlang/
106106
^src/VcpkgPortOverlay/
107+
^src/WinGetMCPServer/WinGetMCPServer.csproj$
107108
ignore$

doc/ReleaseNotes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## New in v1.12
2-
*No applicable update found*
2+
MCP server available; run `winget mcp` for assistance on configuring your client.
33

44
## Experimental Features
55
* Experimental support for Fonts

doc/admx/DesktopAppInstaller.admx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@
176176
<decimal value="0" />
177177
</disabledValue>
178178
</policy>
179+
<policy name="EnableWindowsPackageManagerMcpServer" class="Machine" displayName="$(string.EnableWindowsPackageManagerMcpServer)" explainText="$(string.EnableWindowsPackageManagerMcpServerExplanation)" key="Software\Policies\Microsoft\Windows\AppInstaller" valueName="EnableWindowsPackageManagerMcpServer">
180+
<parentCategory ref="AppInstaller" />
181+
<supportedOn ref="windows:SUPPORTED_Windows_10_0_RS5" />
182+
<enabledValue>
183+
<decimal value="1" />
184+
</enabledValue>
185+
<disabledValue>
186+
<decimal value="0" />
187+
</disabledValue>
188+
</policy>
179189
<policy name="WindowsPackageManagerDefaultProxy" class="Machine" displayName="$(string.WindowsPackageManagerDefaultProxy)" explainText="$(string.WindowsPackageManagerDefaultProxyExplanation)" presentation="$(presentation.WindowsPackageManagerDefaultProxy)" key="Software\Policies\Microsoft\Windows\AppInstaller">
180190
<parentCategory ref="AppInstaller" />
181191
<supportedOn ref="windows:SUPPORTED_Windows_10_0_RS5" />

doc/admx/en-US/DesktopAppInstaller.adml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ If you disable this setting, users will not be able to use the Windows Package M
116116
If you enable this setting, users will be able to configure the Windows Package Manager's use of proxy through the command line.
117117

118118
If you disable or do not configure this setting, users will not be able to to configure the Windows Package Manager's use of proxy through the command line.</string>
119+
<string id="EnableWindowsPackageManagerMcpServer">Enable Windows Package Manager MCP Server</string>
120+
<string id="EnableWindowsPackageManagerMcpServerExplanation">
121+
This policy controls whether the Windows Package Manager Model Context Protocol (MCP) server can be used.
122+
123+
If you enable or do not configure this setting, users will be able to use the Windows Package Manager's MCP server.
124+
125+
If you disable this setting, users will not be able to to use the Windows Package Manager's MCP server.</string>
119126
<string id="WindowsPackageManagerDefaultProxy">Set Windows Package Manager Default Proxy</string>
120127
<string id="WindowsPackageManagerDefaultProxyExplanation">This policy controls the default proxy used by the Windows Package Manager.
121128

src/AppInstallerCLI.sln

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "targets", "targets", "{A0B4
209209
EndProject
210210
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PureLib", "PureLib\PureLib.vcxitems", "{A33223D2-550B-4D99-A53D-488B1F68683E}"
211211
EndProject
212+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinGetMCPServer", "WinGetMCPServer\WinGetMCPServer.csproj", "{33745E4A-39E2-676F-7E23-50FB43848D25}"
213+
EndProject
212214
Global
213215
GlobalSection(SolutionConfigurationPlatforms) = preSolution
214216
Debug|ARM64 = Debug|ARM64
@@ -966,6 +968,30 @@ Global
966968
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU
967969
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU
968970
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU
971+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|ARM64.ActiveCfg = Debug|arm64
972+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|ARM64.Build.0 = Debug|arm64
973+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x64.ActiveCfg = Debug|x64
974+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x64.Build.0 = Debug|x64
975+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x86.ActiveCfg = Debug|x86
976+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x86.Build.0 = Debug|x86
977+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|ARM64.ActiveCfg = Release|arm64
978+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|ARM64.Build.0 = Release|arm64
979+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|x64.ActiveCfg = Release|x64
980+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|x64.Build.0 = Release|x64
981+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|x86.ActiveCfg = Release|x86
982+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Fuzzing|x86.Build.0 = Release|x86
983+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|ARM64.ActiveCfg = Release|arm64
984+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|ARM64.Build.0 = Release|arm64
985+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|x64.ActiveCfg = Release|x64
986+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|x64.Build.0 = Release|x64
987+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|x86.ActiveCfg = Release|x86
988+
{33745E4A-39E2-676F-7E23-50FB43848D25}.Release|x86.Build.0 = Release|x86
989+
{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|ARM64.ActiveCfg = Release|arm64
990+
{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|ARM64.Build.0 = Release|arm64
991+
{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|x64.ActiveCfg = Release|x64
992+
{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|x64.Build.0 = Release|x64
993+
{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|x86.ActiveCfg = Release|x86
994+
{33745E4A-39E2-676F-7E23-50FB43848D25}.ReleaseStatic|x86.Build.0 = Release|x86
969995
EndGlobalSection
970996
GlobalSection(SolutionProperties) = preSolution
971997
HideSolutionNode = FALSE

src/AppInstallerCLICore/AppInstallerCLICore.vcxproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@
325325
<ClInclude Include="Commands\FeaturesCommand.h" />
326326
<ClInclude Include="Commands\HashCommand.h" />
327327
<ClInclude Include="Commands\ListCommand.h" />
328+
<ClInclude Include="Commands\McpCommand.h" />
328329
<ClInclude Include="Commands\PinCommand.h" />
329330
<ClInclude Include="Commands\RepairCommand.h" />
330331
<ClInclude Include="Commands\SearchCommand.h" />
@@ -409,6 +410,7 @@
409410
<ClCompile Include="Commands\ErrorCommand.cpp" />
410411
<ClCompile Include="Commands\FontCommand.cpp" />
411412
<ClCompile Include="Commands\ImportCommand.cpp" />
413+
<ClCompile Include="Commands\McpCommand.cpp" />
412414
<ClCompile Include="Commands\PinCommand.cpp" />
413415
<ClCompile Include="Commands\RepairCommand.cpp" />
414416
<ClCompile Include="Commands\TestCommand.cpp" />
@@ -504,4 +506,4 @@
504506
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.230706.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorTextNuget)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.230706.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
505507
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.230706.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorTextNuget)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.230706.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
506508
</Target>
507-
</Project>
509+
</Project>

src/AppInstallerCLICore/AppInstallerCLICore.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@
293293
<ClInclude Include="Commands\DscAdminSettingsResource.h">
294294
<Filter>Commands\Configuration</Filter>
295295
</ClInclude>
296+
<ClInclude Include="Commands\McpCommand.h">
297+
<Filter>Commands</Filter>
298+
</ClInclude>
296299
</ItemGroup>
297300
<ItemGroup>
298301
<ClCompile Include="pch.cpp">
@@ -553,6 +556,9 @@
553556
<ClCompile Include="Commands\DscAdminSettingsResource.cpp">
554557
<Filter>Commands\Configuration</Filter>
555558
</ClCompile>
559+
<ClCompile Include="Commands\McpCommand.cpp">
560+
<Filter>Commands</Filter>
561+
</ClCompile>
556562
</ItemGroup>
557563
<ItemGroup>
558564
<None Include="PropertySheet.props" />

src/AppInstallerCLICore/Argument.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ namespace AppInstaller::CLI
211211
return { type, "accept-configuration-agreements"_liv };
212212
case Execution::Args::Type::ConfigurationSuppressPrologue:
213213
return { type, "suppress-initial-details"_liv };
214-
case Execution::Args::Type::ConfigurationEnable:
214+
case Execution::Args::Type::ExtendedFeaturesEnable:
215215
return { type, "enable"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::StubType };
216-
case Execution::Args::Type::ConfigurationDisable:
216+
case Execution::Args::Type::ExtendedFeaturesDisable:
217217
return { type, "disable"_liv, ArgTypeCategory::None, ArgTypeExclusiveSet::StubType };
218218
case Execution::Args::Type::ConfigurationModulePath:
219219
return { type, "module-path"_liv };

src/AppInstallerCLICore/Commands/ConfigureCommand.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ namespace AppInstaller::CLI
4141
Argument{ Execution::Args::Type::ConfigurationHistoryItem, Resource::String::ConfigurationHistoryItemArgumentDescription, ArgumentType::Standard, Argument::Visibility::Help },
4242
Argument{ Execution::Args::Type::ConfigurationAcceptWarning, Resource::String::ConfigurationAcceptWarningArgumentDescription, ArgumentType::Flag },
4343
Argument{ Execution::Args::Type::ConfigurationSuppressPrologue, Resource::String::ConfigurationSuppressPrologueArgumentDescription, ArgumentType::Flag, Argument::Visibility::Help },
44-
Argument{ Execution::Args::Type::ConfigurationEnable, Resource::String::ConfigurationEnableMessage, ArgumentType::Flag, Argument::Visibility::Help },
45-
Argument{ Execution::Args::Type::ConfigurationDisable, Resource::String::ConfigurationDisableMessage, ArgumentType::Flag, Argument::Visibility::Help },
44+
Argument{ Execution::Args::Type::ExtendedFeaturesEnable, Resource::String::ExtendedFeaturesEnableMessage, ArgumentType::Flag, Argument::Visibility::Help },
45+
Argument{ Execution::Args::Type::ExtendedFeaturesDisable, Resource::String::ExtendedFeaturesDisableMessage, ArgumentType::Flag, Argument::Visibility::Help },
4646
};
4747
}
4848

@@ -63,15 +63,15 @@ namespace AppInstaller::CLI
6363

6464
void ConfigureCommand::ExecuteInternal(Execution::Context& context) const
6565
{
66-
if (context.Args.Contains(Execution::Args::Type::ConfigurationEnable))
66+
if (context.Args.Contains(Execution::Args::Type::ExtendedFeaturesEnable))
6767
{
6868
context <<
69-
EnableConfiguration;
69+
EnableExtendedFeatures;
7070
}
71-
else if (context.Args.Contains(Execution::Args::Type::ConfigurationDisable))
71+
else if (context.Args.Contains(Execution::Args::Type::ExtendedFeaturesDisable))
7272
{
7373
context <<
74-
DisableConfiguration;
74+
DisableExtendedFeatures;
7575
}
7676
else
7777
{
@@ -90,12 +90,12 @@ namespace AppInstaller::CLI
9090

9191
void ConfigureCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const
9292
{
93-
if (execArgs.Contains(Execution::Args::Type::ConfigurationEnable) ||
94-
execArgs.Contains(Execution::Args::Type::ConfigurationDisable))
93+
if (execArgs.Contains(Execution::Args::Type::ExtendedFeaturesEnable) ||
94+
execArgs.Contains(Execution::Args::Type::ExtendedFeaturesDisable))
9595
{
9696
if (execArgs.GetArgsCount() > 1)
9797
{
98-
throw CommandException(Resource::String::ConfigurationEnableArgumentError);
98+
throw CommandException(Resource::String::ExtendedFeaturesEnableArgumentError);
9999
}
100100
}
101101
else

0 commit comments

Comments
 (0)