PowerShell持久MCP服务器
  
MCP服务器为Claude Code提供持久的PowerShell REPL,具有自定义模块加载和conda/venv环境激活功能。
状态: 生产就绪
特性
持续会话
- 具有可变持久性的命名PowerShell会话
- 会话状态在工具调用中保持不变
- 每个MCP服务器实例有多个独立会话
4个MCP工具
pwsh-使用会话持久性和模式回调执行PowerShellpwsh_output-通过过滤监控后台进程输出stdio-与后台进程交互(stdin/stdout/stop)list_sessions-列出/管理活动的PowerShell会话
AgentBlocks 模块
- 41个用于执行、转换、分析和模式学习的函数
- 49种常用工具(JavaScript、Python、.NET、Build)的预配置模式
- 会话创建时自动加载
- 代币效率高(前期0个代币,通过获取帮助发现)
LoraxMod模块(捆绑发布)
- 28种语言的树型AST解析
- 10个cmdlet:
ConvertTo-LoraxAST,Compare-LoraxAST,Find-LoraxFunction等等。 - 语义差异、函数提取、依赖性分析
- 原生C#通过 TreeSitter。DotNet
- 来源: jacky硬盘/loraxMod
代币效率
- 工具模式:约4000个令牌(4个工具)
- 模块功能:前期0个令牌(通过获取帮助按需发现)
- 调用DevRun:544行->5行摘要(减少99%)
安装
选项1:下载版本(推荐)
下载最新版 pwsh-repl-vX.X.X-win-x64.zip 从 .
包括所有模块:AgentBlocks、LoraxMod(带树形图二进制文件)。
选项2:从源代码构建
git clone https://github.com/jackyHardDisk/pwsh-repl.git
cd pwsh-repl
dotnet build输出: release/v{version}/PowerShellMcpServer.exe
注: 从源代码构建不包括LoraxMod。要添加它,请克隆 loraxMod 并通过配置 PWSH_MCP_MODULES.
配置
复制 .mcp.json.example 到 .mcp.json 并更新路径,或添加到 ~/.claude/settings.json:
{
"mcpServers": {
"pwsh-repl": {
"type": "stdio",
"command": "C:\\path\\to\\PowerShellMcpServer.exe",
"args": [],
"cwd": ".",
"env": {
"PWSH_MCP_TIMEOUT_DEFAULT": "60"
}
}
}
}重要提示: 这 "cwd": "." 字段将服务器的工作目录设置为项目根目录。 这确保了PowerShell脚本使用相对路径(如 .gary/scripts/)正确解决。 每个项目的 .mcp.json 应该包括这个字段。
加载外部模块:
要加载其他PowerShell模块(如LoraxMod),请添加 PWSH_MCP_MODULES 到 env 章节:
{
"mcpServers": {
"pwsh-repl": {
"env": {
"PWSH_MCP_MODULES": "C:\\path\\to\\module1.psd1;C:\\path\\to\\module2.psd1"
}
}
}
}笔记:
- 使用绝对路径(MCP服务器上下文所需)
- 多个模块:以分号分隔
- 会话创建时自动加载模块
环境继承:
PowerShell会话从Claude Code启动的环境继承PATH:
# If Claude Code started from conda base, you get conda python:
pwsh("python --version") # Python 3.12.3 (conda base)
pwsh("Get-Command python | Select Source") # C:\Users\...\anaconda3\python.exe
# To use a different environment for a specific call:
pwsh("python --version", environment="myproject") # Uses conda env 'myproject'
pwsh("python --version", environment="C:\\project\\venv") # Uses venv不存在MCP级别的环境配置-每次调用都通过 environment 参数。
测试
# Import AgentBlocks module to verify setup
Import-Module C:\Path\To\pwsh-repl\src\pwsh-repl\Modules\AgentBlocks\AgentBlocks.psd1
Get-Command -Module AgentBlocks | Measure-Object
# Should show 41 functions工具参考
pwsh-PowerShell执行
目的: 执行具有持久状态的PowerShell脚本
参数:
script(如果提供了模式,则可选)-要执行的PowerShell脚本mode(可选)-要调用AgentBlocks函数(例如,“调用DevRun”、“格式化计数”)name(可选)-结果的缓存名称(自动生成:pwsh_1、pwsh_2等)kwargs(可选)-模式函数作为字典的参数sessionId(可选,默认:“默认”)-状态隔离的会话IDrunInBackground(可选,默认值:false)-在后台运行,使用stdio进行交互timeoutSeconds(可选,默认值:60)-执行超时environment(可选)-为此调用激活不同的Python环境:
- venv:venv目录的完整路径(例如。, C:\project\venv) - conda:环境名称(例如。, myenv)-通过解决 conda info --envs
特征:
- 变量在会话中持续存在
- AgentBlocks函数的模式回调模式
- 后台执行与流程树管理
- $global:DevRunCache中的自动缓存
- 环境激活(conda/venv)
超时行为:
当脚本超过 timeoutSeconds,服务器使用Windows作业对象来:
- 停止PowerShell管道
- 以原子方式终止整个进程树(没有孤立进程)
- 返回带有清理状态的错误消息
作业对象确保所有子进程一起被杀死,没有竞争条件或孤立进程。
例子:
# Set variable
pwsh("$myVar = 42", "session1")
# Retrieve variable (same session)
pwsh("$myVar", "session1")
# Returns: 42
# Different session (isolated)
pwsh("$myVar", "session2")
# Returns: (nothing - different session)
# Complex operations
pwsh("Get-Process | Where-Object { $_.CPU -gt 100 } | Select-Object -First 5", "default")运行Python脚本-这里是字符串模式:
PowerShell解析 {braces} 作为脚本块。Python f字符串类似 {var.attr} 将导致错误。
# BAD - fails with "ScriptBlock should only be specified..."
python -c "print(f'{arr.shape}')"
# GOOD - here-string preserves braces literally
$code = @'
import numpy as np
arr = np.array([1,2,3])
print(f"Shape: {arr.shape}")
'@
$code | python -提示: 将此模式添加到您的项目或用户中 CLAUDE.md 以确保克劳德自动使用它。stdio-后台过程和标准控制
目的: 与C#管理的后台进程或会话stdin管道交互
参数:
name(可选)-后台进程名称(如果提供,则与该进程交互)data(可选)-要写入stdin的字符串close(可选,默认值:false)-关闭stdin以发出EOF信号stop(可选,默认值:false)-停止进程树并缓存Get BackgroundData的输出readOutput(可选,默认值:true)-读取并返回stdout/stderrsessionId(可选,默认:“默认”)-目标会话
例子:
# Start background process
mcp__pwsh-repl__pwsh(script='python server.py', runInBackground=True, name='srv', sessionId='dev')
# Read output from background process
mcp__pwsh-repl__stdio(name='srv', sessionId='dev')
# Write to background process stdin
mcp__pwsh-repl__stdio(name='srv', data='command\n', sessionId='dev')
# Stop process and cache output (kills entire process tree via taskkill /T /F)
mcp__pwsh-repl__stdio(name='srv', stop=True, sessionId='dev')
# Legacy: Write to session stdin pipe (no name)
mcp__pwsh-repl__stdio(data='line1\nline2\n', sessionId='repl')pwsh_output-后台进程监视器
目的: 检索和过滤后台进程的输出
参数:
name(必填)-后台进程名称filter(可选)-用于过滤输出行的正则表达式模式sessionId(可选,默认:“默认”)-目标会话
例子:
# Start long-running build in background
mcp__pwsh-repl__pwsh(script='dotnet build', runInBackground=True, name='build')
# Check progress (non-blocking)
mcp__pwsh-repl__pwsh_output(name='build')
# Filter for errors only
mcp__pwsh-repl__pwsh_output(name='build', filter='error')
# When complete: auto-caches to DevRun for Get-StreamData analysislist_sessions-列出活动会话
目的: 显示所有具有运行状况诊断的活动PowerShell会话ID
参数:
getSessionHealth(可选)-包括运行空间状态和错误计数killAllSessions(可选)-删除所有会话(下次使用时重新创建)killUnhealthy(可选)-仅删除中断的会话
例子:
mcp__pwsh-repl__list_sessions()
# Returns: ['default', 'build_session', 'ssh']
mcp__pwsh-repl__list_sessions(getSessionHealth=True)
# Returns health info per session
mcp__pwsh-repl__list_sessions(killUnhealthy=True)
# Cleans up broken sessionsAgentBlocks 模块
会话创建时自动加载。 功能立即可用,无需导入。
快速参考:
Get-BrickStore # View loaded patterns and state
Find-ProjectTools # Discover available build/test/lint tools
Get-Patterns # List learned regex patterns
Get-Help # Full documentation for any function功能:
- 获取模式、设置模式、测试模式-模式管理
- 注册OutputPattern-从工具输出中学习模式
- 查找项目工具-查找可用的构建/测试/lint工具
预配置模式: ESLint、TypeScript、Pytest、Mypy、MSBuild、NuGet、GCC, Clang、CMake和30+更多。
使用示例:
# Run tests with Invoke-DevRun (via pwsh mode callback)
mcp__pwsh-repl__pwsh(
mode='Invoke-DevRun',
script='pytest tests/',
name='test',
kwargs={'Streams': ['Error', 'Warning']}
)
# Analyze failures with AgentBlocks
mcp__pwsh-repl__pwsh(script='Get-StreamData test Error | Select-RegexMatch -Pattern (Get-Patterns -Name "Pytest-Fail").Pattern | Format-Count')
# Output:
# 8x: tests/test_app.py::test_login
# 3x: tests/test_api.py::test_auth
# 1x: tests/test_db.py::test_query完整文档: 看 文档/AGENTBLOCKS.md
文档
- 代理锁.md -完整的AgentBlocks功能参考
- AGENTLOCKS_EXAMPLES.md -使用示例和工作流程
当前状态
完整的:
- 带stdio协议的核心MCP服务器
- 4个工具:pwsh、pwsh_output、stdio、list_sessions
- 具有命名会话和作业对象进程管理的SessionManager
- AgentBlocks模块(41个功能+49个模式)
- 会话创建时自动加载模块
- 工具描述中的构建时快速参考生成
- 环境激活(conda/venv)支持
建筑亮点
基于通道的池模式:
- 异步友好(无锁)
- 基于PowerAuger的后台处理器
- 5个PowerShell实例,未绑定通道
命名会话管理:
- 用于线程安全访问的ConcurrentDictionary
- 每个会话都有专用的运行空间
- 变量在会话内的调用之间持续存在
代币效率策略:
- 模块功能不在MCP工具模式中
- 代理商通过以下方式发现
Get-Command -Module AgentBlocks - 通过提供全面帮助
Get-Help -Full - 隐藏在模块中的功能,不作为单独的MCP工具公开
混合v1+v2+v3模式:
- v1:具体功能(即时实用程序)
- v2:预配置模式(常用工具)
- v3:元学习(教授新工具)
看 docs/DESIGN_DECISIONS.md 详细的理由。
示例工作流
可复制示例(无外部依赖性)
这些示例无需项目设置即可立即工作:
# Group-Similar: Cluster similar error messages (Jaro-Winkler similarity)
$errors = @(
"Connection timeout to server api.example.com:443"
"Connection timeout to server api.example.com:8080"
"Connection timeout to server db.example.com:5432"
"File not found: config.json"
"File not found: settings.json"
"Permission denied: /var/log/app.log"
"Permission denied: /var/log/error.log"
)
$errors | Group-Similar -Threshold 0.7 | Format-Count
# Output:
# 3x: Connection timeout to server api.example.com:443
# 2x: File not found: config.json
# 2x: Permission denied: /var/log/app.log
# Select-RegexMatch: Parse git status with named groups
$gitOutput = @(" M src/app.js", "?? temp.log", "A new.ts", " D old.txt")
$gitOutput | Select-RegexMatch -Pattern (Get-Patterns -Name Git-Status).Pattern
# Output: @{index= ; worktree=M; file=src/app.js} ...
# Group-By + Format-Count: Aggregate by field
$gitOutput | Select-RegexMatch -Pattern (Get-Patterns -Name Git-Status).Pattern |
Group-By worktree | Format-Count
# Output:
# 1x: M
# 1x: ?
# 1x: D
# Pattern matching: Parse MSBuild errors
$buildLog = @(
"src\App.cs(42,15): error CS0103: The name 'foo' does not exist"
"src\Data.cs(17,8): error CS1061: 'string' has no definition for 'Bar'"
"lib\Help.cs(5,1): warning CS0168: Variable 'x' declared but never used"
)
$buildLog | Select-RegexMatch -Pattern (Get-Patterns -Name MSBuild-Error).Pattern |
Group-By code | Format-Count
# Output:
# 1x: CS0103
# 1x: CS1061工作流1:使用自动摘要调用DevRun
实例-在项目上运行ESLint,获得自动汇总输出:
# Run lint with stream capture (544 lines -> 5-line summary)
Invoke-DevRun -Script 'npm run lint' -Name lint -Streams @('Output','Error')
# Output:
# Script: npm run lint
#
# Outputs: 544 (523 unique)
#
# Top Outputs:
# 2x: error Parsing error: 'import' and 'export' may appear only...
# 1x: warning Async method 'process' has no 'await' expression
# 1x: warning Generic Object Injection Sink
# 1x: error Unexpected constant condition
#
# Stored: $global:DevRunCache['lint']
# Drill down with Group-Similar
Get-StreamData lint Output | Where-Object { $_ -match 'error' } | Group-Similar | Format-Count工作流程2:构建错误分析
# Run build with Invoke-DevRun
Invoke-DevRun -Script 'dotnet build' -Name build -Streams @('Output','Error')
# Analyze with Group-BuildErrors (regex + fuzzy hybrid)
Get-StreamData build Output | Group-BuildErrors | Format-Count
# Deep dive with pattern matching
Get-StreamData build Output |
Select-RegexMatch -Pattern (Get-Patterns -Name MSBuild-Error).Pattern |
Where-Object { $_.Code -eq "CS0103" }工作流程3:测试套件分析
# Discover test command
Find-ProjectTools
# Run tests with Invoke-DevRun
Invoke-DevRun -Script 'npm run test' -Name test -Streams @('Output','Error')
# Extract failures with pattern
Get-StreamData test Output |
Select-RegexMatch -Pattern (Get-Patterns -Name Jest-Error).Pattern |
Format-Count工作流程4:学习自定义工具
# Register custom pattern
Set-Pattern -Name "myapp-error" `
-Pattern '(?ERROR|WARN):\s*\[(?\w+)\]\s*(?.+)' `
-Description "MyApp log format" `
-Category "error"
# Use it immediately
$logs | Select-RegexMatch -Pattern (Get-Patterns -Name myapp-error).Pattern |
Group-By component | Format-Count工作流程5:交互式SSH会话
使用 runInBackground + stdio 用于交互式远程会话。此模式允许 在不阻塞的情况下向持久SSH连接发送多个命令。
# Step 1: Start SSH in background
mcp__pwsh-repl__pwsh(
script='ssh user@remote-server',
runInBackground=True,
name='remote',
sessionId='ssh'
)
# Returns: Background process 'remote' started (PID 12345, running)
# Step 2: Read initial output (may show PTY warning - normal)
mcp__pwsh-repl__stdio(name='remote', sessionId='ssh')
# Returns:
# === stderr ===
# Pseudo-terminal will not be allocated because stdin is not a terminal.
# Step 3: Send a command (include newline!)
mcp__pwsh-repl__stdio(
name='remote',
data='cat ~/bin/my-script\n',
sessionId='ssh'
)
# Returns: Wrote 21 chars to 'remote' stdin
# === stdout ===
# #!/bin/bash
# ... file contents ...
# Step 4: Create/edit remote files using heredoc
mcp__pwsh-repl__stdio(
name='remote',
data='''mkdir -p ~/.config/systemd/user && cat > ~/.config/systemd/user/my-service.service << 'EOF'
[Unit]
Description=My TCP Service
After=network.target
[Service]
Type=simple
ExecStart=/home/user/bin/my-server --host localhost --port 18812
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
EOF
echo "Service file created"
''',
sessionId='ssh'
)
# Step 5: Enable and start the service
mcp__pwsh-repl__stdio(
name='remote',
data='systemctl --user daemon-reload && systemctl --user enable my-service && systemctl --user start my-service && systemctl --user status my-service\n',
sessionId='ssh'
)
# Step 6: Read output
mcp__pwsh-repl__stdio(name='remote', sessionId='ssh')
# Returns:
# === stdout ===
# Service file created
# Created symlink...
# * my-service.service - My TCP Service
# Active: active (running)...
# Step 7: Verify port is listening
mcp__pwsh-repl__stdio(
name='remote',
data='ss -tlnp | grep 18812\n',
sessionId='ssh'
)
# Step 8: Close SSH when done
mcp__pwsh-repl__stdio(name='remote', data='exit\n', sessionId='ssh')
mcp__pwsh-repl__stdio(name='remote', stop=True, sessionId='ssh')
# Returns: Stopped background process 'remote' (output cached)参数参考:
| 参数 | 用途 |
|---|---|
runInBackground=True | 启动流程,立即返回 |
name='remote' | 供以后通过stdio参考的名称 |
sessionId='ssh' | 集团相关业务 |
data='cmd\n' | 发送到stdin(包括换行!) |
stop=True | 终止进程,缓存输出 |
close=True | 关闭标准输入管(信号EOF) |
readOutput=False | 在不读取的情况下检查状态 |
限制:
- 无PTY(伪终端)-某些程序的行为不同
sudo需要-S标志或NOPASSWD配置- 交互式编辑器(vim,less)无法工作
- 最适合脚本远程操作
安全
执行模式: MCP服务器以您的用户权限运行,与任何终端相同。
审核日志记录: 通过环境变量启用命令日志记录:
{
"env": {
"PWSH_MCP_AUDIT_LOG": "C:\\logs\\pwsh-mcp-audit.log"
}
}日志格式:
[2025-01-15 14:32:01.123] EXECUTE session=default content="Get-Process | Select -First 5"需求
- .NET 8.0 SDK(仅用于构建,不需要运行预构建版本)
- Windows x64(PowerShell SDK依赖关系)
- 支持MCP的Claude代码
贡献
这是个人/组织使用的自定义MCP服务器。欢迎捐款:
- 其他AgentBlocks模式
- 性能优化
- 错误修正
- 文档改进
安全考虑
这是一个用于代理编码的本地PowerShell执行环境。根据设计,它执行您或您的AI助手提供的命令。
- 审计日志 (通过以下方式选择加入
PWSH_MCP_AUDIT_LOG):日志包含完整的脚本内容。如果脚本可能包含凭据,请避免在共享环境中启用。 - 后台进程:命令参数可能出现在stderr日志中。
- 模块加载 (
PWSH_MCP_MODULES):仅从您明确配置的路径加载模块。
许可证
MIT许可证-请参阅 许可证 文件以获取详细信息。
