ExMCP.Tasks.Store behaviour (ex_mcp v1.0.0-rc.8)

Copy Markdown View Source

Persistence contract for the MCP Tasks extension.

A store must make create/3 durable before returning success and must apply ownership checks to every operation. Implementations should make lifecycle operations atomic across every node that can serve the same task ID.

ExMCP ships ExMCP.Tasks.Store.ETS as a bounded, node-local reference implementation. Deployments that require task survival across server or node restarts should configure a database-backed implementation.

Summary

Types

owner()

@type owner() :: %{
  principal_id: String.t() | nil,
  tenant_id: String.t() | nil,
  audience: String.t() | nil
}

store_error()

@type store_error() ::
  :already_exists
  | :invalid_task
  | :invalid_input_responses
  | :invalid_transition
  | :not_found_or_unauthorized
  | :store_full
  | :ttl_out_of_range
  | term()

transition()

@type transition() ::
  {:complete, map()}
  | {:fail, map()}
  | {:require_input, map()}
  | {:status_message, String.t() | nil}
  | :cancelled

Callbacks

cancellation_requested?(t, owner, keyword)

@callback cancellation_requested?(String.t(), owner(), keyword()) ::
  {:ok, boolean()} | {:error, store_error()}

create(t, owner, keyword)

@callback create(ExMCP.Tasks.Task.t(), owner(), keyword()) ::
  {:ok, ExMCP.Tasks.Task.t()} | {:error, store_error()}

fetch(t, owner, keyword)

@callback fetch(String.t(), owner(), keyword()) ::
  {:ok, ExMCP.Tasks.Task.t()} | {:error, store_error()}

request_cancel(t, owner, keyword)

@callback request_cancel(String.t(), owner(), keyword()) :: :ok | {:error, store_error()}

submit_input(t, map, owner, keyword)

@callback submit_input(String.t(), map(), owner(), keyword()) ::
  :ok | {:error, store_error()}

take_input_responses(t, owner, keyword)

@callback take_input_responses(String.t(), owner(), keyword()) ::
  {:ok, map()} | {:error, store_error()}

transition(t, transition, owner, keyword)

@callback transition(String.t(), transition(), owner(), keyword()) ::
  {:ok, ExMCP.Tasks.Task.t()} | {:error, store_error()}