PoshMcp is a Model Context Protocol (MCP) server implementation that exposes PowerShell functions as MCP tools. The server dynamically generates MCP tool schemas from PowerShell functions and handles execution through stdio communication.
- PoshMcp.Server/: Main MCP server implementation
Program.cs: Entry point and MCP server setupMcpToolFactoryV2.cs: Dynamic tool schema generation from PowerShell functionsappsettings.json: Configuration for available PowerShell functions
- PoshMcp.Tests/: Comprehensive test suite
Integration/: End-to-end tests with real MCP server processesUnit/: Unit tests for individual componentsFunctional/: Feature-specific functional tests
- TestClient/: Simple test client for manual testing
- .NET 10: Primary runtime and framework
- PowerShell SDK: For executing PowerShell commands and introspection
- Model Context Protocol: JSON-RPC communication standard
- Newtonsoft.Json: JSON serialization and JToken manipulation
- xUnit: Testing framework with shared test infrastructure
- Functions are configured in
appsettings.jsonunderFunctionNamesarray - The server dynamically discovers function signatures using PowerShell reflection
- Parameter types are mapped to JSON Schema types automatically
- Use
McpToolFactoryV2for adding new PowerShell function support
- Use
JObject,JArray, andJValuefrom Newtonsoft.Json for response parsing - Always check JSON token types before casting (JValue vs JObject)
- MCP responses can vary in structure - implement defensive parsing
- Use
JsonConvert.SerializeObject()for proper JSON string serialization
- Integration tests use
InProcessMcpServerwithExternalMcpClientfor realistic stdio testing - Extend
PowerShellTestBasefor consistent logging and test infrastructure - Use shared server/client instances in integration tests for performance
- Add comprehensive debug logging for MCP communication troubleshooting
- Follow JSON-RPC 2.0 specification strictly
- Implement proper error handling with MCP error codes
- Use stdio for client-server communication (not HTTP)
- Support standard MCP methods:
initialize,tools/list,tools/call
- PowerShell functions are configured declaratively in JSON
- Support runtime configuration updates via MCP tools
- Implement configuration reload without server restart
- Validate configuration changes before applying
- Add function name to
appsettings.jsonFunctionNamesarray - The server will automatically discover and expose the function
- Add integration tests to verify the new function works via MCP
- Update documentation if the function has special requirements
- PowerShell execution errors should be wrapped in MCP error responses
- Use appropriate HTTP-like status codes in MCP errors
- Log detailed error information for debugging
- Provide user-friendly error messages in MCP responses
- PowerShell runspace creation is expensive - reuse when possible
- Cache function metadata to avoid repeated reflection
- Use background processes for long-running PowerShell operations
- Implement proper cleanup for PowerShell resources
- Use PascalCase for C# classes and methods
- Use kebab-case for configuration keys where appropriate
- Test files should end with
Tests.cs - Integration tests should be in
Integration/namespace
- Enable detailed logging in tests for MCP communication troubleshooting
- Use
TestOutputHelperto capture logs in test output - Check PowerShell execution contexts and runspace state
- Verify JSON serialization/deserialization with proper type checking
- Microsoft.Extensions.Hosting: For background service hosting
- Microsoft.Extensions.Logging: Comprehensive logging infrastructure
- Microsoft.PowerShell.SDK: PowerShell automation and scripting
- ModelContextProtocol.Server: Core MCP server implementation
- Newtonsoft.Json: JSON manipulation and serialization
- No trailing whitespace
PoshMcp supports containerized deployment using a two-tier architecture pattern.
- Base Image (
poshmcp:latest) — Contains only the MCP server runtime, no modules - Derived Images — User-created images that extend the base with modules, config, and startup scripts
This separation ensures clean boundaries: base = runtime, derived = customization.
Prerequisites: Docker or Podman, Docker Compose or Podman Compose
Build the base image:
# Using helper script (Windows)
.\docker.ps1 build
# Or direct podman/docker
podman build -t poshmcp:latest .Run as web server (HTTP on port 8080):
podman run -d -p 8080:8080 -e POSHMCP_TRANSPORT=http --name poshmcp-web poshmcp:latest
curl http://localhost:8080/healthRun as stdio server:
podman run -it -e POSHMCP_TRANSPORT=stdio poshmcp:latestUsing docker-compose:
# Start web server
podman-compose --profile web up -d
# Start stdio server
podman-compose --profile stdio up -d
# View logs
podman-compose logs -f
# Stop all
podman-compose downCreate a derived image with pre-installed modules (reduces startup time):
FROM poshmcp:latest
USER root
COPY install-modules.ps1 /tmp/
ENV INSTALL_PS_MODULES="Pester PSScriptAnalyzer Az.Accounts"
RUN pwsh /tmp/install-modules.ps1 && rm /tmp/install-modules.ps1
COPY my-appsettings.json /app/server/appsettings.json
USER appuserBuild with:
podman build -f examples/Dockerfile.user -t poshmcp-custom:latest .
podman run -d -p 8080:8080 -e POSHMCP_TRANSPORT=http poshmcp-custom:latestPOSHMCP_TRANSPORT=http— Run HTTP server (default)POSHMCP_TRANSPORT=stdio— Run stdio MCP serverASPNETCORE_ENVIRONMENT=Production— Production modeINSTALL_PS_MODULES— Space-separated module names with optional version constraints (e.g.,"Pester@>=5.0.0 Az.Accounts")
Dockerfile— Base image definitiondocker-compose.yml— Orchestration configuration withwebandstdioprofilesdocker.ps1— Windows helper script (build, run, stop, logs, clean commands)install-modules.ps1— PowerShell module installer (used in derived images)examples/Dockerfile.*— Template Dockerfiles (user, azure, custom patterns)
- Inspect modules in container:
podman run --rm poshmcp:latest pwsh -Command 'Get-Module -ListAvailable' - Run with custom config:
podman run -d -v /path/to/appsettings.json:/app/server/appsettings.json poshmcp:latest - Monitor startup (web mode): Watch logs until
Application startedappears; health endpoint available athttp://localhost:8080/health
- DOCKER.md — Complete Docker deployment guide
- examples/ — Docker Compose examples and sample Dockerfiles
When working on this codebase, focus on maintaining the separation between MCP protocol handling and PowerShell execution, ensure proper error handling and logging, add comprehensive tests for any new functionality, and maintain the two-tier Docker architecture pattern for containerized deployments.