mobile-mcp-ai 2.6.7__tar.gz → 2.6.8__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 (47) hide show
  1. {mobile_mcp_ai-2.6.7/mobile_mcp_ai.egg-info → mobile_mcp_ai-2.6.8}/PKG-INFO +1 -1
  2. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/basic_tools_lite.py +164 -0
  3. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/mcp_tools/mcp_server.py +46 -1
  4. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8/mobile_mcp_ai.egg-info}/PKG-INFO +1 -1
  5. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/setup.py +1 -1
  6. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/LICENSE +0 -0
  7. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/MANIFEST.in +0 -0
  8. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/README.md +0 -0
  9. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/__init__.py +0 -0
  10. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/config.py +0 -0
  11. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/__init__.py +0 -0
  12. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/device_manager.py +0 -0
  13. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/dynamic_config.py +0 -0
  14. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/ios_client_wda.py +0 -0
  15. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/ios_device_manager_wda.py +0 -0
  16. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/mobile_client.py +0 -0
  17. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/template_matcher.py +0 -0
  18. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/templates/close_buttons/auto_x_0112_151217.png +0 -0
  19. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/templates/close_buttons/auto_x_0112_152037.png +0 -0
  20. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/templates/close_buttons/auto_x_0112_152840.png +0 -0
  21. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/templates/close_buttons/auto_x_0112_153256.png +0 -0
  22. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/templates/close_buttons/auto_x_0112_154847.png +0 -0
  23. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/templates/close_buttons/gray_x_stock_ad.png +0 -0
  24. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/utils/__init__.py +0 -0
  25. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/utils/logger.py +0 -0
  26. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/utils/operation_history_manager.py +0 -0
  27. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/core/utils/smart_wait.py +0 -0
  28. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/docs/iOS_SETUP_GUIDE.md +0 -0
  29. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/mcp_tools/__init__.py +0 -0
  30. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/mobile_mcp_ai.egg-info/SOURCES.txt +0 -0
  31. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/mobile_mcp_ai.egg-info/dependency_links.txt +0 -0
  32. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/mobile_mcp_ai.egg-info/entry_points.txt +0 -0
  33. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/mobile_mcp_ai.egg-info/not-zip-safe +0 -0
  34. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/mobile_mcp_ai.egg-info/requires.txt +0 -0
  35. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/mobile_mcp_ai.egg-info/top_level.txt +0 -0
  36. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/requirements.txt +0 -0
  37. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/setup.cfg +0 -0
  38. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/templates/close_buttons/auto_x_0112_151217.png +0 -0
  39. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/templates/close_buttons/auto_x_0112_152037.png +0 -0
  40. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/templates/close_buttons/auto_x_0112_152840.png +0 -0
  41. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/templates/close_buttons/auto_x_0112_153256.png +0 -0
  42. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/templates/close_buttons/auto_x_0112_154847.png +0 -0
  43. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/templates/close_buttons/gray_x_stock_ad.png +0 -0
  44. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/utils/__init__.py +0 -0
  45. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/utils/logger.py +0 -0
  46. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/utils/xml_formatter.py +0 -0
  47. {mobile_mcp_ai-2.6.7 → mobile_mcp_ai-2.6.8}/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.6.7
3
+ Version: 2.6.8
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
@@ -2271,6 +2271,170 @@ class BasicMobileToolsLite:
2271
2271
  time.sleep(seconds)
2272
2272
  return {"success": True, "message": f"✅ 已等待 {seconds} 秒"}
2273
2273
 
