quash-mcp 0.2.4__tar.gz → 0.2.6__tar.gz

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.

Potentially problematic release.


This version of quash-mcp might be problematic. Click here for more details.

Files changed (26) hide show
  1. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/PKG-INFO +1 -1
  2. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/pyproject.toml +1 -1
  3. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/execute_v3.py +51 -1
  4. quash_mcp-0.2.6/test_tools_loading.py +81 -0
  5. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/.gitignore +0 -0
  6. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/README.md +0 -0
  7. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/SETUP_CLAUDE_CODE.md +0 -0
  8. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/__init__.py +0 -0
  9. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/__main__.py +0 -0
  10. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/backend_client.py +0 -0
  11. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/device/__init__.py +0 -0
  12. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/device/adb_tools.py +0 -0
  13. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/device/portal.py +0 -0
  14. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/device/state_capture.py +0 -0
  15. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/server.py +0 -0
  16. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/state.py +0 -0
  17. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/__init__.py +0 -0
  18. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/build.py +0 -0
  19. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/build_old.py +0 -0
  20. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/configure.py +0 -0
  21. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/connect.py +0 -0
  22. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/execute.py +0 -0
  23. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/execute_v2_backup.py +0 -0
  24. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/runsuite.py +0 -0
  25. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/quash_mcp/tools/usage.py +0 -0
  26. {quash_mcp-0.2.4 → quash_mcp-0.2.6}/test_backend_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quash-mcp
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Model Context Protocol server for Quash - AI-powered mobile automation agent
5
5
  Project-URL: Homepage, https://quashbugs.com
6
6
  Project-URL: Repository, https://github.com/quash/quash-mcp
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "quash-mcp"
3
- version = "0.2.4"
3
+ version = "0.2.6"
4
4
  description = "Model Context Protocol server for Quash - AI-powered mobile automation agent"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
@@ -7,12 +7,27 @@ This hybrid approach keeps proprietary code private while allowing local device
7
7
 
8
8
  import time
9
9
  import uuid
10
+ import asyncio
10
11
  from typing import Dict, Any, Callable, Optional
11
12
  from ..state import get_state
12
13
  from ..backend_client import get_backend_client
13
14
  from ..device.state_capture import get_device_state
14
15
  from ..device.adb_tools import AdbTools
15
16
 
17
+ # Import mahoraga components for tool functions
18
+ try:
19
+ from mahoraga.tools import Tools, describe_tools
20
+ from mahoraga.tools.adb import AdbTools as MahoragaAdbTools
21
+ from mahoraga.agent.context.personas import DEFAULT
22
+ from mahoraga.agent.utils.async_utils import async_to_sync
23
+ except ImportError as e:
24
+ print(f"Warning: Could not import mahoraga components: {e}")
25
+ Tools = None
26
+ describe_tools = None
27
+ MahoragaAdbTools = None
28
+ DEFAULT = None
29
+ async_to_sync = None
30
+
16
31
 
17
32
  async def execute_v3(
18
33
  task: str,
@@ -114,11 +129,46 @@ async def execute_v3(
114
129
  # Initialize local ADB tools for code execution
115
130
  adb_tools = AdbTools(serial=state.device_serial, use_tcp=True)
116
131
 
117
- # Code executor namespace
132
+ # Code executor namespace - add tool functions so generated code can call them
118
133
  executor_globals = {
119
134
  "__builtins__": __builtins__,
120
135
  "adb_tools": adb_tools
121
136
  }
137
+
138
+ # Add tool functions to executor namespace (like start_app, swipe, etc.)
139
+ if describe_tools and DEFAULT and MahoragaAdbTools:
140
+ try:
141
+ # Create a mahoraga AdbTools instance for tool execution
142
+ # This instance has all the tool methods like swipe, start_app, etc.
143
+ mahoraga_tools = MahoragaAdbTools(
144
+ serial=state.device_serial,
145
+ use_tcp=True,
146
+ remote_tcp_port=8080
147
+ )
148
+
149
+ # Get all tool functions from mahoraga AdbTools instance
150
+ tool_list = describe_tools(mahoraga_tools, exclude_tools=None)
151
+
152
+ # Filter by allowed tools from DEFAULT persona
153
+ allowed_tool_names = DEFAULT.allowed_tools if hasattr(DEFAULT, 'allowed_tools') else []
154
+ filtered_tools = {name: func for name, func in tool_list.items() if name in allowed_tool_names}
155
+
156
+ # Add each tool function to executor globals
157
+ for tool_name, tool_function in filtered_tools.items():
158
+ # Convert async functions to sync if needed
159
+ if asyncio.iscoroutinefunction(tool_function):
160
+ if async_to_sync:
161
+ tool_function = async_to_sync(tool_function)
162
+
163
+ # Add to globals so code can call it directly
164
+ executor_globals[tool_name] = tool_function
165
+
166
+ log_progress(f"🔧 Loaded {len(filtered_tools)} tool functions: {list(filtered_tools.keys())}")
167
+ except Exception as e:
168
+ log_progress(f"⚠️ Warning: Could not load tool functions: {e}")
169
+ import traceback
170
+ log_progress(f"Traceback: {traceback.format_exc()}")
171
+
122
172
  executor_locals = {}
123
173
 
124
174
  try:
@@ -0,0 +1,81 @@
1
+ """
2
+ Test script to verify tool functions are loaded correctly.
3
+ """
4
+
5
+ import sys
6
+ sys.path.insert(0, '/Users/abhinavsai/POC/mahoraga-mac/quash-mcp')
7
+ sys.path.insert(0, '/Users/abhinavsai/POC/mahoraga-mac/mahoraga')
8
+
9
+ def test_tool_loading():
10
+ print("Testing tool loading...")
11
+
12
+ try:
13
+ # Import mahoraga components
14
+ from mahoraga.tools import Tools, describe_tools
15
+ from mahoraga.tools.adb import AdbTools as MahoragaAdbTools
16
+ from mahoraga.agent.context.personas import DEFAULT
17
+ from mahoraga.agent.utils.async_utils import async_to_sync
18
+
19
+ print("✅ All imports successful")
20
+
21
+ # Create a mahoraga AdbTools instance
22
+ print("\nCreating mahoraga AdbTools instance...")
23
+ mahoraga_tools = MahoragaAdbTools(
24
+ serial="emulator-5554", # Use your device serial
25
+ use_tcp=True,
26
+ remote_tcp_port=8080
27
+ )
28
+ print(f"✅ Created mahoraga AdbTools instance")
29
+ print(f" - Serial: {mahoraga_tools.device.serial}")
30
+ print(f" - TCP forwarded: {mahoraga_tools.tcp_forwarded}")
31
+
32
+ # Get tool list
33
+ print("\nGetting tool list...")
34
+ tool_list = describe_tools(mahoraga_tools, exclude_tools=None)
35
+ print(f"✅ Got {len(tool_list)} tools:")
36
+ for tool_name, tool_func in tool_list.items():
37
+ print(f" - {tool_name}: {tool_func}")
38
+
39
+ # Filter by allowed tools
40
+ print(f"\nFiltering by DEFAULT persona allowed tools...")
41
+ allowed_tool_names = DEFAULT.allowed_tools
42
+ print(f" Allowed tools: {allowed_tool_names}")
43
+
44
+ filtered_tools = {name: func for name, func in tool_list.items() if name in allowed_tool_names}
45
+ print(f"✅ Filtered to {len(filtered_tools)} tools:")
46
+ for tool_name in filtered_tools.keys():
47
+ print(f" - {tool_name}")
48
+
49
+ # Test executor globals setup
50
+ print("\nSetting up executor globals...")
51
+ executor_globals = {"__builtins__": __builtins__}
52
+
53
+ for tool_name, tool_function in filtered_tools.items():
54
+ import asyncio
55
+ if asyncio.iscoroutinefunction(tool_function):
56
+ tool_function = async_to_sync(tool_function)
57
+ executor_globals[tool_name] = tool_function
58
+
59
+ print(f"✅ Executor globals set up with {len(executor_globals)} items")
60
+
61
+ # Test that functions are callable
62
+ print("\nTesting function availability...")
63
+ test_functions = ['start_app', 'swipe', 'press_key', 'tap_by_index']
64
+ for func_name in test_functions:
65
+ if func_name in executor_globals:
66
+ print(f" ✅ {func_name} is available")
67
+ else:
68
+ print(f" ❌ {func_name} is NOT available")
69
+
70
+ print("\n✅ All tests passed!")
71
+ return True
72
+
73
+ except Exception as e:
74
+ print(f"\n❌ Test failed: {e}")
75
+ import traceback
76
+ traceback.print_exc()
77
+ return False
78
+
79
+ if __name__ == "__main__":
80
+ success = test_tool_loading()
81
+ sys.exit(0 if success else 1)
File without changes
File without changes
File without changes
File without changes