# `PtcRunner.Upstream.Transport`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/upstream/transport.ex#L1)

Behaviour for root-owned upstream client transports.

Transports return `PtcRunner.Upstream.Result` tuples and normalize any
protocol-specific envelopes before values reach `tool/call`.

# `call_opts`

```elixir
@type call_opts() :: [timeout: pos_integer(), max_response_bytes: pos_integer()]
```

# `server_name`

```elixir
@type server_name() :: String.t()
```

# `tool_name`

```elixir
@type tool_name() :: String.t()
```

# `tool_schema`

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

# `upstream`

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

# `call`

```elixir
@callback call(upstream(), tool_name(), args :: map(), call_opts()) ::
  PtcRunner.Upstream.Result.t()
```

# `list_tools`

```elixir
@callback list_tools(upstream()) ::
  {:ok, [tool_schema()]}
  | {:error, PtcRunner.Upstream.Result.reason(), String.t()}
```

# `start_trapped`

```elixir
@spec start_trapped(module(), server_name(), map()) :: GenServer.on_start()
```

Start a transport GenServer with `:trap_exit` temporarily enabled in the
caller, so a child that fails during `init/1` surfaces as `{:error, reason}`
instead of crashing the (often unsupervised) caller. The caller's original
`:trap_exit` flag is restored afterward.

Shared by the stateful MCP transports (`McpHttp`, `McpStdio`).

---

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