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

Content validation and transformation utilities for ExMCP.

> #### Experimental {: .warning}
>
> Outside the core Handler/DSL path. Useful helpers for apps that process
> untrusted content; not required to speak MCP/ACP.

## Features

- **Schema Validation**: bounded JSON Schema via `ExJsonSchema` (`validate_schema/3`)
- **Content Sanitization**: HTML escape, script stripping, Unicode NFC
- **Size / MIME checks**: structural validation helpers
- **Security scanning**: best-effort pattern checks

Image **processing** (compress/resize/thumbnail/face detection) is **not** part
of MCP/ACP and is deprecated for removal in 2.0.0. Use `ExMCP.Content.image/2`
to build protocol image blocks only.

## Usage

    alias ExMCP.Content.Validation

    case Validation.validate(content, rules) do
      :ok -> process_content(content)
      {:error, reasons} -> handle_validation_errors(reasons)
    end

    safe_content = Validation.sanitize(content, [:html_escape, :strip_scripts, :normalize_unicode])

# `sanitization_op`

```elixir
@type sanitization_op() ::
  :html_escape
  | :strip_scripts
  | :normalize_unicode
  | :limit_size
  | :remove_metadata
  | :compress_media
  | atom()
```

Sanitization operation

# `transformation_op`

```elixir
@type transformation_op() ::
  :normalize_whitespace
  | :convert_encoding
  | :compress_images
  | :resize_images
  | :extract_text
  | :generate_thumbnails
  | atom()
```

Transformation operation

# `validation_error`

```elixir
@type validation_error() :: %{
  rule: atom(),
  message: String.t(),
  field: String.t() | nil,
  value: any(),
  severity: :error | :warning | :info
}
```

Validation error with context

# `validation_opts`

```elixir
@type validation_opts() :: [
  strict: boolean(),
  max_errors: pos_integer(),
  skip_warnings: boolean(),
  custom_validators: [module()]
]
```

Validation options

# `validation_result`

```elixir
@type validation_result() :: :ok | {:error, [validation_error()]}
```

Validation result with detailed errors

# `validation_rule`

```elixir
@type validation_rule() ::
  atom()
  | {atom(), keyword()}
  | {module(), atom(), keyword()}
  | (ExMCP.Content.Protocol.content() -&gt; :ok | {:error, String.t()})
```

Validation rule specification

# `analyze`

```elixir
@spec analyze(ExMCP.Content.Protocol.content(), [atom()]) :: map()
```

Analyzes content for various properties and metadata.

# `custom_rule`

```elixir
@spec custom_rule((ExMCP.Content.Protocol.content() -&gt; :ok | {:error, String.t()})) ::
  validation_rule()
```

Creates a validation rule from a custom function.

# `detect_sensitive_data`

```elixir
@spec detect_sensitive_data(ExMCP.Content.Protocol.content()) ::
  :ok | {:sensitive, [atom()]}
```

Checks if content contains potentially sensitive information.

# `extract_metadata`

```elixir
@spec extract_metadata(ExMCP.Content.Protocol.content()) :: map()
```

Extracts metadata from content.

# `register_validator`

```elixir
@spec register_validator(atom(), (ExMCP.Content.Protocol.content() -&gt;
                              validation_result())) :: :ok
```

Registers a custom validator function.

# `sanitize`

```elixir
@spec sanitize(ExMCP.Content.Protocol.content(), [sanitization_op()]) ::
  ExMCP.Content.Protocol.content()
```

Sanitizes content to remove potentially dangerous or unwanted elements.

# `sanitize_text`

```elixir
@spec sanitize_text(String.t(), [sanitization_op()]) :: String.t()
```

Sanitizes text content specifically for safe display.

# `scan_security`

```elixir
@spec scan_security(ExMCP.Content.Protocol.content(), [atom()]) ::
  :safe | {:threat, [String.t()]}
```

Scans content for security threats.

# `transform`

```elixir
@spec transform(ExMCP.Content.Protocol.content(), [transformation_op()]) ::
  {:ok, ExMCP.Content.Protocol.content() | [ExMCP.Content.Protocol.content()]}
  | {:error, String.t()}
```

Transforms content through a series of operations.

# `transform_with_validation`

```elixir
@spec transform_with_validation(ExMCP.Content.Protocol.content(), [
  transformation_op() | validation_rule()
]) :: {:ok, ExMCP.Content.Protocol.content()} | {:error, String.t()}
```

Transforms content with validation at each step.

# `validate`

```elixir
@spec validate(
  ExMCP.Content.Protocol.content(),
  [validation_rule()],
  validation_opts()
) ::
  validation_result()
```

Validates content against a set of validation rules.

# `validate_batch`

```elixir
@spec validate_batch(
  [ExMCP.Content.Protocol.content()],
  [validation_rule()],
  validation_opts()
) ::
  :ok | {:error, [validation_result()]}
```

Validates multiple content items efficiently using parallel processing.

# `validate_schema`

```elixir
@spec validate_schema(ExMCP.Content.Protocol.content(), map() | boolean(), keyword()) ::
  :ok | {:error, [String.t()]}
```

Validates content against a JSON schema using ExJsonSchema.

Content is converted to a JSON-compatible map before validation.

---

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