diff --git a/README.md b/README.md index 9cc82e4..105bd40 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # multi-pwsh -Install and manage side-by-side PowerShell versions with aliases and native hosting. +Install and manage side-by-side PowerShell versions with aliases, offline bundles, native hosting, module venvs, and MCP command exposure. ![multi-pwsh](docs/images/multi-pwsh.png) @@ -93,6 +93,7 @@ Rerun the bootstrap script against a newer warmed bundle to update `multi-pwsh` ## More docs - [Native host mode and virtual environments](docs/host-and-venv.md) +- [MCP host mode](docs/mcp.md) - [Feature matrix and roadmap](docs/feature-matrix.md) - [Testing guide](docs/testing.md) - [Release process](RELEASE.md) @@ -218,6 +219,8 @@ multi-pwsh venv list ```text multi-pwsh --version +multi-pwsh -V +multi-pwsh version multi-pwsh --help multi-pwsh help [command] multi-pwsh install [--scope ] [--root ] [--arch ] [--include-prerelease] [--offline-cache ] [--add-path|--no-add-path] [--register-manifest|--no-register-manifest] [--enable-psremoting] [--disable-telemetry] [--add-explorer-context-menu] [--add-file-context-menu] @@ -234,6 +237,7 @@ multi-pwsh alias set multi-pwsh alias set multi-pwsh alias unset multi-pwsh host [-VirtualEnvironment |-venv ] [pwsh arguments...] +multi-pwsh host -mcp -McpCommands [command ...] [-VirtualEnvironment |-venv ] multi-pwsh doctor --repair-aliases ``` @@ -269,11 +273,12 @@ The current LTS line is encoded in the tool; at the moment that is `7.6`. - `multi-pwsh host ...` runs PowerShell through native hosting instead of launching a `pwsh` subprocess. - Use `-venv ` or `-VirtualEnvironment ` to select a managed module root for hosted launches. +- Use `-mcp -McpCommands [command ...]` to expose selected PowerShell commands as stdio MCP tools from the chosen hosted version. - Use `multi-pwsh doctor --repair-aliases` to repair host shims and named aliases. Advanced local replacement mode is also supported: if `multi-pwsh` is renamed to `pwsh`/`pwsh.exe` and placed beside `pwsh.dll` plus `pwsh.runtimeconfig.json`, it runs that adjacent payload directly from the executable directory instead of resolving the managed `pwsh` alias or searching `PATH`. -See [docs/host-and-venv.md](docs/host-and-venv.md) for host shims, local replacement mode, venv layout, import/export, managed paths, and current limitations. +See [docs/host-and-venv.md](docs/host-and-venv.md) for host shims, local replacement mode, venv layout, import/export, managed paths, and current limitations. See [docs/mcp.md](docs/mcp.md) for MCP host mode. ## CLI NuGet package and AppHost mode diff --git a/docs/feature-matrix.md b/docs/feature-matrix.md index cb18f8f..687f577 100644 --- a/docs/feature-matrix.md +++ b/docs/feature-matrix.md @@ -12,8 +12,10 @@ This matrix reflects the current command surface and known gaps for `multi-pwsh` | Update | `multi-pwsh update ` | Channel updates behave like installing the newest matching channel. Line updates refresh line, major, and managed named alias policies after installing the newest patch. `--root` requires explicit `--scope `. | | Uninstall | `multi-pwsh uninstall [--scope ] [--root ] [--force]` | Removes managed files and updates aliases that referenced the removed version. User scope is the default; machine removals require explicit `--scope machine`. | | List | `multi-pwsh list [--scope ] [--root ] [--available] [--include-prerelease]` | Installed listing shows paths, resolved aliases, named alias policies, and minor pins. Available listing queries GitHub releases; installed listings include prerelease versions automatically. | +| Offline cache | `multi-pwsh cache warm [--os ] [--arch ]` | Creates relocatable offline release bundles containing PowerShell archives, checksums, manifests, and optional `multi-pwsh` release artifacts. | | Alias | `multi-pwsh alias set/unset` for `major.minor`, `pwsh`, `pwsh-preview`, and `pwsh-lts` | Minor aliases can be pinned or follow latest in line. Named aliases store policies and resolve only to installed versions. | | Host | `multi-pwsh host [pwsh arguments...]` | Runs through the native host. Alias shims can invoke host mode implicitly from the managed bin directory; a renamed local `pwsh`/`pwsh.exe` can also host an adjacent `pwsh.dll` plus `pwsh.runtimeconfig.json` SDK payload. | +| MCP host bridge | `multi-pwsh host -mcp -McpCommands [command ...]` | Starts a stdio MCP server over a hosted PowerShell runspace and exposes selected commands as tools. Extra `pwsh` arguments are rejected in MCP mode; `-venv` is supported. | | Virtual environments | `multi-pwsh venv create/delete/export/import/list` plus host `-VirtualEnvironment` / `-venv` | Provides a managed module root for hosted PowerShell launches. | | Doctor | `multi-pwsh doctor --repair-aliases` | Repairs host shims, alias files, and managed named alias policy resolutions. | | Package subcommand | `multi-pwsh package install/uninstall/list` | Advanced compatibility command for the scoped install backend; prefer top-level install, update, uninstall, and list. | @@ -77,6 +79,7 @@ Install, update, uninstall, and `doctor --repair-aliases` all reconcile aliases. | Implicit shim host mode | Yes | Alias shims detect their own name and layout, then run the matching selector. | | Local `pwsh` apphost replacement | Yes | Exact `pwsh`/`pwsh.exe` beside `pwsh.dll` and `pwsh.runtimeconfig.json` bypasses alias policy and hosts that adjacent payload directly. | | Reusable AppHost NuGet mode | Yes | `Devolutions.MultiPwsh.Cli` packages RID-specific binaries and opt-in `buildTransitive` targets for downstream apphost replacement. | +| MCP stdio server | Yes | Exposes explicitly selected PowerShell commands as MCP tools using the selected hosted version; tool names normalize to `powershell_*`. | | Virtual environment module path | Yes | Host mode sets startup-hook environment variables and bootstraps module cmdlet aliases for `-Command` and stdin `-File -` scenarios. | | Venv archive import/export | Yes | ZIP import rejects absolute paths and parent-directory traversal. | diff --git a/docs/host-and-venv.md b/docs/host-and-venv.md index e39993d..627c2db 100644 --- a/docs/host-and-venv.md +++ b/docs/host-and-venv.md @@ -13,6 +13,7 @@ - Direct `multi-pwsh host`, `alias`, `doctor`, and `venv` commands operate on the default user layout. Machine-scope aliases are normally entered through the generated machine-scope shims, which carry layout hints. - Copying or renaming `multi-pwsh.exe` to an alias-like name such as `pwsh-7.4.exe` also enters implicit host mode. - `-NamedPipeCommand ` is supported in host mode on Windows. +- `-mcp -McpCommands [command ...]` starts the hosted runspace as a stdio MCP server that exposes selected PowerShell commands as tools. See [MCP host mode](mcp.md). ### Local `pwsh` apphost replacement mode diff --git a/docs/mcp.md b/docs/mcp.md new file mode 100644 index 0000000..58592e0 --- /dev/null +++ b/docs/mcp.md @@ -0,0 +1,59 @@ +# MCP host mode + +`multi-pwsh` can expose selected PowerShell commands as Model Context Protocol (MCP) tools over stdio while running them inside a specific installed PowerShell version. Use this when an MCP client needs predictable PowerShell version selection, native host startup behavior, and optional module venv isolation. + +## Start a server + +```powershell +multi-pwsh install 7.4 +multi-pwsh host 7.4 -mcp -McpCommands Get-Process Get-Service +``` + +`-McpCommands` accepts one or more command names after the flag. Values may also be comma- or semicolon-separated: + +```powershell +multi-pwsh host stable -mcp -McpCommands 'Get-ChildItem,Get-Content' +multi-pwsh host pwsh-7.4 -mcp -McpCommands 'Get-Process;Get-Service' +``` + +MCP mode is part of host mode, so the selector can be any selector supported by `multi-pwsh host`: an exact version, major version, major/minor line, or managed alias such as `pwsh`, `pwsh-preview`, `pwsh-lts`, or `pwsh-7.4`. + +An MCP client configuration typically launches `multi-pwsh` as a stdio server: + +```json +{ + "command": "multi-pwsh", + "args": ["host", "7.4", "-mcp", "-McpCommands", "Get-Process", "Get-Service"] +} +``` + +## Tool shape + +At startup, the bridge resolves each listed command with `Get-Command` in the selected PowerShell runspace and builds an MCP tool from the command metadata. + +- Tool names are prefixed with `powershell_` and normalized to lowercase ASCII with separators converted to `_`; for example, `Get-Process` becomes `powershell_get_process`. +- Tool descriptions use the command help synopsis when available, then fall back to the command definition. +- Mandatory PowerShell parameters become required JSON properties. +- Switch parameters become booleans. Integer, number, array, object, and string parameters are mapped to the closest JSON schema type. +- Commands that normalize to the same MCP tool name are rejected at startup. + +Tool calls splat the JSON arguments into the PowerShell command and return the command output after `Out-String`. `null` values, empty arrays, and `false` switch values are omitted before invocation so PowerShell defaults still apply. + +## Venv support + +`-venv ` and `-VirtualEnvironment ` work in MCP mode: + +```powershell +multi-pwsh venv create graph +multi-pwsh host 7.4 -mcp -McpCommands Get-Module -venv graph +``` + +The selected venv changes module discovery for both command metadata discovery and later tool calls. Path-based venv selection through `PSMODULE_VENV_PATH` is also honored by the native host path. + +## Limits and safety + +- MCP mode exposes only commands named in `-McpCommands`; it is not an interactive shell. +- Extra `pwsh` arguments are rejected in MCP mode. Choose commands with `-McpCommands` and use MCP tool arguments for command parameters. +- The transport is stdio only. +- Tool output is text, not structured PowerShell objects. +- Tool calls run with the current user's privileges in the selected hosted PowerShell version. Expose only trusted commands to trusted MCP clients.