Prompts
MCP spec includes Prompts, which enable servers to define reusable prompt templates and workflows that clients can easily surface to users and LLMs.
Defining Prompts
The MCP::Prompt class provides three ways to create prompts.
1. As a class definition with metadata
Subclass MCP::Prompt and declare the metadata with class-level helpers; template builds the result:
class MyPrompt < MCP::Prompt
prompt_name "my_prompt" # Optional - defaults to underscored class name
title "My Prompt"
description "This prompt performs specific functionality..."
arguments [
MCP::Prompt::Argument.new(
name: "message",
title: "Message Title",
description: "Input message",
required: true
)
]
meta({ version: "1.0", category: "example" })
class << self
def template(args, server_context:)
MCP::Prompt::Result.new(
description: "Response description",
messages: [
MCP::Prompt::Message.new(
role: "user",
content: MCP::Content::Text.new("User message")
),
MCP::Prompt::Message.new(
role: "assistant",
content: MCP::Content::Text.new(args["message"])
)
]
)
end
end
end
prompt = MyPrompt
2. Using the MCP::Prompt.define method
MCP::Prompt.define builds a prompt from keyword arguments, with the block as its template:
prompt = MCP::Prompt.define(
name: "my_prompt",
title: "My Prompt",
description: "This prompt performs specific functionality...",
arguments: [
MCP::Prompt::Argument.new(
name: "message",
title: "Message Title",
description: "Input message",
required: true
)
],
meta: { version: "1.0", category: "example" }
) do |args, server_context:|
MCP::Prompt::Result.new(
description: "Response description",
messages: [
MCP::Prompt::Message.new(
role: "user",
content: MCP::Content::Text.new("User message")
),
MCP::Prompt::Message.new(
role: "assistant",
content: MCP::Content::Text.new(args["message"])
)
]
)
end
3. Using the MCP::Server#define_prompt method
MCP::Server#define_prompt registers the prompt directly on a server instance:
server = MCP::Server.new
server.define_prompt(
name: "my_prompt",
description: "This prompt performs specific functionality...",
arguments: [
Prompt::Argument.new(
name: "message",
title: "Message Title",
description: "Input message",
required: true
)
],
meta: { version: "1.0", category: "example" }
) do |args, server_context:|
Prompt::Result.new(
description: "Response description",
messages: [
Prompt::Message.new(
role: "user",
content: Content::Text.new("User message")
),
Prompt::Message.new(
role: "assistant",
content: Content::Text.new(args["message"])
)
]
)
end
The server_context parameter is the server_context passed into the server and can be used to pass per request information, e.g. around authentication state or user preferences.
Icons for prompts are documented on the Icons page.
Key Components
MCP::Prompt::Argument- Defines input parameters for the prompt template with name, title, description, and required flagMCP::Prompt::Message- Represents a message in the conversation with a role and contentMCP::Prompt::Result- The output of a prompt template containing description and messagesMCP::Content::Text- Text content for messages
Registering Prompts
Register prompts with the MCP server:
server = MCP::Server.new(
name: "my_server",
prompts: [MyPrompt],
server_context: { user_id: current_user.id },
)
The server will handle prompt listing and execution through the MCP protocol methods:
prompts/list- Lists all registered prompts and their schemasprompts/get- Retrieves and executes a specific prompt with arguments
Prompts with Image and Embedded Resource Content
Prompt messages are not limited to text. The same MCP::Content types used in tool responses can be used as message content, letting a prompt template include images or inline resource contents. Unlike tool responses, the content object is passed directly rather than as a hash; MCP::Prompt::Message serializes it when the prompt result is returned:
class CodeReviewPrompt < MCP::Prompt
prompt_name "code_review"
description "Review a source file with an accompanying diagram"
arguments [
MCP::Prompt::Argument.new(name: "file_uri", description: "URI of the file to review", required: true),
]
class << self
def template(args, server_context:)
MCP::Prompt::Result.new(
messages: [
MCP::Prompt::Message.new(
role: "user",
content: MCP::Content::EmbeddedResource.new(
MCP::Resource::TextContents.new(
uri: args["file_uri"],
mime_type: "text/x-ruby",
text: read_source(args["file_uri"]),
),
),
),
MCP::Prompt::Message.new(
role: "user",
content: MCP::Content::Image.new(architecture_diagram_base64, "image/png"),
),
MCP::Prompt::Message.new(
role: "user",
content: MCP::Content::Text.new("Please review the code above, using the diagram for context."),
),
],
)
end
end
end