# `Mead.MCP.Protocol`
[🔗](https://github.com/albertosca/mead/blob/main/lib/mead/mcp/protocol.ex#L1)

Pure JSON-RPC 2.0 codec for the slice of MCP that `mead` speaks as a client: `initialize`,
`notifications/initialized`, `tools/list`, and `tools/call`.

Encoders return one-line JSON binaries (the JSON encoder escapes newlines inside strings), so a
stdio transport can frame messages with a trailing newline. `decode/1` never raises.

# `decoded`

```elixir
@type decoded() ::
  {:response, request_id(), map()}
  | {:error_response, request_id(),
     %{code: integer(), message: String.t(), data: term()}}
  | {:request, request_id(), String.t(), map()}
  | {:notification, String.t(), map()}
  | {:invalid,
     :not_binary
     | :malformed_json
     | :not_jsonrpc
     | :result_and_error
     | :unrecognized}
```

# `request_id`

```elixir
@type request_id() :: integer() | String.t()
```

# `call_tool_request`

```elixir
@spec call_tool_request(request_id(), String.t(), map()) :: binary()
```

# `cancelled_notification`

```elixir
@spec cancelled_notification(request_id(), String.t()) :: binary()
```

Tells the server that nobody waits for the answer to request `id` any more.

# `decode`

```elixir
@spec decode(term()) :: decoded()
```

# `error_response`

```elixir
@spec error_response(request_id() | nil, integer(), String.t()) :: binary()
```

# `initialize_request`

```elixir
@spec initialize_request(request_id()) :: binary()
```

# `initialized_notification`

```elixir
@spec initialized_notification() :: binary()
```

# `list_tools_request`

```elixir
@spec list_tools_request(request_id(), String.t() | nil) :: binary()
```

# `protocol_version`

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

The one protocol version this client negotiates.

# `result_response`

```elixir
@spec result_response(request_id(), map()) :: binary()
```

# `supported_version?`

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

---

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