Configuration Guide
Configure PoshMcp to expose specific PowerShell commands, modules, and tools for your use case.
Creating Configuration
Generate default configuration:
poshmcp create-config
This creates appsettings.json with defaults. Customize using CLI commands:
poshmcp update-config --add-command Get-Process
poshmcp update-config --add-module Az.Accounts
For developers building from source:
dotnet run --project PoshMcp.Server -- create-config
dotnet run --project PoshMcp.Server -- update-config --add-command Get-Process
Configuration Options
Exposing Commands
Specific command names (whitelist):
poshmcp update-config --add-command Get-Service
poshmcp update-config --add-command Restart-Service
poshmcp update-config --add-command Get-Process
Include patterns (wildcard):
poshmcp update-config --add-include-pattern "Get-*"
poshmcp update-config --add-include-pattern "Set-AzVM"
Exclude patterns (blacklist):
poshmcp update-config --add-exclude-pattern "Remove-*"
poshmcp update-config --add-exclude-pattern "*-Credential"
poshmcp update-config --add-exclude-pattern "Invoke-*"
Module Management
Add modules to discovery list:
poshmcp update-config --add-module Az.Accounts
poshmcp update-config --add-module Az.Resources
Install/import behavior and module search paths are configured in appsettings.json under PowerShellConfiguration.Environment.
Noun-Derived Resources
Enable noun-derived resources when you want PoshMcp to expose parameterless Get-* nouns through resources/list and resources/read, and to append MCP resource links to successful tool results for the same noun.
Edit appsettings.json:
{
"PowerShellConfiguration": {
"CommandNames": [
"Get-NounResourceFixture",
"Assert-NounResourceFixture"
],
"EnableNounResources": true,
"NounResourceOverrides": {
"noun_resource_fixture": {
"ResourceName": "fixture_override",
"Uri": "poshmcp://resources/fixture_override",
"DisableResourceLinkBlock": false
}
}
}
}
Behavior:
EnableNounResourcesdefaults tofalse.- A noun is resourceable only when the discovered command set contains a matching
Get-{Noun}command and that command has at least one parameter set with no required user parameters. - The default resource name is the noun converted to snake_case, and the default URI is
poshmcp://resources/{resource_name}. NounResourceOverridesis keyed by the default derived resource name.Disabled: truesuppresses the derived resource and skips tool-result resource links for that noun.DisableResourceLinkBlock: truekeeps the resource available inresources/listandresources/read, but skips the appendedapplication/json+mcp-resource-linkblock on tool results.PowerShellConfiguration.CommandOverrides.<Command>.AssociatedResourceUri(or legacyFunctionOverrides.<Command>.AssociatedResourceUri) overrides the implicit noun-derived link target for that command when the URI resolves to an exposed MCP resource.CommandOverridesstill take precedence over legacyFunctionOverrideswhen both defineAssociatedResourceUrifor the same command.- Explicit
AssociatedResourceUrilinks are appended withrelationship: "context"and are not suppressed byDisableResourceLinkBlock; that flag only suppresses the implicit noun-derived fallback. - If
AssociatedResourceUriis absent or does not resolve for a discovered command override during tool setup, PoshMcp falls back to the existing implicit noun-derived link behavior when available. In that case, PoshMcp logs a warning and continues; it does not perform generic configuration-load validation forAssociatedResourceUrivalues.
Example:
{
"PowerShellConfiguration": {
"CommandOverrides": {
"Invoke-Deployment": {
"AssociatedResourceUri": "poshmcp://resources/deployment-guide"
}
}
}
}
Use poshmcp doctor to verify the effective noun-resource surface. When the feature is enabled, doctor reports registered resources, conflicts, and suppressed nouns in the Noun Resources section.
appsettings.json Reference
Full configuration structure:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"PowerShellConfiguration": {
"CommandNames": [
"Get-Process",
"Get-Service"
],
"IncludePatterns": [
"Get-*"
],
"ExcludePatterns": [
"Remove-*",
"*-Credential"
],
"Modules": [
"Az.Accounts"
],
"Environment": {
"InstallModules": [
{
"Name": "Az.Accounts",
"MinimumVersion": "2.0.0",
"Repository": "PSGallery",
"Scope": "CurrentUser"
}
],
"ImportModules": [
"Az.Accounts",
"Microsoft.PowerShell.Management"
],
"ModulePaths": [
"/mnt/shared-modules"
],
"TrustPSGallery": true,
"SkipPublisherCheck": true,
"InstallTimeoutSeconds": 600,
"StartupScript": "$Global:Ready = $true",
"StartupScriptPath": "./startup.ps1"
},
"Performance": {
"EnableResultCaching": false,
"UseDefaultDisplayProperties": true
},
"EnableDynamicReloadTools": false,
"RuntimeMode": "InProcess",
"SubprocessHostMode": "Pool",
"SubprocessRunspacePoolSize": 0
}
}
Runtime Mode
PowerShellConfiguration.RuntimeMode selects whether commands execute in-process (default) or in a separate pwsh subprocess:
InProcess(default) — embedded PowerShell SDK; lowest overhead.OutOfProcess— commands run in a managedpwshsubprocess for module isolation. Recommended when loading heavy modules such asAz.*orMicrosoft.Graph.*.
When RuntimeMode is OutOfProcess, SubprocessHostMode selects the subprocess topology (Pool is the default since 2026-05-06):
SubprocessHostMode |
When to use |
|---|---|
Pool (default) |
Best concurrent throughput; recommended for typical MCP workloads. |
ProcessPool |
Trust-boundary or tail-latency-sensitive workloads. |
Single |
Backward-compatible serialized mode; useful for bisecting regressions. |
See Advanced Configuration → Out-of-Process PowerShell for sizing options (SubprocessRunspacePoolSize, SubprocessPoolSize, SubprocessMinHealthyForStartup), the cancellation contract, and the benchmark study driving the default.
Environment Variables
Override configuration via environment variables:
# Set transport mode
export POSHMCP_TRANSPORT=http
# Set log level (info, debug, trace, warning, error)
export POSHMCP_LOG_LEVEL=debug
# Use custom config file
export POSHMCP_CONFIGURATION=/config/appsettings.json
# Session timeout (minutes)
export POSHMCP_SESSION_TIMEOUT_MINUTES=120
# Container module pre-install
export POSHMCP_MODULES="Az.Accounts Az.Resources Az.Storage"
You can also provide full appsettings-style configuration purely through environment variables (no physical appsettings.json required):
# Expose Get-Process and Get-Service without mounting a config file
export PowerShellConfiguration__CommandNames__0=Get-Process
export PowerShellConfiguration__CommandNames__1=Get-Service
export PowerShellConfiguration__EnableDynamicReloadTools=true
PoshMcp resolves this as an environment-only configuration source.
Configuration Source In Doctor Output
poshmcp doctor reports both the configuration path and configuration mode under Runtime Settings.
configurationPathindicates the resolved file path, or(environment-only configuration)when no file is used.configurationModeindicates eitherfile-backedorenvironment-only.- Both entries include a
sourcevalue (for examplecwd,user,env,cli).
Example text output snippet:
── Runtime Settings ──────────────────────────
configuration: (environment-only configuration) (env)
config-mode : environment-only (env)
Example JSON output snippet (poshmcp doctor --format json):
{
"runtimeSettings": {
"configurationPath": {
"value": "(environment-only configuration)",
"source": "env"
},
"configurationMode": {
"value": "environment-only",
"source": "env"
}
}
}
Startup Scripts
Run PowerShell code when the server starts:
Inline startup script:
Edit appsettings.json:
{
"PowerShellConfiguration": {
"Environment": {
"StartupScript": "$Global:CompanyName = 'Acme'; Write-Host 'Ready!'"
}
}
}
From file:
{
"PowerShellConfiguration": {
"Environment": {
"StartupScriptPath": "./startup.ps1"
}
}
}
Example startup.ps1:
# Company-specific initialization
$Global:CompanyName = 'Acme'
$Global:Environment = 'Production'
# Azure setup
Connect-AzAccount -Identity -ErrorAction Stop
# Custom functions
function Get-CompanyInfo {
[PSCustomObject]@{
Company = $Global:CompanyName
Environment = $Global:Environment
}
}
Write-Host "✓ Environment initialized" -ForegroundColor Green
Performance Tuning
Enable result caching:
poshmcp update-config --enable-result-caching true
This caches command output for repeated queries (useful for read-only operations).
Use display properties:
Set UseDefaultDisplayProperties: true to leverage PowerShell's default display formatting (faster for large result sets).
Pre-install modules in Docker:
docker build \
--build-arg MODULES="Az.Accounts Az.Resources" \
-t poshmcp:fast .
Security Configuration
Command Filtering
Restrict dangerous commands:
poshmcp update-config --add-exclude-pattern "Remove-*"
poshmcp update-config --add-exclude-pattern "Disable-*"
poshmcp update-config --add-exclude-pattern "*-Credential"
poshmcp update-config --add-exclude-pattern "Format-*"
poshmcp update-config --add-exclude-pattern "ConvertTo-SecureString"
Authentication
PoshMcp supports both authentication modes in the same Authentication model:
- Entra ID (OAuth 2.1 / JwtBearer): Use for enterprise identity and token-based clients. See Authentication Guide - Entra ID.
- API key (ApiKey): Use for trusted internal clients and automation. Example:
{
"Authentication": {
"Enabled": true,
"DefaultScheme": "ApiKey",
"DefaultPolicy": {
"RequireAuthentication": true,
"RequiredScopes": [],
"RequiredRoles": ["reader"]
},
"Schemes": {
"ApiKey": {
"Type": "ApiKey",
"HeaderName": "X-API-Key",
"Keys": {
"key-reader": {
"Scopes": [],
"Roles": ["reader"]
},
"key-ops": {
"Scopes": [],
"Roles": ["ops", "reader"]
}
}
}
}
},
"PowerShellConfiguration": {
"CommandNames": ["Get-Process", "Get-Service"],
"Modules": [],
"ExcludePatterns": [],
"IncludePatterns": [],
"CommandOverrides": {
"Get-Process": {
"RequiredRoles": ["ops"]
},
"Get-Service": {
"RequiredRoles": ["reader", "support"]
}
}
}
}
Behavior:
Authentication.DefaultPolicy.RequiredRolesandRequiredScopesapply to all tools by default.- API key role and scope claims come from the matching
Schemes.ApiKey.Keysentry. PowerShellConfiguration.CommandOverrides.<ToolName>.RequiredRolesandRequiredScopestake precedence overAuthentication.DefaultPolicyfor that tool.CommandOverridesmatching checks exact tool names first (for exampleget_process_name), then normalized command-name candidates. Use command names (for exampleGet-Process) for stable configuration across generated parameter-set tool names.
For full Entra ID and API key setup guidance, see Authentication Guide.
Next: Transport Modes