Commit a65d2c4

mo khan <mo@mokhan.ca>
2026-09-07 14:53:43
refactor: symbolize MCP tool params before handing them to Toolbox#add
Core's Tool.with_array_items dropped its string-keyed branch, which existed only to support this gem's JSON-parsed inputSchema.properties. Own that normalization here instead, at the point the JSON enters the system. Claude-Session: https://claude.ai/code/session_01DUuj4amvRrPxDnHPHBkvz5
1 parent 56ee2aa
Changed files (2)
lib/elelem/mcp/client.rb
@@ -25,7 +25,7 @@ module Elelem
               "#{name}_#{tool["name"]}",
               {
                 description: tool["description"],
-                params: tool.dig("inputSchema", "properties") || {},
+                params: symbolize(tool.dig("inputSchema", "properties") || {}),
                 required: tool.dig("inputSchema", "required") || [],
                 fn: ->(a) { server(name).call(tool["name"], a) }
               }
@@ -40,6 +40,10 @@ module Elelem
 
       private
 
+      def symbolize(hash)
+        JSON.parse(JSON.generate(hash), symbolize_names: true)
+      end
+
       def load_config(configurations)
         configurations.each_with_object({}) do |path, merged|
           file = File.expand_path(path)
Gemfile.lock
@@ -19,29 +19,23 @@ GEM
   specs:
     base64 (0.3.0)
     bigdecimal (4.1.2)
-    date (3.5.1)
     diff-lcs (1.6.2)
     digest (3.2.1)
-    elelem (0.10.0)
-      base64 (~> 0.1)
-      date (~> 3.0)
-      digest (~> 3.0)
+    elelem (0.11.0)
       erb (~> 6.0)
-      fileutils (~> 1.0)
-      json (~> 2.0)
-      json_schemer (~> 2.0)
-      logger (~> 1.0)
-      net-hippie (~> 1.0)
-      open3 (~> 0.1)
-      optparse (~> 0.1)
-      pathname (~> 0.1)
-      reline (~> 0.6)
-      securerandom (~> 0.1)
+      fileutils (~> 1.8)
+      io-console (~> 0.9)
+      json (~> 2.21)
+      json_schemer (~> 2.5)
+      logger (~> 1.7)
+      open3 (~> 0.2)
+      optparse (~> 0.8)
+      pathname (~> 0.5)
+      reline (~> 0.7)
       shellwords (~> 0.2)
-      stringio (~> 3.0)
+      stringio (~> 3.2)
       tempfile (~> 0.3)
       uri (~> 1.0)
-      webrick (~> 1.9)
     erb (6.0.7)
     fileutils (1.8.0)
     hana (1.3.7)
@@ -58,20 +52,9 @@ GEM
       regexp_parser (~> 2.0)
       simpleidn (~> 0.2)
     logger (1.7.0)
-    monitor (0.2.0)
-    net-hippie (1.5.1)
-      base64 (~> 0.1)
-      json (~> 2.0)
-      logger (~> 1.0)
-      monitor (~> 0.1)
-      net-http (~> 0.1)
-      openssl (~> 4.0)
-      resolv (~> 0.1)
-      timeout (~> 0.1)
     net-http (0.9.1)
       uri (>= 0.11.1)
     open3 (0.2.1)
-    openssl (4.0.2)
     optparse (0.8.1)
     pathname (0.5.0)
     pp (0.6.4)
@@ -91,7 +74,6 @@ GEM
     regexp_parser (2.12.0)
     reline (0.7.0)
       io-console (~> 0.5)
-    resolv (0.7.2)
     rspec (3.13.2)
       rspec-core (~> 3.13.0)
       rspec-expectations (~> 3.13.0)
@@ -129,10 +111,9 @@ CHECKSUMS
   base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
   bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
   bundler (4.0.20) sha256=7978a8ac648767f5e635bc522445b79e80a52b907a39a36c2d8085ed6bc762ae
-  date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
   diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
   digest (3.2.1) sha256=ab3312b4e272d7d5dc41c564c86a25861a1f34ac5153374199a0b74861395947
-  elelem (0.10.0) sha256=de67f3a28351640da471e6e80e7a1d79e83e293cbc502a9e98c3c609cad2e237
+  elelem (0.11.0)
   elelem-mcp (0.1.0)
   erb (6.0.7) sha256=c5ca6dc25b0ef974a44dc8f59fe847577122483b1968a38dec305c60bf91ee92
   fileutils (1.8.0) sha256=8c6b1df54e2540bdb2f39258f08af78853aa70bad52b4d394bbc6424593c6e02
@@ -142,11 +123,8 @@ CHECKSUMS
   json (2.21.2) sha256=1f1d3b7cf2b3ba1a69beca0bb6db13d5438b80bff3cd54cdaaa620b9b07c1c6a
   json_schemer (2.5.0) sha256=2f01fb4cce721a4e08dd068fc2030cffd0702a7f333f1ea2be6e8991f00ae396
   logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
-  monitor (0.2.0) sha256=18698584f161ca6611d73130663990ca7dc439d9d88095226e683035d66f1f0f
-  net-hippie (1.5.1) sha256=76ecfc7d8df7866c3ed4f2e25fe963d87537451a1fb0d318b58eca161127fbcc
   net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996
   open3 (0.2.1) sha256=8e2d7d2113526351201438c1aa35c8139f0141c9e8913baa007c898973bf3952
-  openssl (4.0.2) sha256=1037ad2868ae58df9ad917891c0c0f9815a1172f6846d4bcdd508e4c2ee747c2
   optparse (0.8.1) sha256=42bea10d53907ccff4f080a69991441d611fbf8733b60ed1ce9ee365ce03bd1a
   pathname (0.5.0) sha256=d5a331784f6e1f2fefb31c2ff0b8855aabfb661d807284ead9fa47b883d81623
   pp (0.6.4) sha256=dfcb0fce700c41456265922884f9fe195d7fbb0674a3578e6c0f69588e82b570
@@ -157,7 +135,6 @@ CHECKSUMS
   rdoc (8.0.0) sha256=03bf8c08a9639658855a0cfd77c0abca8325c227693f7f33f82957811348c469
   regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
   reline (0.7.0) sha256=5b012d8e55dbf9d450f12bde2cf7d15ff546ae80b3f8f3b30e570d431815583d
-  resolv (0.7.2) sha256=626d044d975ab2daac759bf898416f1b51e2cb8dcd6727c2b5b5b28b97ead2e1
   rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
   rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
   rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836