Skip to content

Releases: yotsuda/PowerShell.MCP

v1.8.0

02 May 10:46

Choose a tag to compare

Highlights

Verbose / Debug / native exe stderr are now visible to the AI. Pre-1.8 the tool description explicitly told you "Verbose and Debug streams are NOT visible to you" and native exe stderr (e.g. cmd /c '... 1>&2') was effectively swallowed. They now appear in the AI response in the same time-ordered position as everything else — closing the AI's biggest documented blind spot in the Output→Error→Warning→Verbose→Debug capture surface.

New Features

  • Hybrid stream capture: chronological pipeline replaces bucketed sections. Output, Error, Warning, Verbose, and Debug records now interleave in a single time-ordered text block in the AI response — the AI sees each event in its actual position relative to surrounding output. Pre-1.8 the four separate === ERRORS === / === WARNINGS === etc. sections lost the "warning fired between step-A and step-B, then the error hit" context.
  • Five output channels that used to bypass the AI's view are now captured:
    • Write-Verbose (was the AI's blind spot that the tool description explicitly called out as "Verbose and Debug streams are NOT visible to you").
    • Write-Debug (same).
    • [Console]::WriteLine / [Console]::Error.WriteLine direct writes (and any .NET interop that writes to System.Console without going through PowerShell streams) → new === CONSOLE.OUT (direct) === / === CONSOLE.ERR (direct) === sections.
    • Native exe stderr (cmd /c "..."-style) → ErrorRecord in the chronological pipeline, in emit order alongside surrounding output.
    • What if: text from $PSCmdlet.ShouldProcess and direct $Host.UI.WriteLine calls → new === HOST.UI (direct) === section.
  • Auto-route on busy console. When invoke_expression finds the chosen PowerShell console busy with a user-typed or another AI command, the proxy now spawns a new console at the source's cwd and re-runs the pipeline there in the same tool call. Pre-1.8 the AI got Pipeline NOT executed - verify location and re-execute and had to re-send manually with whatever cwd they wanted, costing two MCP round-trips for every busy race.
  • LastExit: N status-line tag surfaces the case where a pipeline overall succeeded ($? is true) but a native exe within it returned non-zero. The green ✓ badge no longer silently hides those signals.

Bug Fixes

  • get_current_location now sets the window title when it claims an unowned console. Pre-fix, an AI whose first tool call was get_current_location (instead of invoke_expression or start_console, both of which already handled this) left the user's pre-existing Import-Module PowerShell.MCP console with the placeholder title #PID ____ until some later tool call redrew it. Symptom appeared intermittently depending on which tool the AI happened to call first.

Improvements

  • Real-time streaming preserved through the new capture wiring — items render to the visible console as they arrive, not collected and rendered after the pipeline finishes.
  • Color preserved on the visible console for every stream type: red Write-Error, yellow WARNING:, yellow VERBOSE: / DEBUG: prefixes, and Write-Host's user-chosen ForegroundColor.
  • Write-Progress keeps rendering on the visible console for AI-initiated commands (Compress-Archive, Invoke-WebRequest, etc.) so the user can watch progress. Each redraw of pwsh 7's "Minimal" Progress view also writes the bar text to Console.Out; the polling engine recognizes those overlay blocks by their reverse-video bracketed-status framing — an ANSI SGR escape, then [, then a reverse-video toggle (ESC[7mESC[27m), then ] and reset (ESC[0m) — and strips them from the captured === CONSOLE.OUT (direct) === buffer before surfacing to the AI, so the response stays clean.

Internal

  • New TeeTextWriter for [Console]::Out / [Console]::Error tee, written to in parallel with the original streams so visible-console output is unaffected.
  • New TeePSHostUserInterface decorator wrapping $Host.UI (reflected swap on _externalUI) for host-UI-level capture of Write/WriteLine paths that bypass both PowerShell streams and [Console]::Out.
  • Stream merge map widened to 2>&1 3>&1 4>&1 5>&1. Stream 6 (Information) remains unmerged so Write-Host's user-chosen ForegroundColor survives to the visible console.
  • Single shared BuildInitCommand now drives the PowerShell init script for every non-Windows launcher (macOS tempFile, Linux Base64-encoded terminal launch, Linux headless ArgumentList path). Each platform keeps its own delivery mechanism for documented reasons — AppleScript echo on macOS, multi-shell quoting on Linux — but the script body and its single-quote escaping are now built in one place. xUnit pins the escaping for every platform that calls the helper.

PowerShell.MCP v1.7.7 - Authenticode-Signed Windows Binaries

18 Apr 02:45

Choose a tag to compare

Authenticode-Signed Windows Binaries

PowerShell.MCP.dll and PowerShell.MCP.Proxy.exe (win-x64) are now Authenticode-signed with the yotsuda code-signing certificate. This unblocks installation on machines with Windows Defender Application Control (WDAC) / Device Guard policies that require trusted publisher signatures.

The same certificate signs binaries across all yotsuda OSS projects, so trusting it once covers future releases of all of them.

Closes #46 — thanks @rblinton for the report!

What's New

Authenticode signing (Windows binaries)

Windows binaries are now signed with a self-signed certificate. The public certificate (yotsuda.cer) and full installation instructions for personal PCs, Active Directory domains, and WDAC environments are published at:

https://github.com/yotsuda/code-signing

Verify a signed binary on your machine:

Get-AuthenticodeSignature `
    "$((Get-Module PowerShell.MCP -ListAvailable).ModuleBase)\bin\win-x64\PowerShell.MCP.Proxy.exe"

The signer thumbprint should match the values below.

Certificate details

Field Value
Subject CN=yotsuda, O=Yoshifumi Tsuda, C=JP
Validity 2026-04-18 to 2036-04-18
Thumbprint (SHA-1) 74E5208228DFB12A067747D536BF497B6E98C73C
Thumbprint (SHA-256) ABCE0AFEE35BD19EE1DF8F16E64436439516DDC3FD40229EA7786A8B23BC8013

Note on other platforms: Authenticode is Windows-specific. macOS and Linux binaries are not signed in this release — their security models differ (macOS uses Gatekeeper/notarization with a paid Apple Developer ID; Linux has no comparable system enforcement).

Third-party license notices (Ude.NetStandard)

The bundled Ude.NetStandard.dll (used for character set detection) is redistributed under LGPL-2.1. The full license text and attribution are now included in the module under licenses/Ude.NetStandard/ and THIRD_PARTY_NOTICES.md.

Status line fix (multi-line pipelines)

Pipelines with leading newlines previously rendered a useless Pipeline: ... (or empty Pipeline:) in the status line. Status line truncation now strips leading whitespace before extracting the first line, so multi-line scripts are summarized correctly.

macOS console launch fix (Terminal.app / zsh quoting)

On macOS, Terminal.app's zsh parsed ''default'' in the spawned pwsh -Command argument as the bareword default, breaking $global:PowerShellMCPAgentId assignment and the IPC handshake — so the MCP connection would briefly show "Connected" and then drop. The init command is now written to a temp .ps1 file and executed with pwsh -File, avoiding shell quoting entirely. Same class of bug as #39 (Linux), now fixed for macOS.

Closes #45 — thanks @ben1440 for the detailed report with reproduction steps and the pointer to the Linux fix, and @mikenelson-io for confirming the issue!


What's Changed Since v1.7.6

  • Authenticode signing for PowerShell.MCP.dll and PowerShell.MCP.Proxy.exe (win-x64)
  • Build-AllPlatforms.ps1 gains a -Sign switch (off by default; signing only happens on publish builds, with the PFX passphrase prompted interactively)
  • licenses/Ude.NetStandard/ and THIRD_PARTY_NOTICES.md added (LGPL-2.1 compliance for bundled Ude.NetStandard.dll)
  • README: new "Enterprise Deployment (WDAC / Device Guard)" section linking to the code-signing repo
  • Status line: leading whitespace/newlines no longer collapse the displayed pipeline to ... or empty
  • macOS: Terminal.app/zsh quoting fix — init script now delivered via temp .ps1 file to avoid ''default'' bareword parsing (closes #45)

Installation & Upgrade

Windows

# New installation
Install-PSResource PowerShell.MCP

# Upgrade existing
Update-PSResource PowerShell.MCP

Linux / macOS

# Install
Install-PSResource PowerShell.MCP

# Set execute permission
chmod +x (Get-MCPProxyPath)

Update MCP Configuration

For Claude Code:

Register-PwshToClaudeCode

For Claude Desktop:

Register-PwshToClaudeDesktop

For other MCP clients: Run Get-MCPProxyPath -Escape to get the JSON-escaped executable path, then add it to your client's configuration file manually.

Restart your MCP client after updating.


Full Documentation: https://github.com/yotsuda/PowerShell.MCP

Questions? GitHub Discussions | Report Issues: GitHub Issues

Internal: issue #45 macOS test artifact

17 Apr 04:12

Choose a tag to compare

Pre-release

Temporary pre-release for macOS E2E testing. Not for distribution.

PowerShell.MCP v1.7.6 - -Skip/-First Compatibility for All Line-Range Cmdlets

05 Apr 14:22
a46fb98

Choose a tag to compare

-Skip/-First Compatibility for All Line-Range Cmdlets

AI agents frequently attempt -Skip/-First (the standard PowerShell paging idiom) before discovering that PowerShell.MCP uses -LineRange. This release adds -Skip/-First as compatibility parameters across all four line-range cmdlets, so the first attempt just works.

Closes #41 — thanks @doraemonkeys for the suggestion!

What's New

-Skip/-First Compatibility (Show-TextFiles, Remove-LinesFromFile, Update-LinesInFile, Update-MatchInFile)

All cmdlets that accept -LineRange now also accept -Skip and -First. The parameters are mapped to -LineRange internally:

# These are equivalent:
Show-TextFiles file.txt -Skip 200 -First 50
Show-TextFiles file.txt -LineRange 201-250

# -First alone:
Show-TextFiles file.txt -First 20
Show-TextFiles file.txt -LineRange 1-20

# -Skip alone (to end of file):
Show-TextFiles file.txt -Skip 100
Show-TextFiles file.txt -LineRange 101,-1

# Works with all four cmdlets:
Remove-LinesFromFile file.txt -Skip 10 -First 5
Update-LinesInFile file.txt -Skip 3 -First 2 -Content "A", "B"
Update-MatchInFile file.txt -OldText "foo" -Replacement "bar" -First 20

Design decisions:

  • -LineRange remains the canonical interface
  • -Skip/-First cannot be mixed with -LineRange

What's Changed Since v1.7.5

  • -Skip/-First compatibility parameters added to Show-TextFiles, Remove-LinesFromFile, Update-LinesInFile, Update-MatchInFile
  • PlatyPS help updated for new parameters

Installation & Upgrade

Windows

# New installation
Install-PSResource PowerShell.MCP

# Upgrade existing
Update-PSResource PowerShell.MCP

Linux / macOS

# Install
Install-PSResource PowerShell.MCP

# Set execute permission
chmod +x (Get-MCPProxyPath)

Update MCP Configuration

For Claude Code:

Register-PwshToClaudeCode

For Claude Desktop:

Register-PwshToClaudeDesktop

For other MCP clients: Run Get-MCPProxyPath -Escape to get the JSON-escaped executable path, then add it to your client's configuration file manually.

Restart your MCP client after updating.


Full Documentation: https://github.com/yotsuda/PowerShell.MCP

Questions? GitHub Discussions | Report Issues: GitHub Issues

PowerShell.MCP v1.7.5 - PromptAI Companion Module, Closed-Console Detection & MSIX Fix

01 Apr 21:35

Choose a tag to compare

PromptAI Companion Module, Closed-Console Detection & MSIX Fix

New companion module PromptAI brings Invoke-Claude, Invoke-GPT, and Invoke-Gemini to the console. Closed-console detection is overhauled so errors surface immediately and clearly. Register-PwshToClaudeDesktop now works correctly on MSIX (Microsoft Store) installs of Claude Desktop.

🐛 Bug Fixes

MSIX Detection in Register-PwshToClaudeDesktop

  • Previously always wrote to %APPDATA%\Claude\, which MSIX (Microsoft Store) installs of Claude Desktop don't read
  • Now detects MSIX by checking for the package directory (%LOCALAPPDATA%\Packages\Claude_*) and writes to the correct virtualized path

Closed-Console Detection Overhaul

  • Closed consoles are now reported immediately when pipe communication fails, not deferred
  • Fixed duplicate closed-console messages in AllPipesStatusInfo
  • Fixed start_console not reporting closed consoles when reusing a standby pipe
  • Fixed duplicate message when active pipe PID was in KnownBusyPids
  • Error messages now show the console display name (e.g., #1234 MyFolder) instead of raw pipe names

📦 PromptAI Module

A new companion module PromptAI adds Invoke-Claude, Invoke-GPT, and Invoke-Gemini cmdlets for calling AI APIs directly from PowerShell. Responses stream to the console in real time, pipe cleanly to other cmdlets, and are returned to the MCP client without duplication. This also enables AI-to-AI communication — an MCP client can call other AI models through the console and use their responses as part of its own workflow:

Install-PSResource PromptAI

🔧 Improvements

  • PlatyPS help migrated to v2 (Microsoft.PowerShell.PlatyPS 1.0.1)
  • Fixed flaky macOS test: isolated agent ID to prevent parallel test class interference

📊 What's Changed Since v1.7.4

  • 📦 New companion module PromptAI: Invoke-Claude / Invoke-GPT / Invoke-Gemini cmdlets
  • 🐛 Register-PwshToClaudeDesktop now correctly detects MSIX installs without existing config file
  • 🐛 Closed-console detection: immediate reporting, no duplicates, display names in errors
  • 🔧 PlatyPS v2 migration
  • 🔧 Test stability fix for macOS CI

🔄 Installation & Upgrade

Windows

# New installation
Install-PSResource PowerShell.MCP

# Upgrade existing
Update-PSResource PowerShell.MCP

Linux / macOS

# Install
Install-PSResource PowerShell.MCP

# Set execute permission
chmod +x (Get-MCPProxyPath)

Update MCP Configuration

For Claude Code:

Register-PwshToClaudeCode

For Claude Desktop:

Register-PwshToClaudeDesktop

For other MCP clients: Run Get-MCPProxyPath -Escape to get the JSON-escaped executable path, then add it to your client's configuration file manually.

Restart your MCP client after updating.


📖 Full Documentation: https://github.com/yotsuda/PowerShell.MCP

💬 Questions? GitHub Discussions | 🐞 Report Issues: GitHub Issues

PowerShell.MCP v1.7.4 - Orphaned Console Detection, Register Cmdlets & Robustness Improvements

28 Mar 16:14

Choose a tag to compare

Orphaned Console Detection, Register Cmdlets & Robustness Improvements

Consoles now detect when their parent AI proxy dies and automatically become available for reuse. New Register-Pwsh* cmdlets simplify MCP client configuration. Tool renamed from start_powershell_console to start_console.

✨ New Features

Proxy Liveness Detection

  • Consoles monitor their parent proxy PID every ~5 seconds via pipe name inspection
  • When the proxy process dies (e.g., AI client is closed), the console automatically:
    • Reverts to unowned state (available for the next proxy to claim)
    • Updates window title to #PID ____ to indicate waiting state
    • Displays a disconnect message: "AI session disconnected. Waiting for next connection."
  • On the next AI session, the orphaned console is discovered and reused instead of creating a new window

Register-PwshToClaudeCode / Register-PwshToClaudeDesktop

  • One-command MCP client registration — no manual path copying or JSON editing
  • Registers as "pwsh" — shorter to type in prompts (e.g., "use pwsh" instead of "use PowerShell")
  • Automatically migrates legacy "PowerShell" entry to the new "pwsh" server name
  • Register-PwshToClaudeCode checks for claude CLI availability before executing

LineRange Parameter Upgrade

  • LineRange type changed from string to string[] — comma syntax (-LineRange 10,20) now works without quoting
  • Added validation to reject ambiguous multi-dash input (e.g., 10-20-30)

🔧 Improvements

Tool Renamed: start_console

  • start_powershell_console renamed to start_console across all tools, prompts, and error messages
  • reason parameter description strengthened to reduce unnecessary console creation

Console Reuse Improvements

  • Console title set before reading location on reuse, so status line shows the new name immediately
  • Stricter reason parameter: omitting it now prefers reusing existing standby consoles

Error Handling Hardened

  • Fire-and-forget ClaimConsoleAsync now logs exceptions via ContinueWith
  • Mutex operations use WaitOne(timeout) with safe ReleaseMutex pattern
  • CleanupCategory catch narrowed to IOException/UnauthorizedAccessException
  • Cancellation token check added in pipe discovery polling loop
  • Silent catch blocks in PowerShellService and MCPModuleInitializer now log to stderr
  • IsModuleInstalled guards against missing C:\Program Files\PowerShell directory
  • Inner exception preserved in McpException wrapping

Other

  • Set-Content/Add-Content error messages now recommend Add-LinesToFile with examples
  • Markdown hint regex extended to match .markdown extension
  • Version mismatch error message now suggests Register-PwshToClaudeCode/Register-PwshToClaudeDesktop
  • macOS CI: install PowerShell from GitHub Release instead of broken Homebrew tap/cask

📊 What's Changed Since v1.7.3

  • ✨ Proxy liveness detection: orphaned consoles auto-revert to unowned state for reuse
  • Register-PwshToClaudeCode / Register-PwshToClaudeDesktop cmdlets for one-command setup
  • LineRange type upgraded to string[] — comma syntax works without quoting
  • 🔧 Tool renamed: start_powershell_consolestart_console
  • 🔧 Error handling hardened across proxy and module (mutex, logging, cancellation)
  • 🔧 Console title set before location read on reuse
  • 🔧 macOS CI fixed (Homebrew → GitHub Release)

🔄 Installation & Upgrade

Windows

# New installation
Install-PSResource PowerShell.MCP

# Upgrade existing
Update-PSResource PowerShell.MCP

Linux / macOS

# Install
Install-PSResource PowerShell.MCP

# Set execute permission
chmod +x (Get-MCPProxyPath)

Update MCP Configuration

For Claude Code:

Register-PwshToClaudeCode

For Claude Desktop:

Register-PwshToClaudeDesktop

For other MCP clients: Run Get-MCPProxyPath -Escape to get the JSON-escaped executable path, then add it to your client's configuration file manually.

Restart your MCP client after updating.


📖 Full Documentation: https://github.com/yotsuda/PowerShell.MCP

💬 Questions? GitHub Discussions | 🐞 Report Issues: GitHub Issues

PowerShell.MCP v1.7.3 - Text Cmdlet Improvements, Console Naming & MarkdownPointer Hint

28 Mar 16:13

Choose a tag to compare

Text Cmdlet Improvements, Console Naming & MarkdownPointer Hint

Text file cmdlets get improved parameters, console display is unified, and a new one-time hint promotes the MarkdownPointer module.

✨ New Feature

One-Time MarkdownPointer Module Hint

  • When invoke_expression output contains .md file references, a hint message is appended to the response (Windows only)
  • The hint is shown once per session to avoid being noisy
  • MarkdownPointer — Vibe editing for Markdown with Mermaid/KaTeX support and MCP server integration
  • Message varies based on installation status:
    • Installed: Suggests using mdp .\README.md to render and preview, mentions MCP server integration
    • Not installed: Suggests Install-Module MarkdownPointer and Get-Command -Module MarkdownPointer to explore commands after installation

🔧 Improvements

Text File Cmdlet Enhancements

  • LineRange parameter changed from int[] to string — now supports both dash ('10-20') and comma ('10,20') formats across Show-TextFiles, Update-MatchInFile, Update-LinesInFile, and Remove-LinesFromFile
  • Update-MatchInFile: added -Contains as alias for -OldText to match Show-TextFiles naming convention

Unified Console Display Name

  • All console references now use consistent PID #xxx Title format (e.g., PID #12345 Phoenix)
  • Previously mixed formats: PID#xxx, pwsh PID: xxx, Console PID xxx
  • Closed consoles retain their friendly name in status messages

📊 What's Changed Since v1.7.2

  • ✨ One-time MarkdownPointer module hint when .md files detected in output (Windows only)
  • 🔧 LineRange parameter: int[]string, supports '10-20' and '10,20' formats
  • 🔧 Update-MatchInFile: -Contains alias for -OldText
  • 🔧 Unified console naming to PID #xxx Title format

🔄 Installation & Upgrade

Windows

# New installation
Install-PSResource PowerShell.MCP

# Upgrade existing
Update-PSResource PowerShell.MCP

Linux / macOS

# Install
Install-PSResource PowerShell.MCP

# Set execute permission
chmod +x (Get-MCPProxyPath)

Update MCP Configuration

For Claude Code:

claude mcp add PowerShell -s user -- "$(Get-MCPProxyPath)"

For Claude Desktop — Update claude_desktop_config.json:

Get-MCPProxyPath -Escape  # Returns JSON-escaped path
{
  "mcpServers": {
    "PowerShell": {
      "command": "C:\Users\YourName\Documents\PowerShell\Modules\PowerShell.MCP\1.7.3\bin\win-x64\PowerShell.MCP.Proxy.exe"
    }
  }
}

Restart your MCP client after updating.


📖 Full Documentation: https://github.com/yotsuda/PowerShell.MCP

💬 Questions? GitHub Discussions | 🐞 Report Issues: GitHub Issues

PowerShell.MCP v1.7.2 - Sub-Agent ID Redesign & Dead Console Detection

09 Mar 15:17

Choose a tag to compare

Sub-Agent ID Redesign & Dead Console Detection

This release redesigns sub-agent identification to prevent infinite console creation loops, and surfaces dead console warnings in all MCP tool responses.

🔧 Improvements

Server-Issued Sub-Agent IDs

  • Replaced the generate_agent_id MCP tool with a simpler is_subagent parameter on start_powershell_console, invoke_expression, get_current_location, and wait_for_completion
  • When is_subagent=true is passed (without an agent_id), the server automatically allocates a unique ID (sa-xxxxxxxx) and returns it in the response with 🔑 Your agent_id is: ...
  • Any agent_id not previously allocated by the server is rejected with an error, preventing the infinite console creation loop that occurred when AI agents mistakenly passed console names as agent IDs
  • wait_for_completion with is_subagent=true but no agent_id returns an error (since there is no console to wait on)

Dead Console Detection in All Tools

  • invoke_expression and get_current_location now report closed console warnings (e.g., ⚠ Console PID 12345 was closed)
  • Previously, dead console detection was only surfaced in wait_for_completion
  • Agents are now immediately aware when a console has died, regardless of which tool they call

🐛 Bug Fixes

Revert Progress Bar Remnant Clearing

  • Reverted the \e[0K (Erase in Line) escape sequences added in v1.7.1 to clear progress bar remnants after prompt display
  • While the escape sequences did clear remnants, they caused incorrect caret positioning that broke the console display
  • Progress bar remnants may occasionally appear but are less disruptive than the caret position issues

🗑 Removed

generate_agent_id MCP Tool

  • Removed in favor of the is_subagent parameter approach, which is simpler and less error-prone

📊 What's Changed Since v1.7.1

  • 🔧 is_subagent parameter replaces generate_agent_id tool — server issues validated sa-xxxxxxxx IDs
  • 🔧 Invalid agent_id values are now rejected, preventing infinite console creation loops
  • 🔧 Dead console warnings surfaced in invoke_expression and get_current_location
  • 🐛 Reverted progress bar remnant clearing (\e[0K) that caused caret position issues
  • 🗑 Removed generate_agent_id MCP tool

📖 Full Documentation: https://github.com/yotsuda/PowerShell.MCP

💬 Questions? GitHub Discussions | 🐞 Report Issues: GitHub Issues

PowerShell.MCP v1.7.1 - Cross-Platform Fixes, Cmdlet Display Improvements & Skills Removal

05 Mar 11:59

Choose a tag to compare

Cross-Platform Fixes, Cmdlet Display Improvements & Skills Removal

This release fixes critical issues on macOS/Linux, improves file editing cmdlet output, and removes the now-redundant skills infrastructure.

🐛 Bug Fixes

macOS/Linux: Commands No Longer Require Manual Enter (#38)

  • On macOS/Linux, after Remove-Module PSReadLine, the built-in PSConsoleHostReadLine called Console.ReadLine() which blocked the main runspace, preventing MCP timer events from firing
  • Replaced with a custom PSConsoleHostReadLine that polls Console.KeyAvailable + Start-Sleep -Milliseconds 50, allowing the MCP timer action block to run between input polls
  • This fixes the issue where commands sent via invoke_expression appeared in Terminal.app but required pressing Enter to execute

Linux: Terminal Launch Shell Quoting (#39)

  • On Linux, launching pwsh via terminal emulators (konsole, gnome-terminal, etc.) failed due to nested shell quoting issues with the -Command argument
  • Replaced with -EncodedCommand (Base64 UTF-16LE), which completely bypasses shell quote interpretation
  • Verified on Ubuntu + konsole (same terminal emulator as the reporter)

macOS: Named Pipe Path Too Long

  • On macOS, UNIX domain socket paths are limited to 104 characters (sun_path)
  • The previous pipe name CoreFxPipe_PowerShell.MCP.Communication.{proxyPid}.{agentId}.{pwshPid} exceeded this limit under /var/folders/.../T/
  • Shortened the base pipe name from PowerShell.MCP.Communication to PSMCP
  • ⚠️ Note: Due to the pipe name change, mixing v1.7.0 Proxy with v1.7.1 Module (or vice versa) will fail silently instead of showing the usual version mismatch error. After upgrading, make sure to update your MCP client configuration so the Proxy path points to the new version

🔧 Improvements

File Edit Cmdlet Display

  • With the var1var4 parameters added to invoke_expression in v1.7.0, file content is passed via variables instead of inline strings. The actual content being written is no longer visible in the console command line, so the cmdlet output now shows the full detail of what was changed.
  • Add-LinesToFile: Now displays added content in green when creating new or empty files
  • Remove-LinesFromFile: Shows actual deleted line content in red instead of position markers ( :)
  • Update-LinesInFile: Replaced deferred context buffer with real-time single-pass display (pre-context → deleted lines in red → inserted lines in green → post-context)

Get-Content / Set-Content Usage Warning

  • When Get-Content (or aliases: gc, cat, type) or Set-Content is used via invoke_expression, a warning is now appended to the response suggesting the optimized PowerShell.MCP cmdlets instead:
    • Show-TextFiles instead of Get-Content
    • Update-MatchInFile, Update-LinesInFile, Add-LinesToFile, Remove-LinesFromFile instead of Set-Content
  • Warning is shown once per command invocation (not noisy)

Multi-Line Command History Warning Removed

  • Removed the warning that discouraged 3+ line commands due to console history limitations
  • This warning caused AI to write less readable single-line pipelines; history recall is not a primary use case for MCP-driven sessions

Cmdlet Help Streamlined

  • Removed boilerplate -WhatIf, -Confirm, -ProgressAction parameter sections from all cmdlet help (covered by CommonParameters)
  • Added var1/var2 usage hints to NOTES section for cmdlets that accept text content
  • Help now provides all essential information with or without -Full / -Examples flags

🗑 Removed

Install-ClaudeSkill Cmdlet & Skills Infrastructure

  • Removed Install-ClaudeSkill cmdlet and the skills/ folder
  • Claude Code now supports MCP prompts as slash commands natively, making the separate skills installation mechanism unnecessary
  • MCP prompts (served by PowerShell.MCP.Proxy) continue to work as before
  • If you previously ran Install-ClaudeSkill, you can safely remove the installed files:
    rm -rf ~/.claude/skills/ps-*

🧪 Testing

macOS Terminal E2E Test

  • Added GitHub Actions workflow (macos-terminal-test.yml) that launches Terminal.app on macOS, starts pwsh with the MCP module, and verifies command execution via Named Pipe
  • Tests: quick command, 5-second delayed command (#38 scenario), long-running command, and post-long-running command

📊 What's Changed Since v1.7.0

  • 🐛 macOS/Linux: custom PSConsoleHostReadLine polling loop fixes blocked MCP commands (#38)
  • 🐛 Linux: -EncodedCommand fixes terminal launch shell quoting (#39)
  • 🐛 macOS: shortened pipe name (PSMCP) fixes 104-char UNIX socket path limit
  • ⚠️ Pipe name changed — update MCP client configuration after upgrading
  • 🔧 File edit cmdlets: real-time display with colored deleted/inserted lines
  • 🔧 Get-Content/Set-Content usage warning guides AI to optimized cmdlets
  • 🔧 Removed noisy multi-line command history warning
  • 🔧 Streamlined cmdlet help with var1/var2 hints
  • 🗑 Removed Install-ClaudeSkill and skills infrastructure (replaced by MCP prompts)
  • 🧪 Added macOS Terminal E2E test in GitHub Actions

🙏 Acknowledgements

  • @davidbordenwi — Detailed analysis of the macOS blocking issue (#38), including the PSConsoleHostReadLine polling approach that became the fix
  • @Fabelwesen — Root cause analysis and -EncodedCommand solution for the Linux terminal launch failure (#39), plus the caseFix empty path guard

📖 Full Documentation: https://github.com/yotsuda/PowerShell.MCP

💬 Questions? GitHub Discussions | 🐞 Report Issues: GitHub Issues

PowerShell.MCP v1.7.0 - Reliability, Thread Safety & Security Hardening

20 Feb 13:55

Choose a tag to compare

Reliability, Thread Safety & Security Hardening

This release focuses on internal reliability and security improvements. Thread safety issues in the command execution pipeline have been resolved, named pipe communication has been hardened, and several resource management and code quality fixes have been applied.

🔒 Security Hardening

Named Pipe Access Control

  • Unix/macOS: Named pipe socket permissions are now set to 0600 (owner-only), preventing other local users from connecting
  • All platforms: Added 10 MB upper bound on message length to prevent out-of-memory from malformed length headers

Stop-AllPwsh Confirmation

  • Stop-AllPwsh now requires explicit confirmation (SupportsShouldProcess with ConfirmImpact=High) before killing all pwsh processes

SHA256 for File Comparison

  • Replaced MD5 with SHA256 for file comparison in module loader

🐛 Bug Fixes

Thread Safety in Command Execution

  • ExecutionState: Replaced _cacheLock with a unified _lock protecting all shared state (_isBusy, _currentPipeline, _shouldCacheOutput, heartbeat fields) to eliminate race conditions between status reads and state mutations
  • McpServerHost: Replaced volatile fields with lock-protected private fields and atomic ConsumeCommand/ConsumeSilentCommand methods to prevent partial reads across command+variables fields
  • PowerShellCommunication: Replaced ManualResetEvent with Monitor.Wait/PulseAll and a submitted/completed generation counter pair to prevent lost wakeups from late-completing timed-out commands

One-Shot Timer for Polling Engine

  • Redesigned from AutoReset = $true to one-shot mode (AutoReset = $false with try/finally restart), preventing event queue buildup while the main runspace is busy

Atomic File Replacement

  • FileOperationHelper: Now uses File.Replace for truly atomic file replacement instead of 3-step move sequence
  • Added millisecond precision to backup timestamps to prevent collisions

Resource Leaks

  • ConsoleSessionManager: Dispose Process object from GetProcessById to prevent handle leaks
  • PowerShellProcessManager: Dispose fire-and-forget Process from terminal emulator launch
  • Module loader: Added try/finally for StreamReader/Stream dispose

🔧 Code Quality

  • EncodingHelper: Consolidated duplicated encoding alias switch expressions into single GetEncodingByName method
  • MCPPollingEngine.ps1: Fixed $null comparison order to prevent collection filtering gotcha ($null -ne ... instead of ... -ne $null)
  • PipelineHelper: Marked static display-state booleans as volatile
  • MCPModuleInitializer: Added _serverLock to protect _namedPipeServer and _tokenSource from concurrent access; escaped single quotes in error messages

📊 What's Changed Since v1.6.8

  • 🔒 Named pipe socket restricted to owner-only on Unix/macOS
  • 🔒 Message length validation (10 MB cap) on pipe communication
  • 🔒 Stop-AllPwsh now requires confirmation
  • 🐛 Thread safety: unified locking in ExecutionState, atomic command consumption, lost-wakeup prevention
  • 🐛 Polling engine: one-shot timer to prevent event accumulation
  • 🐛 Atomic file replacement in FileOperationHelper
  • 🐛 Resource leak fixes (Process handles, StreamReader)
  • 🔧 SHA256 for file comparison, encoding helper consolidation, null comparison fix

📖 Full Documentation: https://github.com/yotsuda/PowerShell.MCP

💬 Questions? GitHub Discussions | 🐞 Report Issues: GitHub Issues