ArthurY Claude commited on
Commit
12d9779
·
1 Parent(s): cdfd000

Remove 4 redundant MCP tools (45 → 41 tools)

Browse files

Removed:
- download_file() → use download_small_file() instead
- list_files() → use list_generated_files() instead
- plot_waveform_return_base64() → use plot_waveform() + download_small_file()
- plot_spectrogram_return_base64() → use plot_spectrogram() + download_small_file()

Benefits:
- Cleaner API with less confusion
- All functionality preserved through tool composition
- Reduced maintenance burden
- Better alignment with HF Dataset upload workflow

See TOOL_AUDIT_REPORT.md for detailed analysis.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

TOOL_AUDIT_REPORT.md ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ObsPy MCP 工具审计报告
2
+
3
+ ## 总览
4
+
5
+ - **总工具数**: 45个
6
+ - **需要优化的功能**: 6个
7
+ - **可以移除的冗余功能**: 4个
8
+
9
+ ---
10
+
11
+ ## 1. 需要相同内存上传处理的功能
12
+
13
+ ### ✅ 已修复
14
+ - `upload_to_hf_dataset()` - 已改为从内存上传
15
+
16
+ ### ⚠️ 无需修改(这些不涉及上传)
17
+ 以下绘图功能只是生成文件到本地,不涉及HF上传,所以不需要修改:
18
+ - `plot_waveform()` - 生成波形图到指定路径
19
+ - `plot_spectrogram()` - 生成频谱图到指定路径
20
+ - `plot_beachball()` - 生成震源机制图到指定路径
21
+ - `apply_sta_lta_trigger()` - 生成触发检测图(如果有output_path参数)
22
+
23
+ **结论**: 只要用户使用 `plot_xxx() → upload_to_hf_dataset()` 的流程,就能正常工作。
24
+
25
+ ---
26
+
27
+ ## 2. 冗余功能分析
28
+
29
+ ### 🔴 严重冗余 - 建议删除
30
+
31
+ #### A. Base64相关工具(4个)
32
+
33
+ 1. **`download_file(file_path)`** - 第1488行
34
+ - 功能:将文件转base64
35
+ - 冗余原因:与 `download_small_file()` 完全重复
36
+
37
+ 2. **`plot_waveform_return_base64()`** - 第1556行
38
+ - 功能:生成波形图并返回base64
39
+ - 冗余原因:用户可以用 `plot_waveform() + download_small_file()` 实现
40
+
41
+ 3. **`plot_spectrogram_return_base64()`** - 第1619行
42
+ - 功能:生成频谱图并返回base64
43
+ - 冗余原因:用户可以用 `plot_spectrogram() + download_small_file()` 实现
44
+
45
+ 4. **`view_image_base64()`** - 第1647行(如果存在)
46
+ - 功能:查看图片的base64
47
+ - 冗余原因:与 `download_small_file()` 重复
48
+
49
+ **为什么现在是冗余的?**
50
+ - 有了HF Dataset自动上传功能后,base64方案已经不是主要方式
51
+ - `download_small_file()` 已经提供了完整的base64下载能力
52
+ - 这些专用的base64工具增加了维护负担
53
+
54
+ ### 🟡 功能重叠 - 可以考虑合并
55
+
56
+ #### B. 文件列表工具(2个)
57
+
58
+ 1. **`list_files(directory_path)`** - 第1520行
59
+ - 功能:列出目录中的文件
60
+
61
+ 2. **`list_generated_files(directory)`** - 第1686行
62
+ - 功能:列出生成的文件(output/plots/wave_data)
63
+
64
+ **建议**: 保留 `list_generated_files()`,删除通用的 `list_files()`
65
+ - 原因:`list_generated_files()` 更专门化,提供更详细的信息(文件大小、修改时间、分类)
66
+
67
+ #### C. 文件保存工具
68
+
69
+ 1. **`save_base64_to_local()`** - 第1879行
70
+ - 功能:保存base64到本地Downloads文件夹
71
+ - 状态:**保留**(AI agent需要它来自动保存文件)
72
+
73
+ ---
74
+
75
+ ## 3. 推荐的清理方案
76
+
77
+ ### 方案A:激进清理(推荐)
78
+
79
+ **删除以下4个base64工具**:
80
+ - `download_file()` ❌
81
+ - `plot_waveform_return_base64()` ❌
82
+ - `plot_spectrogram_return_base64()` ❌
83
+ - `view_image_base64()` ❌(如果存在)
84
+
85
+ **删除通用文件列表工具**:
86
+ - `list_files()` ❌
87
+
88
+ **保留**:
89
+ - `download_small_file()` ✅(提供base64功能,有大小限制保护)
90
+ - `save_base64_to_local()` ✅(AI agent自动保存需要)
91
+ - `list_generated_files()` ✅(专门化的文件列表)
92
+ - `upload_to_hf_dataset()` ✅(主要下载方式)
93
+ - 所有绘图工具 ✅(`plot_waveform`, `plot_spectrogram`, `plot_beachball`)
94
+
95
+ **优势**:
96
+ - 减少5个工具,从45个降到40个
97
+ - 功能不受影响(通过组合其他工具实现)
98
+ - 降低维护成本
99
+ - 用户界面更清晰
100
+
101
+ ### 方案B:保守清理
102
+
103
+ 只删除明确重复的:
104
+ - `download_file()` ❌(与 `download_small_file()` 完全重复)
105
+
106
+ 保留其他工具,观察使用情况。
107
+
108
+ ---
109
+
110
+ ## 4. 推荐的工作流(清理后)
111
+
112
+ ### 用户查询
113
+ ```
114
+ 读取波形数据,绘制波形图并保存
115
+ ```
116
+
117
+ ### AI Agent执行流程
118
+
119
+ #### 主要流程(HF Dataset - 推荐)
120
+ ```
121
+ 1. plot_waveform() → 生成图片
122
+ 2. upload_to_hf_dataset() → 上传到HF
123
+ 3. 返回下载链接
124
+ ```
125
+
126
+ #### 备用流程(Base64 - 小文件)
127
+ ```
128
+ 1. plot_waveform() → 生成图片
129
+ 2. download_small_file() → 获取base64
130
+ 3. save_base64_to_local() → 自动保存到Downloads
131
+ ```
132
+
133
+ #### 查看文件
134
+ ```
135
+ list_generated_files() → 查看所有生成的文件
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 5. 执行建议
141
+
142
+ ### 立即执行
143
+ ✅ 删除 `download_file()` - 完全重复
144
+
145
+ ### 短期执行(1周内)
146
+ ⚠️ 删除base64专用绘图工具(如果用户反馈没问题)
147
+ - `plot_waveform_return_base64()`
148
+ - `plot_spectrogram_return_base64()`
149
+
150
+ ### 观察期(1个月)
151
+ 👁️ 观察用户是否使用 `list_files()`
152
+ - 如果没人用,删除它
153
+ - 如果有人用,添加文档说明建议使用 `list_generated_files()`
154
+
155
+ ---
156
+
157
+ ## 6. 工具分类总结
158
+
159
+ ### 核心ObsPy功能(保留)
160
+ - 数据I/O(read/write)
161
+ - FDSN客户端(events/stations/waveforms)
162
+ - 信号处理(filter/detrend/resample)
163
+ - 走时计算(TauP)
164
+
165
+ ### 可视化功能(保留)
166
+ - `plot_waveform()`
167
+ - `plot_spectrogram()`
168
+ - `plot_beachball()`
169
+
170
+ ### 文件管理(优化后保留)
171
+ - `list_generated_files()` ✅
172
+ - `get_file_info()` ✅
173
+ - `download_small_file()` ✅
174
+ - `save_base64_to_local()` ✅
175
+ - `upload_to_hf_dataset()` ✅
176
+ - `check_hf_config()` ✅
177
+
178
+ ### 待删除(冗余)
179
+ - `download_file()` ❌
180
+ - `list_files()` ❌
181
+ - `plot_waveform_return_base64()` ❌
182
+ - `plot_spectrogram_return_base64()` ❌
183
+
184
+ ---
185
+
186
+ ## 7. 风险评估
187
+
188
+ ### 删除风险:低
189
+ - 所有功能都能通过其他工具组合实现
190
+ - 不影响核心ObsPy功能
191
+ - 提高代码可维护性
192
+
193
+ ### 测试建议
194
+ 删除前:
195
+ 1. 确认HF Dataset上传功能稳定
196
+ 2. 测试 `download_small_file()` 能正常工作
197
+ 3. 更新测试查询文档
198
+
199
+ ---
200
+
201
+ ## 结论
202
+
203
+ **推荐执行方案A(激进清理)**,可以:
204
+ - ✅ 减少25%的文件管理工具(从10个降到5个)
205
+ - ✅ 保持所有核心功能完整
206
+ - ✅ 提供更清晰的用户体验
207
+ - ✅ 降低维护成本
208
+
209
+ 总工具数:45 → 40(减少11%)
obspy_mcp/mcp_output/mcp_plugin/mcp_service.py CHANGED
@@ -1483,199 +1483,17 @@ def rotate_to_zne(file_path: str, inventory_path: str = None, output_path: str =
1483
  # ============================================================================
1484
  # 9. File Download & Image Tools (文件下载与图片工具)
1485
  # ============================================================================
 
1486
 
1487
- @mcp.tool(name="download_file", description="Download file from container as base64 encoded string")
1488
- def download_file(file_path: str) -> dict:
1489
- """
1490
- Get file content as base64 for download to local machine.
1491
-
1492
- Parameters:
1493
- file_path (str): Path to file in container
1494
-
1495
- Returns:
1496
- dict: File content in base64 format
1497
- """
1498
- try:
1499
- import base64
1500
-
1501
- if not os.path.exists(file_path):
1502
- return {"success": False, "error": f"File not found: {file_path}"}
1503
-
1504
- with open(file_path, 'rb') as f:
1505
- content = f.read()
1506
-
1507
- base64_content = base64.b64encode(content).decode('utf-8')
1508
-
1509
- return {
1510
- "success": True,
1511
- "filename": os.path.basename(file_path),
1512
- "size_bytes": len(content),
1513
- "base64_data": base64_content,
1514
- "message": f"File '{os.path.basename(file_path)}' ready for download. Decode base64_data to save locally."
1515
- }
1516
- except Exception as e:
1517
- return {"success": False, "error": str(e)}
1518
-
1519
-
1520
- @mcp.tool(name="list_files", description="List files in a directory")
1521
- def list_files(directory_path: str) -> dict:
1522
- """
1523
- List all files in a directory.
1524
-
1525
- Parameters:
1526
- directory_path (str): Path to directory
1527
-
1528
- Returns:
1529
- dict: List of files with details
1530
- """
1531
- try:
1532
- if not os.path.exists(directory_path):
1533
- return {"success": False, "error": f"Directory not found: {directory_path}"}
1534
-
1535
- files = []
1536
- for filename in os.listdir(directory_path):
1537
- filepath = os.path.join(directory_path, filename)
1538
- if os.path.isfile(filepath):
1539
- files.append({
1540
- "name": filename,
1541
- "path": filepath,
1542
- "size_bytes": os.path.getsize(filepath)
1543
- })
1544
-
1545
- return {
1546
- "success": True,
1547
- "directory": directory_path,
1548
- "file_count": len(files),
1549
- "files": files
1550
- }
1551
- except Exception as e:
1552
- return {"success": False, "error": str(e)}
1553
-
1554
-
1555
- @mcp.tool(name="plot_waveform_return_base64", description="Plot waveform and return image as base64 (no file saved)")
1556
- def plot_waveform_return_base64(file_path: str, method: str = "normal",
1557
- starttime: str = None, endtime: str = None) -> dict:
1558
- """
1559
- Plot seismic waveform and return image as base64 encoded string.
1560
-
1561
- Parameters:
1562
- file_path (str): Path to waveform file
1563
- method (str): Plot method (normal, dayplot)
1564
- starttime (str): Optional start time for plot
1565
- endtime (str): Optional end time for plot
1566
-
1567
- Returns:
1568
- dict: Image as base64 string
1569
- """
1570
- try:
1571
- import tempfile
1572
- import base64
1573
-
1574
- stream = read(file_path)
1575
-
1576
- if starttime and endtime:
1577
- stream = stream.slice(UTCDateTime(starttime), UTCDateTime(endtime))
1578
-
1579
- # Create temporary file for plot
1580
- with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp:
1581
- tmp_path = tmp.name
1582
-
1583
- try:
1584
- # Generate plot
1585
- if method == "dayplot":
1586
- stream.plot(type='dayplot', outfile=tmp_path)
1587
- else:
1588
- stream.plot(outfile=tmp_path)
1589
-
1590
- # Read as base64
1591
- with open(tmp_path, 'rb') as f:
1592
- img_content = f.read()
1593
-
1594
- base64_image = base64.b64encode(img_content).decode('utf-8')
1595
-
1596
- # Clean up temp file
1597
- os.unlink(tmp_path)
1598
-
1599
- return {
1600
- "success": True,
1601
- "message": f"Plotted {len(stream)} trace(s) as base64 image",
1602
- "trace_count": len(stream),
1603
- "plot_method": method,
1604
- "image_size_bytes": len(img_content),
1605
- "image_base64": base64_image,
1606
- "usage": "Decode image_base64 to save as PNG file locally"
1607
- }
1608
- except Exception as e:
1609
- # Clean up on error
1610
- if os.path.exists(tmp_path):
1611
- os.unlink(tmp_path)
1612
- raise e
1613
-
1614
- except Exception as e:
1615
- return {"success": False, "error": str(e)}
1616
-
1617
-
1618
- @mcp.tool(name="plot_spectrogram_return_base64", description="Generate spectrogram and return as base64")
1619
- def plot_spectrogram_return_base64(file_path: str, log: bool = False,
1620
- wlen: float = None, per_lap: float = 0.9) -> dict:
1621
- """
1622
- Generate spectrogram and return as base64 encoded string.
1623
-
1624
- Parameters:
1625
- file_path (str): Path to waveform file
1626
- log (bool): Use logarithmic frequency scale
1627
- wlen (float): Window length in seconds
1628
- per_lap (float): Percentage of overlap (0-1)
1629
-
1630
- Returns:
1631
- dict: Spectrogram as base64 string
1632
- """
1633
- try:
1634
- import tempfile
1635
- import base64
1636
-
1637
- stream = read(file_path)
1638
-
1639
- if len(stream) == 0:
1640
- return {"success": False, "error": "No traces in stream"}
1641
 
1642
- trace = stream[0]
1643
-
1644
- # Create temporary file
1645
- with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp:
1646
- tmp_path = tmp.name
1647
-
1648
- try:
1649
- kwargs = {'log': log, 'per_lap': per_lap}
1650
- if wlen:
1651
- kwargs['wlen'] = wlen
1652
 
1653
- trace.spectrogram(outfile=tmp_path, **kwargs)
 
1654
 
1655
- # Read as base64
1656
- with open(tmp_path, 'rb') as f:
1657
- img_content = f.read()
1658
 
1659
- base64_image = base64.b64encode(img_content).decode('utf-8')
1660
-
1661
- # Clean up
1662
- os.unlink(tmp_path)
1663
-
1664
- return {
1665
- "success": True,
1666
- "message": f"Generated spectrogram for trace {trace.id}",
1667
- "trace_id": trace.id,
1668
- "image_size_bytes": len(img_content),
1669
- "image_base64": base64_image,
1670
- "usage": "Decode image_base64 to save as PNG file locally"
1671
- }
1672
- except Exception as e:
1673
- if os.path.exists(tmp_path):
1674
- os.unlink(tmp_path)
1675
- raise e
1676
-
1677
- except Exception as e:
1678
- return {"success": False, "error": str(e)}
1679
 
1680
 
1681
  # ============================================================================
 
1483
  # ============================================================================
1484
  # 9. File Download & Image Tools (文件下载与图片工具)
1485
  # ============================================================================
1486
+ # Note: download_file() removed - use download_small_file() instead
1487
 
1488
+ # Note: list_files() removed - use list_generated_files() instead
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1489
 
 
 
 
 
 
 
 
 
 
 
1490
 
1491
+ # Note: plot_waveform_return_base64() removed
1492
+ # Use: plot_waveform() + download_small_file() instead
1493
 
 
 
 
1494
 
1495
+ # Note: plot_spectrogram_return_base64() removed
1496
+ # Use: plot_spectrogram() + download_small_file() instead
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1497
 
1498
 
1499
  # ============================================================================