mobile-mcp-ai 2.5.4__py3-none-any.whl → 2.5.6__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.
- mobile_mcp/core/basic_tools_lite.py +69 -13
- mobile_mcp/mcp_tools/mcp_server.py +46 -7
- {mobile_mcp_ai-2.5.4.dist-info → mobile_mcp_ai-2.5.6.dist-info}/METADATA +30 -30
- {mobile_mcp_ai-2.5.4.dist-info → mobile_mcp_ai-2.5.6.dist-info}/RECORD +8 -8
- {mobile_mcp_ai-2.5.4.dist-info → mobile_mcp_ai-2.5.6.dist-info}/WHEEL +1 -1
- {mobile_mcp_ai-2.5.4.dist-info/licenses → mobile_mcp_ai-2.5.6.dist-info}/LICENSE +0 -0
- {mobile_mcp_ai-2.5.4.dist-info → mobile_mcp_ai-2.5.6.dist-info}/entry_points.txt +0 -0
- {mobile_mcp_ai-2.5.4.dist-info → mobile_mcp_ai-2.5.6.dist-info}/top_level.txt +0 -0
|
@@ -1587,8 +1587,14 @@ class BasicMobileToolsLite:
|
|
|
1587
1587
|
|
|
1588
1588
|
# ==================== 导航操作 ====================
|
|
1589
1589
|
|
|
1590
|
-
async def swipe(self, direction: str) -> Dict:
|
|
1591
|
-
"""滑动屏幕
|
|
1590
|
+
async def swipe(self, direction: str, y: Optional[int] = None, y_percent: Optional[float] = None) -> Dict:
|
|
1591
|
+
"""滑动屏幕
|
|
1592
|
+
|
|
1593
|
+
Args:
|
|
1594
|
+
direction: 滑动方向 (up/down/left/right)
|
|
1595
|
+
y: 左右滑动时指定的高度坐标(像素)
|
|
1596
|
+
y_percent: 左右滑动时指定的高度百分比 (0-100)
|
|
1597
|
+
"""
|
|
1592
1598
|
try:
|
|
1593
1599
|
if self._is_ios():
|
|
1594
1600
|
ios_client = self._get_ios_client()
|
|
@@ -1602,11 +1608,26 @@ class BasicMobileToolsLite:
|
|
|
1602
1608
|
|
|
1603
1609
|
center_x, center_y = width // 2, height // 2
|
|
1604
1610
|
|
|
1611
|
+
# 对于左右滑动,如果指定了 y 或 y_percent,使用指定的高度
|
|
1612
|
+
if direction in ['left', 'right']:
|
|
1613
|
+
if y_percent is not None:
|
|
1614
|
+
if not (0 <= y_percent <= 100):
|
|
1615
|
+
return {"success": False, "message": f"❌ y_percent 必须在 0-100 之间: {y_percent}"}
|
|
1616
|
+
swipe_y = int(height * y_percent / 100)
|
|
1617
|
+
elif y is not None:
|
|
1618
|
+
if not (0 <= y <= height):
|
|
1619
|
+
return {"success": False, "message": f"❌ y 坐标超出屏幕范围 (0-{height}): {y}"}
|
|
1620
|
+
swipe_y = y
|
|
1621
|
+
else:
|
|
1622
|
+
swipe_y = center_y
|
|
1623
|
+
else:
|
|
1624
|
+
swipe_y = center_y
|
|
1625
|
+
|
|
1605
1626
|
swipe_map = {
|
|
1606
1627
|
'up': (center_x, int(height * 0.8), center_x, int(height * 0.2)),
|
|
1607
1628
|
'down': (center_x, int(height * 0.2), center_x, int(height * 0.8)),
|
|
1608
|
-
'left': (int(width * 0.8),
|
|
1609
|
-
'right': (int(width * 0.2),
|
|
1629
|
+
'left': (int(width * 0.8), swipe_y, int(width * 0.2), swipe_y),
|
|
1630
|
+
'right': (int(width * 0.2), swipe_y, int(width * 0.8), swipe_y),
|
|
1610
1631
|
}
|
|
1611
1632
|
|
|
1612
1633
|
if direction not in swipe_map:
|
|
@@ -1619,9 +1640,23 @@ class BasicMobileToolsLite:
|
|
|
1619
1640
|
else:
|
|
1620
1641
|
self.client.u2.swipe(x1, y1, x2, y2, duration=0.5)
|
|
1621
1642
|
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1643
|
+
# 记录操作信息
|
|
1644
|
+
record_info = {'direction': direction}
|
|
1645
|
+
if y is not None:
|
|
1646
|
+
record_info['y'] = y
|
|
1647
|
+
if y_percent is not None:
|
|
1648
|
+
record_info['y_percent'] = y_percent
|
|
1649
|
+
self._record_operation('swipe', **record_info)
|
|
1650
|
+
|
|
1651
|
+
# 构建返回消息
|
|
1652
|
+
msg = f"✅ 滑动成功: {direction}"
|
|
1653
|
+
if direction in ['left', 'right']:
|
|
1654
|
+
if y_percent is not None:
|
|
1655
|
+
msg += f" (高度: {y_percent}% = {swipe_y}px)"
|
|
1656
|
+
elif y is not None:
|
|
1657
|
+
msg += f" (高度: {y}px)"
|
|
1658
|
+
|
|
1659
|
+
return {"success": True, "message": msg}
|
|
1625
1660
|
except Exception as e:
|
|
1626
1661
|
return {"success": False, "message": f"❌ 滑动失败: {e}"}
|
|
1627
1662
|
|
|
@@ -2325,22 +2360,43 @@ class BasicMobileToolsLite:
|
|
|
2325
2360
|
return 0.5
|
|
2326
2361
|
|
|
2327
2362
|
def assert_text(self, text: str) -> Dict:
|
|
2328
|
-
"""
|
|
2363
|
+
"""检查页面是否包含文本(支持精确匹配和包含匹配)"""
|
|
2329
2364
|
try:
|
|
2365
|
+
exists = False
|
|
2366
|
+
match_type = ""
|
|
2367
|
+
|
|
2330
2368
|
if self._is_ios():
|
|
2331
2369
|
ios_client = self._get_ios_client()
|
|
2332
2370
|
if ios_client and hasattr(ios_client, 'wda'):
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2371
|
+
# 先尝试精确匹配
|
|
2372
|
+
if ios_client.wda(name=text).exists or ios_client.wda(label=text).exists:
|
|
2373
|
+
exists = True
|
|
2374
|
+
match_type = "精确匹配"
|
|
2375
|
+
# 再尝试包含匹配
|
|
2376
|
+
elif ios_client.wda(nameContains=text).exists or ios_client.wda(labelContains=text).exists:
|
|
2377
|
+
exists = True
|
|
2378
|
+
match_type = "包含匹配"
|
|
2379
|
+
else:
|
|
2380
|
+
# Android: 先尝试精确匹配
|
|
2381
|
+
if self.client.u2(text=text).exists():
|
|
2382
|
+
exists = True
|
|
2383
|
+
match_type = "精确匹配"
|
|
2384
|
+
# 再尝试包含匹配
|
|
2385
|
+
elif self.client.u2(textContains=text).exists():
|
|
2386
|
+
exists = True
|
|
2387
|
+
match_type = "包含匹配"
|
|
2388
|
+
|
|
2389
|
+
if exists:
|
|
2390
|
+
message = f"✅ 文本'{text}' 存在({match_type})"
|
|
2336
2391
|
else:
|
|
2337
|
-
|
|
2392
|
+
message = f"❌ 文本'{text}' 不存在"
|
|
2338
2393
|
|
|
2339
2394
|
return {
|
|
2340
2395
|
"success": True,
|
|
2341
2396
|
"found": exists,
|
|
2342
2397
|
"text": text,
|
|
2343
|
-
"
|
|
2398
|
+
"match_type": match_type if exists else None,
|
|
2399
|
+
"message": message
|
|
2344
2400
|
}
|
|
2345
2401
|
except Exception as e:
|
|
2346
2402
|
return {"success": False, "message": f"❌ 断言失败: {e}"}
|
|
@@ -34,9 +34,21 @@ from pathlib import Path
|
|
|
34
34
|
from typing import Optional
|
|
35
35
|
|
|
36
36
|
# 添加项目根目录到 Python 路径
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
# 支持两种运行方式:
|
|
38
|
+
# 1. 从源码运行:__file__ 在 mcp_tools/ 目录下,往上两级到项目根目录
|
|
39
|
+
# 2. 从已安装包运行:包已安装时,mobile_mcp 应该可以直接导入
|
|
40
|
+
# 先尝试从已安装的包导入,如果失败则从源码路径导入
|
|
41
|
+
try:
|
|
42
|
+
# 尝试导入已安装的包
|
|
43
|
+
import mobile_mcp.core.mobile_client
|
|
44
|
+
import mobile_mcp.core.basic_tools_lite
|
|
45
|
+
# 如果成功,说明包已安装,不需要添加路径
|
|
46
|
+
except ImportError:
|
|
47
|
+
# 包未安装或导入失败,从源码运行
|
|
48
|
+
# __file__ 在 mcp_tools/ 目录下,往上两级到项目根目录
|
|
49
|
+
project_root = Path(__file__).parent.parent
|
|
50
|
+
if str(project_root) not in sys.path:
|
|
51
|
+
sys.path.insert(0, str(project_root))
|
|
40
52
|
|
|
41
53
|
# 尝试导入 MCP,处理可能的路径冲突
|
|
42
54
|
try:
|
|
@@ -115,8 +127,19 @@ class MobileMCPServer:
|
|
|
115
127
|
platform = self._detect_platform()
|
|
116
128
|
|
|
117
129
|
try:
|
|
118
|
-
|
|
119
|
-
|
|
130
|
+
# 尝试导入,如果失败会抛出 ImportError
|
|
131
|
+
try:
|
|
132
|
+
from mobile_mcp.core.mobile_client import MobileClient
|
|
133
|
+
from mobile_mcp.core.basic_tools_lite import BasicMobileToolsLite
|
|
134
|
+
except ImportError as import_err:
|
|
135
|
+
# 如果导入失败,尝试从源码路径导入
|
|
136
|
+
# 这通常发生在开发模式下,包未安装时
|
|
137
|
+
project_root = Path(__file__).parent.parent
|
|
138
|
+
if str(project_root) not in sys.path:
|
|
139
|
+
sys.path.insert(0, str(project_root))
|
|
140
|
+
# 再次尝试导入
|
|
141
|
+
from mobile_mcp.core.mobile_client import MobileClient
|
|
142
|
+
from mobile_mcp.core.basic_tools_lite import BasicMobileToolsLite
|
|
120
143
|
|
|
121
144
|
self.client = MobileClient(platform=platform)
|
|
122
145
|
self.tools = BasicMobileToolsLite(self.client)
|
|
@@ -480,7 +503,11 @@ class MobileMCPServer:
|
|
|
480
503
|
# ==================== 导航操作 ====================
|
|
481
504
|
tools.append(Tool(
|
|
482
505
|
name="mobile_swipe",
|
|
483
|
-
description="👆 滑动屏幕。方向:up/down/left/right"
|
|
506
|
+
description="👆 滑动屏幕。方向:up/down/left/right\n\n"
|
|
507
|
+
"💡 左右滑动时,可指定高度坐标或百分比:\n"
|
|
508
|
+
"- y: 指定高度坐标(像素)\n"
|
|
509
|
+
"- y_percent: 指定高度百分比 (0-100)\n"
|
|
510
|
+
"- 两者都未指定时,使用屏幕中心高度",
|
|
484
511
|
inputSchema={
|
|
485
512
|
"type": "object",
|
|
486
513
|
"properties": {
|
|
@@ -488,6 +515,14 @@ class MobileMCPServer:
|
|
|
488
515
|
"type": "string",
|
|
489
516
|
"enum": ["up", "down", "left", "right"],
|
|
490
517
|
"description": "滑动方向"
|
|
518
|
+
},
|
|
519
|
+
"y": {
|
|
520
|
+
"type": "integer",
|
|
521
|
+
"description": "左右滑动时指定的高度坐标(像素,0-屏幕高度)"
|
|
522
|
+
},
|
|
523
|
+
"y_percent": {
|
|
524
|
+
"type": "number",
|
|
525
|
+
"description": "左右滑动时指定的高度百分比 (0-100)"
|
|
491
526
|
}
|
|
492
527
|
},
|
|
493
528
|
"required": ["direction"]
|
|
@@ -880,7 +915,11 @@ class MobileMCPServer:
|
|
|
880
915
|
|
|
881
916
|
# 导航
|
|
882
917
|
elif name == "mobile_swipe":
|
|
883
|
-
result = await self.tools.swipe(
|
|
918
|
+
result = await self.tools.swipe(
|
|
919
|
+
arguments["direction"],
|
|
920
|
+
y=arguments.get("y"),
|
|
921
|
+
y_percent=arguments.get("y_percent")
|
|
922
|
+
)
|
|
884
923
|
return [TextContent(type="text", text=self.format_response(result))]
|
|
885
924
|
|
|
886
925
|
elif name == "mobile_press_key":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: mobile-mcp-ai
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.6
|
|
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
|
|
@@ -31,21 +31,6 @@ Provides-Extra: ai
|
|
|
31
31
|
Requires-Dist: dashscope>=1.10.0; extra == "ai"
|
|
32
32
|
Requires-Dist: openai>=1.0.0; extra == "ai"
|
|
33
33
|
Requires-Dist: anthropic>=0.3.0; extra == "ai"
|
|
34
|
-
Provides-Extra: test
|
|
35
|
-
Requires-Dist: pytest>=8.0.0; extra == "test"
|
|
36
|
-
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
|
|
37
|
-
Requires-Dist: allure-pytest>=2.13.0; extra == "test"
|
|
38
|
-
Provides-Extra: dev
|
|
39
|
-
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
40
|
-
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
41
|
-
Requires-Dist: twine>=4.0.0; extra == "dev"
|
|
42
|
-
Requires-Dist: build>=0.10.0; extra == "dev"
|
|
43
|
-
Provides-Extra: ios
|
|
44
|
-
Requires-Dist: tidevice>=0.11.0; extra == "ios"
|
|
45
|
-
Requires-Dist: facebook-wda>=1.4.0; extra == "ios"
|
|
46
|
-
Provides-Extra: h5
|
|
47
|
-
Requires-Dist: Appium-Python-Client>=3.0.0; extra == "h5"
|
|
48
|
-
Requires-Dist: selenium>=4.0.0; extra == "h5"
|
|
49
34
|
Provides-Extra: all
|
|
50
35
|
Requires-Dist: dashscope>=1.10.0; extra == "all"
|
|
51
36
|
Requires-Dist: openai>=1.0.0; extra == "all"
|
|
@@ -55,19 +40,21 @@ Requires-Dist: selenium>=4.0.0; extra == "all"
|
|
|
55
40
|
Requires-Dist: pytest>=8.0.0; extra == "all"
|
|
56
41
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "all"
|
|
57
42
|
Requires-Dist: allure-pytest>=2.13.0; extra == "all"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
43
|
+
Provides-Extra: dev
|
|
44
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
45
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
46
|
+
Requires-Dist: twine>=4.0.0; extra == "dev"
|
|
47
|
+
Requires-Dist: build>=0.10.0; extra == "dev"
|
|
48
|
+
Provides-Extra: h5
|
|
49
|
+
Requires-Dist: Appium-Python-Client>=3.0.0; extra == "h5"
|
|
50
|
+
Requires-Dist: selenium>=4.0.0; extra == "h5"
|
|
51
|
+
Provides-Extra: ios
|
|
52
|
+
Requires-Dist: tidevice>=0.11.0; extra == "ios"
|
|
53
|
+
Requires-Dist: facebook-wda>=1.4.0; extra == "ios"
|
|
54
|
+
Provides-Extra: test
|
|
55
|
+
Requires-Dist: pytest>=8.0.0; extra == "test"
|
|
56
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
|
|
57
|
+
Requires-Dist: allure-pytest>=2.13.0; extra == "test"
|
|
71
58
|
|
|
72
59
|
# 📱 Mobile MCP AI
|
|
73
60
|
|
|
@@ -408,10 +395,18 @@ tidevice list
|
|
|
408
395
|
|:---:|------|------|
|
|
409
396
|
| 📋 | `mobile_list_elements` | 列出页面元素 |
|
|
410
397
|
| 📸 | `mobile_take_screenshot` | 截图 |
|
|
398
|
+
| 📸 | `mobile_screenshot_with_som` | Set-of-Mark 截图(智能标注) |
|
|
399
|
+
| 📸 | `mobile_screenshot_with_grid` | 带网格坐标的截图 |
|
|
411
400
|
| 📐 | `mobile_get_screen_size` | 屏幕尺寸 |
|
|
412
401
|
| 👆 | `mobile_click_by_text` | 文本点击 |
|
|
413
402
|
| 👆 | `mobile_click_by_id` | ID 点击 |
|
|
414
403
|
| 👆 | `mobile_click_at_coords` | 坐标点击 |
|
|
404
|
+
| 👆 | `mobile_click_by_percent` | 百分比点击 |
|
|
405
|
+
| 👆 | `mobile_click_by_som` | SoM 编号点击 |
|
|
406
|
+
| 👆 | `mobile_long_press_by_id` | ID 长按 |
|
|
407
|
+
| 👆 | `mobile_long_press_by_text` | 文本长按 |
|
|
408
|
+
| 👆 | `mobile_long_press_by_percent` | 百分比长按 |
|
|
409
|
+
| 👆 | `mobile_long_press_at_coords` | 坐标长按 |
|
|
415
410
|
| ⌨️ | `mobile_input_text_by_id` | ID 输入 |
|
|
416
411
|
| ⌨️ | `mobile_input_at_coords` | 坐标输入 |
|
|
417
412
|
| 👆 | `mobile_swipe` | 滑动 |
|
|
@@ -422,6 +417,11 @@ tidevice list
|
|
|
422
417
|
| 📦 | `mobile_list_apps` | 列出应用 |
|
|
423
418
|
| 📱 | `mobile_list_devices` | 列出设备 |
|
|
424
419
|
| 🔌 | `mobile_check_connection` | 检查连接 |
|
|
420
|
+
| 🔍 | `mobile_find_close_button` | 查找关闭按钮 |
|
|
421
|
+
| 🚫 | `mobile_close_popup` | 关闭弹窗 |
|
|
422
|
+
| 🚫 | `mobile_close_ad` | 智能关闭广告弹窗 |
|
|
423
|
+
| 🎯 | `mobile_template_close` | 模板匹配关闭弹窗 |
|
|
424
|
+
| ➕ | `mobile_template_add` | 添加 X 号模板 |
|
|
425
425
|
| ✅ | `mobile_assert_text` | 断言文本 |
|
|
426
426
|
| 📜 | `mobile_get_operation_history` | 操作历史 |
|
|
427
427
|
| 🗑️ | `mobile_clear_operation_history` | 清空历史 |
|
|
@@ -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=
|
|
4
|
+
mobile_mcp/core/basic_tools_lite.py,sha256=BgzErXm0jfYaVK8Se8vCvMXqCudEnUYWI3yivyzxktg,152356
|
|
5
5
|
mobile_mcp/core/device_manager.py,sha256=PX3-B5bJFnKNt6C8fT7FSY8JwD-ngZ3toF88bcOV9qA,8766
|
|
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=PvKXImfN9Irru3bQJUjf4FLGn8LjY2VLzUNEl-i7xLE,8601
|
|
21
21
|
mobile_mcp/mcp_tools/__init__.py,sha256=xkro8Rwqv_55YlVyhh-3DgRFSsLE3h1r31VIb3bpM6E,143
|
|
22
|
-
mobile_mcp/mcp_tools/mcp_server.py,sha256=
|
|
22
|
+
mobile_mcp/mcp_tools/mcp_server.py,sha256=XP4nWbeNW0jM7QFvUiQ1DM0CU3UMW8Do8uxwRLAARYc,49527
|
|
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.5.
|
|
28
|
-
mobile_mcp_ai-2.5.
|
|
29
|
-
mobile_mcp_ai-2.5.
|
|
30
|
-
mobile_mcp_ai-2.5.
|
|
31
|
-
mobile_mcp_ai-2.5.
|
|
32
|
-
mobile_mcp_ai-2.5.
|
|
27
|
+
mobile_mcp_ai-2.5.6.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
28
|
+
mobile_mcp_ai-2.5.6.dist-info/METADATA,sha256=dd3JeAJ-53sZNKzN9-ga11MFJ8rf4YF9Cb8RX6fYq64,10213
|
|
29
|
+
mobile_mcp_ai-2.5.6.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
30
|
+
mobile_mcp_ai-2.5.6.dist-info/entry_points.txt,sha256=KB_FglozgPHBprSM1vFbIzGyheFuHFmGanscRdMJ_8A,68
|
|
31
|
+
mobile_mcp_ai-2.5.6.dist-info/top_level.txt,sha256=lLm6YpbTv855Lbh8BIA0rPxhybIrvYUzMEk9OErHT94,11
|
|
32
|
+
mobile_mcp_ai-2.5.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|