actionmcp 0.100.1 → 0.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5df97e0bdac66054109edabe63756d639e74bb3068d70d4028bd990b2bee8442
4
- data.tar.gz: db73f42cf5307f09e3b4484799057fc10ee4a5341efa58aef99ab25be82abc4c
3
+ metadata.gz: 9bf1821cef23dc83ceb6798b128cecc43a2585d3bd7c75996824cbfb960f085a
4
+ data.tar.gz: fb1b755390487c5b4fff6a75e94540470ef21135bed4978465da9f16f8f201c3
5
5
  SHA512:
6
- metadata.gz: 0fa54e67f4f7c5e60ba16bd708557534e3b374e19e16d8456289e269e3649c4117407d5e6b4c2ce5c3645476084ab7444e81681a7a900953b4d25da50e534ddc
7
- data.tar.gz: 1b783e0ddb8c502cf9438049b7f88c74a89e2bb8e48fdd795789741a7de77b12507412c4b66116b299f7a6b7c75b0279bddf787c6ca522e246e66bee139dd694
6
+ metadata.gz: a0764d4fea510580d99b6b51428b91545bfd17d9e6ae9828a88b127e6d91c2f5f1d77fb0816f4043ed6de596c0c55719d2b16c73efc38a7dedf5ff027a5236a4
7
+ data.tar.gz: d828f74be45e7b33877b01265a159fcc76961bba326ac4f31205243bd6bbcd5cb1f4935be627d5ae6bb8aad1fa7644f8611b2514637f94cab74eab7f6184a2d8
@@ -47,7 +47,9 @@ module ActionMCP
47
47
  # --- Tasks Options (MCP 2025-11-25) ---
48
48
  :tasks_enabled,
49
49
  :tasks_list_enabled,
50
- :tasks_cancel_enabled
50
+ :tasks_cancel_enabled,
51
+ # --- Schema Validation Options ---
52
+ :validate_structured_content
51
53
 
52
54
  def initialize
53
55
  @logging_enabled = false
@@ -69,6 +71,9 @@ module ActionMCP
69
71
  @tasks_list_enabled = true
70
72
  @tasks_cancel_enabled = true
71
73
 
74
+ # Schema validation - disabled by default for backward compatibility
75
+ @validate_structured_content = false
76
+
72
77
  # Gateway - resolved lazily to account for Zeitwerk autoloading
73
78
  @gateway_class_name = nil
74
79
 
@@ -127,12 +127,12 @@ module ActionMCP
127
127
  end
128
128
 
129
129
  # Define an object property
130
- # @param name [Symbol] Object property name
130
+ # @param name [Symbol, nil] Object property name. If nil, returns schema directly (for array items)
131
131
  # @param required [Boolean] Whether the object is required
132
132
  # @param description [String] Property description
133
133
  # @param additional_properties [Boolean, Hash] Whether to allow additional properties
134
134
  # @param block [Proc] Block defining object properties
135
- def object(name, required: false, description: nil, additional_properties: nil, &block)
135
+ def object(name = nil, required: false, description: nil, additional_properties: nil, &block)
136
136
  raise ArgumentError, "Object definition requires a block" unless block_given?
137
137
 
138
138
  # Create nested builder for object properties
@@ -149,10 +149,14 @@ module ActionMCP
149
149
  # Add additionalProperties if specified
150
150
  add_additional_properties_to_schema(schema, additional_properties)
151
151
 
152
- @properties[name.to_s] = schema
153
- @required << name.to_s if required
154
-
155
- name.to_s
152
+ if name
153
+ @properties[name.to_s] = schema
154
+ @required << name.to_s if required
155
+ name.to_s
156
+ else
157
+ # Return schema directly for use in array items
158
+ schema
159
+ end
156
160
  end
157
161
 
158
162
  # Set additionalProperties for the root schema
@@ -490,6 +490,9 @@ module ActionMCP
490
490
  # Override render to collect Content objects and support structured content
491
491
  def render(structured: nil, **args)
492
492
  if structured
493
+ # Validate structured content against output_schema if enabled
494
+ validate_structured_content!(structured) if self.class._output_schema
495
+
493
496
  # Render structured content
494
497
  set_structured_content(structured)
495
498
  structured
@@ -553,6 +556,42 @@ module ActionMCP
553
556
  @response.set_structured_content(content)
554
557
  end
555
558
 
559
+ # Validates structured content against the declared output_schema
560
+ # Only runs if validate_structured_content is enabled in configuration
561
+ # @param content [Hash] The structured content to validate
562
+ # @raise [StructuredContentValidationError] If content doesn't match schema
563
+ def validate_structured_content!(content)
564
+ return unless ActionMCP.configuration.validate_structured_content
565
+
566
+ schema = self.class._output_schema
567
+ return unless schema.present?
568
+
569
+ # Lazy load json_schemer - only required if validation is enabled
570
+ gem "json_schemer", ">= 2.4"
571
+ require "json_schemer"
572
+
573
+ schemer = JSONSchemer.schema(schema.deep_stringify_keys)
574
+ errors = schemer.validate(deep_stringify_content(content)).to_a
575
+
576
+ return if errors.empty?
577
+
578
+ error_messages = errors.map { |e| e["error"] }.join(", ")
579
+ raise ActionMCP::StructuredContentValidationError,
580
+ "Structured content does not match output_schema: #{error_messages}"
581
+ end
582
+
583
+ # Deep stringify keys for validation (handles symbols and nested structures)
584
+ def deep_stringify_content(content)
585
+ case content
586
+ when Hash
587
+ content.transform_keys(&:to_s).transform_values { |v| deep_stringify_content(v) }
588
+ when Array
589
+ content.map { |v| deep_stringify_content(v) }
590
+ else
591
+ content
592
+ end
593
+ end
594
+
556
595
  private
557
596
 
558
597
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative "gem_version"
4
4
  module ActionMCP
5
- VERSION = "0.100.1"
5
+ VERSION = "0.101.0"
6
6
 
7
7
  class << self
8
8
  alias version gem_version
data/lib/action_mcp.rb CHANGED
@@ -31,6 +31,9 @@ module ActionMCP
31
31
  require_relative "action_mcp/version"
32
32
  require_relative "action_mcp/client"
33
33
 
34
+ # Error raised when structured content doesn't match the declared output_schema
35
+ class StructuredContentValidationError < StandardError; end
36
+
34
37
  # Protocol version constants
35
38
  SUPPORTED_VERSIONS = [
36
39
  "2025-11-25", # The Task Master - Tasks, icons, tool naming, polling SSE
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionmcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.100.1
4
+ version: 0.101.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
@@ -125,16 +125,16 @@ dependencies:
125
125
  name: json_schemer
126
126
  requirement: !ruby/object:Gem::Requirement
127
127
  requirements:
128
- - - "~>"
128
+ - - ">="
129
129
  - !ruby/object:Gem::Version
130
- version: '2.0'
130
+ version: '2.4'
131
131
  type: :development
132
132
  prerelease: false
133
133
  version_requirements: !ruby/object:Gem::Requirement
134
134
  requirements:
135
- - - "~>"
135
+ - - ">="
136
136
  - !ruby/object:Gem::Version
137
- version: '2.0'
137
+ version: '2.4'
138
138
  description: A streamlined, production-focused toolkit for building MCP servers in
139
139
  Rails applications. Provides essential base classes, authentication gateways, and
140
140
  HTTP transport with minimal dependencies.