ExMCP.Content.Builders (ex_mcp v0.9.2)

View Source

Smart constructors and builder patterns for ExMCP content creation.

This module provides an intuitive, chainable API for building complex content structures with validation, type safety, and helpful defaults.

Features

  • Chainable API: Fluent interface for building content
  • Type Safety: Compile-time type checking and validation
  • Smart Defaults: Sensible defaults for common use cases
  • File Integration: Direct file loading with automatic type detection
  • Batch Operations: Efficient creation of multiple content items
  • Template System: Reusable content templates

Usage

use ExMCP.Content.Builders

# Simple text content
content = text("Hello, world!")

# Chainable building
content = text("# Header")
|> as_markdown()
|> with_metadata(%{author: "user"})

# File-based content
content = from_file("image.png")
|> with_alt_text("Product screenshot")
|> resize(800, 600)

# Batch creation
contents = batch([
  text("First message"),
  image_from_file("diagram.png"),
  text("Summary", format: :markdown)
])

Summary

Types

Content builder state

File processing options

Functions

Creates a new annotation builder.

Sets content as code format with optional language.

Sets content as HTML format.

Sets content as markdown format.

Creates a new audio content builder from base64 data.

Creates audio content from a file.

Creates multiple content items efficiently.

Creates a content collection with shared metadata.

Compresses image content (placeholder).

Extracts text content from various content types.

Filters content by type.

Creates content from a file with automatic type detection.

Creates content from a template with substitutions.

Creates a new image content builder from base64 data.

Creates image content from a file.

Resizes image content data (requires image processing library). Note: This is a placeholder - actual implementation would require ImageMagick or similar.

Creates a new resource reference builder.

Creates a new text content builder.

Creates text content from a file with format detection.

Transforms content with a function, handling errors gracefully.

Validates a list of content items.

Adds alt text to image content.

Adds confidence to annotation content.

Sets dimensions for image content.

Sets duration for audio content.

Adds metadata to any content type.

Adds transcript to audio content.

Types

builder()

@type builder() :: %{
  content: ExMCP.Content.Protocol.content() | nil,
  errors: [String.t()],
  metadata: map()
}

Content builder state

file_opts()

@type file_opts() :: [
  max_size: pos_integer(),
  mime_types: [String.t()],
  auto_resize: {pos_integer(), pos_integer()},
  quality: float()
]

File processing options

Functions

annotation(annotation_type, opts \\ [])

@spec annotation(
  String.t(),
  keyword()
) :: ExMCP.Content.Protocol.annotation()

Creates a new annotation builder.

as_code(content, language \\ nil)

Sets content as code format with optional language.

Examples

content = text("console.log()") |> as_code("javascript")
content = text("SELECT * FROM users") |> as_code("sql")

as_html(content)

Sets content as HTML format.

as_markdown(content)

Sets content as markdown format.

Examples

content = text("# Header") |> as_markdown()

audio(base64_data, mime_type, opts \\ [])

Creates a new audio content builder from base64 data.

audio_from_file(file_path, opts \\ [])

@spec audio_from_file(
  String.t(),
  keyword()
) :: ExMCP.Content.Protocol.audio() | {:error, String.t()}

Creates audio content from a file.

batch(content_specs)

Creates multiple content items efficiently.

Examples

contents = batch([
  text("First message"),
  image_from_file("chart.png"),
  text("Summary", format: :markdown)
])

collection(contents, shared_metadata)

Creates a content collection with shared metadata.

Examples

contents = collection([
  text("Message 1"),
  text("Message 2")
], %{conversation_id: "abc123", timestamp: DateTime.utc_now()})

compress(content, opts \\ [])

Compresses image content (placeholder).

extract_text(arg1)

@spec extract_text(ExMCP.Content.Protocol.content()) :: String.t() | nil

Extracts text content from various content types.

Examples

text_content = extract_text(image_content)  # Uses alt_text
text_content = extract_text(audio_content)  # Uses transcript

filter_by_type(contents, type)

