Table of Contents

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 to min(ProcessorCount, 8). Ignored in Single and ProcessPool modes.
  • SubprocessPoolSize (ProcessPool mode): independent subprocess hosts to launch. Default 4.
  • SubprocessMinHealthyForStartup (ProcessPool mode): minimum healthy hosts required for the pool to start. Clamped to [1, SubprocessPoolSize]. Default 1.

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: PoolDispatcher looks up the active [powershell] instance by request id and calls BeginStop. 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. If BeginStop unwinds 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: SingleDispatcher calls BeginStop on 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