Anubis.Server.Component.Resource behaviour (anubis_mcp v0.14.0)

Defines the behaviour for MCP resources.

Resources represent data that can be read by the client, such as files, documents, or any other content. Each resource is identified by a URI and can provide content in various formats.

Example

defmodule MyServer.Resources.Documentation do
  @behaviour Anubis.Server.Behaviour.Resource

  alias Anubis.Server.Frame

  @impl true
  def uri, do: "file:///docs/readme.md"

  @impl true
  def name, do: "Project README"

  @impl true
  def description, do: "The main documentation for this project"

  @impl true
  def mime_type, do: "text/markdown"

  @impl true
  def read(_params, frame) do
    case File.read("README.md") do
      {:ok, content} -> 
        # Can track access in frame
        new_frame = Frame.assign(frame, :last_resource_access, DateTime.utc_now())
        {:ok, content, new_frame}

      {:error, reason} -> 
        {:error, "Failed to read README: #{inspect(reason)}"}
    end
  end
end

Example with dynamic content

defmodule MyServer.Resources.SystemStatus do
  @behaviour Anubis.Server.Behaviour.Resource

  @impl true
  def uri, do: "system://status"

  @impl true
  def name, do: "System Status"

  @impl true
  def description, do: "Current system status and metrics"

  @impl true
  def mime_type, do: "application/json"

  @impl true
  def read(_params, frame) do
    status = %{
      uptime: System.uptime(),
      memory: :erlang.memory(),
      user_id: frame.assigns[:user_id],
      timestamp: DateTime.utc_now()
    }

    {:ok, Jason.encode!(status), frame}
  end
end

Summary

Callbacks

Returns the MIME type of the resource content.

Returns the name that identifies this resource.

Reads the resource content.

Returns the title that identifies this resource.

Returns the URI that identifies this resource.

Types

content()

@type content() :: binary() | String.t()

params()

@type params() :: map()

t()

@type t() :: %Anubis.Server.Component.Resource{
  description: String.t() | nil,
  handler: module() | nil,
  mime_type: String.t(),
  name: String.t(),
  title: String.t() | nil,
  uri: String.t(),
  uri_template: String.t() | nil
}

Callbacks

mime_type()

@callback mime_type() :: String.t()

Returns the MIME type of the resource content.

Common MIME types:

  • text/plain for plain text
  • text/markdown for Markdown
  • application/json for JSON data
  • text/html for HTML
  • application/octet-stream for binary data

name()

@callback name() :: String.t()

Returns the name that identifies this resource.

Intended for programmatic or logical use, but used as a display name in past specs or fallback (if title isn't present).

read(params, frame)

@callback read(params :: params(), frame :: Anubis.Server.Frame.t()) ::
  {:reply, response :: Anubis.Server.Response.t(),
   new_state :: Anubis.Server.Frame.t()}
  | {:noreply, new_state :: Anubis.Server.Frame.t()}
  | {:error, error :: Anubis.MCP.Error.t(),
     new_state :: Anubis.Server.Frame.t()}

Reads the resource content.

Parameters

  • params - Optional parameters from the client (typically empty for resources)
  • frame - The server frame containing context and state

Return Values

  • {:ok, content} - Resource read successfully, frame unchanged
  • {:ok, content, new_frame} - Resource read successfully with frame updates
  • {:error, reason} - Failed to read resource

Content Types

The content should match the declared MIME type:

  • For text types, return a String
  • For binary types, return binary data
  • For JSON, return the JSON-encoded string

title()

(optional)
@callback title() :: String.t()

Returns the title that identifies this resource.

Intended for UI and end-user contexts — optimized to be human-readable and easily understood, even by those unfamiliar with domain-specific terminology.

If not provided, the name should be used for display.

uri()

@callback uri() :: String.t()

Returns the URI that identifies this resource.

The URI should be unique within the server and follow standard URI conventions. Common schemes include:

  • file:// for file-based resources
  • http:// or https:// for web resources
  • Custom schemes for application-specific resources