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

Builds and validates MCP `_meta` objects.

MCP 2026-07-28 moves protocol version and client capabilities into every
request. This module owns those reserved fields and the common metadata key
grammar so outbound and inbound paths cannot drift.

# `kind`

```elixir
@type kind() :: :request | :notification | :result
```

# `validation_error`

```elixir
@type validation_error() ::
  {:invalid_meta, :not_an_object}
  | {:invalid_meta_key, term()}
  | {:missing_meta_field, String.t()}
  | {:invalid_meta_field, String.t()}
```

# `build_request_meta`

```elixir
@spec build_request_meta(map(), String.t(), map(), keyword()) ::
  {:ok, map()} | {:error, validation_error()}
```

Builds the metadata required on a modern request.

Caller metadata is preserved after key validation. ExMCP always overwrites
`protocolVersion`, `clientCapabilities`, and `clientInfo` with the connection
values supplied here. Optional W3C trace-context fields may be supplied via
`:trace_context`.

# `client_capabilities_key`

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

Returns the reserved per-request client-capabilities key.

# `parse`

```elixir
@spec parse(map() | nil, kind()) :: {:ok, map()} | {:error, validation_error()}
```

Parses a `_meta` object according to its message kind.

# `parse_notification_meta`

```elixir
@spec parse_notification_meta(map() | nil) ::
  {:ok, map()} | {:error, validation_error()}
```

Parses optional notification metadata.

# `parse_request_meta`

```elixir
@spec parse_request_meta(map()) :: {:ok, map()} | {:error, validation_error()}
```

Parses and validates metadata on a modern request.

# `parse_result_meta`

```elixir
@spec parse_result_meta(map() | nil) :: {:ok, map()} | {:error, validation_error()}
```

Parses optional result metadata.

# `protocol_version_key`

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

Returns the reserved request protocol-version key.

# `reserved_key?`

```elixir
@spec reserved_key?(term()) :: boolean()
```

Returns whether a key's prefix is reserved for MCP protocol use.

# `valid_key?`

```elixir
@spec valid_key?(term()) :: boolean()
```

Returns whether a metadata key follows the MCP key grammar.

# `validate`

```elixir
@spec validate(map()) :: :ok | {:error, validation_error()}
```

Validates the keys of a metadata object.

---

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