Skip to content
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
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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)

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 <stable|preview|lts|version|major|major.minor|major.minor.x> [--scope <user|machine>] [--root <path>] [--arch <auto|x64|x86|arm64|arm32>] [--include-prerelease] [--offline-cache <path>] [--add-path|--no-add-path] [--register-manifest|--no-register-manifest] [--enable-psremoting] [--disable-telemetry] [--add-explorer-context-menu] [--add-file-context-menu]
Expand All @@ -234,6 +237,7 @@ multi-pwsh alias set <major.minor> <version|latest>
multi-pwsh alias set <pwsh|pwsh-preview|pwsh-lts> <stable|preview|lts|version>
multi-pwsh alias unset <major.minor|pwsh|pwsh-preview|pwsh-lts>
multi-pwsh host <version|major|major.minor|pwsh-alias> [-VirtualEnvironment <name>|-venv <name>] [pwsh arguments...]
multi-pwsh host <version|major|major.minor|pwsh-alias> -mcp -McpCommands <command> [command ...] [-VirtualEnvironment <name>|-venv <name>]
multi-pwsh doctor --repair-aliases
```

Expand Down Expand Up @@ -269,11 +273,12 @@ The current LTS line is encoded in the tool; at the moment that is `7.6`.

- `multi-pwsh host <selector> ...` runs PowerShell through native hosting instead of launching a `pwsh` subprocess.
- Use `-venv <name>` or `-VirtualEnvironment <name>` to select a managed module root for hosted launches.
- Use `-mcp -McpCommands <command> [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

Expand Down
3 changes: 3 additions & 0 deletions docs/feature-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ This matrix reflects the current command surface and known gaps for `multi-pwsh`
| Update | `multi-pwsh update <stable\|preview\|lts\|major.minor>` | 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 <user\|machine>`. |
| Uninstall | `multi-pwsh uninstall <version> [--scope <user\|machine>] [--root <path>] [--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 <user\|machine\|all>] [--root <path>] [--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 <selector> [--os <windows\|linux\|macos\|all>] [--arch <x64\|x86\|arm64\|arm32\|all>]` | 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 <version\|major\|major.minor\|pwsh-alias> [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 <selector> -mcp -McpCommands <command> [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. |
Expand Down Expand Up @@ -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. |

Expand Down
1 change: 1 addition & 0 deletions docs/host-and-venv.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <pipeName>` is supported in host mode on Windows.
- `-mcp -McpCommands <command> [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

Expand Down
59 changes: 59 additions & 0 deletions docs/mcp.md
Original file line number Diff line number Diff line change
@@ -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 <name>` and `-VirtualEnvironment <name>` 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.