Skip to content

Update ISHRemoteMcpServer MCP Protocol Version from '2024-11-05' handshake to dual-era '2026-07-28' stateless #244

Description

@ddemeyer

Summary

The MCP 2026-07-28 ("MCP 2.0") specification replaces the initialize handshake with a
stateless, per-request protocol model. This issue tracks making ISHRemoteMcpServer a
dual-era server: serving modern requests at 2026-07-28 while still answering the
legacy initialize handshake for existing clients.

Companion issue: #243 — fixes the stdin-EOF infinite loop that this work also depends on.

Why this is a good investment

MCP 2.0 is not just a different protocol version — it is a measurably better platform for
agentic automation of Tridion Docs Content Manager. The table below maps each spec change
to a concrete improvement for ISHRemote users and their LLM clients.

MCP 2.0 change What is better today vs. before
Stateless per-request protocol A crashed or restarted MCP server process loses no session state; clients retry in-flight requests against the fresh process without re-initializing. Today a dead server leaves the LLM stuck waiting for a handshake that will never arrive.
server/discover (mandatory) AI tools (VS Code, Claude Desktop, Cursor, GitHub Copilot) can enumerate the server's capabilities, supported versions, and instructions in a single call before invoking any tool. No separate probe-then-initialize round trip; faster startup and better IDE integration.
resultType: "complete" / "input_required" The client knows structurally whether a result is final or whether the server needs more information (Multi Round-Trip Requests). Today every result looks the same to the client regardless of whether the tool succeeded or is mid-flight.
isError: true in tools/call results Tool execution errors (invalid field names, session not found, Tridion Docs API failures) are surfaced to the LLM as actionable feedback. The LLM can self-correct and retry with adjusted parameters. Today errors are swallowed into the log (Invoke-IshRemoteMcpHandleRequest.ps1:53-66) and the LLM receives no signal that anything went wrong, producing silent wrong answers.
Protocol error -32602 for unknown tool A misconfigured or hallucinated tool name returns a clear JSON-RPC error the client can surface to the user. Today the server silently returns an empty result.
structuredContent + outputSchema Tools can return typed JSON objects alongside the human-readable text. LLMs and downstream scripts can parse and validate results reliably instead of extracting data from free-form Out-String output. Enables richer agentic pipelines.
Caching hints (ttlMs, cacheScope) on tools/list The large ISHRemote tool list (100+ cmdlets) can be cached by the client, cutting token usage and latency on every conversation that needs it. Also improves LLM prompt-cache hit rates when the tool list is included in the system prompt.
Version negotiation (-32022) Server and client can independently upgrade to future MCP versions. If a client speaks a version the server does not support, it gets a structured error with the supported list and retries — no silent breakage.
title on tool definitions IDE and chat UIs display a clean human-readable label (e.g. Get ISH Folder) separate from the programmatic cmdlet name (Get-IshFolder), improving discoverability for end users.
EOF exit (companion #243) Server process exits cleanly when the client closes stdin, eliminating orphaned hidden pwsh processes that accumulate across sessions.

Current state

Invoke-IshRemoteMcpHandleRequest.ps1 is pure legacy-era 2024-11-05:

  • Line 17 — initialize returns hardcoded "protocolVersion":"2024-11-05" and placeholder
    serverInfo "PowerShell MCP Server (Template)" / "0.2.0".
  • No server/discover; modern clients receive -32601 and fall back to initialize, so
    nothing breaks today — but the server is pinned to 2024-11-05 semantics and gains none of
    the improvements above.
  • Lines 53-66 — tools/call swallows all execution errors and always returns isError:false.
  • Unknown tool returns an empty result rather than a protocol error.

Proposed change — dual-era server

Keep the legacy initialize branch intact for existing clients; add modern handling alongside it.

  1. Era detection — request carries _meta["io.modelcontextprotocol/protocolVersion"]
    → modern path; method == "initialize" → legacy path.
  2. server/discoverDiscoverResult with supportedVersions (e.g. ["2026-07-28"]),
    capabilities, resultType: "complete", ttlMs, cacheScope, instructions (reuse
    Register-IshRemoteMcpInstructions), _meta serverInfo.
  3. resultType: "complete" on all modern ping, tools/list, and tools/call results;
    add required ttlMs / cacheScope to tools/list.
  4. Version gate — unsupported _meta version → -32022
    UnsupportedProtocolVersionError with data.supported.
  5. tools/call semantics — unknown tool → protocol error -32602; tool execution
    errors → result with isError: true so the LLM can self-correct.
  6. serverInfo — replace placeholder with ISHRemoteMcpServer and the actual module version.
  7. Register-IshRemoteMcpTool.ps1 — add title; use
    {"type":"object","additionalProperties":false} for no-parameter tools.

Files

  • Source/ISHRemote/Trisoft.ISHRemote/Scripts/Public/Invoke-IshRemoteMcpHandleRequest.ps1
  • Source/ISHRemote/Trisoft.ISHRemote/Scripts/Public/Start-IshRemoteMcpServer.ps1
  • Source/ISHRemote/Trisoft.ISHRemote/Scripts/Public/Register-IshRemoteMcpTool.ps1
  • Source/ISHRemote/Trisoft.ISHRemote/Scripts/Public/Invoke-IshRemoteMcpHandleRequest.Tests.ps1
  • Source/ISHRemote/Trisoft.ISHRemote/Scripts/Public/Start-IshRemoteMcpServer.Tests.ps1

Test plan

Extend Invoke-IshRemoteMcpHandleRequest.Tests.ps1:

  • server/discover returns correct shape (supportedVersions, capabilities, resultType,
    ttlMs, cacheScope, instructions, _meta.serverInfo).
  • All modern results include resultType: "complete".
  • Unsupported _meta version returns -32022 with data.supported.
  • Unknown tool returns -32602.
  • Tool execution error returns result with isError: true.
  • Legacy initialize still returns "protocolVersion":"2024-11-05" (dual-era regression test).

Spec references

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions