# `SuperPi.MCP.Transport`
[🔗](https://github.com/oleksandr/super-pi-beam/blob/v0.1.0/lib/super_pi/mcp/transport.ex#L1)

How `SuperPi.MCP.Client` talks to one MCP server. The client owns the protocol (handshake,
request ids, timeouts); a transport only moves JSON-RPC messages.

A transport runs inside the client process and keeps its state in a term the client holds.
Whatever the transport spawns (a port, an HTTP request task) sends its results to the client
process as ordinary messages. The client hands every message it does not know to
`c:handle_info/2`, which turns it into JSON-RPC messages or reports that the server is gone.

Built in: `SuperPi.MCP.Transport.Stdio` (a child process) and
`SuperPi.MCP.Transport.StreamableHTTP` (a URL).

# `message`

```elixir
@type message() :: map()
```

# `state`

```elixir
@type state() :: term()
```

# `close`

```elixir
@callback close(state()) :: :ok
```

Releases the transport's resources.

# `handle_info`

```elixir
@callback handle_info(state(), term()) ::
  {:messages, [message()], state()}
  | {:ignore, state()}
  | {:closed, term(), state()}
```

Handles a message sent to the owner. Returns the JSON-RPC messages it carried, `:ignore`
for a message that carries none, or `:closed` when the server is gone.

# `protocol_version`

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

The `protocolVersion` the client offers in `initialize` over this transport.

# `send_message`

```elixir
@callback send_message(state(), message()) :: state()
```

Sends one JSON-RPC message. Never waits for the answer: it arrives through `c:handle_info/2`.

# `start`

```elixir
@callback start(opts :: keyword()) :: {:ok, state()} | {:error, term()}
```

Opens the transport. The calling process is the owner and receives its messages.

---

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