mobile-mcp-ai 2.6.0__py3-none-any.whl → 2.6.1__py3-none-any.whl

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.
@@ -2349,6 +2349,7 @@ class BasicMobileToolsLite:
2349
2349
  for elem in root.iter():
2350
2350
  text = elem.attrib.get('text', '')
2351
2351
  content_desc = elem.attrib.get('content-desc', '')
2352
+ resource_id = elem.attrib.get('resource-id', '')
2352
2353
  bounds_str = elem.attrib.get('bounds', '')
2353
2354
  class_name = elem.attrib.get('class', '')
2354
2355
  clickable = elem.attrib.get('clickable', 'false') == 'true'
@@ -2383,6 +2384,13 @@ class BasicMobileToolsLite:
2383
2384
  score = 90
2384
2385
  reason = f"描述='{content_desc}'"
2385
2386
 
2387
+ # 策略2.5:resource-id 包含关闭关键词(如 close_icon, ad_close 等)
2388
+ elif resource_id and any(kw in resource_id.lower() for kw in ['close', 'dismiss', 'skip', 'cancel']):
2389
+ score = 95
2390
+ # 提取简短的 id 名
2391
+ short_id = resource_id.split('/')[-1] if '/' in resource_id else resource_id
2392
+ reason = f"resource-id='{short_id}'"
2393
+
2386
2394
  # 策略3:小尺寸的 clickable 元素(可能是 X 图标)
2387
2395
  elif clickable:
2388
2396
  min_size = max(20, int(screen_width * 0.03))
@@ -2417,7 +2425,9 @@ class BasicMobileToolsLite:
2417
2425
  'center_y': center_y,
2418
2426
  'x_percent': x_percent,
2419
2427
  'y_percent': y_percent,
2420
- 'size': f"{width}x{height}"
2428
+ 'size': f"{width}x{height}",
2429
+ 'resource_id': resource_id,
2430
+ 'text': text
2421
2431
  })
2422
2432
 
2423
2433
  if not candidates:
@@ -2443,7 +2453,16 @@ class BasicMobileToolsLite:
2443
2453
  candidates.sort(key=lambda x: x['score'], reverse=True)
2444
2454
  best = candidates[0]
2445
2455
 
