Table of Contents

Transport Modes

PoshMcp supports two transport modes for different deployment scenarios. The production implementation uses ModelContextProtocol and ModelContextProtocol.AspNetCore 2.0.0 and defaults to MCP protocol 2026-07-28 (Stateless mode). Protocol 2025-11-25 remains available for legacy clients via Stateful mode.

Stdio Mode

Best for: Local development, GitHub Copilot integration, single-connection scenarios.

Characteristics:

  • Single persistent connection
  • Stream-based communication
  • One runspace per connection
  • Minimal overhead

Start:

poshmcp serve --transport stdio

Configure in MCP client:

{
  "mcpServers": {
    "poshmcp": {
      "command": "poshmcp",
      "args": ["serve", "--transport", "stdio"]
    }
  }
}

HTTP Mode

Best for: Multi-user deployments, web integration, cloud infrastructure.

Characteristics:

  • MCP Streamable HTTP (2026-07-28, Stateless default)
  • Per-call isolation via reset-before-reuse pool
  • Horizontal scaling capable
  • Built-in health checks

Start:

poshmcp serve --transport http --port 8080

MCP Endpoint and Protocol

The default Streamable HTTP endpoint is /; /mcp is also available as a compatibility alias. For a production deployment, set a dedicated endpoint with --mcp-path /mcp (or POSHMCP_MCP_PATH=/mcp) and publish only that endpoint through the reverse proxy or ingress.

In Stateless (default) mode, clients initialize with a JSON-RPC POST containing protocolVersion: "2026-07-28" and Accept: application/json, text/event-stream. No Mcp-Session-Id is issued and none is required; each tool call is served by a pooled runspace that is reset before reuse — PowerShell state does not persist between calls. In Stateful mode (opt-in), the server issues a Mcp-Session-Id for MCP protocol session continuity; even then, Mcp-Session-Id does not bind a caller to a specific PowerShell runspace or preserve variables across calls. Responses may be JSON or Server-Sent Events, according to the client's Accept header.

# Initialize a Stateless HTTP session (default).
curl -i https://poshmcp.example/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"example","version":"1.0"}}}'

# Open the optional server-to-client event stream.
curl -N https://poshmcp.example/mcp \
  -H "Accept: text/event-stream" \
  -H "MCP-Protocol-Version: 2026-07-28"

# Stateful mode only — explicitly end the MCP session.
curl -X DELETE https://poshmcp.example/mcp \
  -H "Mcp-Session-Id: <session-id>" \
  -H "MCP-Protocol-Version: 2026-07-28"

The server returns 400 for a missing, invalid, or unsupported negotiated protocol version. In Stateful mode, DELETE returns 200 for a live session; requests made after deletion or idle expiry return 404 and the client must initialize a new session. McpServer:IdleSessionTimeoutSeconds applies only in Stateful mode and governs MCP session idle expiry — not a dedicated runspace. Pool worker lifetime is governed by McpServer:RunspacePool:IdleTtl (default 00:05:00); the pool replenishment sweep runs at McpServer:RunspacePool:SweepInterval (default 00:00:30).

2024-11-05 Streamable HTTP clients remain supported for compatibility and may omit the protocol-version header after initialization. The deprecated HTTP-with-SSE transport is disabled by default. Enable it only for a required legacy-client transition:

{
  "McpServer": {
    "EnableLegacySse": true
  }
}

Deployment Security

When an Origin header is present on an MCP request, PoshMcp accepts only a same-origin request or a value in Authentication:Cors:AllowedOrigins; other origins receive 403. Configure exact HTTPS origins for browser clients rather than using a wildcard. Non-browser clients normally omit Origin.

Enable Authentication:Enabled for external deployments. MCP endpoints then require the configured McpAccess policy; /health and /health/ready remain anonymous for platform probes. See Authentication for Entra ID and API-key setup.

Health probes remain separate from the MCP endpoint:

curl https://poshmcp.example/health
curl https://poshmcp.example/health/ready

Override via Environment Variable

export POSHMCP_TRANSPORT=http
poshmcp serve