@spec filter_by_type([ExMCP.Content.Protocol.content()], atom() | [atom()]) :: [
  ExMCP.Content.Protocol.content()
]

Filters content by type.

Examples

text_only = filter_by_type(contents, :text)
media_content = filter_by_type(contents, [:image, :audio])

from_file(file_path, opts \\ [])

@spec from_file(String.t(), file_opts()) ::
  ExMCP.Content.Protocol.content() | {:error, String.t()}

Creates content from a file with automatic type detection.

Examples

# Image file
content = from_file("screenshot.png")

# Text file
content = from_file("README.md")

# With options
content = from_file("large_image.jpg", max_size: 1_000_000, auto_resize: {800, 600})

from_template(template, substitutions)

Creates content from a template with substitutions.

Examples

template = text("Hello, {{name}}! Your score is {{score}}")
content = from_template(template, %{name: "Alice", score: 95})
# Results in: text("Hello, Alice! Your score is 95")

image(base64_data, mime_type, opts \\ [])

Creates a new image content builder from base64 data.

Examples

iex> image("iVBORw0K...", "image/png")
%{type: :image, data: "iVBORw0K...", mime_type: "image/png", ...}

image_from_file(file_path, opts \\ [])

@spec image_from_file(
  String.t(),
  keyword()
) :: ExMCP.Content.Protocol.image() | {:error, String.t()}

Creates image content from a file.

Examples

content = image_from_file("photo.jpg")
content = image_from_file("diagram.png", alt_text: "System architecture", auto_resize: {800, 600})

resize(content, width, height)

Resizes image content data (requires image processing library). Note: This is a placeholder - actual implementation would require ImageMagick or similar.

Examples

resized = resize(image_content, 800, 600)

resource(uri, opts \\ [])

@spec resource(
  String.t(),
  keyword()
) :: ExMCP.Content.Protocol.resource()

Creates a new resource reference builder.

text(content, opts \\ [])

@spec text(
  String.t(),
  keyword()
) :: ExMCP.Content.Protocol.text()

Creates a new text content builder.

Examples

iex> text("Hello")
%{type: :text, text: "Hello", format: :plain, language: nil, metadata: %{}}

iex> text("console.log('hi')", format: :code, language: "javascript")
%{type: :text, text: "console.log('hi')", format: :code, language: "javascript", metadata: %{}}

text_from_file(file_path, opts \\ [])

@spec text_from_file(
  String.t(),
  keyword()
) :: ExMCP.Content.Protocol.text() | {:error, String.t()}

Creates text content from a file with format detection.

Examples

content = text_from_file("README.md")  # Auto-detects markdown
content = text_from_file("script.js")  # Auto-detects code with language

transform(content, transformer)

Transforms content with a function, handling errors gracefully.

Examples

result = transform(content, fn c -> with_metadata(c, %{processed: true}) end)

validate_all(contents)

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

Validates a list of content items.

Examples

contents = [text("Hello"), image(data, "image/png")]
case validate_all(contents) do
  :ok -> contents
  {:error, errors} -> handle_errors(errors)
end

with_alt_text(content, alt_text)

Adds alt text to image content.

Examples

content = image(data, "image/png") |> with_alt_text("Product screenshot")

with_confidence(content, confidence)

Adds confidence to annotation content.

Examples

content = annotation("sentiment") |> with_confidence(0.95)

with_dimensions(content, width, height)

Sets dimensions for image content.

Examples

content = image(data, "image/png") |> with_dimensions(800, 600)

with_duration(content, duration)

Sets duration for audio content.

Examples

content = audio(data, "audio/wav") |> with_duration(45.5)

with_metadata(content, metadata)

Adds metadata to any content type.

Examples

content = text("Hello") |> with_metadata(%{author: "user", timestamp: DateTime.utc_now()})

with_transcript(content, transcript)

Adds transcript to audio content.

Examples

content = audio(data, "audio/wav") |> with_transcript("Hello, this is a recording")