2446
- return {
2456
+ # 生成推荐的点击命令(优先使用 resource-id)
2457
+ if best.get('resource_id'):
2458
+ short_id = best['resource_id'].split('/')[-1] if '/' in best['resource_id'] else best['resource_id']
2459
+ click_cmd = f"mobile_click_by_id('{best['resource_id']}')"
2460
+ elif best.get('text') and best['text'] in ['×', 'X', 'x', '关闭', '取消', '跳过', '知道了']:
2461
+ click_cmd = f"mobile_click_by_text('{best['text']}')"
2462
+ else:
2463
+ click_cmd = f"mobile_click_by_percent({best['x_percent']}, {best['y_percent']})"
2464
+
2465
+ result = {
2447
2466
  "success": True,
2448
2467
  "message": f"✅ 找到可能的关闭按钮",
2449
2468
  "best_candidate": {
@@ -2454,7 +2473,7 @@ class BasicMobileToolsLite:
2454
2473
  "size": best['size'],
2455
2474
  "score": best['score']
2456
2475
  },
2457
- "click_command": f"mobile_click_by_percent({best['x_percent']}, {best['y_percent']})",
2476
+ "click_command": click_cmd,
2458
2477
  "other_candidates": [
2459
2478
  {"reason": c['reason'], "percent": f"({c['x_percent']}%, {c['y_percent']}%)", "score": c['score']}
2460
2479
  for c in candidates[1:4]
@@ -2462,6 +2481,14 @@ class BasicMobileToolsLite:
2462
2481
  "screen_size": {"width": screen_width, "height": screen_height}
2463
2482
  }
2464
2483
 
2484
+ # 如果有 resource-id,额外提供
2485
+ if best.get('resource_id'):
2486
+ result["best_candidate"]["resource_id"] = best['resource_id']
2487
+ if best.get('text'):
2488
+ result["best_candidate"]["text"] = best['text']
2489
+
2490
+ return result
2491
+
2465
2492
  except Exception as e:
2466
2493
  return {"success": False, "message": f"❌ 查找关闭按钮失败: {e}"}
2467
2494
 
@@ -3442,6 +3469,16 @@ class BasicMobileToolsLite:
3442
3469
  reason = f"文本含'{kw}'"
3443
3470
  break
3444
3471
 
3472
+ # resource-id 匹配(如 close_icon, ad_close 等)
3473
+ if resource_id:
3474
+ res_id_lower = resource_id.lower()
3475
+ for kw in ['close', 'dismiss', 'skip', 'cancel']:
3476
+ if kw in res_id_lower:
3477
+ score += 9
3478
+ short_id = resource_id.split('/')[-1] if '/' in resource_id else resource_id
3479
+ reason = f"resource-id='{short_id}'"
3480
+ break
3481
+
3445
3482
  # content-desc 匹配
3446
3483
  for kw in close_content_desc:
3447
3484
  if kw.lower() in content_desc.lower():
@@ -610,22 +610,25 @@ class MobileMCPServer:
610
610
  name="mobile_find_close_button",
611
611
  description="""🔍 智能查找关闭按钮(只找不点,返回位置)
612
612
 
613
- 从元素树中找最可能的关闭按钮,返回坐标和百分比位置。
613
+ ⚡ 【推荐首选】遇到弹窗时优先调用此工具!无需先截图。
614
+
615
+ 从元素树中找最可能的关闭按钮,返回坐标和推荐的点击命令。
614
616
 
615
617
  🎯 识别策略(优先级):
616
- 1. 文本匹配:×、X、关闭、取消、跳过
617
- 2. 描述匹配:content-desc 包含 close/关闭
618
- 3. 小尺寸 clickable 元素(右上角优先)
618
+ 1. 文本匹配:×、X、关闭、取消、跳过 等(得分100)
619
+ 2. resource-id 匹配:包含 close/dismiss/skip(得分95)
620
+ 3. content-desc 匹配:包含 close/关闭(得分90)
621
+ 4. 小尺寸 clickable 元素(右上角优先,得分70+)
619
622
 
620
623
  ✅ 返回内容:
621
624
  - 坐标 (x, y) 和百分比 (x%, y%)
622
- - 推荐的点击命令:mobile_click_by_percent(x%, y%)
623
- - 多个候选位置(供确认)
625
+ - resource-id(如果有)
626
+ - 推荐的点击命令(优先 click_by_id,其次 click_by_text,最后 click_by_percent)
624
627
 
625
628
  💡 使用流程:
626
- 1. 调用此工具找到关闭按钮位置
627
- 2. 确认位置正确后,用 mobile_click_by_percent 点击
628
- 3. 百分比点击兼容不同分辨率手机""",
629
+ 1. 直接调用此工具(无需先截图/列元素)
630
+ 2. 根据返回的 click_command 执行点击
631
+ 3. 如果返回 success=false,才需要截图分析""",
629
632
  inputSchema={"type": "object", "properties": {}, "required": []}
630
633
  ))
631
634
 
@@ -711,24 +714,26 @@ class MobileMCPServer:
711
714
  name="mobile_close_ad",
712
715
  description="""🚫 【推荐】智能关闭广告弹窗
713
716
 
714
- 专门用于关闭广告弹窗,按优先级自动尝试多种方式:
717
+ ⚡ 直接调用即可,无需先截图!会自动按优先级尝试:
715
718
 
716
- 1️⃣ **控件树查找**(最可靠)
717
- - 自动查找"关闭"、"跳过"、"×"等关闭按钮
719
+ 1️⃣ **控件树查找**(最可靠,优先)
720
+ - 自动查找 resource-id 包含 close/dismiss
721
+ - 查找文本"关闭"、"跳过"、"×"等
718
722
  - 找到直接点击,实时可靠
719
723
 
720
724
  2️⃣ **模板匹配**(次优)
721
725
  - 用 OpenCV 匹配已保存的 X 按钮模板
722
- - 需要积累模板库,模板越多成功率越高
726
+ - 模板越多成功率越高
723
727
 
724
728
  3️⃣ **返回截图供 AI 分析**(兜底)
725
- - 如果前两步失败,返回截图
729
+ - 前两步都失败才截图
726
730
  - AI 分析后用 mobile_click_by_percent 点击
727
- - 点击成功后用 mobile_template_add 添加模板(自动学习)
731
+ - 点击成功后用 mobile_template_add 添加模板
728
732
 
729
- 💡 使用流程:
730
- 1. 遇到广告弹窗 → 调用此工具
733
+ 💡 正确流程:
734
+ 1. 遇到广告弹窗 → 直接调用此工具
731
735
  2. 如果成功 → 完成
736
+ 3. 只有失败时才需要截图分析
732
737
  3. 如果失败 → 看截图找 X → 点击 → 添加模板""",
733
738
  inputSchema={
734
739
  "type": "object",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mobile-mcp-ai
3
- Version: 2.6.0
3
+ Version: 2.6.1
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
@@ -1,7 +1,7 @@
1
1
  mobile_mcp/__init__.py,sha256=sQJZTL_sxQFzmcS7jOtS2AHCfUySz40vhX96N6u1qy4,816
2
2
  mobile_mcp/config.py,sha256=yaFLAV4bc2wX0GQPtZDo7OYF9E88tXV-av41fQsJwK4,4480
3
3
  mobile_mcp/core/__init__.py,sha256=ndMy-cLAIsQDG5op7gM_AIplycqZSZPWEkec1pEhvEY,170
4
- mobile_mcp/core/basic_tools_lite.py,sha256=7QbmeNduFm-KDuKMGMmlnC3HqzNAlKFHcNpquicakAs,179209
4
+ mobile_mcp/core/basic_tools_lite.py,sha256=zBKruc_z-iYaa5PysC91AAB0eydt_qDFNTT7o5OuUqU,181240
5
5
  mobile_mcp/core/device_manager.py,sha256=xG5DoeNFs45pl-FTEhEWblqVwxtFK-FmVEGlNL6EqRI,8798
6
6
  mobile_mcp/core/dynamic_config.py,sha256=Ja1n1pfb0HspGByqk2_A472mYVniKmGtNEWyjUjmgK8,9811
7
7
  mobile_mcp/core/ios_client_wda.py,sha256=Nq9WxevhTWpVpolM-Ymp-b0nUQV3tXLFszmJHbDC4wA,18770
@@ -19,14 +19,14 @@ mobile_mcp/core/utils/logger.py,sha256=XXQAHUwT1jc70pq_tYFmL6f_nKrFlYm3hcgl-5RYR
19
19
  mobile_mcp/core/utils/operation_history_manager.py,sha256=gi8S8HJAMqvkUrY7_-kVbko3Xt7c4GAUziEujRd-N-Y,4792
20
20
  mobile_mcp/core/utils/smart_wait.py,sha256=N5wKTUYrNWPruBILqrAjpvtso8Z3GRWCfMIR_aZxPLg,8649
21
21
  mobile_mcp/mcp_tools/__init__.py,sha256=xkro8Rwqv_55YlVyhh-3DgRFSsLE3h1r31VIb3bpM6E,143
22
- mobile_mcp/mcp_tools/mcp_server.py,sha256=fr42BjulYQCBreWoLx5lkWEZjT60Df6RCo_kyXMOHfI,49868
22
+ mobile_mcp/mcp_tools/mcp_server.py,sha256=T6H3jAEfxQzGeQgiTg9ROn2GpgonARrrlFWrzVfxmKU,50135
23
23
  mobile_mcp/utils/__init__.py,sha256=8EH0i7UGtx1y_j_GEgdN-cZdWn2sRtZSEOLlNF9HRnY,158
24
24
  mobile_mcp/utils/logger.py,sha256=Sqq2Nr0Y4p03erqcrbYKVPCGiFaNGHMcE_JwCkeOfU4,3626
25
25
  mobile_mcp/utils/xml_formatter.py,sha256=uwTRb3vLbqhT8O-udzWT7s7LsV-DyDUz2DkofD3hXOE,4556
26
26
  mobile_mcp/utils/xml_parser.py,sha256=QhL8CWbdmNDzmBLjtx6mEnjHgMFZzJeHpCL15qfXSpI,3926
27
- mobile_mcp_ai-2.6.0.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
28
- mobile_mcp_ai-2.6.0.dist-info/METADATA,sha256=QeGdsOiTatw7dLmpFxeWxvIXt2bG3zuIt-HXlm-9XDw,10495
29
- mobile_mcp_ai-2.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
- mobile_mcp_ai-2.6.0.dist-info/entry_points.txt,sha256=KB_FglozgPHBprSM1vFbIzGyheFuHFmGanscRdMJ_8A,68
31
- mobile_mcp_ai-2.6.0.dist-info/top_level.txt,sha256=lLm6YpbTv855Lbh8BIA0rPxhybIrvYUzMEk9OErHT94,11
32
- mobile_mcp_ai-2.6.0.dist-info/RECORD,,
27
+ mobile_mcp_ai-2.6.1.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
28
+ mobile_mcp_ai-2.6.1.dist-info/METADATA,sha256=oa_vxBNab-rKPX3yXVbetv6Joc-jjdh_XxgYA7vbEfY,10495
29
+ mobile_mcp_ai-2.6.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
+ mobile_mcp_ai-2.6.1.dist-info/entry_points.txt,sha256=KB_FglozgPHBprSM1vFbIzGyheFuHFmGanscRdMJ_8A,68
31
+ mobile_mcp_ai-2.6.1.dist-info/top_level.txt,sha256=lLm6YpbTv855Lbh8BIA0rPxhybIrvYUzMEk9OErHT94,11
32
+ mobile_mcp_ai-2.6.1.dist-info/RECORD,,