# `ExMCP.Authorization.MetadataFetcher`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/authorization/metadata_fetcher.ex#L1)

Fail-closed HTTP fetch boundary for OAuth metadata documents.

Fetches use HTTPS by default, reject userinfo and fragments, resolve and
validate every address on every hop, pin the connection to one approved
public address, and follow only bounded same-origin redirects unless another
exact HTTPS origin is explicitly allowed. Tests and local development may
explicitly allow plain HTTP on loopback addresses. Requests carry fixed
metadata headers and never inherit authorization, cookie, or application
transport headers.

# `fetch_error`

```elixir
@type fetch_error() :: {:metadata_fetch_error, atom()}
```

# `response`

```elixir
@type response() :: %{
  status: pos_integer(),
  headers: [{String.t(), String.t()}],
  body: binary(),
  final_url: String.t()
}
```

# `fetch`

```elixir
@spec fetch(
  String.t(),
  keyword()
) :: {:ok, response()} | {:error, fetch_error()}
```

Fetches one OAuth metadata document through the hardened network boundary.

# `validate_url`

```elixir
@spec validate_url(
  String.t(),
  keyword()
) :: :ok | {:error, fetch_error()}
```

Validates the URL form accepted by the metadata fetch boundary.

---

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