# `ExMCP.Content.SchemaPolicy`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/content/schema_policy.ex#L1)

Fail-closed resource policy for JSON Schema compilation and validation.

Cross-document `$ref` resolution is disabled by default before `ExJsonSchema`
sees a schema, even if the host application configured ExJsonSchema's global
remote resolver. Local fragment references remain supported. Network
references can be enabled only through ExMCP's allowlisted, IP-pinned resolver.

Schema size, structural depth, composition depth, total subschema count,
resolution time, and validation time are bounded. Defaults can be adjusted
with `config :ex_mcp, :json_schema, ...` or per call.

The opt-in resolver revalidates every redirect and DNS result, rejects
non-public addresses, pins the connection to an approved address, rejects
compressed responses and proxies, and bounds response bytes, aggregate bytes,
document count, reference depth, redirects, DNS, connection, and request time.
Fetched schemas are scoped to one compilation and are never globally cached.

# `compile_result`

```elixir
@type compile_result() :: {:ok, term()} | {:error, policy_error()}
```

# `policy_error`

```elixir
@type policy_error() ::
  :network_ref_forbidden
  | {:schema_limit_exceeded, atom(), non_neg_integer()}
  | {:schema_resolution_timeout, non_neg_integer()}
  | {:schema_validation_timeout, non_neg_integer()}
  | {:invalid_schema_policy_option, atom()}
  | {:invalid_schema, String.t()}
  | {:schema_validation_failed, String.t()}
  | {:network_schema_error, atom()}
```

# `validation_result`

```elixir
@type validation_result() :: :ok | {:error, term()}
```

# `compile`

```elixir
@spec compile(
  map() | boolean(),
  keyword()
) :: compile_result()
```

Preflights and resolves a schema within the configured deadline.

# `format_error`

```elixir
@spec format_error(policy_error()) :: String.t()
```

Formats a policy failure without including remote-reference values.

# `json_compatible`

```elixir
@spec json_compatible(term()) :: term()
```

Normalizes atom-keyed schema terms to their JSON wire representation.

# `options`

```elixir
@spec options(keyword()) :: keyword()
```

Returns the effective schema-policy options.

# `preflight`

```elixir
@spec preflight(
  map() | boolean(),
  keyword()
) :: :ok | {:error, policy_error()}
```

Checks a raw schema without resolving references.

# `validate`

```elixir
@spec validate(term(), term(), keyword()) :: validation_result()
```

Validates data with a resolved or raw schema within a hard deadline.

---

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