# `ExMCP.Protocol.VersionNegotiator`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/protocol/version_negotiator.ex#L1)

Negotiates legacy MCP revisions during the `initialize` handshake.

This compatibility API covers the initialize-based revisions from
2024-11-05 through 2025-11-25. MCP 2026-07-28 is wire-incompatible: clients
select it with `:protocol_mode` and establish it through `server/discover`,
not through this module. Consequently, `latest_version/0` means the newest
legacy revision rather than the latest upstream MCP revision.

# `build_capabilities`

> This function is deprecated. Use ExMCP.Protocol.Initialize or ExMCP.Server.Capabilities.

```elixir
@spec build_capabilities(String.t()) :: map()
```

Build a legacy initialize-result wrapper using the canonical capability registry.

This function is retained as a 1.x compatibility shim. Initialization is
handled by ExMCP's server dispatchers; code that only needs the capability
map should use `ExMCP.Server.Capabilities.build_capabilities/2`.

# `latest_version`

```elixir
@spec latest_version() :: String.t()
```

Get the newest legacy revision supported by initialize negotiation.

Modern MCP 2026-07-28 uses `server/discover` and is selected with a protocol
mode instead of this legacy negotiator.

# `negotiate`

```elixir
@spec negotiate([String.t()]) :: {:ok, String.t()} | {:error, :no_compatible_version}
```

Negotiates a legacy protocol revision from the client's offered versions.

Takes the client's supported versions and returns the best matching version
that both client and server support.

## Parameters

- `client_versions` - List of protocol versions supported by the client

## Returns

- `{:ok, version}` - Successfully negotiated version
- `{:error, :no_compatible_version}` - No compatible version found

## Examples

    iex> ExMCP.Protocol.VersionNegotiator.negotiate(["2025-11-25", "2025-06-18"])
    {:ok, "2025-11-25"}

    iex> ExMCP.Protocol.VersionNegotiator.negotiate(["2024-01-01"])
    {:error, :no_compatible_version}

# `supported?`

```elixir
@spec supported?(String.t()) :: boolean()
```

Checks whether a revision is supported by legacy initialize negotiation.

# `supported_versions`

```elixir
@spec supported_versions() :: [String.t()]
```

Returns the initialize-compatible legacy revisions.

Use `ExMCP.Types.V20260728` and a modern-enabled `:protocol_mode` for MCP
2026-07-28 rather than expecting it in this list.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
