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 +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/ask/mcp/adapters/tool_server.rb +25 -26
- data/lib/ask/mcp/server/stdio.rb +1 -0
- data/lib/ask/mcp/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 909c171336e0497c2377c2f4106e1ec0314adbbbf15791819caf6be0c9d04035
|
|
4
|
+
data.tar.gz: 5a5e95508499f38e310cce0052fcd4c9dfd2c95f8a4e965621c37d35c392293d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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)
|
data/lib/ask/mcp/server/stdio.rb
CHANGED
data/lib/ask/mcp/version.rb
CHANGED