Advanced Configuration
Advanced topics for power users and enterprise deployments.
Custom Startup Scripts
Define PowerShell functions and utilities available to all sessions:
# startup.ps1
function Get-HealthCheck {
$critical = @('wuauserv', 'spooler', 'w32time')
$critical | ForEach-Object {
$service = Get-Service -Name $_
[PSCustomObject]@{
Service = $service.Name
Status = $service.Status
StartType = $service.StartType
}
}
}
Write-Host "✓ Custom utilities loaded" -ForegroundColor Green
Multi-Module Configuration
Expose tools from multiple modules with module-specific settings:
poshmcp update-config --add-include-pattern "Get-AzVM"
poshmcp update-config --add-include-pattern "Get-AzResource"
poshmcp update-config --add-include-pattern "Get-Service"
poshmcp update-config --add-exclude-pattern "Remove-*"
poshmcp update-config --add-exclude-pattern "Invoke-*"
poshmcp update-config --add-module Az.Accounts
poshmcp update-config --add-module Az.Compute
Azure Scaffold Workflow
For Azure-first deployments, use the scaffold workflow documented in Azure Integration to generate infra/azure assets with poshmcp scaffold and then run deploy.ps1 from the generated folder.
Performance Tuning
Enable Result Caching
Cache command output for repeated queries:
poshmcp update-config --enable-result-caching true
Use Default Display Properties
Leverage PowerShell's default formatting for faster output:
# In appsettings.json
{
"PowerShellConfiguration": {
"Performance": {
"UseDefaultDisplayProperties": true
}
}
}
Pre-install Modules in Docker
docker build \
--build-arg MODULES="Az.Accounts Az.Resources Az.Storage" \
-t poshmcp:optimized .
Out-of-Process PowerShell
Run PowerShell in a separate pwsh subprocess so that heavy or conflicting modules (Az, Microsoft.Graph) cannot crash or destabilize the MCP server. Requires PowerShell 7.x on PATH.
Enable Out-of-Process Mode
Set RuntimeMode in appsettings.json:
{
"PowerShellConfiguration": {
"RuntimeMode": "OutOfProcess"
}
}
Or via environment variable:
export POSHMCP_RUNTIME_MODE=OutOfProcess
poshmcp serve --transport http
The environment variable takes precedence over the config file value. Valid values: InProcess, OutOfProcess (kebab-case in-process / out-of-process is also accepted by the env var and CLI). Unrecognized values cause the server to fail startup with InvalidOperationException (Unsupported runtime mode '<value>'. Supported runtime modes: in-process, out-of-process.).
Subprocess Host Modes
When RuntimeMode is OutOfProcess, SubprocessHostMode selects the subprocess topology:
SubprocessHostMode |
Topology | When to use |
|---|---|---|
Pool (default) |
One subprocess, runspace pool inside it | Default since 2026-05-06. Best concurrent warm-invoke throughput; recommended for typical MCP workloads. |
ProcessPool |
N independent single-runspace subprocess hosts, leased per request | Trust-boundary or tail-latency-sensitive workloads. Crashes are reconciled per slot without disturbing other hosts. |
Single |
One subprocess, one runspace, serialized requests | Backward-compatible legacy mode. Useful for bisecting regressions or when only cold-start latency matters. |
The default flip from Single to Pool was driven by benchmark study — Pool posted ~4.86× warm-invoke throughput at concurrency 10 versus Single. See specs/004-out-of-process-execution/benchmark-findings.md for full data.
Pool Sizing
{
"PowerShellConfiguration": {
"RuntimeMode": "OutOfProcess",
"SubprocessHostMode": "Pool",
"SubprocessRunspacePoolSize": 0
}
}
SubprocessRunspacePoolSize(Pool mode): runspaces in the pool.0(default) auto-sizes tomin(ProcessorCount, 8). Ignored inSingleandProcessPoolmodes.SubprocessPoolSize(ProcessPool mode): independent subprocess hosts to launch. Default4.SubprocessMinHealthyForStartup(ProcessPool mode): minimum healthy hosts required for the pool to start. Clamped to[1, SubprocessPoolSize]. Default1.
ProcessPool example for tenant isolation:
{
"PowerShellConfiguration": {
"RuntimeMode": "OutOfProcess",
"SubprocessHostMode": "ProcessPool",
"SubprocessPoolSize": 4,
"SubprocessMinHealthyForStartup": 2
}
}
Cancellation
The MCP request CancellationToken sends a best-effort cancel control frame
through OutOfProcessHost.SendRequestAsync. The host dispatcher attempts a
cooperative BeginStop on the in-flight pipeline; cancellation is not a
guarantee that a blocked cmdlet has already stopped. Per-mode behavior:
Pool:PoolDispatcherlooks up the active[powershell]instance by request id and callsBeginStop. When the pipeline unwinds, its runspace returns to the pool; a wedged invocation continues to consume capacity until the timeout backstop intervenes.ProcessPool: each leased host inherits the same cooperative cancellation. IfBeginStopunwinds the pipeline, the slot returns to the pool and other hosts remain unaffected. The per-request timeout can restart a wedged host, such as one blocked in unmanaged code.Single:SingleDispatchercallsBeginStopon the matching[powershell]instance. The host remains usable after a successful unwind; the per-request timeout recycles it only as a backstop.
Diagnostics
poshmcp doctor reports the resolved host mode, effective pool sizes, host-script path, and any clamp warnings under Runtime Settings.
Dynamic Tool Reloading
Automatically reload tool definitions when configuration changes (experimental):
# In appsettings.json
{
"PowerShellConfiguration": {
"EnableDynamicReloadTools": true
}
}
Note: This can be slow; use sparingly. In HTTP mode, reload releases all managed session runspaces. Established clients must initialize a new MCP session afterwards and should treat session-scoped PowerShell state as lost.
See also: Configuration Guide | Security