Module: OdataDuty::McpInputSchemas
- Extended by:
- McpInputSchemas
- Included in:
- McpInputSchemas
- Defined in:
- lib/odata_duty/mcp_input_schemas.rb
Constant Summary collapse
- QUERY_OPTION_ALIASES =
$-prefixed OData system query options are not valid Anthropic tool-schema property keys (^[a-zA-Z0-9_.-]{1,64}$), so tool schemas expose theseodata_*aliases instead. McpServerBuilder uses the same mapping (inverted) to translatetools/callarguments back. { '$filter' => 'odata_filter', '$select' => 'odata_select', '$search' => 'odata_search', '$top' => 'odata_top', '$skip' => 'odata_skip' }.freeze
Instance Method Summary collapse
-
#add_alias!(properties, entity_type, query_option_key, value, tool_name:) ⇒ Object
Raises when an entity property is literally named like a reserved
odata_*alias and would silently overwrite (or be overwritten by) the reserved query-option key in the samepropertieshash — see McpServerBuilder's tool-name/property-key validation. - #alias_for(query_option_key) ⇒ Object
- #count_input_schema(supports_search:) ⇒ Object
- #create_input_schema(entity_type) ⇒ Object
- #delete_input_schema(entity_type) ⇒ Object
- #get_input_schema(entity_type, tool_name:) ⇒ Object
- #list_input_schema(supports_search:) ⇒ Object
- #query_option(type, description) ⇒ Object
- #update_input_schema(entity_type) ⇒ Object
Instance Method Details
#add_alias!(properties, entity_type, query_option_key, value, tool_name:) ⇒ Object
Raises when an entity property is literally named like a reserved odata_* alias and
would silently overwrite (or be overwritten by) the reserved query-option key in the same
properties hash — see McpServerBuilder's tool-name/property-key validation.
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 42 def add_alias!(properties, entity_type, query_option_key, value, tool_name:) key = alias_for(query_option_key) if properties.keys.map(&:to_s).include?(key) raise InvalidMcpIdentifierError, "#{entity_type.name} property \"#{key}\" collides with the reserved #{key} " \ "query-option key in the #{tool_name} tool input schema" end properties[key] = value end |
#alias_for(query_option_key) ⇒ Object
81 82 83 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 81 def alias_for(query_option_key) QUERY_OPTION_ALIASES.fetch(query_option_key) end |
#count_input_schema(supports_search:) ⇒ Object
19 20 21 22 23 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 19 def count_input_schema(supports_search:) properties = { alias_for('$filter') => { 'type' => 'string' } } properties[alias_for('$search')] = { 'type' => 'string' } if supports_search { 'properties' => properties, 'required' => [] } end |
#create_input_schema(entity_type) ⇒ Object
53 54 55 56 57 58 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 53 def create_input_schema(entity_type) writable = entity_type.properties.select(&:settable_on_create?) properties = writable.to_h { |p| [p.name, p.to_oas2] } required = writable.reject(&:nullable).map(&:name) { 'properties' => properties, 'required' => required } end |
#delete_input_schema(entity_type) ⇒ Object
76 77 78 79 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 76 def delete_input_schema(entity_type) key = entity_type.property_refs.first { 'properties' => { key.name => key.to_oas2 }, 'required' => [key.name] } end |
#get_input_schema(entity_type, tool_name:) ⇒ Object
68 69 70 71 72 73 74 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 68 def get_input_schema(entity_type, tool_name:) key = entity_type.property_refs.first properties = { key.name => key.to_oas2 } select_value = query_option('string', 'Comma-separated properties to return') add_alias!(properties, entity_type, '$select', select_value, tool_name: tool_name) { 'properties' => properties, 'required' => [key.name] } end |
#list_input_schema(supports_search:) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 25 def list_input_schema(supports_search:) properties = { alias_for('$filter') => query_option('string', 'OData $filter expression'), alias_for('$select') => query_option('string', 'Comma-separated properties to return') } if supports_search properties[alias_for('$search')] = query_option('string', 'Search expression (AND, OR, NOT)') end properties[alias_for('$top')] = query_option('integer', 'Max records to return') properties[alias_for('$skip')] = query_option('integer', 'Records to skip') { 'properties' => properties, 'required' => [] } end |
#query_option(type, description) ⇒ Object
85 86 87 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 85 def query_option(type, description) { 'type' => type, 'description' => description } end |
#update_input_schema(entity_type) ⇒ Object
60 61 62 63 64 65 66 |
# File 'lib/odata_duty/mcp_input_schemas.rb', line 60 def update_input_schema(entity_type) key = entity_type.property_refs.first writable = entity_type.properties.select(&:settable_on_update?) properties = { key.name => key.to_oas2 } writable.each { |p| properties[p.name] = p.to_oas2 } { 'properties' => properties, 'required' => [key.name] } end |