diff --git a/README.md b/README.md index 64606e8..ce50c9d 100644 --- a/README.md +++ b/README.md @@ -629,6 +629,7 @@ class MyPrompt < MCP::Prompt required: true ) ] + meta({ version: "1.0", category: "example" }) class << self def template(args, server_context:) @@ -666,7 +667,8 @@ prompt = MCP::Prompt.define( description: "Input message", required: true ) - ] + ], + meta: { version: "1.0", category: "example" } ) do |args, server_context:| MCP::Prompt::Result.new( description: "Response description", @@ -698,7 +700,8 @@ server.define_prompt( description: "Input message", required: true ) - ] + ], + meta: { version: "1.0", category: "example" } ) do |args, server_context:| Prompt::Result.new( description: "Response description", diff --git a/lib/mcp/prompt.rb b/lib/mcp/prompt.rb index 8f69925..a414bdc 100644 --- a/lib/mcp/prompt.rb +++ b/lib/mcp/prompt.rb @@ -8,13 +8,20 @@ module MCP attr_reader :title_value attr_reader :description_value attr_reader :arguments_value + attr_reader :meta_value def template(args, server_context: nil) raise NotImplementedError, "Subclasses must implement template" end def to_h - { name: name_value, title: title_value, description: description_value, arguments: arguments_value.map(&:to_h) }.compact + { + name: name_value, + title: title_value, + description: description_value, + arguments: arguments_value&.map(&:to_h), + _meta: meta_value, + }.compact end def inherited(subclass) @@ -23,6 +30,7 @@ module MCP subclass.instance_variable_set(:@title_value, nil) subclass.instance_variable_set(:@description_value, nil) subclass.instance_variable_set(:@arguments_value, nil) + subclass.instance_variable_set(:@meta_value, nil) end def prompt_name(value = NOT_SET) @@ -61,7 +69,15 @@ module MCP end end - def define(name: nil, title: nil, description: nil, arguments: [], &block) + def meta(value = NOT_SET) + if value == NOT_SET + @meta_value + else + @meta_value = value + end + end + + def define(name: nil, title: nil, description: nil, arguments: [], meta: nil, &block) Class.new(self) do prompt_name name title title @@ -70,6 +86,7 @@ module MCP define_singleton_method(:template) do |args, server_context: nil| instance_exec(args, server_context:, &block) end + meta meta end end diff --git a/test/mcp/prompt_test.rb b/test/mcp/prompt_test.rb index c5853be..41f3857 100644 --- a/test/mcp/prompt_test.rb +++ b/test/mcp/prompt_test.rb @@ -120,6 +120,7 @@ module MCP required: true, ), ], + meta: { foo: "bar" }, ) do |args, server_context:| content = Content::Text.new(args["test_argument"] + " user: #{server_context[:user_id]}") @@ -135,6 +136,10 @@ module MCP assert_equal "mock_prompt", prompt.name_value assert_equal "a mock prompt for testing", prompt.description assert_equal "test_argument", prompt.arguments.first.name + assert_equal "Test argument title", prompt.arguments.first.title + assert_equal "This is a test argument description", prompt.arguments.first.description + assert prompt.arguments.first.required + assert_equal({ foo: "bar" }, prompt.meta_value) expected = { description: "Hello, world!", @@ -147,5 +152,43 @@ module MCP result = prompt.template({ "test_argument" => "Hello, friend!" }, server_context: { user_id: 123 }) assert_equal expected, result.to_h end + + test "#to_h returns a hash with name, title, description, arguments, and meta" do + class FullPrompt < Prompt + prompt_name "test_prompt" + description "Test prompt description" + title "Test Prompt title" + arguments [ + Prompt::Argument.new(name: "test_argument", description: "Test argument", required: true), + ] + meta({ test: "meta" }) + end + + expected = { + name: "test_prompt", + title: "Test Prompt title", + description: "Test prompt description", + arguments: [ + { name: "test_argument", description: "Test argument", required: true }, + ], + _meta: { test: "meta" }, + } + + assert_equal expected, FullPrompt.to_h + end + + test "#to_h handles nil arguments value" do + class NoArgumentsPrompt < Prompt + description "No arguments prompt" + end + prompt = NoArgumentsPrompt + + expected = { + name: "no_arguments_prompt", + description: "No arguments prompt", + } + + assert_equal expected, prompt.to_h + end end end