ask-mcp 0.4.0 → 0.4.1

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: ae155e99332cb2a3fcec6b65c6d0ac20aa9b2b81b27f1e3aa3c667dc0c7a42fb
4
- data.tar.gz: af84c5f5aae82c640e2c12316cde40444fe7733d6ad5aaddd6780242b98e1a1c
3
+ metadata.gz: 909c171336e0497c2377c2f4106e1ec0314adbbbf15791819caf6be0c9d04035
4
+ data.tar.gz: 5a5e95508499f38e310cce0052fcd4c9dfd2c95f8a4e965621c37d35c392293d
5
5
  SHA512:
6
- metadata.gz: 62f473ff0fdc35b25adcdadf3aeb2a65c330767f7b73cc85bed204a32bff7fcc28f0348c2ee3f8e8ae1e3d7eaf3977714af67d67038c1be990d9feca2199d81f
7
- data.tar.gz: e511364526282fcb429740dbd65bbce3e51d0bde06a06cb672e33a0c30b1b09e1971c663145f1b272d7e01015060349447bb7d53081b8dd9813dea02f19591e9
6
+ metadata.gz: 52526b46e9574fb4289ddde3b7ff340945eead680763ad7ece3903a8bea89a5a535cb3b9951b0236f6749808b22254c9f4b691133eff56e24a7438eb68ae8743
7
+ data.tar.gz: be8c62053892b8aa52e5216fcb58c7857ecfdff12b025173d9cd1be1a384cced8dd41ef4f9e17ca531fe6d869743dbc63caad275fbccb82014ddd4d94d49c3a2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [0.4.1] - 2026-07-31
2
+
3
+ ### Changed
4
+
5
+ - **`ToolServer` result wrapping** — plain `String` results are always treated
6
+ as success; result-like objects (`Ask::Result`, OpenStruct, etc.) use
7
+ `ok?`/`ok` and `output`/`error_message`; any other value is treated as
8
+ success with `to_s` used for the response.
9
+
10
+ ### Fixed
11
+
12
+ - **Stdio server protocol version** — pins `PROTOCOL_VERSION` to
13
+ `2025-06-18` and echoes it back in the `initialize` response.
14
+
1
15
  ## [0.4.0] - 2026-06-26
2
16
 
3
17
  ### Added
@@ -8,28 +8,18 @@ module Ask
8
8
  # respond to +name+, +description+, +params_schema+, and +call(args)+ and
9
9
  # exposes them over MCP.
10
10
  #
11
- # Usage:
12
- # class MyTool
13
- # def name; "hello" end
14
- # def description; "Says hello" end
15
- # def params_schema; nil end
16
- # def call(args = {}); OpenStruct.new(ok?: true, output: "Hello!") end
17
- # end
18
- #
19
- # adapter = ToolServer.new([MyTool.new])
20
- # adapter.definitions # => [{ name: "hello", ... }]
21
- # adapter.call("hello", {}) # => { content: [...], isError: false }
11
+ # Tools can return:
12
+ # - An object responding to #ok?/#ok and #output/#error_message (Ask::Result style)
13
+ # - A plain String (treated as success)
14
+ # - Any other value (treated as success, .to_s is used for the response)
22
15
  class ToolServer
23
16
  attr_reader :tools
24
17
 
25
- # @param tools [Array<#call, #name, #description, #params_schema>] tool instances to expose
26
18
  def initialize(tools = [])
27
19
  @tools = tools
28
20
  @tool_map = tools.each_with_object({}) { |t, h| h[t.name] = t }
29
21
  end
30
22
 
31
- # MCP tool definitions for tools/list
32
- # @return [Array<Hash>]
33
23
  def definitions
34
24
  @tools.map do |tool|
35
25
  schema = tool.params_schema || { type: "object", properties: {}, required: [] }
@@ -41,10 +31,6 @@ module Ask
41
31
  end
42
32
  end
43
33
 
44
- # Call a tool and wrap the result in MCP format
45
- # @param name [String] tool name
46
- # @param arguments [Hash] arguments (may have symbol or string keys)
47
- # @return [Hash] { content: [...], isError: true/false }
48
34
  def call(name, arguments = {})
49
35
  tool = @tool_map[name]
50
36
  unless tool
@@ -64,18 +50,31 @@ module Ask
64
50
  private
65
51
 
66
52
  def wrap_result(result)
67
- if result.respond_to?(:ok?) ? result.ok? : result.ok
68
- output = result.respond_to?(:output) ? result.output : result.to_s
69
- text = output.is_a?(Hash) ? (output[:summary] || output.to_s) : output.to_s
70
- { content: [{ type: "text", text: text }], isError: false }
71
- else
72
- msg = result.respond_to?(:error_message) ? result.error_message : result.to_s
73
- { content: [{ type: "text", text: "Error: #{msg}" }], isError: true }
53
+ # Plain strings are always a success
54
+ if result.is_a?(String)
55
+ return { content: [{ type: "text", text: result }], isError: false }
56
+ end
57
+
58
+ # Result-like objects (Ask::Result, OpenStruct, etc.)
59
+ if result.respond_to?(:ok?) || result.respond_to?(:ok)
60
+ ok = result.respond_to?(:ok?) ? result.ok? : result.ok
61
+ return success_result(result, ok) if ok
62
+ return error_result(result.respond_to?(:error_message) ? result.error_message : result.to_s)
74
63
  end
64
+
65
+ # Everything else — treat as success
66
+ text = result.is_a?(Hash) ? (result[:summary] || result.to_s) : result.to_s
67
+ { content: [{ type: "text", text: text }], isError: false }
68
+ end
69
+
70
+ def success_result(result, _ok)
71
+ output = result.respond_to?(:output) ? result.output : result.to_s
72
+ text = output.is_a?(Hash) ? (output[:summary] || output.to_s) : output.to_s
73
+ { content: [{ type: "text", text: text }], isError: false }
75
74
  end
76
75
 
77
76
  def error_result(message)
78
- { content: [{ type: "text", text: message }], isError: true }
77
+ { content: [{ type: "text", text: "Error: #{message}" }], isError: true }
79
78
  end
80
79
 
81
80
  def deep_stringify_keys(obj)
@@ -9,6 +9,7 @@ module Ask
9
9
  # MCP server over stdio transport.
10
10
  class Stdio
11
11
  MAX_RESULT_CACHE = 100
12
+ PROTOCOL_VERSION = "2025-06-18"
12
13
 
13
14
  attr_reader :name, :tools, :capabilities, :resources, :prompts
14
15
 
@@ -1,5 +1,5 @@
1
1
  module Ask
2
2
  module MCP
3
- VERSION = "0.4.0"
3
+ VERSION = "0.4.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto