mobile-mcp-ai 2.3.2__tar.gz → 2.3.3__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.
Files changed (44) hide show
  1. {mobile_mcp_ai-2.3.2/mobile_mcp_ai.egg-info → mobile_mcp_ai-2.3.3}/PKG-INFO +1 -1
  2. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/basic_tools_lite.py +91 -0
  3. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/mobile_client.py +27 -22
  4. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/mcp_tools/mcp_server.py +33 -0
  5. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3/mobile_mcp_ai.egg-info}/PKG-INFO +1 -1
  6. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/setup.py +1 -1
  7. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/LICENSE +0 -0
  8. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/MANIFEST.in +0 -0
  9. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/README.md +0 -0
  10. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/__init__.py +0 -0
  11. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/config.py +0 -0
  12. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/__init__.py +0 -0
  13. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/device_manager.py +0 -0
  14. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/dynamic_config.py +0 -0
  15. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/ios_client_wda.py +0 -0
  16. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/ios_device_manager_wda.py +0 -0
  17. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/utils/__init__.py +0 -0
  18. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/utils/logger.py +0 -0
  19. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/utils/operation_history_manager.py +0 -0
  20. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/core/utils/smart_wait.py +0 -0
  21. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/docs/iOS_SETUP_GUIDE.md +0 -0
  22. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/mcp_tools/__init__.py +0 -0
  23. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/mobile_mcp_ai.egg-info/SOURCES.txt +0 -0
  24. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/mobile_mcp_ai.egg-info/dependency_links.txt +0 -0
  25. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/mobile_mcp_ai.egg-info/entry_points.txt +0 -0
  26. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/mobile_mcp_ai.egg-info/not-zip-safe +0 -0
  27. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/mobile_mcp_ai.egg-info/requires.txt +0 -0
  28. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/mobile_mcp_ai.egg-info/top_level.txt +0 -0
  29. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/requirements.txt +0 -0
  30. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/setup.cfg +0 -0
  31. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_mind_cloud_my_space.py +0 -0
  32. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_mind_correct.py +0 -0
  33. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_mind_improved.py +0 -0
  34. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_mind_optimized.py +0 -0
  35. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_open_mind.py +0 -0
  36. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_priority_demo.py +0 -0
  37. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_simple.py +0 -0
  38. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_/344/270/276/346/212/245.py" +0 -0
  39. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_/345/210/207/346/215/242/350/257/255/350/250/200/345/210/260English.py" +0 -0
  40. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/tests/test_/346/265/213/350/257/225.py" +0 -0
  41. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/utils/__init__.py +0 -0
  42. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/utils/logger.py +0 -0
  43. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/utils/xml_formatter.py +0 -0
  44. {mobile_mcp_ai-2.3.2 → mobile_mcp_ai-2.3.3}/utils/xml_parser.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mobile-mcp-ai
3
- Version: 2.3.2
3
+ Version: 2.3.3
4
4
  Summary: 移动端自动化 MCP Server - 支持 Android/iOS,AI 功能可选(基础工具不需要 AI)
5
5
  Home-page: https://github.com/test111ddff-hash/mobile-mcp-ai
6
6
  Author: douzi
@@ -813,6 +813,97 @@ class BasicMobileToolsLite:
813
813
  except Exception as e:
814
814
  return {"success": False, "message": f"❌ 断言失败: {e}"}
815
815
 
816
+ def close_ad(self, keywords: Optional[List[str]] = None, max_attempts: int = 3) -> Dict:
817
+ """关闭广告弹窗
818
+
819
+ 自动检测并点击广告关闭按钮,支持多种关闭方式:
820
+ 1. 文本匹配:关闭、跳过、Skip、Close 等
821
+ 2. 特殊符号:×、X、✕ 等
822
+ 3. content-desc 匹配
823
+
824
+ Args:
825
+ keywords: 自定义关键词列表,默认使用内置关键词
826
+ max_attempts: 最大尝试次数,默认3次(处理多层弹窗)
827
+
828
+ Returns:
829
+ 关闭结果,包含关闭的广告数量
830
+ """
831
+ # 默认关键词(按优先级排序)
832
+ default_keywords = [
833
+ '关闭', '跳过', 'Skip', 'Close', 'close',
834
+ '×', 'X', '✕', '╳',
835
+ '我知道了', '稍后再说', '不再提示', '取消',
836
+ '知道了', '好的', '确定',
837
+ 'Later', 'No thanks', 'Not now', 'Dismiss'
838
+ ]
839
+
840
+ search_keywords = keywords if keywords else default_keywords
841
+ closed_count = 0
842
+ closed_items = []
843
+
844
+ try:
845
+ for attempt in range(max_attempts):
846
+ found_in_this_round = False
847
+
848
+ for keyword in search_keywords:
849
+ try:
850
+ if self._is_ios():
851
+ ios_client = self._get_ios_client()
852
+ if ios_client and hasattr(ios_client, 'wda'):
853
+ # iOS: 尝试 name 和 label
854
+ elem = ios_client.wda(name=keyword)
855
+ if not elem.exists:
856
+ elem = ios_client.wda(label=keyword)
857
+ if not elem.exists:
858
+ elem = ios_client.wda(nameContains=keyword)
859
+
860
+ if elem.exists:
861
+ elem.click()
862
+ time.sleep(0.5)
863
+ closed_count += 1
864
+ closed_items.append(keyword)
865
+ found_in_this_round = True
866
+ break
867
+ else:
868
+ # Android: 尝试 text 和 content-desc
869
+ elem = self.client.u2(text=keyword)
870
+ if not elem.exists(timeout=0.2):
871
+ elem = self.client.u2(textContains=keyword)
872
+ if not elem.exists(timeout=0.2):
873
+ elem = self.client.u2(description=keyword)
874
+ if not elem.exists(timeout=0.2):
875
+ elem = self.client.u2(descriptionContains=keyword)
876
+
877
+ if elem.exists(timeout=0.2):
878
+ elem.click()
879
+ time.sleep(0.5)
880
+ closed_count += 1
881
+ closed_items.append(keyword)
882
+ found_in_this_round = True
883
+ break
884
+ except Exception:
885
+ continue
886
+
887
+ if not found_in_this_round:
888
+ # 这一轮没找到广告,退出
889
+ break
890
+
891
+ if closed_count > 0:
892
+ return {
893
+ "success": True,
894
+ "closed_count": closed_count,
895
+ "closed_items": closed_items,
896
+ "message": f"✅ 已关闭 {closed_count} 个广告弹窗: {', '.join(closed_items)}"
897
+ }
898
+ else:
899
+ return {
900
+ "success": True,
901
+ "closed_count": 0,
902
+ "message": "✅ 未发现广告弹窗(或已全部关闭)"
903
+ }
904
+ except Exception as e:
905
+ return {"success": False, "message": f"❌ 关闭广告失败: {e}"}
906
+
816
907
  # ==================== 脚本生成 ====================
817
908
 
818
909
  def get_operation_history(self, limit: Optional[int] = None) -> Dict:
@@ -825,29 +825,34 @@ class MobileClient:
825
825
  return {"success": False, "reason": str(e)}
826
826
 
827
827
  # Android平台
828
- # 🎯 优先使用智能启动(推荐)
828
+ # 🎯 尝试使用智能启动(如果模块存在)
829
829
  if smart_wait:
