mewmew 0.1.0 โ 0.1.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/Rakefile +17 -1
- data/examples/example_cli.rb +2 -2
- data/lib/mewmew/thor_introspector.rb +48 -52
- data/lib/mewmew/version.rb +1 -1
- data/test/integration_test.rb +13 -13
- data/test/smoke_test.rb +2 -2
- metadata +1 -2
- data/test/run_tests.sh +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8111f3e967716c082666bd43c644c221fcda2cf498dde0c5dc1e04d9b4e6cb0c
|
4
|
+
data.tar.gz: b66f53aaa0906114f8fb63d87b93fb2400049dcb732ea11063b4c03f64f5089e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9468767688529d27b51fa3ff15b0cfd891c15cdab3e1d4b33d05c01cf727dcb71cbcd4622750946a0bf66788038f723aa3865608ec9f18f1a65c01bc7aaaedc4
|
7
|
+
data.tar.gz: c261983b8174f4fb044538841a72e396eed60c9f4b229f4d83156f6e38e3cedef93591a2f9b96c00b0ba2cc1ae1ba270bc07dd974ed0651ea5e1e5187dbc25b3
|
data/Rakefile
CHANGED
@@ -7,4 +7,20 @@ RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
8
8
|
require "standard/rake"
|
9
9
|
|
10
|
-
|
10
|
+
desc "Run integration tests"
|
11
|
+
task :test do
|
12
|
+
puts "๐งช Running MCP Integration Tests"
|
13
|
+
puts "=" * 50
|
14
|
+
|
15
|
+
# Run smoke test first
|
16
|
+
puts "\n๐ฅ Running smoke test..."
|
17
|
+
sh "bundle exec ruby test/smoke_test.rb"
|
18
|
+
|
19
|
+
# Run full integration tests
|
20
|
+
puts "\n๐ Running full integration tests..."
|
21
|
+
sh "bundle exec ruby test/integration_test.rb"
|
22
|
+
|
23
|
+
puts "\nโจ All tests completed successfully!"
|
24
|
+
end
|
25
|
+
|
26
|
+
task default: %i[spec standard test]
|
data/examples/example_cli.rb
CHANGED
@@ -84,7 +84,7 @@ class McuCli < Thor
|
|
84
84
|
end
|
85
85
|
|
86
86
|
ranked.first&.first
|
87
|
-
rescue
|
87
|
+
rescue
|
88
88
|
nil
|
89
89
|
end
|
90
90
|
|
@@ -95,7 +95,7 @@ class McuCli < Thor
|
|
95
95
|
uri = URI("https://#{lang}.wikipedia.org/api/rest_v1/page/summary/#{slug}")
|
96
96
|
data = fetch_json(uri)
|
97
97
|
data && (data["extract"] || data["description"])
|
98
|
-
rescue
|
98
|
+
rescue
|
99
99
|
nil
|
100
100
|
end
|
101
101
|
|
@@ -20,60 +20,59 @@ module Mewmew
|
|
20
20
|
|
21
21
|
# Get all commands from the Thor class
|
22
22
|
def commands
|
23
|
-
@commands ||= thor_class.commands.
|
23
|
+
@commands ||= thor_class.commands.except("help", "mcp")
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
# Convert Thor commands to MCP tools
|
27
|
+
def to_mcp_tools
|
28
|
+
commands.map do |name, command|
|
29
|
+
create_tool_class(name, command, thor_class)
|
30
|
+
end
|
30
31
|
end
|
31
|
-
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
33
|
+
private
|
34
|
+
|
35
|
+
def create_tool_class(command_name, thor_command, thor_class)
|
36
|
+
# Dynamically create a tool class that inherits from MCP::Tool
|
37
|
+
Class.new(MCP::Tool) do
|
38
|
+
# Set the tool metadata
|
39
|
+
tool_name command_name
|
40
|
+
description thor_command.description || "Execute the #{command_name} command"
|
41
|
+
|
42
|
+
# Build input schema from method signature and options
|
43
|
+
schema_properties = {}
|
44
|
+
schema_required = []
|
45
|
+
|
46
|
+
# Handle command arguments from method signature
|
47
|
+
method = thor_class.instance_method(command_name.to_sym)
|
48
|
+
method.parameters.each do |param_type, param_name|
|
49
|
+
case param_type
|
50
|
+
when :req
|
51
|
+
schema_properties[param_name] = {
|
52
|
+
type: "string",
|
53
|
+
description: "#{param_name.to_s.capitalize} argument"
|
54
|
+
}
|
55
|
+
schema_required << param_name.to_s
|
56
|
+
when :opt
|
57
|
+
schema_properties[param_name] = {
|
58
|
+
type: "string",
|
59
|
+
description: "#{param_name.to_s.capitalize} argument (optional)"
|
60
|
+
}
|
61
|
+
when :rest
|
62
|
+
schema_properties[param_name] = {
|
63
|
+
type: "array",
|
64
|
+
items: {type: "string"},
|
65
|
+
description: "Additional #{param_name.to_s.capitalize} arguments"
|
66
|
+
}
|
67
|
+
end
|
67
68
|
end
|
68
|
-
end
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
thor_command.options.each do |option_name, option|
|
70
|
+
# Handle command options
|
71
|
+
thor_command.options&.each do |option_name, option|
|
73
72
|
next if option_name == :help
|
74
73
|
|
75
74
|
schema = {
|
76
|
-
description: option.description || "#{option.name.to_s.
|
75
|
+
description: option.description || "#{option.name.to_s.tr("_", " ").capitalize} option"
|
77
76
|
}
|
78
77
|
|
79
78
|
case option.type
|
@@ -85,7 +84,7 @@ module Mewmew
|
|
85
84
|
schema[:default] = option.default if !option.default.nil?
|
86
85
|
when :array
|
87
86
|
schema[:type] = "array"
|
88
|
-
schema[:items] = {
|
87
|
+
schema[:items] = {type: "string"}
|
89
88
|
schema[:default] = option.default if option.default
|
90
89
|
else
|
91
90
|
schema[:type] = "string"
|
@@ -94,13 +93,11 @@ module Mewmew
|
|
94
93
|
|
95
94
|
schema_properties[option_name] = schema
|
96
95
|
end
|
97
|
-
end
|
98
96
|
|
99
|
-
|
97
|
+
input_schema(properties: schema_properties, required: schema_required)
|
100
98
|
|
101
|
-
|
102
|
-
|
103
|
-
begin
|
99
|
+
# Define the class method to execute the command
|
100
|
+
define_singleton_method :call do |server_context: nil, **args|
|
104
101
|
# Create a new instance of the Thor class
|
105
102
|
thor_instance = thor_class.new
|
106
103
|
|
@@ -157,7 +154,6 @@ module Mewmew
|
|
157
154
|
end
|
158
155
|
end
|
159
156
|
end
|
160
|
-
end
|
161
157
|
|
162
158
|
private
|
163
159
|
|
data/lib/mewmew/version.rb
CHANGED
data/test/integration_test.rb
CHANGED
@@ -26,7 +26,7 @@ class MCPIntegrationTest
|
|
26
26
|
test_boolean_option
|
27
27
|
|
28
28
|
print_summary
|
29
|
-
exit(@passed_tests == @total_tests ? 0 : 1)
|
29
|
+
exit((@passed_tests == @total_tests) ? 0 : 1)
|
30
30
|
end
|
31
31
|
|
32
32
|
private
|
@@ -43,7 +43,7 @@ class MCPIntegrationTest
|
|
43
43
|
actual_tools = tools.map { |t| t["name"] }.sort
|
44
44
|
|
45
45
|
if actual_tools == expected_tools.sort
|
46
|
-
assert_pass(test_name, "Found expected tools: #{actual_tools.join(
|
46
|
+
assert_pass(test_name, "Found expected tools: #{actual_tools.join(", ")}")
|
47
47
|
|
48
48
|
# Check tool schemas
|
49
49
|
lookup_tool = tools.find { |t| t["name"] == "lookup" }
|
@@ -64,7 +64,7 @@ class MCPIntegrationTest
|
|
64
64
|
test_name = "Lookup with Query"
|
65
65
|
puts "\n๐ Testing: #{test_name}"
|
66
66
|
|
67
|
-
result = run_mcp_command("tools/call", tool_name: "lookup", args: {
|
67
|
+
result = run_mcp_command("tools/call", tool_name: "lookup", args: {query: "mjolnir"})
|
68
68
|
|
69
69
|
if result[:success] && result[:data]
|
70
70
|
content = result[:data]["content"]
|
@@ -88,7 +88,7 @@ class MCPIntegrationTest
|
|
88
88
|
test_name = "Lookup with Language Option"
|
89
89
|
puts "\n๐ Testing: #{test_name}"
|
90
90
|
|
91
|
-
result = run_mcp_command("tools/call", tool_name: "lookup", args: {
|
91
|
+
result = run_mcp_command("tools/call", tool_name: "lookup", args: {query: "thor", lang: "en"})
|
92
92
|
|
93
93
|
if result[:success] && result[:data]
|
94
94
|
content = result[:data]["content"]
|
@@ -163,7 +163,7 @@ class MCPIntegrationTest
|
|
163
163
|
puts "\n๐ Testing: #{test_name}"
|
164
164
|
|
165
165
|
# Test with lang option (string) - should work
|
166
|
-
result = run_mcp_command("tools/call", tool_name: "lookup", args: {
|
166
|
+
result = run_mcp_command("tools/call", tool_name: "lookup", args: {query: "test", lang: "fr"})
|
167
167
|
|
168
168
|
if result[:success] && result[:data]
|
169
169
|
assert_pass(test_name, "Boolean/string options handled correctly")
|
@@ -187,34 +187,34 @@ class MCPIntegrationTest
|
|
187
187
|
cmd_parts += ["--tool-arg", "#{key}=#{value}"]
|
188
188
|
end
|
189
189
|
|
190
|
-
puts " ๐ป Running: #{cmd_parts.join(
|
190
|
+
puts " ๐ป Running: #{cmd_parts.join(" ")}"
|
191
191
|
|
192
192
|
stdout, stderr, status = Open3.capture3(*cmd_parts)
|
193
193
|
|
194
194
|
if status.success?
|
195
195
|
begin
|
196
196
|
data = JSON.parse(stdout)
|
197
|
-
{
|
197
|
+
{success: true, data: data}
|
198
198
|
rescue JSON::ParserError => e
|
199
|
-
{
|
199
|
+
{success: false, error: "JSON parse error: #{e.message}, output: #{stdout}"}
|
200
200
|
end
|
201
201
|
else
|
202
|
-
{
|
202
|
+
{success: false, error: "Command failed (#{status.exitstatus}): #{stderr}"}
|
203
203
|
end
|
204
204
|
rescue => e
|
205
|
-
{
|
205
|
+
{success: false, error: "Exception: #{e.message}"}
|
206
206
|
end
|
207
207
|
|
208
208
|
def assert_pass(test_name, message)
|
209
209
|
@total_tests += 1
|
210
210
|
@passed_tests += 1
|
211
|
-
@test_results << {
|
211
|
+
@test_results << {name: test_name, status: :pass, message: message}
|
212
212
|
puts " โ
PASS: #{message}"
|
213
213
|
end
|
214
214
|
|
215
215
|
def assert_fail(test_name, message)
|
216
216
|
@total_tests += 1
|
217
|
-
@test_results << {
|
217
|
+
@test_results << {name: test_name, status: :fail, message: message}
|
218
218
|
puts " โ FAIL: #{message}"
|
219
219
|
end
|
220
220
|
|
@@ -224,7 +224,7 @@ class MCPIntegrationTest
|
|
224
224
|
puts "=" * 50
|
225
225
|
|
226
226
|
@test_results.each do |result|
|
227
|
-
icon = result[:status] == :pass ? "โ
" : "โ"
|
227
|
+
icon = (result[:status] == :pass) ? "โ
" : "โ"
|
228
228
|
puts "#{icon} #{result[:name]}: #{result[:message]}"
|
229
229
|
end
|
230
230
|
|
data/test/smoke_test.rb
CHANGED
@@ -21,7 +21,7 @@ if status.success?
|
|
21
21
|
data = JSON.parse(stdout)
|
22
22
|
tools = data["tools"]
|
23
23
|
puts "โ
Server started successfully"
|
24
|
-
puts "โ
Found #{tools.length} tools: #{tools.map { |t| t[
|
24
|
+
puts "โ
Found #{tools.length} tools: #{tools.map { |t| t["name"] }.join(", ")}"
|
25
25
|
rescue JSON::ParserError => e
|
26
26
|
puts "โ JSON parse error: #{e.message}"
|
27
27
|
puts "Raw output: #{stdout}"
|
@@ -50,7 +50,7 @@ if status.success?
|
|
50
50
|
content = data["content"]
|
51
51
|
if content && content[0] && content[0]["text"]
|
52
52
|
puts "โ
Tool call successful"
|
53
|
-
puts "โ
Response: #{content[0][
|
53
|
+
puts "โ
Response: #{content[0]["text"].strip[0..100]}..."
|
54
54
|
else
|
55
55
|
puts "โ No content in response"
|
56
56
|
exit 1
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mewmew
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Emde
|
@@ -56,7 +56,6 @@ files:
|
|
56
56
|
- lib/mewmew/version.rb
|
57
57
|
- sig/mewmew.rbs
|
58
58
|
- test/integration_test.rb
|
59
|
-
- test/run_tests.sh
|
60
59
|
- test/smoke_test.rb
|
61
60
|
homepage: https://github.com/martinemde/mewmew
|
62
61
|
licenses:
|
data/test/run_tests.sh
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
# Test runner for MCP integration tests
|
3
|
-
|
4
|
-
set -e
|
5
|
-
|
6
|
-
echo "๐งช MCP Integration Test Runner"
|
7
|
-
echo "=============================="
|
8
|
-
|
9
|
-
# Change to project root
|
10
|
-
cd "$(dirname "$0")/.."
|
11
|
-
|
12
|
-
echo "๐ Working directory: $(pwd)"
|
13
|
-
|
14
|
-
# Ensure bundle is available
|
15
|
-
echo "๐ฆ Checking bundle..."
|
16
|
-
if ! command -v bundle &> /dev/null; then
|
17
|
-
echo "โ Bundle not found. Please install bundler."
|
18
|
-
exit 1
|
19
|
-
fi
|
20
|
-
|
21
|
-
# Install dependencies
|
22
|
-
echo "๐ฅ Installing dependencies..."
|
23
|
-
bundle install --quiet
|
24
|
-
|
25
|
-
# Run smoke test first
|
26
|
-
echo ""
|
27
|
-
echo "๐ฅ Running smoke test..."
|
28
|
-
bundle exec ruby test/smoke_test.rb
|
29
|
-
|
30
|
-
# Run full integration tests
|
31
|
-
echo ""
|
32
|
-
echo "๐ Running full integration tests..."
|
33
|
-
bundle exec ruby test/integration_test.rb
|
34
|
-
|
35
|
-
echo ""
|
36
|
-
echo "โจ All tests completed successfully!"
|