# `Phantom.Prompt`
[🔗](https://github.com/dbernheisel/phantom_mcp/blob/main/lib/phantom/prompt.ex#L1)

The Model Context Protocol (MCP) provides a standardized way
for servers to expose prompt templates to clients. Prompts
allow servers to provide structured messages and instructions
for interacting with language models. Clients can discover
available prompts, retrieve their contents, and provide arguments
to customize them.

```mermaid
sequenceDiagram
    participant Client
    participant Server

    Note over Client,Server: Discovery
    Client->>Server: prompts/list
    Server-->>Client: List of prompts

    Note over Client,Server: Usage
    Client->>Server: prompts/get
    Server-->>Client: Prompt content

    opt listChanged
      Note over Client,Server: Changes
      Server--)Client: prompts/list_changed
      Client->>Server: prompts/list
      Server-->>Client: Updated prompts
    end
```

https://modelcontextprotocol.io/specification/2025-03-26/server/prompts

# `audio_content`

```elixir
@type audio_content() :: %{
  type: :audio,
  data: base64_encoded :: String.t(),
  mimeType: String.t()
}
```

# `content`

```elixir
@type content() ::
  text_content()
  | image_content()
  | audio_content()
  | embedded_resource_content()
```

# `embedded_resource_content`

```elixir
@type embedded_resource_content() :: %{
  type: :resource,
  resource: Phantom.Resource.blob_content() | Phantom.Resource.text_content()
}
```

# `image_content`

```elixir
@type image_content() :: %{
  type: :image,
  data: base64_encoded :: String.t(),
  mimeType: String.t()
}
```

# `json`

```elixir
@type json() :: %{
  :name =&gt; String.t(),
  optional(:description) =&gt; String.t(),
  optional(:arguments) =&gt; %{required(String.t()) =&gt; String.t()}
}
```

# `message`

```elixir
@type message() :: %{role: :assistant | :user, content: content()}
```

# `message_input`

```elixir
@type message_input() :: {role :: :assistant | :user, content()}
```

# `response`

```elixir
@type response() :: %{description: String.t(), messages: [message()]}
```

# `t`

```elixir
@type t() :: %Phantom.Prompt{
  arguments: [Phantom.Prompt.Argument.t()],
  completion_function: atom(),
  description: String.t(),
  function: atom(),
  handler: module(),
  icons: [Phantom.Icon.t()] | nil,
  meta: map(),
  name: String.t()
}
```

# `text_content`

```elixir
@type text_content() :: %{type: :text, text: String.t()}
```

# `audio`

```elixir
@spec audio(binary(), String.t()) :: audio_content()
```

Build an audio message for the prompt

The provided binary will be base64-encoded.

# `build`

```elixir
@spec build(map() | Keyword.t()) :: t()
```

Build a prompt spec

The `Phantom.Router.prompt/3` macro will build these specs.

Fields:
  - `:name` - The name of the prompt.
  - `:description` - The description of the resource and when to use it.
  - `:handler` - The module to call.
  - `:function` - The function to call on the handler module.
  - `:completion_function` - The function to call on the handler module that will provide possible completion results.
  - `:arguments` - A list of arguments that the prompt takes.

Argument fields:
  - `:name` - the name of the argument, eg: "username"
  - `:description` - description of the argument, eg, "Your Github username"
  - `:required` - whether the argument is required in order to be called, ie: `true` or `false`

# `embedded_resource`

```elixir
@spec embedded_resource(string_uri :: String.t(), map()) ::
  embedded_resource_content()
```

Embedded resource reponse.

# `image`

```elixir
@spec image(binary(), String.t()) :: image_content()
```

Build an image message for the prompt

The provided binary will be base64-encoded.

# `response`
*macro* 

Formats the response from an MCP Router to the MCP specification

Provide a keyword list of messages with a keyword list. The key
should contain the role, and the value contain the message.

For example:

    require Phantom.Prompt, as: Prompt
    {:ok, uri, resource} = MyApp.MCP.Router.read_resource(session, :my_resource, 123)

    Prompt.response([
      assistant: Prompt.audio(File.read!("foo.wav"), "audio/wav"),
      user: Prompt.text("Wow that was interesting"),
      assistant: Prompt.image(File.read!("bar.png"), "image/png"),
      user: Prompt.text("amazing"),
      assistant: Prompt.embedded_resource(uri, resource)
    ])

# `response`

```elixir
@spec response([message_input()], t()) :: response()
```

Construct a prompt response with the provided messages for the given prompt

See `response/1` macro version that do the same thing but will fetch the
prompt spec from the current session.

# `text`

```elixir
@spec text(String.t()) :: text_content()
```

Build a text message for the prompt

# `to_json`

```elixir
@spec to_json(t()) :: json()
```

Represent a Prompt spec as json when listing the available prompts to clients.

---

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