2274
+ async def drag_progress_bar(self, direction: str = "right", distance_percent: float = 30.0,
2275
+ y_percent: Optional[float] = None, y: Optional[int] = None) -> Dict:
2276
+ """智能拖动进度条
2277
+
2278
+ 自动检测进度条是否可见:
2279
+ - 如果进度条已显示,直接拖动(无需先点击播放区域)
2280
+ - 如果进度条未显示,先点击播放区域显示控制栏,再拖动
2281
+
2282
+ Args:
2283
+ direction: 拖动方向,'left'(倒退)或 'right'(前进),默认 'right'
2284
+ distance_percent: 拖动距离百分比 (0-100),默认 30%
2285
+ y_percent: 进度条的垂直位置百分比 (0-100),如果未指定则自动检测
2286
+ y: 进度条的垂直位置坐标(像素),如果未指定则自动检测
2287
+ """
2288
+ try:
2289
+ import xml.etree.ElementTree as ET
2290
+ import re
2291
+
2292
+ if self._is_ios():
2293
+ return {"success": False, "message": "❌ iOS 暂不支持,请使用 mobile_swipe"}
2294
+
2295
+ if direction not in ['left', 'right']:
2296
+ return {"success": False, "message": f"❌ 拖动方向必须是 'left' 或 'right': {direction}"}
2297
+
2298
+ screen_width, screen_height = self.client.u2.window_size()
2299
+
2300
+ # 获取 XML 查找进度条
2301
+ xml_string = self.client.u2.dump_hierarchy(compressed=False)
2302
+ root = ET.fromstring(xml_string)
2303
+
2304
+ progress_bar_found = False
2305
+ progress_bar_y = None
2306
+ progress_bar_y_percent = None
2307
+
2308
+ # 查找进度条元素(SeekBar、ProgressBar)
2309
+ for elem in root.iter():
2310
+ class_name = elem.attrib.get('class', '')
2311
+ resource_id = elem.attrib.get('resource-id', '')
2312
+ bounds_str = elem.attrib.get('bounds', '')
2313
+
2314
+ # 检查是否是进度条
2315
+ is_progress_bar = (
2316
+ 'SeekBar' in class_name or
2317
+ 'ProgressBar' in class_name or
2318
+ 'progress' in resource_id.lower() or
2319
+ 'seek' in resource_id.lower()
2320
+ )
2321
+
2322
+ if is_progress_bar and bounds_str:
2323
+ # 解析 bounds 获取进度条位置
2324
+ match = re.match(r'\[(\d+),(\d+)\]\[(\d+),(\d+)\]', bounds_str)
2325
+ if match:
2326
+ x1, y1, x2, y2 = map(int, match.groups())
2327
+ center_y = (y1 + y2) // 2
2328
+ progress_bar_y = center_y
2329
+ progress_bar_y_percent = round(center_y / screen_height * 100, 1)
2330
+ progress_bar_found = True
2331
+ break
2332
+
2333
+ # 如果未找到进度条,尝试点击播放区域显示控制栏
2334
+ if not progress_bar_found:
2335
+ # 点击屏幕中心显示控制栏
2336
+ center_x, center_y = screen_width // 2, screen_height // 2
2337
+ self.client.u2.click(center_x, center_y)
2338
+ time.sleep(0.5)
2339
+
2340
+ # 再次查找进度条
2341
+ xml_string = self.client.u2.dump_hierarchy(compressed=False)
2342
+ root = ET.fromstring(xml_string)
2343
+
2344
+ for elem in root.iter():
2345
+ class_name = elem.attrib.get('class', '')
2346
+ resource_id = elem.attrib.get('resource-id', '')
2347
+ bounds_str = elem.attrib.get('bounds', '')
2348
+
2349
+ is_progress_bar = (
2350
+ 'SeekBar' in class_name or
2351
+ 'ProgressBar' in class_name or
2352
+ 'progress' in resource_id.lower() or
2353
+ 'seek' in resource_id.lower()
2354
+ )
2355
+
2356
+ if is_progress_bar and bounds_str:
2357
+ match = re.match(r'\[(\d+),(\d+)\]\[(\d+),(\d+)\]', bounds_str)
2358
+ if match:
2359
+ x1, y1, x2, y2 = map(int, match.groups())
2360
+ center_y = (y1 + y2) // 2
2361
+ progress_bar_y = center_y
2362
+ progress_bar_y_percent = round(center_y / screen_height * 100, 1)
2363
+ progress_bar_found = True
2364
+ break
2365
+
2366
+ # 确定使用的高度位置
2367
+ if y_percent is not None:
2368
+ swipe_y = int(screen_height * y_percent / 100)
2369
+ used_y_percent = y_percent
2370
+ elif y is not None:
2371
+ swipe_y = y
2372
+ used_y_percent = round(y / screen_height * 100, 1)
2373
+ elif progress_bar_found:
2374
+ swipe_y = progress_bar_y
2375
+ used_y_percent = progress_bar_y_percent
2376
+ else:
2377
+ # 默认使用屏幕底部附近(进度条常见位置)
2378
+ swipe_y = int(screen_height * 0.91)
2379
+ used_y_percent = 91.0
2380
+
2381
+ # 计算滑动距离
2382
+ swipe_distance = int(screen_width * distance_percent / 100)
2383
+
2384
+ # 计算起始和结束位置
2385
+ center_x = screen_width // 2
2386
+ if direction == 'left':
2387
+ start_x = min(center_x + swipe_distance // 2, screen_width - 10)
2388
+ end_x = start_x - swipe_distance
2389
+ if end_x < 10:
2390
+ end_x = 10
2391
+ start_x = min(end_x + swipe_distance, screen_width - 10)
2392
+ else: # right
2393
+ start_x = max(center_x - swipe_distance // 2, 10)
2394
+ end_x = start_x + swipe_distance
2395
+ if end_x > screen_width - 10:
2396
+ end_x = screen_width - 10
2397
+ start_x = max(end_x - swipe_distance, 10)
2398
+
2399
+ # 执行拖动
2400
+ self.client.u2.swipe(start_x, swipe_y, end_x, swipe_y, duration=0.5)
2401
+ time.sleep(0.3)
2402
+
2403
+ # 记录操作
2404
+ self._record_swipe(direction)
2405
+
2406
+ # 检查应用是否跳转
2407
+ app_check = self._check_app_switched()
2408
+ return_result = None
2409
+ if app_check['switched']:
2410
+ return_result = self._return_to_target_app()
2411
+
2412
+ # 构建返回消息
2413
+ msg = f"✅ 进度条拖动成功: {direction} (高度: {used_y_percent}%, 距离: {distance_percent}%)"
2414
+ if not progress_bar_found:
2415
+ msg += "\n💡 已自动点击播放区域显示控制栏"
2416
+ else:
2417
+ msg += "\n💡 进度条已显示,直接拖动"
2418
+
2419
+ if app_check['switched']:
2420
+ msg += f"\n{app_check['message']}"
2421
+ if return_result and return_result.get('success'):
2422
+ msg += f"\n{return_result['message']}"
2423
+
2424
+ return {
2425
+ "success": True,
2426
+ "message": msg,
2427
+ "progress_bar_found": progress_bar_found,
2428
+ "y_percent": used_y_percent,
2429
+ "distance_percent": distance_percent,
2430
+ "direction": direction,
2431
+ "app_check": app_check,
2432
+ "return_to_app": return_result
2433
+ }
2434
+
2435
+ except Exception as e:
2436
+ return {"success": False, "message": f"❌ 拖动进度条失败: {e}"}
2437
+
2274
2438
  # ==================== 应用管理 ====================
2275
2439
 
2276
2440
  async def launch_app(self, package_name: str) -> Dict:
@@ -530,7 +530,8 @@ class MobileMCPServer:
530
530
  "- 📌 拖动进度条时,distance_percent 控制拖动幅度\n\n"
531
531
  "💡 拖动进度条示例:\n"
532
532
  "- 倒退:direction='left', y_percent=91(进度条位置), distance_percent=30\n"
533
- "- 前进:direction='right', y_percent=91, distance_percent=30",
533
+ "- 前进:direction='right', y_percent=91, distance_percent=30\n\n"
534
+ "⚠️ **推荐使用 mobile_drag_progress_bar 拖动进度条**(自动检测进度条位置,无需手动指定)",
534
535
  inputSchema={
535
536
  "type": "object",
536
537
  "properties": {
@@ -560,6 +561,50 @@ class MobileMCPServer:
560
561
  }
561
562
  ))
562
563
 
564
+ tools.append(Tool(
565
+ name="mobile_drag_progress_bar",
566
+ description="🎯 智能拖动进度条(⭐⭐ 推荐用于拖动视频/音频进度条)\n\n"
567
+ "✅ **自动检测进度条是否可见**:\n"
568
+ "- 如果进度条已显示,直接拖动(无需先点击播放区域)\n"
569
+ "- 如果进度条未显示,自动点击播放区域显示控制栏,再拖动\n\n"
570
+ "🎯 优势:\n"
571
+ "- 自动检测进度条位置,无需手动指定 y_percent\n"
572
+ "- 智能判断是否需要显示控制栏\n"
573
+ "- 使用 swipe 拖动,更稳定可靠\n\n"
574
+ "💡 参数说明:\n"
575
+ "- direction: 'left'(倒退)或 'right'(前进),默认 'right'\n"
576
+ "- distance_percent: 拖动距离百分比 (0-100),默认 30%\n"
577
+ "- y_percent: 进度条位置(可选,未指定则自动检测)\n"
578
+ "- y: 进度条位置坐标(可选,未指定则自动检测)\n\n"
579
+ "📋 使用示例:\n"
580
+ "- 前进30%:mobile_drag_progress_bar(direction='right', distance_percent=30)\n"
581
+ "- 倒退30%:mobile_drag_progress_bar(direction='left', distance_percent=30)\n"
582
+ "- 前进到指定位置:先点击进度条位置,或使用 mobile_swipe",
583
+ inputSchema={
584
+ "type": "object",
585
+ "properties": {
586
+ "direction": {
587
+ "type": "string",
588
+ "enum": ["left", "right"],
589
+ "description": "拖动方向:'left'(倒退)或 'right'(前进),默认 'right'"
590
+ },
591
+ "distance_percent": {
592
+ "type": "number",
593
+ "description": "拖动距离百分比 (0-100),默认 30%"
594
+ },
595
+ "y_percent": {
596
+ "type": "number",
597
+ "description": "进度条的垂直位置百分比 (0-100),可选,未指定则自动检测"
598
+ },
599
+ "y": {
600
+ "type": "integer",
601
+ "description": "进度条的垂直位置坐标(像素),可选,未指定则自动检测"
602
+ }
603
+ },
604
+ "required": []
605
+ }
606
+ ))
607
+
563
608
  tools.append(Tool(
564
609
  name="mobile_press_key",
565
610
  description="⌨️ 按键操作。支持:home, back, enter, search",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mobile-mcp-ai
3
- Version: 2.6.7
3
+ Version: 2.6.8
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.6.7", # 增强弹窗检测 - 添加浮动关闭按钮检测
28
+ version="2.6.8", # 增强弹窗检测 - 添加浮动关闭按钮检测
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