Ectomancer.Resource (Ectomancer v1.3.0)

Copy Markdown View Source

Custom resource DSL for defining MCP resources.

Resources are one of the three MCP primitives (tools, resources, prompts). They represent data that the LLM can read - documents, metrics, logs, configuration, or any content identified by a URI.

Examples

defmodule MyApp.MCP do
  use Ectomancer

  # Static resource — fixed URI
  resource :system_status do
    description "Current system health metrics"
    uri "metrics://status"
    mime_type "application/json"

    read fn _params, _actor ->
      status = %{status: "healthy", uptime: System.uptime(), memory: :erlang.memory()}
      {:ok, Jason.encode!(status)}
    end
  end

  # Templated resource — URI with parameters
  resource :documentation do
    description "Project documentation files"
    uri "docs://{path}"
    mime_type "text/markdown"

    read fn %{path: path}, _actor ->
      case File.read("docs/#{path}.md") do
        {:ok, content} -> {:ok, content}
        _ -> {:error, :not_found}
      end
    end
  end

  # Resource with authorization
  resource :admin_metrics do
    description "Admin-only system metrics"
    uri "admin://metrics"
    mime_type "application/json"

    authorize fn actor, _action ->
      actor != nil && actor.role == :admin
    end

    read fn _params, _actor ->
      {:ok, Jason.encode!(MyApp.System.sensitive_metrics())}
    end
  end
end

DSL Functions

  • description/1 - Human-readable description of the resource
  • uri/1 - Resource URI (static: "docs://readme" or templated: "docs://{path}")
  • mime_type/1 - MIME type of the content (default: "text/plain")
  • authorize/1 - Optional authorization handler
  • read/1 - Handler function fn params, actor -> {:ok, content} | {:error, reason} end

URI Templates

URI templates follow RFC 6570 Level 1 syntax: {variable} placeholders in the URI path. When the LLM reads a resource by a concrete URI that matches the template pattern, the extracted variables are passed as a map to the read handler.

Return Values

The read handler should return:

  • {:ok, content} - Content is a string (will be served with the configured mime_type)
  • {:error, reason} - Reason can be :not_found (will return proper MCP error) or a custom string (returned as generic error)

Summary

Functions

Defines a new resource within an Ectomancer module.

Functions

resource(name, list)

(macro)

Defines a new resource within an Ectomancer module.

Example

resource :system_status do
  description "Current system metrics"
  uri "metrics://status"
  mime_type "application/json"

  read fn _params, _actor ->
    {:ok, Jason.encode!(%{status: "healthy"})}
  end
end