solidworks-mcp-python 1.5.0__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.
- solidworks_mcp/__init__.py +57 -0
- solidworks_mcp/adapters/__init__.py +40 -0
- solidworks_mcp/adapters/base.py +1882 -0
- solidworks_mcp/adapters/circuit_breaker.py +2052 -0
- solidworks_mcp/adapters/com_executor.py +252 -0
- solidworks_mcp/adapters/complexity_analyzer.py +272 -0
- solidworks_mcp/adapters/connection_pool.py +1884 -0
- solidworks_mcp/adapters/factory.py +366 -0
- solidworks_mcp/adapters/intelligent_router.py +218 -0
- solidworks_mcp/adapters/mock_adapter.py +4016 -0
- solidworks_mcp/adapters/pywin32_adapter.py +2842 -0
- solidworks_mcp/adapters/solidworks/__init__.py +17 -0
- solidworks_mcp/adapters/solidworks/bitmap.py +180 -0
- solidworks_mcp/adapters/solidworks/com_utils.py +56 -0
- solidworks_mcp/adapters/solidworks/dimension_layout.py +753 -0
- solidworks_mcp/adapters/solidworks/documentation.py +1476 -0
- solidworks_mcp/adapters/solidworks/drawing_standard.py +1993 -0
- solidworks_mcp/adapters/solidworks/face_selection.py +392 -0
- solidworks_mcp/adapters/solidworks/features.py +3362 -0
- solidworks_mcp/adapters/solidworks/io.py +3649 -0
- solidworks_mcp/adapters/solidworks/rebuild_diagnostics.py +269 -0
- solidworks_mcp/adapters/solidworks/rebuild_inspector.py +146 -0
- solidworks_mcp/adapters/solidworks/selection.py +308 -0
- solidworks_mcp/adapters/solidworks/sketch.py +2545 -0
- solidworks_mcp/adapters/sw_feature_errors.py +66 -0
- solidworks_mcp/adapters/sw_type_info.py +317 -0
- solidworks_mcp/adapters/vba_adapter.py +318 -0
- solidworks_mcp/adapters/vba_macro_executor.py +215 -0
- solidworks_mcp/agents/__init__.py +68 -0
- solidworks_mcp/agents/design_knowledge/assembly_patterns.md +127 -0
- solidworks_mcp/agents/design_knowledge/hinges.md +118 -0
- solidworks_mcp/agents/design_knowledge/snap_fits.md +93 -0
- solidworks_mcp/agents/design_knowledge/solidworks_basics.md +3 -0
- solidworks_mcp/agents/design_knowledge/tolerancing.md +128 -0
- solidworks_mcp/agents/harness.py +216 -0
- solidworks_mcp/agents/history_db.py +1508 -0
- solidworks_mcp/agents/retrieval_index.py +164 -0
- solidworks_mcp/agents/schemas.py +165 -0
- solidworks_mcp/agents/smoke_test.py +285 -0
- solidworks_mcp/agents/soc_exporter.py +650 -0
- solidworks_mcp/agents/soc_pickup.py +332 -0
- solidworks_mcp/agents/soc_rewind.py +221 -0
- solidworks_mcp/agents/vector_rag.py +665 -0
- solidworks_mcp/cache/__init__.py +5 -0
- solidworks_mcp/cache/response_cache.py +164 -0
- solidworks_mcp/config.py +729 -0
- solidworks_mcp/exceptions.py +37 -0
- solidworks_mcp/security/__init__.py +68 -0
- solidworks_mcp/security/auth.py +128 -0
- solidworks_mcp/security/cors.py +27 -0
- solidworks_mcp/security/rate_limiting.py +90 -0
- solidworks_mcp/security/runtime.py +155 -0
- solidworks_mcp/server.py +777 -0
- solidworks_mcp/server_cli_fixed.py +120 -0
- solidworks_mcp/setup/__init__.py +1 -0
- solidworks_mcp/setup/cli.py +399 -0
- solidworks_mcp/setup/clients.py +157 -0
- solidworks_mcp/setup/config_file.py +230 -0
- solidworks_mcp/setup/handshake.py +202 -0
- solidworks_mcp/setup/launcher.py +102 -0
- solidworks_mcp/setup/legacy.py +100 -0
- solidworks_mcp/setup/registration.py +193 -0
- solidworks_mcp/setup/solidworks.py +49 -0
- solidworks_mcp/tools/__init__.py +64 -0
- solidworks_mcp/tools/analysis.py +723 -0
- solidworks_mcp/tools/automation.py +578 -0
- solidworks_mcp/tools/docs_discovery.py +1476 -0
- solidworks_mcp/tools/drawing.py +1015 -0
- solidworks_mcp/tools/drawing_analysis.py +456 -0
- solidworks_mcp/tools/drawing_automation.py +627 -0
- solidworks_mcp/tools/engineering_data.py +466 -0
- solidworks_mcp/tools/error_classifier.py +232 -0
- solidworks_mcp/tools/export.py +833 -0
- solidworks_mcp/tools/file_facts.py +40 -0
- solidworks_mcp/tools/file_management.py +1473 -0
- solidworks_mcp/tools/input_compat.py +17 -0
- solidworks_mcp/tools/macro_recording.py +464 -0
- solidworks_mcp/tools/modeling.py +2360 -0
- solidworks_mcp/tools/sketching.py +1422 -0
- solidworks_mcp/tools/template_management.py +367 -0
- solidworks_mcp/tools/tool_boundary.py +280 -0
- solidworks_mcp/tools/vba_generation.py +1145 -0
- solidworks_mcp/ui/__init__.py +9 -0
- solidworks_mcp/ui/local_llm.py +725 -0
- solidworks_mcp/ui/routers/__init__.py +10 -0
- solidworks_mcp/ui/routers/checkpoint.py +24 -0
- solidworks_mcp/ui/routers/docs.py +47 -0
- solidworks_mcp/ui/routers/llm.py +83 -0
- solidworks_mcp/ui/routers/local_model.py +69 -0
- solidworks_mcp/ui/routers/model.py +75 -0
- solidworks_mcp/ui/routers/preview.py +38 -0
- solidworks_mcp/ui/routers/session.py +161 -0
- solidworks_mcp/ui/routers/viewer.py +154 -0
- solidworks_mcp/ui/schemas.py +502 -0
- solidworks_mcp/ui/server.py +298 -0
- solidworks_mcp/ui/service.py +481 -0
- solidworks_mcp/ui/services/__init__.py +136 -0
- solidworks_mcp/ui/services/_utils.py +958 -0
- solidworks_mcp/ui/services/checkpoint_service.py +1110 -0
- solidworks_mcp/ui/services/docs_service.py +282 -0
- solidworks_mcp/ui/services/llm_service.py +956 -0
- solidworks_mcp/ui/services/model_service.py +459 -0
- solidworks_mcp/ui/services/parameter_repair_service.py +314 -0
- solidworks_mcp/ui/services/preview_service.py +489 -0
- solidworks_mcp/ui/services/session_service.py +1389 -0
- solidworks_mcp/utils/__init__.py +9 -0
- solidworks_mcp/utils/feature_tree_classifier.py +342 -0
- solidworks_mcp/utils/logging.py +76 -0
- solidworks_mcp/utils/validation.py +77 -0
- solidworks_mcp/version.py +8 -0
- solidworks_mcp_python-1.5.0.dist-info/METADATA +410 -0
- solidworks_mcp_python-1.5.0.dist-info/RECORD +115 -0
- solidworks_mcp_python-1.5.0.dist-info/WHEEL +4 -0
- solidworks_mcp_python-1.5.0.dist-info/entry_points.txt +3 -0
- solidworks_mcp_python-1.5.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
"""Export tools for SolidWorks MCP Server.
|
|
2
|
+
|
|
3
|
+
Provides tools for exporting SolidWorks models to various formats including STEP, IGES,
|
|
4
|
+
STL, PDF, DWG, and image formats.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, TypeVar
|
|
8
|
+
|
|
9
|
+
from fastmcp import FastMCP
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
from ..adapters.base import SolidWorksAdapter
|
|
13
|
+
from .input_compat import CompatInput
|
|
14
|
+
from .tool_boundary import (
|
|
15
|
+
UnsupportedOperationError,
|
|
16
|
+
normalize_input,
|
|
17
|
+
require_capability,
|
|
18
|
+
require_success,
|
|
19
|
+
with_tool_boundary,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
TInput = TypeVar("TInput", bound=BaseModel)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Input schemas using Python 3.14 built-in types
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ExportFileInput(CompatInput):
|
|
29
|
+
"""Input schema for exporting files.
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
file_path (str): The file path value.
|
|
33
|
+
format_type (str): The format type value.
|
|
34
|
+
options (dict[str, Any] | None): The options value.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
file_path: str = Field(description="Full path for the exported file")
|
|
38
|
+
format_type: str = Field(
|
|
39
|
+
description="Export format (step, iges, stl, pdf, dwg, jpg, png)"
|
|
40
|
+
)
|
|
41
|
+
options: dict[str, Any] | None = Field(
|
|
42
|
+
default=None, description="Format-specific export options"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ExportImageInput(CompatInput):
|
|
47
|
+
"""Input schema for exporting images.
|
|
48
|
+
|
|
49
|
+
Attributes:
|
|
50
|
+
file_path (str | None): The file path value.
|
|
51
|
+
format (str | None): The format value.
|
|
52
|
+
format_type (str): The format type value.
|
|
53
|
+
height (int): The height value.
|
|
54
|
+
image_format (str | None): The image format value.
|
|
55
|
+
model_path (str | None): The model path value.
|
|
56
|
+
orientation (str | None): The orientation value.
|
|
57
|
+
output_path (str | None): The output path value.
|
|
58
|
+
resolution (str | None): The resolution value.
|
|
59
|
+
view_orientation (str): The view orientation value.
|
|
60
|
+
width (int): The width value.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
file_path: str | None = Field(
|
|
64
|
+
default=None, description="Full path for the exported image"
|
|
65
|
+
)
|
|
66
|
+
output_path: str | None = Field(default=None, description="Alternative output path")
|
|
67
|
+
model_path: str | None = Field(default=None, description="Path to the model file")
|
|
68
|
+
format_type: str = Field(
|
|
69
|
+
default="jpg", description="Image format (jpg, png, bmp, tiff)"
|
|
70
|
+
)
|
|
71
|
+
format: str | None = Field(default=None, description="Alternative format field")
|
|
72
|
+
image_format: str | None = Field(default=None, description="Image format alias")
|
|
73
|
+
width: int = Field(default=1920, description="Image width in pixels")
|
|
74
|
+
height: int = Field(default=1080, description="Image height in pixels")
|
|
75
|
+
resolution: str | None = Field(default=None, description="Resolution alias")
|
|
76
|
+
view_orientation: str = Field(
|
|
77
|
+
default="isometric",
|
|
78
|
+
description="View orientation (front, top, right, isometric, current)",
|
|
79
|
+
)
|
|
80
|
+
orientation: str | None = Field(
|
|
81
|
+
default=None, description="Alternative orientation field"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def model_post_init(self, __context: Any) -> None:
|
|
85
|
+
"""Provide model post init support for the export image input.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
__context (Any): The context value.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
None: None.
|
|
92
|
+
"""
|
|
93
|
+
if self.file_path is None:
|
|
94
|
+
self.file_path = self.output_path
|
|
95
|
+
if self.image_format is not None:
|
|
96
|
+
self.format_type = self.image_format.lower()
|
|
97
|
+
if self.resolution and "x" in self.resolution.lower():
|
|
98
|
+
width, height = self.resolution.lower().split("x", 1)
|
|
99
|
+
self.width = int(width)
|
|
100
|
+
self.height = int(height)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ExportSTEPInput(CompatInput):
|
|
104
|
+
"""Input schema for STEP export.
|
|
105
|
+
|
|
106
|
+
Attributes:
|
|
107
|
+
file_path (str | None): The file path value.
|
|
108
|
+
model_path (str | None): The model path value.
|
|
109
|
+
output_path (str | None): The output path value.
|
|
110
|
+
precision (float): The precision value.
|
|
111
|
+
step_version (str | None): The step version value.
|
|
112
|
+
units (str): The units value.
|
|
113
|
+
version (str): The version value.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
file_path: str | None = Field(
|
|
117
|
+
default=None, description="Output file path for STEP file"
|
|
118
|
+
)
|
|
119
|
+
model_path: str | None = Field(default=None, description="Path to the model file")
|
|
120
|
+
output_path: str | None = Field(default=None, description="Alternative output path")
|
|
121
|
+
precision: float = Field(default=0.01, description="Export precision")
|
|
122
|
+
units: str = Field(default="mm", description="Units for export")
|
|
123
|
+
version: str = Field(default="AP214", description="STEP version")
|
|
124
|
+
step_version: str | None = Field(
|
|
125
|
+
default=None, description="Alternative STEP version"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def model_post_init(self, __context: Any) -> None:
|
|
129
|
+
"""Provide model post init support for the export stepinput.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
__context (Any): The context value.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
None: None.
|
|
136
|
+
"""
|
|
137
|
+
if self.file_path is None:
|
|
138
|
+
self.file_path = self.output_path
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class ExportIGESInput(CompatInput):
|
|
142
|
+
"""Input schema for IGES export.
|
|
143
|
+
|
|
144
|
+
Attributes:
|
|
145
|
+
file_path (str | None): The file path value.
|
|
146
|
+
iges_version (str | None): The iges version value.
|
|
147
|
+
model_path (str | None): The model path value.
|
|
148
|
+
output_path (str | None): The output path value.
|
|
149
|
+
precision (float): The precision value.
|
|
150
|
+
surface_type (str): The surface type value.
|
|
151
|
+
units (str): The units value.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
file_path: str | None = Field(
|
|
155
|
+
default=None, description="Output file path for IGES file"
|
|
156
|
+
)
|
|
157
|
+
model_path: str | None = Field(default=None, description="Path to the model file")
|
|
158
|
+
output_path: str | None = Field(default=None, description="Alternative output path")
|
|
159
|
+
precision: float = Field(default=0.01, description="Export precision")
|
|
160
|
+
units: str = Field(default="mm", description="Units for export")
|
|
161
|
+
surface_type: str = Field(default="NURBS", description="Surface type")
|
|
162
|
+
iges_version: str | None = Field(
|
|
163
|
+
default=None, description="Alternative IGES version"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
def model_post_init(self, __context: Any) -> None:
|
|
167
|
+
"""Provide model post init support for the export igesinput.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
__context (Any): The context value.
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
None: None.
|
|
174
|
+
"""
|
|
175
|
+
if self.file_path is None:
|
|
176
|
+
self.file_path = self.output_path
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class ExportSTLInput(CompatInput):
|
|
180
|
+
"""Input schema for STL export.
|
|
181
|
+
|
|
182
|
+
Attributes:
|
|
183
|
+
binary_format (bool): The binary format value.
|
|
184
|
+
file_format (str | None): The file format value.
|
|
185
|
+
file_path (str | None): The file path value.
|
|
186
|
+
format_type (str): The format type value.
|
|
187
|
+
model_path (str | None): The model path value.
|
|
188
|
+
output_path (str | None): The output path value.
|
|
189
|
+
resolution (str): The resolution value.
|
|
190
|
+
units (str): The units value.
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
file_path: str | None = Field(
|
|
194
|
+
default=None, description="Output file path for STL file"
|
|
195
|
+
)
|
|
196
|
+
model_path: str | None = Field(default=None, description="Path to the model file")
|
|
197
|
+
output_path: str | None = Field(default=None, description="Alternative output path")
|
|
198
|
+
resolution: str = Field(
|
|
199
|
+
default="fine", description="Mesh resolution (coarse, fine, custom)"
|
|
200
|
+
)
|
|
201
|
+
binary_format: bool = Field(default=True, description="Use binary STL format")
|
|
202
|
+
format_type: str = Field(default="Binary", description="STL format type")
|
|
203
|
+
file_format: str | None = Field(
|
|
204
|
+
default=None, description="Alternative STL format field"
|
|
205
|
+
)
|
|
206
|
+
units: str = Field(default="mm", description="Units for export")
|
|
207
|
+
|
|
208
|
+
def model_post_init(self, __context: Any) -> None:
|
|
209
|
+
"""Provide model post init support for the export stlinput.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
__context (Any): The context value.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
None: None.
|
|
216
|
+
"""
|
|
217
|
+
if self.file_path is None:
|
|
218
|
+
self.file_path = self.output_path
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class ExportPDFInput(CompatInput):
|
|
222
|
+
"""Input schema for PDF export.
|
|
223
|
+
|
|
224
|
+
Attributes:
|
|
225
|
+
color_mode (str): The color mode value.
|
|
226
|
+
drawing_path (str | None): The drawing path value.
|
|
227
|
+
file_path (str | None): The file path value.
|
|
228
|
+
include_3d (bool): The include 3d value.
|
|
229
|
+
output_path (str | None): The output path value.
|
|
230
|
+
quality (str): The quality value.
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
file_path: str | None = Field(
|
|
234
|
+
default=None, description="Output file path for PDF file"
|
|
235
|
+
)
|
|
236
|
+
drawing_path: str | None = Field(
|
|
237
|
+
default=None, description="Path to the drawing file"
|
|
238
|
+
)
|
|
239
|
+
output_path: str | None = Field(default=None, description="Alternative output path")
|
|
240
|
+
quality: str = Field(default="high", description="PDF quality (low, medium, high)")
|
|
241
|
+
include_3d: bool = Field(default=False, description="Include 3D PDF content")
|
|
242
|
+
color_mode: str = Field(default="Color", description="Color mode")
|
|
243
|
+
|
|
244
|
+
def model_post_init(self, __context: Any) -> None:
|
|
245
|
+
"""Provide model post init support for the export pdfinput.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
__context (Any): The context value.
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
None: None.
|
|
252
|
+
"""
|
|
253
|
+
if self.file_path is None:
|
|
254
|
+
self.file_path = self.output_path
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class ExportDWGInput(CompatInput):
|
|
258
|
+
"""Input schema for DWG export.
|
|
259
|
+
|
|
260
|
+
Attributes:
|
|
261
|
+
autocad_version (str | None): The autocad version value.
|
|
262
|
+
drawing_path (str | None): The drawing path value.
|
|
263
|
+
dwg_version (str): The dwg version value.
|
|
264
|
+
file_path (str | None): The file path value.
|
|
265
|
+
layer_mapping (bool): The layer mapping value.
|
|
266
|
+
output_path (str | None): The output path value.
|
|
267
|
+
units (str): The units value.
|
|
268
|
+
version (str): The version value.
|
|
269
|
+
"""
|
|
270
|
+
|
|
271
|
+
file_path: str | None = Field(
|
|
272
|
+
default=None, description="Output file path for DWG file"
|
|
273
|
+
)
|
|
274
|
+
drawing_path: str | None = Field(
|
|
275
|
+
default=None, description="Path to the drawing file"
|
|
276
|
+
)
|
|
277
|
+
output_path: str | None = Field(default=None, description="Alternative output path")
|
|
278
|
+
version: str = Field(
|
|
279
|
+
default="2018", description="AutoCAD version (2018, 2014, 2010, etc.)"
|
|
280
|
+
)
|
|
281
|
+
autocad_version: str | None = Field(
|
|
282
|
+
default=None, description="AutoCAD version alias"
|
|
283
|
+
)
|
|
284
|
+
units: str = Field(default="mm", description="Units for export")
|
|
285
|
+
dwg_version: str = Field(default="2018", description="DWG version")
|
|
286
|
+
layer_mapping: bool = Field(default=False, description="Enable layer mapping")
|
|
287
|
+
|
|
288
|
+
def model_post_init(self, __context: Any) -> None:
|
|
289
|
+
"""Provide model post init support for the export dwginput.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
__context (Any): The context value.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
None: None.
|
|
296
|
+
"""
|
|
297
|
+
if self.file_path is None:
|
|
298
|
+
self.file_path = self.output_path
|
|
299
|
+
if self.autocad_version is not None:
|
|
300
|
+
self.version = self.autocad_version
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
class BatchExportInput(CompatInput):
|
|
304
|
+
"""Input schema for batch export operations.
|
|
305
|
+
|
|
306
|
+
Attributes:
|
|
307
|
+
export_format (str | None): The export format value.
|
|
308
|
+
file_pattern (str | None): The file pattern value.
|
|
309
|
+
file_patterns (list[str]): The file patterns value.
|
|
310
|
+
format_type (str | None): The format type value.
|
|
311
|
+
include_subdirectories (bool): The include subdirectories value.
|
|
312
|
+
output_directory (str): The output directory value.
|
|
313
|
+
recursive (bool): The recursive value.
|
|
314
|
+
source_directory (str): The source directory value.
|
|
315
|
+
"""
|
|
316
|
+
|
|
317
|
+
source_directory: str = Field(description="Directory containing SolidWorks files")
|
|
318
|
+
output_directory: str = Field(description="Directory for exported files")
|
|
319
|
+
format_type: str | None = Field(default=None, description="Target export format")
|
|
320
|
+
export_format: str | None = Field(
|
|
321
|
+
default=None, description="Alternative export format"
|
|
322
|
+
)
|
|
323
|
+
file_pattern: str | None = Field(default=None, description="File pattern alias")
|
|
324
|
+
recursive: bool = Field(
|
|
325
|
+
default=False, description="Search subdirectories recursively"
|
|
326
|
+
)
|
|
327
|
+
include_subdirectories: bool = Field(
|
|
328
|
+
default=False, description="Include subdirectories in search"
|
|
329
|
+
)
|
|
330
|
+
file_patterns: list[str] = Field(
|
|
331
|
+
default=["*.sldprt", "*.sldasm", "*.slddrw"],
|
|
332
|
+
description="File patterns to include",
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
def model_post_init(self, __context: Any) -> None:
|
|
336
|
+
"""Provide model post init support for the batch export input.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
__context (Any): The context value.
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
None: None.
|
|
343
|
+
"""
|
|
344
|
+
if self.format_type is None:
|
|
345
|
+
self.format_type = self.export_format
|
|
346
|
+
if self.file_pattern:
|
|
347
|
+
self.file_patterns = [self.file_pattern]
|
|
348
|
+
if self.include_subdirectories:
|
|
349
|
+
self.recursive = True
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
async def register_export_tools(
|
|
353
|
+
mcp: FastMCP, adapter: SolidWorksAdapter, config: dict[str, Any]
|
|
354
|
+
) -> int:
|
|
355
|
+
"""Register export tools with FastMCP.
|
|
356
|
+
|
|
357
|
+
Registers comprehensive file export tools for SolidWorks automation supporting multiple
|
|
358
|
+
industry-standard formats including neutral CAD formats, manufacturing formats, and
|
|
359
|
+
documentation outputs.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
mcp (FastMCP): The mcp value.
|
|
363
|
+
adapter (SolidWorksAdapter): Adapter instance used for the operation.
|
|
364
|
+
config (dict[str, Any]): Configuration values for the operation.
|
|
365
|
+
|
|
366
|
+
Returns:
|
|
367
|
+
int: The computed numeric result.
|
|
368
|
+
|
|
369
|
+
Example:
|
|
370
|
+
```python
|
|
371
|
+
from solidworks_mcp.tools.export import register_export_tools
|
|
372
|
+
|
|
373
|
+
tool_count = await register_export_tools(mcp, adapter, config)
|
|
374
|
+
print(f"Registered {tool_count} export tools")
|
|
375
|
+
```
|
|
376
|
+
"""
|
|
377
|
+
mcp = with_tool_boundary(mcp)
|
|
378
|
+
tool_count = 0
|
|
379
|
+
|
|
380
|
+
@mcp.tool()
|
|
381
|
+
async def export_step(input_data: ExportFileInput) -> dict[str, Any]:
|
|
382
|
+
"""Export the current model to STEP format.
|
|
383
|
+
|
|
384
|
+
Exports SolidWorks models to STEP (Standard for the Exchange of Product Data) format,
|
|
385
|
+
the preferred neutral CAD format for interoperability between different CAD systems and
|
|
386
|
+
manufacturers.
|
|
387
|
+
|
|
388
|
+
Args:
|
|
389
|
+
input_data (ExportFileInput): The input data value.
|
|
390
|
+
|
|
391
|
+
Returns:
|
|
392
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
393
|
+
|
|
394
|
+
Example:
|
|
395
|
+
```python
|
|
396
|
+
# Export part to STEP for manufacturing
|
|
397
|
+
result = await export_step({
|
|
398
|
+
"file_path": "C:/Exports/bracket.step",
|
|
399
|
+
"format_type": "step",
|
|
400
|
+
"options": {
|
|
401
|
+
"units": "mm",
|
|
402
|
+
"version": "214",
|
|
403
|
+
"precision": 0.01
|
|
404
|
+
}
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
if result["status"] == "success":
|
|
408
|
+
export = result["export"]
|
|
409
|
+
print(f"STEP file created: {export['file_path']}")
|
|
410
|
+
# Ready for CNC programming or CAM software
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Note:
|
|
414
|
+
- STEP format preserves precise geometric data for manufacturing
|
|
415
|
+
- Most widely supported neutral CAD format in industry
|
|
416
|
+
- Recommended for supplier collaboration and CNC machining
|
|
417
|
+
- Supports assemblies, parts, and surface models
|
|
418
|
+
"""
|
|
419
|
+
if hasattr(input_data, "model_dump"):
|
|
420
|
+
payload = input_data.model_dump()
|
|
421
|
+
file_path = input_data.file_path
|
|
422
|
+
else:
|
|
423
|
+
payload = dict(input_data)
|
|
424
|
+
file_path = str(payload.get("file_path") or "")
|
|
425
|
+
|
|
426
|
+
if hasattr(adapter, "export_step"):
|
|
427
|
+
result = await adapter.export_step(payload)
|
|
428
|
+
else:
|
|
429
|
+
result = await adapter.export_file(file_path, "step")
|
|
430
|
+
|
|
431
|
+
require_success(result, context="Failed to export STEP")
|
|
432
|
+
if hasattr(adapter, "export_step"):
|
|
433
|
+
return {
|
|
434
|
+
"status": "success",
|
|
435
|
+
"message": f"Exported to STEP format: {file_path}",
|
|
436
|
+
"data": result.data,
|
|
437
|
+
"execution_time": result.execution_time,
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
"status": "success",
|
|
441
|
+
"message": f"Exported to STEP format: {file_path}",
|
|
442
|
+
"export": {
|
|
443
|
+
"file_path": file_path,
|
|
444
|
+
"format": "STEP",
|
|
445
|
+
"size_estimate": "Unknown", # Would get actual file size
|
|
446
|
+
},
|
|
447
|
+
"execution_time": result.execution_time,
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
@mcp.tool()
|
|
451
|
+
async def export_iges(input_data: ExportFileInput) -> dict[str, Any]:
|
|
452
|
+
"""Export the current model to IGES format.
|
|
453
|
+
|
|
454
|
+
Exports SolidWorks models to IGES (Initial Graphics Exchange Specification) format, a
|
|
455
|
+
legacy neutral CAD format still widely used for surface modeling and older CAD system
|
|
456
|
+
compatibility.
|
|
457
|
+
|
|
458
|
+
Args:
|
|
459
|
+
input_data (ExportFileInput): The input data value.
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
463
|
+
|
|
464
|
+
Example:
|
|
465
|
+
```python
|
|
466
|
+
# Export surface model for legacy CAD system
|
|
467
|
+
result = await export_iges({
|
|
468
|
+
"file_path": "C:/Exports/surface_model.iges",
|
|
469
|
+
"format_type": "iges",
|
|
470
|
+
"options": {
|
|
471
|
+
"units": "mm",
|
|
472
|
+
"surfaces_only": True,
|
|
473
|
+
"trim_curves": True
|
|
474
|
+
}
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
if result["status"] == "success":
|
|
478
|
+
export = result["export"]
|
|
479
|
+
print(f"IGES file created: {export['file_path']}")
|
|
480
|
+
# Compatible with older CAD/CAM systems
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
Note:
|
|
484
|
+
- IGES format is older but still required for some legacy systems
|
|
485
|
+
- Excellent for surface modeling and complex curve data
|
|
486
|
+
- Use STEP format for newer systems when possible
|
|
487
|
+
- Common in aerospace and automotive surface design
|
|
488
|
+
"""
|
|
489
|
+
if hasattr(adapter, "export_iges"):
|
|
490
|
+
result = await adapter.export_iges(input_data.model_dump())
|
|
491
|
+
else:
|
|
492
|
+
result = await adapter.export_file(input_data.file_path, "iges")
|
|
493
|
+
|
|
494
|
+
require_success(result, context="Failed to export IGES")
|
|
495
|
+
if hasattr(adapter, "export_iges"):
|
|
496
|
+
return {
|
|
497
|
+
"status": "success",
|
|
498
|
+
"message": f"Exported to IGES format: {input_data.file_path}",
|
|
499
|
+
"data": result.data,
|
|
500
|
+
"execution_time": result.execution_time,
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
"status": "success",
|
|
504
|
+
"message": f"Exported to IGES format: {input_data.file_path}",
|
|
505
|
+
"export": {
|
|
506
|
+
"file_path": input_data.file_path,
|
|
507
|
+
"format": "IGES",
|
|
508
|
+
"size_estimate": "Unknown",
|
|
509
|
+
},
|
|
510
|
+
"execution_time": result.execution_time,
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
@mcp.tool()
|
|
514
|
+
async def export_stl(input_data: ExportFileInput) -> dict[str, Any]:
|
|
515
|
+
"""Export the current model to STL format.
|
|
516
|
+
|
|
517
|
+
Exports SolidWorks models to STL (Stereolithography) format, the standard file format
|
|
518
|
+
for 3D printing, rapid prototyping, and additive manufacturing applications.
|
|
519
|
+
|
|
520
|
+
Args:
|
|
521
|
+
input_data (ExportFileInput): The input data value.
|
|
522
|
+
|
|
523
|
+
Returns:
|
|
524
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
525
|
+
|
|
526
|
+
Example:
|
|
527
|
+
```python
|
|
528
|
+
# Export high-resolution STL for 3D printing
|
|
529
|
+
result = await export_stl({
|
|
530
|
+
"file_path": "C:/3DPrint/prototype.stl",
|
|
531
|
+
"format_type": "stl",
|
|
532
|
+
"options": {
|
|
533
|
+
"resolution": "fine",
|
|
534
|
+
"units": "mm",
|
|
535
|
+
"ascii": False,
|
|
536
|
+
"deviation": 0.1
|
|
537
|
+
}
|
|
538
|
+
})
|
|
539
|
+
|
|
540
|
+
if result["status"] == "success":
|
|
541
|
+
export = result["export"]
|
|
542
|
+
print(f"STL ready for 3D printing: {export['file_path']}")
|
|
543
|
+
# Load into slicer software for printing
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
Note:
|
|
547
|
+
- STL format creates triangulated mesh representation
|
|
548
|
+
- Resolution affects both file size and print quality
|
|
549
|
+
- Binary format is more compact than ASCII
|
|
550
|
+
- Essential for 3D printing and rapid prototyping workflows
|
|
551
|
+
"""
|
|
552
|
+
if hasattr(adapter, "export_stl"):
|
|
553
|
+
result = await adapter.export_stl(input_data.model_dump())
|
|
554
|
+
else:
|
|
555
|
+
result = await adapter.export_file(input_data.file_path, "stl")
|
|
556
|
+
|
|
557
|
+
require_success(result, context="Failed to export STL")
|
|
558
|
+
if hasattr(adapter, "export_stl"):
|
|
559
|
+
return {
|
|
560
|
+
"status": "success",
|
|
561
|
+
"message": f"Exported to STL format: {input_data.file_path}",
|
|
562
|
+
"data": result.data,
|
|
563
|
+
"execution_time": result.execution_time,
|
|
564
|
+
}
|
|
565
|
+
return {
|
|
566
|
+
"status": "success",
|
|
567
|
+
"message": f"Exported to STL format: {input_data.file_path}",
|
|
568
|
+
"export": {
|
|
569
|
+
"file_path": input_data.file_path,
|
|
570
|
+
"format": "STL",
|
|
571
|
+
"use_case": "3D printing and rapid prototyping",
|
|
572
|
+
"size_estimate": "Unknown",
|
|
573
|
+
},
|
|
574
|
+
"execution_time": result.execution_time,
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
@mcp.tool()
|
|
578
|
+
async def export_pdf(input_data: ExportFileInput) -> dict[str, Any]:
|
|
579
|
+
"""Export the current model or drawing to PDF format.
|
|
580
|
+
|
|
581
|
+
Creates PDF documents from SolidWorks drawings, assemblies, or parts for documentation,
|
|
582
|
+
sharing, review, and archival purposes. Essential for design review and manufacturing
|
|
583
|
+
documentation.
|
|
584
|
+
|
|
585
|
+
Args:
|
|
586
|
+
input_data (ExportFileInput): The input data value.
|
|
587
|
+
|
|
588
|
+
Returns:
|
|
589
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
590
|
+
|
|
591
|
+
Example:
|
|
592
|
+
```python
|
|
593
|
+
# Export technical drawings to secured PDF
|
|
594
|
+
result = await export_pdf({
|
|
595
|
+
"file_path": "C:/Documentation/assembly_drawing.pdf",
|
|
596
|
+
"format_type": "pdf",
|
|
597
|
+
"options": {
|
|
598
|
+
"quality": "high",
|
|
599
|
+
"sheets": "all",
|
|
600
|
+
"3d_pdf": False,
|
|
601
|
+
"security": {
|
|
602
|
+
"password": "project123",
|
|
603
|
+
"allow_printing": True,
|
|
604
|
+
"allow_editing": False
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
})
|
|
608
|
+
|
|
609
|
+
if result["status"] == "success":
|
|
610
|
+
export = result["export"]
|
|
611
|
+
print(f"PDF documentation: {export['file_path']}")
|
|
612
|
+
# Ready for distribution and review
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
Note:
|
|
616
|
+
- PDF format preserves drawing layout and annotations
|
|
617
|
+
- Ideal for design reviews and manufacturing documentation
|
|
618
|
+
- Can include multiple sheets from drawing files
|
|
619
|
+
- Supports password protection and access controls
|
|
620
|
+
"""
|
|
621
|
+
if hasattr(adapter, "export_pdf"):
|
|
622
|
+
result = await adapter.export_pdf(input_data.model_dump())
|
|
623
|
+
else:
|
|
624
|
+
result = await adapter.export_file(input_data.file_path, "pdf")
|
|
625
|
+
|
|
626
|
+
require_success(result, context="Failed to export PDF")
|
|
627
|
+
if hasattr(adapter, "export_pdf"):
|
|
628
|
+
return {
|
|
629
|
+
"status": "success",
|
|
630
|
+
"message": f"Exported to PDF format: {input_data.file_path}",
|
|
631
|
+
"data": result.data,
|
|
632
|
+
"execution_time": result.execution_time,
|
|
633
|
+
}
|
|
634
|
+
return {
|
|
635
|
+
"status": "success",
|
|
636
|
+
"message": f"Exported to PDF format: {input_data.file_path}",
|
|
637
|
+
"export": {
|
|
638
|
+
"file_path": input_data.file_path,
|
|
639
|
+
"format": "PDF",
|
|
640
|
+
"use_case": "Documentation and sharing",
|
|
641
|
+
"size_estimate": "Unknown",
|
|
642
|
+
},
|
|
643
|
+
"execution_time": result.execution_time,
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
@mcp.tool()
|
|
647
|
+
async def export_dwg(input_data: ExportFileInput) -> dict[str, Any]:
|
|
648
|
+
"""Export the current drawing to DWG format.
|
|
649
|
+
|
|
650
|
+
Converts SolidWorks drawings to DWG (Drawing) format, the native AutoCAD file format
|
|
651
|
+
widely used in architecture, engineering, and construction industries for 2D technical
|
|
652
|
+
drawings.
|
|
653
|
+
|
|
654
|
+
Args:
|
|
655
|
+
input_data (ExportFileInput): The input data value.
|
|
656
|
+
|
|
657
|
+
Returns:
|
|
658
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
659
|
+
|
|
660
|
+
Example:
|
|
661
|
+
```python
|
|
662
|
+
# Export architectural drawings to AutoCAD format
|
|
663
|
+
result = await export_dwg({
|
|
664
|
+
"file_path": "C:/CAD/floor_plan.dwg",
|
|
665
|
+
"format_type": "dwg",
|
|
666
|
+
"options": {
|
|
667
|
+
"version": "2018",
|
|
668
|
+
"units": "mm",
|
|
669
|
+
"layers": True,
|
|
670
|
+
"line_weights": True
|
|
671
|
+
}
|
|
672
|
+
})
|
|
673
|
+
|
|
674
|
+
if result["status"] == "success":
|
|
675
|
+
export = result["export"]
|
|
676
|
+
print(f"AutoCAD file ready: {export['file_path']}")
|
|
677
|
+
# Compatible with AutoCAD and DWG viewers
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
Note:
|
|
681
|
+
- DWG format ensures compatibility with AutoCAD ecosystem
|
|
682
|
+
- Only applicable to SolidWorks drawing files (not 3D models)
|
|
683
|
+
- Version compatibility important for legacy AutoCAD systems
|
|
684
|
+
- Preserves dimensions, annotations, and drawing structure
|
|
685
|
+
"""
|
|
686
|
+
if hasattr(adapter, "export_dwg"):
|
|
687
|
+
result = await adapter.export_dwg(input_data.model_dump())
|
|
688
|
+
else:
|
|
689
|
+
result = await adapter.export_file(input_data.file_path, "dwg")
|
|
690
|
+
|
|
691
|
+
require_success(result, context="Failed to export DWG")
|
|
692
|
+
if hasattr(adapter, "export_dwg"):
|
|
693
|
+
return {
|
|
694
|
+
"status": "success",
|
|
695
|
+
"message": f"Exported to DWG format: {input_data.file_path}",
|
|
696
|
+
"data": result.data,
|
|
697
|
+
"execution_time": result.execution_time,
|
|
698
|
+
}
|
|
699
|
+
return {
|
|
700
|
+
"status": "success",
|
|
701
|
+
"message": f"Exported to DWG format: {input_data.file_path}",
|
|
702
|
+
"export": {
|
|
703
|
+
"file_path": input_data.file_path,
|
|
704
|
+
"format": "DWG",
|
|
705
|
+
"use_case": "AutoCAD compatibility",
|
|
706
|
+
"size_estimate": "Unknown",
|
|
707
|
+
},
|
|
708
|
+
"execution_time": result.execution_time,
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
@mcp.tool()
|
|
712
|
+
async def export_image(input_data: ExportImageInput) -> dict[str, Any]:
|
|
713
|
+
"""Export images of the current model.
|
|
714
|
+
|
|
715
|
+
Captures high-quality rendered images of SolidWorks models from various view
|
|
716
|
+
orientations for documentation, presentations, marketing materials, and web publication.
|
|
717
|
+
|
|
718
|
+
Args:
|
|
719
|
+
input_data (ExportImageInput): The input data value.
|
|
720
|
+
|
|
721
|
+
Returns:
|
|
722
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
723
|
+
|
|
724
|
+
Example:
|
|
725
|
+
```python
|
|
726
|
+
# Create high-res marketing image
|
|
727
|
+
result = await export_images({
|
|
728
|
+
"file_path": "C:/Marketing/product_hero.png",
|
|
729
|
+
"format_type": "png",
|
|
730
|
+
"width": 3840, "height": 2160, # 4K resolution
|
|
731
|
+
"view_orientation": "isometric"
|
|
732
|
+
})
|
|
733
|
+
|
|
734
|
+
if result["status"] == "success":
|
|
735
|
+
export = result["export"]
|
|
736
|
+
print(f"High-res image: {export['dimensions']} {export['format']}")
|
|
737
|
+
# Ready for marketing and presentation use
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
Note:
|
|
741
|
+
- PNG format supports transparency for overlay graphics
|
|
742
|
+
- Higher resolutions create larger file sizes but better quality
|
|
743
|
+
- Isometric views are ideal for technical documentation
|
|
744
|
+
- Consider lighting and material settings for best results
|
|
745
|
+
"""
|
|
746
|
+
input_data = normalize_input(input_data, ExportImageInput)
|
|
747
|
+
if hasattr(adapter, "export_image"):
|
|
748
|
+
result = await adapter.export_image(input_data.model_dump())
|
|
749
|
+
require_success(result, "Failed to export image")
|
|
750
|
+
return {
|
|
751
|
+
"status": "success",
|
|
752
|
+
"message": f"Exported image: {input_data.file_path}",
|
|
753
|
+
"data": result.data,
|
|
754
|
+
"execution_time": result.execution_time,
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if hasattr(adapter, "export_file") and input_data.file_path:
|
|
758
|
+
result = await adapter.export_file( # type: ignore[assignment]
|
|
759
|
+
input_data.file_path, input_data.format_type
|
|
760
|
+
)
|
|
761
|
+
require_success(result, "Failed to export image")
|
|
762
|
+
return {
|
|
763
|
+
"status": "success",
|
|
764
|
+
"message": f"Exported image: {input_data.file_path}",
|
|
765
|
+
"export": {
|
|
766
|
+
"file_path": input_data.file_path,
|
|
767
|
+
"format": input_data.format_type.upper(),
|
|
768
|
+
"dimensions": f"{input_data.width}x{input_data.height}",
|
|
769
|
+
"view": input_data.view_orientation,
|
|
770
|
+
"use_case": "Documentation and presentations",
|
|
771
|
+
},
|
|
772
|
+
"execution_time": result.execution_time,
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
raise UnsupportedOperationError(
|
|
776
|
+
"Active adapter does not support export_image or "
|
|
777
|
+
"export_file; no image was exported."
|
|
778
|
+
)
|
|
779
|
+
|
|
780
|
+
@mcp.tool()
|
|
781
|
+
async def batch_export(input_data: BatchExportInput) -> dict[str, Any]:
|
|
782
|
+
"""Batch export multiple SolidWorks files to a target format.
|
|
783
|
+
|
|
784
|
+
Processes entire directories of SolidWorks files and converts them to specified target
|
|
785
|
+
formats. Essential for project migrations, supplier deliverables, and large-scale format
|
|
786
|
+
conversions.
|
|
787
|
+
|
|
788
|
+
Args:
|
|
789
|
+
input_data (BatchExportInput): The input data value.
|
|
790
|
+
|
|
791
|
+
Returns:
|
|
792
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
793
|
+
|
|
794
|
+
Example:
|
|
795
|
+
```python
|
|
796
|
+
# Convert entire project to STEP for manufacturing
|
|
797
|
+
result = await batch_export({
|
|
798
|
+
"source_directory": "C:/SolidWorks_Project/Parts",
|
|
799
|
+
"output_directory": "C:/Manufacturing/STEP_Files",
|
|
800
|
+
"format_type": "step",
|
|
801
|
+
"recursive": True,
|
|
802
|
+
"file_patterns": ["*.sldprt", "*.sldasm"]
|
|
803
|
+
})
|
|
804
|
+
|
|
805
|
+
if result["status"] == "success":
|
|
806
|
+
batch = result["batch_export"]
|
|
807
|
+
print(f"Processed {batch['files_processed']} files")
|
|
808
|
+
print(f"Success: {batch['files_successful']}, Failed: {batch['files_failed']}")
|
|
809
|
+
# All parts ready for CNC programming
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
Note:
|
|
813
|
+
- Process can take significant time for large directories
|
|
814
|
+
- Failed exports are logged with specific error messages
|
|
815
|
+
- Maintains directory structure in output location
|
|
816
|
+
- Essential for project deliverables and supplier packages
|
|
817
|
+
"""
|
|
818
|
+
require_capability(
|
|
819
|
+
adapter,
|
|
820
|
+
"batch_export",
|
|
821
|
+
"Active adapter does not support batch_export; no files were exported.",
|
|
822
|
+
)
|
|
823
|
+
result = await adapter.batch_export(input_data.model_dump())
|
|
824
|
+
require_success(result, "Batch export failed")
|
|
825
|
+
return {
|
|
826
|
+
"status": "success",
|
|
827
|
+
"message": f"Batch export completed to {input_data.format_type} format",
|
|
828
|
+
"data": result.data,
|
|
829
|
+
"execution_time": result.execution_time,
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
tool_count = 7 # Number of tools registered
|
|
833
|
+
return tool_count
|