830
- from .smart_app_launcher import SmartAppLauncher
831
- launcher = SmartAppLauncher(self)
832
- # 优化:快速模式,最多3秒
833
- smart_wait_time = min(wait_time, 3)
834
-
835
- # 🎯 从环境变量读取是否自动关闭广告(默认True)
836
- import os
837
- auto_close_ads = os.environ.get('AUTO_CLOSE_ADS', 'true').lower() in ['true', '1', 'yes']
838
-
839
- result = await launcher.launch_with_smart_wait(
840
- package_name,
841
- max_wait=smart_wait_time,
842
- auto_close_ads=auto_close_ads
843
- )
844
-
845
- # 打印截图路径(供Cursor AI查看验证)
846
- if result.get('screenshot_path'):
847
- print(f"\n📸 启动截图已保存: {result['screenshot_path']}", file=sys.stderr)
848
- print(f"💡 提示: 请查看截图确认App是否已正确进入主页", file=sys.stderr)
849
-
850
- return result
830
+ try:
831
+ from .smart_app_launcher import SmartAppLauncher
832
+ launcher = SmartAppLauncher(self)
833
+ # 优化:快速模式,最多3
834
+ smart_wait_time = min(wait_time, 3)
835
+
836
+ # 🎯 从环境变量读取是否自动关闭广告(默认True)
837
+ import os
838
+ auto_close_ads = os.environ.get('AUTO_CLOSE_ADS', 'true').lower() in ['true', '1', 'yes']
839
+
840
+ result = await launcher.launch_with_smart_wait(
841
+ package_name,
842
+ max_wait=smart_wait_time,
843
+ auto_close_ads=auto_close_ads
844
+ )
845
+
846
+ # 打印截图路径(供Cursor AI查看验证)
847
+ if result.get('screenshot_path'):
848
+ print(f"\n📸 启动截图已保存: {result['screenshot_path']}", file=sys.stderr)
849
+ print(f"💡 提示: 请查看截图确认App是否已正确进入主页", file=sys.stderr)
850
+
851
+ return result
852
+ except ImportError:
853
+ # SmartAppLauncher 模块不存在,使用传统方式
854
+ print(f" 💡 智能启动模块未安装,使用传统启动方式", file=sys.stderr)
855
+ # 继续执行下面的传统方式
851
856
 
852
857
  # 传统方式(快速启动,不等待加载)
853
858
  print(f" 📱 启动App: {package_name}", file=sys.stderr)
@@ -379,6 +379,32 @@ class MobileMCPServer:
379
379
  }
380
380
  ))
381
381
 
382
+ tools.append(Tool(
383
+ name="mobile_close_ad",
384
+ description="📢 关闭广告弹窗(自动检测并点击关闭按钮)\n\n"
385
+ "🎯 自动检测以下关闭方式:\n"
386
+ "- 文本:关闭、跳过、Skip、Close、我知道了、稍后再说\n"
387
+ "- 符号:×、X、✕ 等\n"
388
+ "- 无障碍描述(content-desc)\n\n"
389
+ "💡 支持多层弹窗,最多尝试3次\n"
390
+ "✅ 比视觉识别更准确,推荐使用!",
391
+ inputSchema={
392
+ "type": "object",
393
+ "properties": {
394
+ "keywords": {
395
+ "type": "array",
396
+ "items": {"type": "string"},
397
+ "description": "自定义关键词列表(可选,默认使用内置关键词)"
398
+ },
399
+ "max_attempts": {
400
+ "type": "number",
401
+ "description": "最大尝试次数(可选,默认3次,用于处理多层弹窗)"
402
+ }
403
+ },
404
+ "required": []
405
+ }
406
+ ))
407
+
382
408
  # ==================== pytest 脚本生成 ====================
383
409
  tools.append(Tool(
384
410
  name="mobile_get_operation_history",
@@ -514,6 +540,13 @@ class MobileMCPServer:
514
540
  result = self.tools.assert_text(arguments["text"])
515
541
  return [TextContent(type="text", text=self.format_response(result))]
516
542
 
543
+ elif name == "mobile_close_ad":
544
+ result = self.tools.close_ad(
545
+ arguments.get("keywords"),
546
+ arguments.get("max_attempts", 3)
547
+ )
548
+ return [TextContent(type="text", text=self.format_response(result))]
549
+
517
550
  # 脚本生成
518
551
  elif name == "mobile_get_operation_history":
519
552
  result = self.tools.get_operation_history(arguments.get("limit"))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mobile-mcp-ai
3
- Version: 2.3.2
3
+ Version: 2.3.3
4
4
  Summary: 移动端自动化 MCP Server - 支持 Android/iOS,AI 功能可选(基础工具不需要 AI)
5
5
  Home-page: https://github.com/test111ddff-hash/mobile-mcp-ai
6
6
  Author: douzi
@@ -25,7 +25,7 @@ if requirements_file.exists():
25
25
 
26
26
  setup(
27
27
  name="mobile-mcp-ai",
28
- version="2.3.2", # 修复 CursorVisionHelper 模块不存在时的异常处理
28
+ version="2.3.3", # 新增 mobile_close_ad 广告关闭工具 + 修复 SmartAppLauncher 异常
29
29
  author="douzi",
30
30
  author_email="1492994674@qq.com",
31
31
  description="移动端自动化 MCP Server - 支持 Android/iOS,AI 功能可选(基础工具不需要 AI)",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes