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,1015 @@
|
|
|
1
|
+
"""Drawing tools for SolidWorks MCP Server.
|
|
2
|
+
|
|
3
|
+
Provides tools for creating drawing views, adding dimensions, annotations, and managing
|
|
4
|
+
technical drawings in SolidWorks.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
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
|
+
# Input schemas using Python 3.14 built-in types
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class CreateDrawingViewInput(BaseModel):
|
|
26
|
+
"""Input schema for creating drawing views.
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
model_path (str): The model path value.
|
|
30
|
+
orientation (str): The orientation value.
|
|
31
|
+
position_x (float): The position x value.
|
|
32
|
+
position_y (float): The position y value.
|
|
33
|
+
scale (float): The scale value.
|
|
34
|
+
view_type (str): The view type value.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
model_path: str = Field(description="Path to the SolidWorks model file")
|
|
38
|
+
view_type: str = Field(
|
|
39
|
+
description="Type of view (orthographic, isometric, section, detail)"
|
|
40
|
+
)
|
|
41
|
+
position_x: float = Field(default=100.0, description="X position in drawing (mm)")
|
|
42
|
+
position_y: float = Field(default=200.0, description="Y position in drawing (mm)")
|
|
43
|
+
scale: float = Field(default=1.0, description="View scale factor")
|
|
44
|
+
orientation: str = Field(
|
|
45
|
+
default="front", description="View orientation (front, top, right, isometric)"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class AddDimensionInput(BaseModel):
|
|
50
|
+
"""Input schema for adding dimensions.
|
|
51
|
+
|
|
52
|
+
Attributes:
|
|
53
|
+
dimension_type (str): The dimension type value.
|
|
54
|
+
entity1 (str): The entity1 value.
|
|
55
|
+
entity2 (str | None): The entity2 value.
|
|
56
|
+
position_x (float): The position x value.
|
|
57
|
+
position_y (float): The position y value.
|
|
58
|
+
precision (int): The precision value.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
dimension_type: str = Field(
|
|
62
|
+
description="Type of dimension (linear, radial, angular, diameter)"
|
|
63
|
+
)
|
|
64
|
+
entity1: str = Field(description="First entity to dimension (edge, face, point)")
|
|
65
|
+
entity2: str | None = Field(
|
|
66
|
+
default=None, description="Second entity for linear/angular dimensions"
|
|
67
|
+
)
|
|
68
|
+
position_x: float = Field(description="X position for dimension text")
|
|
69
|
+
position_y: float = Field(description="Y position for dimension text")
|
|
70
|
+
precision: int = Field(default=2, description="Number of decimal places")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class AddNoteInput(BaseModel):
|
|
74
|
+
"""Input schema for adding notes/annotations.
|
|
75
|
+
|
|
76
|
+
Attributes:
|
|
77
|
+
font_size (float): The font size value.
|
|
78
|
+
leader_attachment (str | None): The leader attachment value.
|
|
79
|
+
position_x (float): The position x value.
|
|
80
|
+
position_y (float): The position y value.
|
|
81
|
+
text (str): The text value.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
text: str = Field(description="Note text content")
|
|
85
|
+
position_x: float = Field(description="X position for note")
|
|
86
|
+
position_y: float = Field(description="Y position for note")
|
|
87
|
+
font_size: float = Field(default=12.0, description="Font size in points")
|
|
88
|
+
leader_attachment: str | None = Field(
|
|
89
|
+
default=None, description="Entity to attach leader line to"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class CreateSectionViewInput(BaseModel):
|
|
94
|
+
"""Input schema for creating section views.
|
|
95
|
+
|
|
96
|
+
Attributes:
|
|
97
|
+
label (str): The label value.
|
|
98
|
+
scale (float): The scale value.
|
|
99
|
+
section_line_end (list[float]): The section line end value.
|
|
100
|
+
section_line_start (list[float]): The section line start value.
|
|
101
|
+
view_position_x (float): The view position x value.
|
|
102
|
+
view_position_y (float): The view position y value.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
section_line_start: list[float] = Field(
|
|
106
|
+
description="Start point of section line as [x, y]",
|
|
107
|
+
min_length=2,
|
|
108
|
+
max_length=2,
|
|
109
|
+
json_schema_extra={"items": {"type": "number"}},
|
|
110
|
+
)
|
|
111
|
+
section_line_end: list[float] = Field(
|
|
112
|
+
description="End point of section line as [x, y]",
|
|
113
|
+
min_length=2,
|
|
114
|
+
max_length=2,
|
|
115
|
+
json_schema_extra={"items": {"type": "number"}},
|
|
116
|
+
)
|
|
117
|
+
view_position_x: float = Field(description="X position for section view")
|
|
118
|
+
view_position_y: float = Field(description="Y position for section view")
|
|
119
|
+
scale: float = Field(default=1.0, description="Section view scale")
|
|
120
|
+
label: str = Field(default="A", description="Section view label")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class CreateDetailViewInput(BaseModel):
|
|
124
|
+
"""Input schema for creating detail views.
|
|
125
|
+
|
|
126
|
+
Attributes:
|
|
127
|
+
center_x (float): The center x value.
|
|
128
|
+
center_y (float): The center y value.
|
|
129
|
+
label (str): The label value.
|
|
130
|
+
radius (float): The radius value.
|
|
131
|
+
scale (float): The scale value.
|
|
132
|
+
view_position_x (float): The view position x value.
|
|
133
|
+
view_position_y (float): The view position y value.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
center_x: float = Field(description="X center of detail circle")
|
|
137
|
+
center_y: float = Field(description="Y center of detail circle")
|
|
138
|
+
radius: float = Field(description="Radius of detail circle")
|
|
139
|
+
view_position_x: float = Field(description="X position for detail view")
|
|
140
|
+
view_position_y: float = Field(description="Y position for detail view")
|
|
141
|
+
scale: float = Field(default=2.0, description="Detail view scale")
|
|
142
|
+
label: str = Field(default="A", description="Detail view label")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class UpdateSheetFormatInput(BaseModel):
|
|
146
|
+
"""Input schema for updating sheet format.
|
|
147
|
+
|
|
148
|
+
Attributes:
|
|
149
|
+
approved_by (str): The approved by value.
|
|
150
|
+
checked_by (str): The checked by value.
|
|
151
|
+
drawing_number (str): The drawing number value.
|
|
152
|
+
drawn_by (str): The drawn by value.
|
|
153
|
+
format_file (str): The format file value.
|
|
154
|
+
sheet_size (str): The sheet size value.
|
|
155
|
+
title (str): The title value.
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
format_file: str = Field(description="Path to sheet format template (.slddrt)")
|
|
159
|
+
sheet_size: str = Field(default="A3", description="Sheet size (A4, A3, A2, A1, A0)")
|
|
160
|
+
title: str = Field(default="", description="Drawing title")
|
|
161
|
+
drawn_by: str = Field(default="", description="Drawn by field")
|
|
162
|
+
checked_by: str = Field(default="", description="Checked by field")
|
|
163
|
+
approved_by: str = Field(default="", description="Approved by field")
|
|
164
|
+
drawing_number: str = Field(default="", description="Drawing number")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class AutoCenterMarksInput(CompatInput):
|
|
168
|
+
"""Input schema for auto-inserting drawing centre marks.
|
|
169
|
+
|
|
170
|
+
Attributes:
|
|
171
|
+
view_name (str): Name of a view on the active drawing.
|
|
172
|
+
mark_holes (bool): Mark holes / bores.
|
|
173
|
+
mark_fillets (bool): Mark fillets.
|
|
174
|
+
mark_slots (bool): Mark slots.
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
view_name: str = Field(
|
|
178
|
+
description="Name of a view on the active drawing, e.g. 'Drawing View1'"
|
|
179
|
+
)
|
|
180
|
+
mark_holes: bool = Field(default=True, description="Mark holes / bores")
|
|
181
|
+
mark_fillets: bool = Field(default=False, description="Mark fillets")
|
|
182
|
+
mark_slots: bool = Field(default=True, description="Mark slots")
|
|
183
|
+
|
|
184
|
+
def model_post_init(self, __context: Any) -> None:
|
|
185
|
+
if not self.view_name.strip():
|
|
186
|
+
raise ValueError("view_name is required")
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class DrawingCreationInput(CompatInput):
|
|
190
|
+
"""Input schema for creating a new drawing.
|
|
191
|
+
|
|
192
|
+
Attributes:
|
|
193
|
+
auto_populate_views (bool): The auto populate views value.
|
|
194
|
+
model_file (str | None): The model file value.
|
|
195
|
+
output_path (str | None): The output path value.
|
|
196
|
+
scale (str): The scale value.
|
|
197
|
+
sheet_format (str | None): The sheet format value.
|
|
198
|
+
sheet_size (str): The sheet size value.
|
|
199
|
+
template (str | None): The template value.
|
|
200
|
+
title (str): The title value.
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
template: str | None = Field(default=None, description="Drawing template file path")
|
|
204
|
+
model_file: str | None = Field(
|
|
205
|
+
default=None, description="Model file to create drawing from"
|
|
206
|
+
)
|
|
207
|
+
sheet_size: str = Field(default="A3", description="Sheet size")
|
|
208
|
+
title: str = Field(default="", description="Drawing title")
|
|
209
|
+
output_path: str | None = Field(default=None, description="Output drawing path")
|
|
210
|
+
sheet_format: str | None = Field(default=None, description="Sheet format")
|
|
211
|
+
scale: str = Field(default="1:1", description="Drawing scale")
|
|
212
|
+
auto_populate_views: bool = Field(
|
|
213
|
+
default=False, description="Automatically populate standard views"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class DrawingViewInput(CompatInput):
|
|
218
|
+
"""Input schema for drawing view operations.
|
|
219
|
+
|
|
220
|
+
Attributes:
|
|
221
|
+
drawing_path (str | None): The drawing path value.
|
|
222
|
+
model_file (str | None): The model file value.
|
|
223
|
+
operation (str): The operation value.
|
|
224
|
+
parameters (dict[str, Any]): The parameters value.
|
|
225
|
+
parent_view (str | None): The parent view value.
|
|
226
|
+
position (list[float] | None): The position value.
|
|
227
|
+
scale (str | None): The scale value.
|
|
228
|
+
view_name (str | None): The view name value.
|
|
229
|
+
view_type (str | None): The view type value.
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
drawing_path: str | None = Field(default=None, description="Path to drawing file")
|
|
233
|
+
view_name: str | None = Field(default=None, description="Name of the drawing view")
|
|
234
|
+
operation: str = Field(
|
|
235
|
+
default="add", description="Operation to perform (create, update, delete)"
|
|
236
|
+
)
|
|
237
|
+
model_file: str | None = Field(default=None, description="Model file path")
|
|
238
|
+
view_type: str | None = Field(default=None, description="Type of view")
|
|
239
|
+
parent_view: str | None = Field(default=None, description="Parent view alias")
|
|
240
|
+
position: list[float] | None = Field(default=None, description="View position")
|
|
241
|
+
scale: str | None = Field(default=None, description="View scale")
|
|
242
|
+
parameters: dict[str, Any] = Field(default={}, description="View parameters")
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class DimensionInput(CompatInput):
|
|
246
|
+
"""Input schema for dimension operations.
|
|
247
|
+
|
|
248
|
+
Attributes:
|
|
249
|
+
dimension_name (str | None): The dimension name value.
|
|
250
|
+
dimension_type (str | None): The dimension type value.
|
|
251
|
+
drawing_path (str | None): The drawing path value.
|
|
252
|
+
entities (list[str] | None): The entities value.
|
|
253
|
+
entity1 (str | None): The entity1 value.
|
|
254
|
+
entity2 (str | None): The entity2 value.
|
|
255
|
+
operation (str | None): The operation value.
|
|
256
|
+
position (list[float] | None): The position value.
|
|
257
|
+
position_x (float | None): The position x value.
|
|
258
|
+
position_y (float | None): The position y value.
|
|
259
|
+
precision (int): The precision value.
|
|
260
|
+
tolerance (str | None): The tolerance value.
|
|
261
|
+
value (float | None): The value value.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
drawing_path: str | None = Field(default=None, description="Path to drawing file")
|
|
265
|
+
dimension_name: str | None = Field(
|
|
266
|
+
default=None, description="Name of the dimension"
|
|
267
|
+
)
|
|
268
|
+
operation: str | None = Field(
|
|
269
|
+
default="add", description="Operation to perform (add, update, delete)"
|
|
270
|
+
)
|
|
271
|
+
value: float | None = Field(default=None, description="Dimension value")
|
|
272
|
+
dimension_type: str | None = Field(default=None, description="Type of dimension")
|
|
273
|
+
entities: list[str] | None = Field(
|
|
274
|
+
default=None, description="Entities to dimension"
|
|
275
|
+
)
|
|
276
|
+
entity1: str | None = Field(default=None, description="Primary entity alias")
|
|
277
|
+
entity2: str | None = Field(default=None, description="Secondary entity alias")
|
|
278
|
+
position: list[float] | None = Field(default=None, description="Dimension position")
|
|
279
|
+
position_x: float | None = Field(default=None, description="Position X alias")
|
|
280
|
+
position_y: float | None = Field(default=None, description="Position Y alias")
|
|
281
|
+
precision: int = Field(default=2, description="Precision alias")
|
|
282
|
+
tolerance: str | None = Field(default=None, description="Dimension tolerance")
|
|
283
|
+
|
|
284
|
+
def model_post_init(self, __context: Any) -> None:
|
|
285
|
+
"""Provide model post init support for the dimension input.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
__context (Any): The context value.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
None: None.
|
|
292
|
+
"""
|
|
293
|
+
if self.entities:
|
|
294
|
+
if self.entity1 is None and len(self.entities) >= 1:
|
|
295
|
+
self.entity1 = self.entities[0]
|
|
296
|
+
if self.entity2 is None and len(self.entities) >= 2:
|
|
297
|
+
self.entity2 = self.entities[1]
|
|
298
|
+
if self.position and len(self.position) >= 2:
|
|
299
|
+
if self.position_x is None:
|
|
300
|
+
self.position_x = float(self.position[0])
|
|
301
|
+
if self.position_y is None:
|
|
302
|
+
self.position_y = float(self.position[1])
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
class AnnotationInput(CompatInput):
|
|
306
|
+
"""Input schema for annotation operations.
|
|
307
|
+
|
|
308
|
+
Attributes:
|
|
309
|
+
annotation_type (str): The annotation type value.
|
|
310
|
+
approved_by (str): The approved by value.
|
|
311
|
+
checked_by (str): The checked by value.
|
|
312
|
+
drawing_number (str): The drawing number value.
|
|
313
|
+
drawing_path (str | None): The drawing path value.
|
|
314
|
+
drawn_by (str): The drawn by value.
|
|
315
|
+
font_size (float): The font size value.
|
|
316
|
+
leader_attachment (str | None): The leader attachment value.
|
|
317
|
+
position (list[float] | None): The position value.
|
|
318
|
+
position_x (float | None): The position x value.
|
|
319
|
+
position_y (float | None): The position y value.
|
|
320
|
+
text (str): The text value.
|
|
321
|
+
"""
|
|
322
|
+
|
|
323
|
+
drawing_path: str | None = Field(default=None, description="Path to drawing file")
|
|
324
|
+
annotation_type: str = Field(
|
|
325
|
+
description="Type of annotation (note, balloon, surface_finish, etc.)"
|
|
326
|
+
)
|
|
327
|
+
text: str = Field(description="Annotation text content")
|
|
328
|
+
position_x: float | None = Field(
|
|
329
|
+
default=None, description="X position for annotation"
|
|
330
|
+
)
|
|
331
|
+
position_y: float | None = Field(
|
|
332
|
+
default=None, description="Y position for annotation"
|
|
333
|
+
)
|
|
334
|
+
position: list[float] | None = Field(
|
|
335
|
+
default=None, description="Annotation position"
|
|
336
|
+
)
|
|
337
|
+
font_size: float = Field(default=12.0, description="Font size in points")
|
|
338
|
+
leader_attachment: str | None = Field(
|
|
339
|
+
default=None, description="Entity to attach leader line to"
|
|
340
|
+
)
|
|
341
|
+
drawn_by: str = Field(default="", description="Drawn by field")
|
|
342
|
+
checked_by: str = Field(default="", description="Checked by field")
|
|
343
|
+
approved_by: str = Field(default="", description="Approved by field")
|
|
344
|
+
drawing_number: str = Field(default="", description="Drawing number")
|
|
345
|
+
|
|
346
|
+
def model_post_init(self, __context: Any) -> None:
|
|
347
|
+
"""Provide model post init support for the annotation input.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
__context (Any): The context value.
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
None: None.
|
|
354
|
+
"""
|
|
355
|
+
if self.position is not None and len(self.position) >= 2:
|
|
356
|
+
if self.position_x is None:
|
|
357
|
+
self.position_x = float(self.position[0])
|
|
358
|
+
if self.position_y is None:
|
|
359
|
+
self.position_y = float(self.position[1])
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
async def register_drawing_tools(
|
|
363
|
+
mcp: FastMCP, adapter: SolidWorksAdapter, config: dict[str, Any]
|
|
364
|
+
) -> int:
|
|
365
|
+
"""Register drawing tools with FastMCP.
|
|
366
|
+
|
|
367
|
+
Registers comprehensive technical drawing tools for SolidWorks automation including view
|
|
368
|
+
creation, dimensioning, annotation, and drawing standards validation. Essential for
|
|
369
|
+
automated documentation workflows.
|
|
370
|
+
|
|
371
|
+
Args:
|
|
372
|
+
mcp (FastMCP): The mcp value.
|
|
373
|
+
adapter (SolidWorksAdapter): Adapter instance used for the operation.
|
|
374
|
+
config (dict[str, Any]): Configuration values for the operation.
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
int: The computed numeric result.
|
|
378
|
+
|
|
379
|
+
Example:
|
|
380
|
+
```python
|
|
381
|
+
from solidworks_mcp.tools.drawing import register_drawing_tools
|
|
382
|
+
|
|
383
|
+
tool_count = await register_drawing_tools(mcp, adapter, config)
|
|
384
|
+
print(f"Registered {tool_count} drawing tools")
|
|
385
|
+
```
|
|
386
|
+
"""
|
|
387
|
+
mcp = with_tool_boundary(mcp)
|
|
388
|
+
tool_count = 0
|
|
389
|
+
|
|
390
|
+
@mcp.tool()
|
|
391
|
+
async def create_drawing_view(input_data: CreateDrawingViewInput) -> dict[str, Any]:
|
|
392
|
+
"""Create a drawing view of a SolidWorks model.
|
|
393
|
+
|
|
394
|
+
Creates technical drawing views including orthographic projections, isometric views,
|
|
395
|
+
section views, and detail views from 3D models. Essential for generating production
|
|
396
|
+
drawings and technical documentation.
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
input_data (CreateDrawingViewInput): The input data value.
|
|
400
|
+
|
|
401
|
+
Returns:
|
|
402
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
403
|
+
|
|
404
|
+
Example:
|
|
405
|
+
```python
|
|
406
|
+
# Create front orthographic view of a part
|
|
407
|
+
result = await create_drawing_view({
|
|
408
|
+
"model_path": "C:/Models/bracket.sldprt",
|
|
409
|
+
"view_type": "orthographic",
|
|
410
|
+
"position_x": 150.0, "position_y": 250.0,
|
|
411
|
+
"scale": 1.0,
|
|
412
|
+
"orientation": "front"
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
if result["status"] == "success":
|
|
416
|
+
view = result["drawing_view"]
|
|
417
|
+
print(f"Created {view['view_type']} view at {view['scale']}:1 scale")
|
|
418
|
+
# Ready for dimensioning and annotation
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Note:
|
|
422
|
+
- Model file must exist and be accessible
|
|
423
|
+
- Drawing sheet must be active before creating views
|
|
424
|
+
- View positioning follows drawing sheet coordinate system
|
|
425
|
+
- Multiple views can reference the same model file
|
|
426
|
+
"""
|
|
427
|
+
require_capability(
|
|
428
|
+
adapter,
|
|
429
|
+
"create_drawing_view",
|
|
430
|
+
"Active adapter does not support create_drawing_view; no "
|
|
431
|
+
f"{input_data.view_type} view of {input_data.model_path} was created.",
|
|
432
|
+
)
|
|
433
|
+
result = await adapter.create_drawing_view(input_data.model_dump())
|
|
434
|
+
require_success(result, "Failed to create drawing view")
|
|
435
|
+
return {
|
|
436
|
+
"status": "success",
|
|
437
|
+
"message": f"Created {input_data.view_type} view of {input_data.model_path}",
|
|
438
|
+
"data": result.data,
|
|
439
|
+
"execution_time": result.execution_time,
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
@mcp.tool()
|
|
443
|
+
async def add_dimension(input_data: AddDimensionInput) -> dict[str, Any]:
|
|
444
|
+
"""Add a dimension to the current drawing.
|
|
445
|
+
|
|
446
|
+
Creates dimensional annotations on drawing views including linear, radial, angular, and
|
|
447
|
+
diameter dimensions. Essential for manufacturing specifications and quality control
|
|
448
|
+
documentation.
|
|
449
|
+
|
|
450
|
+
Args:
|
|
451
|
+
input_data (AddDimensionInput): The input data value.
|
|
452
|
+
|
|
453
|
+
Returns:
|
|
454
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
455
|
+
|
|
456
|
+
Example:
|
|
457
|
+
```python
|
|
458
|
+
# Add diameter dimension to a hole
|
|
459
|
+
result = await add_dimension({
|
|
460
|
+
"dimension_type": "diameter",
|
|
461
|
+
"entity1": "Circle1",
|
|
462
|
+
"entity2": None,
|
|
463
|
+
"position_x": 100.0, "position_y": 150.0,
|
|
464
|
+
"precision": 2
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
if result["status"] == "success":
|
|
468
|
+
dim = result["dimension"]
|
|
469
|
+
print(f"Added {dim['type']} dimension with {dim['precision']} decimals")
|
|
470
|
+
# Dimension now drives manufacturing specification
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
Note:
|
|
474
|
+
- Entities must be visible in current drawing view
|
|
475
|
+
- Dimension placement affects drawing readability
|
|
476
|
+
- Precision should match manufacturing tolerances
|
|
477
|
+
- Some dimension types require specific entity combinations
|
|
478
|
+
"""
|
|
479
|
+
if hasattr(input_data, "model_dump"):
|
|
480
|
+
payload = input_data.model_dump()
|
|
481
|
+
else:
|
|
482
|
+
payload = dict(input_data)
|
|
483
|
+
|
|
484
|
+
dimension_type = payload.get("dimension_type")
|
|
485
|
+
entity1 = payload.get("entity1")
|
|
486
|
+
entity2 = payload.get("entity2")
|
|
487
|
+
position_x = payload.get("position_x")
|
|
488
|
+
position_y = payload.get("position_y")
|
|
489
|
+
|
|
490
|
+
if (entity1 is None or entity2 is None) and payload.get("entities"):
|
|
491
|
+
entities = payload["entities"]
|
|
492
|
+
if entity1 is None and len(entities) >= 1:
|
|
493
|
+
entity1 = entities[0]
|
|
494
|
+
if entity2 is None and len(entities) >= 2:
|
|
495
|
+
entity2 = entities[1]
|
|
496
|
+
|
|
497
|
+
if (position_x is None or position_y is None) and payload.get("position"):
|
|
498
|
+
position = payload["position"]
|
|
499
|
+
if len(position) >= 2:
|
|
500
|
+
if position_x is None:
|
|
501
|
+
position_x = position[0]
|
|
502
|
+
if position_y is None:
|
|
503
|
+
position_y = position[1]
|
|
504
|
+
|
|
505
|
+
# Feed the alias-normalized values back into the payload so the
|
|
506
|
+
# adapter call sees entity1/entity2/position_x/position_y even
|
|
507
|
+
# when the caller only supplied entities/position.
|
|
508
|
+
payload["entity1"] = entity1
|
|
509
|
+
payload["entity2"] = entity2
|
|
510
|
+
payload["position_x"] = position_x
|
|
511
|
+
payload["position_y"] = position_y
|
|
512
|
+
|
|
513
|
+
require_capability(
|
|
514
|
+
adapter,
|
|
515
|
+
"add_dimension",
|
|
516
|
+
f"Active adapter does not support add_dimension; no "
|
|
517
|
+
f"{dimension_type} dimension was added.",
|
|
518
|
+
)
|
|
519
|
+
result = await adapter.add_dimension(payload)
|
|
520
|
+
require_success(result, "Failed to add dimension")
|
|
521
|
+
return {
|
|
522
|
+
"status": "success",
|
|
523
|
+
"message": "Dimension added successfully",
|
|
524
|
+
"data": result.data,
|
|
525
|
+
"execution_time": result.execution_time,
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
@mcp.tool()
|
|
529
|
+
async def add_note(input_data: AddNoteInput) -> dict[str, Any]:
|
|
530
|
+
"""Add a note or annotation to the current drawing.
|
|
531
|
+
|
|
532
|
+
Creates text annotations, callouts, and notes on drawings for specifications,
|
|
533
|
+
instructions, and additional manufacturing information. Essential for comprehensive
|
|
534
|
+
technical documentation.
|
|
535
|
+
|
|
536
|
+
Args:
|
|
537
|
+
input_data (AddNoteInput): The input data value.
|
|
538
|
+
|
|
539
|
+
Returns:
|
|
540
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
541
|
+
|
|
542
|
+
Example:
|
|
543
|
+
```python
|
|
544
|
+
# Add material specification note with leader
|
|
545
|
+
result = await add_note({
|
|
546
|
+
"text": "Material: AISI 1018 Steel
|
|
547
|
+
Hardness: 150-200 HB",
|
|
548
|
+
"position_x": 200.0, "position_y": 50.0,
|
|
549
|
+
"font_size": 10.0,
|
|
550
|
+
"leader_attachment": "Face1"
|
|
551
|
+
})
|
|
552
|
+
|
|
553
|
+
if result["status"] == "success":
|
|
554
|
+
note = result["note"]
|
|
555
|
+
print(f"Added note at {note['font_size']}pt font size")
|
|
556
|
+
# Note provides critical manufacturing information
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
Note:
|
|
560
|
+
- Text supports standard annotation symbols and formatting
|
|
561
|
+
- Leader attachment improves clarity for specific features
|
|
562
|
+
- Font size should comply with drawing standards
|
|
563
|
+
- Position carefully to avoid dimension conflicts
|
|
564
|
+
"""
|
|
565
|
+
require_capability(
|
|
566
|
+
adapter,
|
|
567
|
+
"add_note",
|
|
568
|
+
"Active adapter does not support add_note; no note was added.",
|
|
569
|
+
)
|
|
570
|
+
result = await adapter.add_note(input_data.model_dump())
|
|
571
|
+
require_success(result, "Failed to add note")
|
|
572
|
+
return {
|
|
573
|
+
"status": "success",
|
|
574
|
+
"message": f"Added note: {input_data.text[:30]}...",
|
|
575
|
+
"data": result.data,
|
|
576
|
+
"execution_time": result.execution_time,
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
@mcp.tool()
|
|
580
|
+
async def create_section_view(input_data: CreateSectionViewInput) -> dict[str, Any]:
|
|
581
|
+
"""Create a section view of the current drawing.
|
|
582
|
+
|
|
583
|
+
Generates section views that show internal features by cutting through the part along a
|
|
584
|
+
specified section line. Essential for revealing hidden geometry, internal structures,
|
|
585
|
+
and complex assemblies.
|
|
586
|
+
|
|
587
|
+
Args:
|
|
588
|
+
input_data (CreateSectionViewInput): The input data value.
|
|
589
|
+
|
|
590
|
+
Returns:
|
|
591
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
592
|
+
|
|
593
|
+
Example:
|
|
594
|
+
```python
|
|
595
|
+
# Create vertical section through center of part
|
|
596
|
+
result = await create_section_view({
|
|
597
|
+
"section_line_start": (50.0, 0.0),
|
|
598
|
+
"section_line_end": (50.0, 100.0),
|
|
599
|
+
"view_position_x": 300.0, "view_position_y": 150.0,
|
|
600
|
+
"scale": 1.5,
|
|
601
|
+
"label": "A"
|
|
602
|
+
})
|
|
603
|
+
|
|
604
|
+
if result["status"] == "success":
|
|
605
|
+
section = result["section_view"]
|
|
606
|
+
print(f"Created section {section['label']}-A at {section['scale']}:1")
|
|
607
|
+
# Section reveals internal features clearly
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
Note:
|
|
611
|
+
- Section line direction determines view orientation
|
|
612
|
+
- Section views automatically show cut surfaces with hatching
|
|
613
|
+
- Label follows ANSI/ISO drafting standards (A-A, B-B, etc.)
|
|
614
|
+
- Essential for showing internal features and assemblies
|
|
615
|
+
"""
|
|
616
|
+
raise UnsupportedOperationError(
|
|
617
|
+
"No adapter capability exists for cutting a section view "
|
|
618
|
+
"along a section line; create_section_view cannot compute "
|
|
619
|
+
"the cut geometry, so no view was created. Use SolidWorks "
|
|
620
|
+
"directly (Insert > Drawing View > Section) instead."
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
@mcp.tool()
|
|
624
|
+
async def create_detail_view(input_data: CreateDetailViewInput) -> dict[str, Any]:
|
|
625
|
+
"""Create a detail view of a specific area.
|
|
626
|
+
|
|
627
|
+
Generates magnified detail views of specific regions to show fine features, tight
|
|
628
|
+
tolerances, and intricate geometry that requires enhanced visibility for manufacturing
|
|
629
|
+
and inspection.
|
|
630
|
+
|
|
631
|
+
Args:
|
|
632
|
+
input_data (CreateDetailViewInput): The input data value.
|
|
633
|
+
|
|
634
|
+
Returns:
|
|
635
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
636
|
+
|
|
637
|
+
Example:
|
|
638
|
+
```python
|
|
639
|
+
# Create 4x detail view of small threaded hole
|
|
640
|
+
result = await create_detail_view({
|
|
641
|
+
"center_x": 25.0, "center_y": 15.0,
|
|
642
|
+
"radius": 8.0, # 16mm diameter detail area
|
|
643
|
+
"view_position_x": 250.0, "view_position_y": 300.0,
|
|
644
|
+
"scale": 4.0, # 4:1 magnification
|
|
645
|
+
"label": "A"
|
|
646
|
+
})
|
|
647
|
+
|
|
648
|
+
if result["status"] == "success":
|
|
649
|
+
detail = result["detail_view"]
|
|
650
|
+
print(f"Created detail {detail['label']} at {detail['scale']}:1")
|
|
651
|
+
# Detail shows thread profile clearly for machining
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
Note:
|
|
655
|
+
- Detail circle size determines what geometry is magnified
|
|
656
|
+
- Higher scale factors reveal fine features for precision work
|
|
657
|
+
- Label follows standard drafting conventions (Detail A, etc.)
|
|
658
|
+
- Essential for communicating tight tolerance requirements
|
|
659
|
+
"""
|
|
660
|
+
raise UnsupportedOperationError(
|
|
661
|
+
"No adapter capability exists for magnifying the "
|
|
662
|
+
"geometry inside a detail circle; create_detail_view "
|
|
663
|
+
"cannot compute the detail geometry, so no view was "
|
|
664
|
+
"created. Use SolidWorks directly (Insert > Drawing "
|
|
665
|
+
"View > Detail) instead."
|
|
666
|
+
)
|
|
667
|
+
|
|
668
|
+
@mcp.tool()
|
|
669
|
+
async def update_sheet_format(input_data: UpdateSheetFormatInput) -> dict[str, Any]:
|
|
670
|
+
"""Update the sheet format and title block information.
|
|
671
|
+
|
|
672
|
+
Applies drawing templates and updates title block fields with project information,
|
|
673
|
+
revision data, and drawing metadata. Essential for standardized documentation and
|
|
674
|
+
drawing control.
|
|
675
|
+
|
|
676
|
+
Args:
|
|
677
|
+
input_data (UpdateSheetFormatInput): The input data value.
|
|
678
|
+
|
|
679
|
+
Returns:
|
|
680
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
681
|
+
|
|
682
|
+
Example:
|
|
683
|
+
```python
|
|
684
|
+
# Apply company standard format with project info
|
|
685
|
+
result = await update_sheet_format({
|
|
686
|
+
"format_file": "C:/Templates/company_format.slddrt",
|
|
687
|
+
"sheet_size": "A3",
|
|
688
|
+
"title": "Mounting Bracket Assembly",
|
|
689
|
+
"drawn_by": "J. Smith",
|
|
690
|
+
"checked_by": "M. Johnson",
|
|
691
|
+
"approved_by": "R. Wilson",
|
|
692
|
+
"drawing_number": "DWG-001-Rev-A"
|
|
693
|
+
})
|
|
694
|
+
|
|
695
|
+
if result["status"] == "success":
|
|
696
|
+
format_info = result["sheet_format"]
|
|
697
|
+
print(f"Applied {format_info['sheet_size']} format")
|
|
698
|
+
# Drawing now has proper title block and company branding
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
Note:
|
|
702
|
+
- Format file must exist and be compatible with SolidWorks version
|
|
703
|
+
- Title block fields support company-specific customization
|
|
704
|
+
- Sheet size affects drawing layout and scaling decisions
|
|
705
|
+
- Essential for drawing control and document management systems
|
|
706
|
+
"""
|
|
707
|
+
require_capability(
|
|
708
|
+
adapter,
|
|
709
|
+
"update_sheet_format",
|
|
710
|
+
"Active adapter does not support update_sheet_format; the "
|
|
711
|
+
"sheet format and title block were not changed.",
|
|
712
|
+
)
|
|
713
|
+
result = await adapter.update_sheet_format(input_data.model_dump())
|
|
714
|
+
require_success(result, "Failed to update sheet format")
|
|
715
|
+
return {
|
|
716
|
+
"status": "success",
|
|
717
|
+
"message": f"Updated sheet format to {input_data.sheet_size}",
|
|
718
|
+
"data": result.data,
|
|
719
|
+
"execution_time": result.execution_time,
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
@mcp.tool()
|
|
723
|
+
async def auto_dimension_view(input_data: dict[str, Any]) -> dict[str, Any]:
|
|
724
|
+
"""Automatically dimension a drawing view.
|
|
725
|
+
|
|
726
|
+
Analyzes drawing view geometry and automatically adds common dimensions including
|
|
727
|
+
overall sizes, hole diameters, radii, and critical features. Accelerates drawing
|
|
728
|
+
completion and ensures comprehensive dimensioning coverage.
|
|
729
|
+
|
|
730
|
+
Args:
|
|
731
|
+
input_data (dict[str, Any]): The input data value.
|
|
732
|
+
|
|
733
|
+
Returns:
|
|
734
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
735
|
+
|
|
736
|
+
Example:
|
|
737
|
+
```python
|
|
738
|
+
# Auto-dimension main view with baseline dimensions
|
|
739
|
+
result = await auto_dimension_view({
|
|
740
|
+
"view_name": "Front View",
|
|
741
|
+
"dimension_types": ["linear", "diameter"],
|
|
742
|
+
"include_baseline": True,
|
|
743
|
+
"include_centerlines": True
|
|
744
|
+
})
|
|
745
|
+
|
|
746
|
+
if result["status"] == "success":
|
|
747
|
+
auto_dims = result["auto_dimensions"]
|
|
748
|
+
print(f"Added {auto_dims['dimensions_added']} dimensions")
|
|
749
|
+
print(f"Coverage: {auto_dims['coverage']}")
|
|
750
|
+
# Drawing now has comprehensive dimensioning
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
Note:
|
|
754
|
+
- Analyzes feature geometry to determine appropriate dimensions
|
|
755
|
+
- Follows drafting standards for dimension placement
|
|
756
|
+
- May require manual adjustment for optimal readability
|
|
757
|
+
- Significantly reduces manual dimensioning time
|
|
758
|
+
"""
|
|
759
|
+
require_capability(
|
|
760
|
+
adapter,
|
|
761
|
+
"auto_dimension_view",
|
|
762
|
+
"Active adapter does not support auto_dimension_view; no "
|
|
763
|
+
"dimensions were added.",
|
|
764
|
+
)
|
|
765
|
+
result = await adapter.auto_dimension_view(input_data)
|
|
766
|
+
require_success(result, "Failed to auto-dimension view")
|
|
767
|
+
return {
|
|
768
|
+
"status": "success",
|
|
769
|
+
"message": "Auto-dimensioned drawing view",
|
|
770
|
+
"data": result.data,
|
|
771
|
+
"execution_time": result.execution_time,
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
@mcp.tool()
|
|
775
|
+
async def check_drawing_standards(input_data: dict[str, Any]) -> dict[str, Any]:
|
|
776
|
+
"""Check the current drawing against drafting standards.
|
|
777
|
+
|
|
778
|
+
Validates drawing compliance with industry drafting standards including ANSI Y14.5, ISO
|
|
779
|
+
128, and DIN standards. Identifies non-compliance issues and provides recommendations
|
|
780
|
+
for improvement.
|
|
781
|
+
|
|
782
|
+
Args:
|
|
783
|
+
input_data (dict[str, Any]): The input data value.
|
|
784
|
+
|
|
785
|
+
Returns:
|
|
786
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
787
|
+
|
|
788
|
+
Example:
|
|
789
|
+
```python
|
|
790
|
+
# Comprehensive ANSI standards check
|
|
791
|
+
result = await check_drawing_standards({
|
|
792
|
+
"standard": "ANSI",
|
|
793
|
+
"check_categories": ["dimensions", "tolerances", "symbols"],
|
|
794
|
+
"severity_filter": "warning"
|
|
795
|
+
})
|
|
796
|
+
|
|
797
|
+
if result["status"] == "success":
|
|
798
|
+
check = result["standards_check"]
|
|
799
|
+
print(f"Compliance Score: {check['compliance_score']}%")
|
|
800
|
+
print(f"Warnings: {len(check['warnings'])}")
|
|
801
|
+
print(f"Errors: {len(check['errors'])}")
|
|
802
|
+
# Address issues to improve drawing quality
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
Note:
|
|
806
|
+
- Standards compliance ensures drawing acceptance in industry
|
|
807
|
+
- Regular checking prevents costly revision cycles
|
|
808
|
+
- Automated validation reduces human error in review process
|
|
809
|
+
- Essential for quality management and ISO certification
|
|
810
|
+
"""
|
|
811
|
+
raise UnsupportedOperationError(
|
|
812
|
+
"No adapter capability exists for checking drafting "
|
|
813
|
+
"standards compliance; check_drawing_standards cannot "
|
|
814
|
+
"inspect the drawing, so no compliance score was "
|
|
815
|
+
"computed. Use SolidWorks Design Checker for this."
|
|
816
|
+
)
|
|
817
|
+
|
|
818
|
+
@mcp.tool()
|
|
819
|
+
async def create_technical_drawing(
|
|
820
|
+
input_data: DrawingCreationInput,
|
|
821
|
+
) -> dict[str, Any]:
|
|
822
|
+
"""Create a technical drawing from a SolidWorks part or assembly.
|
|
823
|
+
|
|
824
|
+
Supports selecting a template, output path, sheet format, scale, and optional auto-
|
|
825
|
+
population of standard views for documentation.
|
|
826
|
+
|
|
827
|
+
Args:
|
|
828
|
+
input_data (DrawingCreationInput): The input data value.
|
|
829
|
+
|
|
830
|
+
Returns:
|
|
831
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
832
|
+
"""
|
|
833
|
+
require_capability(
|
|
834
|
+
adapter,
|
|
835
|
+
"create_technical_drawing",
|
|
836
|
+
"Active adapter does not support create_technical_drawing; "
|
|
837
|
+
"no drawing was created.",
|
|
838
|
+
)
|
|
839
|
+
result = await adapter.create_technical_drawing(input_data.model_dump())
|
|
840
|
+
require_success(result, "Failed to create technical drawing")
|
|
841
|
+
return {
|
|
842
|
+
"status": "success",
|
|
843
|
+
"message": "Technical drawing created successfully",
|
|
844
|
+
"data": result.data,
|
|
845
|
+
"execution_time": result.execution_time,
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
@mcp.tool()
|
|
849
|
+
async def add_drawing_view(input_data: DrawingViewInput) -> dict[str, Any]:
|
|
850
|
+
"""Add, update, or remove a drawing view in an existing drawing.
|
|
851
|
+
|
|
852
|
+
Supports configuring the target drawing, view type, parent view, scale, and placement
|
|
853
|
+
coordinates for common drawing view workflows.
|
|
854
|
+
|
|
855
|
+
Args:
|
|
856
|
+
input_data (DrawingViewInput): The input data value.
|
|
857
|
+
|
|
858
|
+
Returns:
|
|
859
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
860
|
+
"""
|
|
861
|
+
require_capability(
|
|
862
|
+
adapter,
|
|
863
|
+
"add_drawing_view",
|
|
864
|
+
"Active adapter does not support add_drawing_view; no view was added.",
|
|
865
|
+
)
|
|
866
|
+
result = await adapter.add_drawing_view(input_data.model_dump())
|
|
867
|
+
require_success(result, "Failed to add drawing view")
|
|
868
|
+
return {
|
|
869
|
+
"status": "success",
|
|
870
|
+
"message": "Drawing view added successfully",
|
|
871
|
+
"data": result.data,
|
|
872
|
+
"execution_time": result.execution_time,
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
@mcp.tool()
|
|
876
|
+
async def add_annotation(input_data: AnnotationInput) -> dict[str, Any]:
|
|
877
|
+
"""Add an annotation such as a note, balloon, or surface symbol.
|
|
878
|
+
|
|
879
|
+
Places annotation text in a drawing with optional font size, leader attachment, and
|
|
880
|
+
title-block style metadata fields.
|
|
881
|
+
|
|
882
|
+
Args:
|
|
883
|
+
input_data (AnnotationInput): The input data value.
|
|
884
|
+
|
|
885
|
+
Returns:
|
|
886
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
887
|
+
"""
|
|
888
|
+
require_capability(
|
|
889
|
+
adapter,
|
|
890
|
+
"add_annotation",
|
|
891
|
+
"Active adapter does not support add_annotation; no annotation was added.",
|
|
892
|
+
)
|
|
893
|
+
result = await adapter.add_annotation(input_data.model_dump())
|
|
894
|
+
require_success(result, "Failed to add annotation")
|
|
895
|
+
return {
|
|
896
|
+
"status": "success",
|
|
897
|
+
"message": "Annotation added successfully",
|
|
898
|
+
"data": result.data,
|
|
899
|
+
"execution_time": result.execution_time,
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
@mcp.tool()
|
|
903
|
+
async def update_title_block(input_data: dict[str, Any]) -> dict[str, Any]:
|
|
904
|
+
"""Update title block fields for the active drawing.
|
|
905
|
+
|
|
906
|
+
Applies drawing metadata such as title, drawing number, and approval fields to keep
|
|
907
|
+
documentation aligned with standards.
|
|
908
|
+
|
|
909
|
+
Args:
|
|
910
|
+
input_data (dict[str, Any]): The input data value.
|
|
911
|
+
|
|
912
|
+
Returns:
|
|
913
|
+
dict[str, Any]: A dictionary containing the resulting values.
|
|
914
|
+
"""
|
|
915
|
+
require_capability(
|
|
916
|
+
adapter,
|
|
917
|
+
"update_title_block",
|
|
918
|
+
"Active adapter does not support update_title_block; the "
|
|
919
|
+
"title block was not changed.",
|
|
920
|
+
)
|
|
921
|
+
result = await adapter.update_title_block(input_data)
|
|
922
|
+
require_success(result, "Failed to update title block")
|
|
923
|
+
return {
|
|
924
|
+
"status": "success",
|
|
925
|
+
"message": "Title block updated successfully",
|
|
926
|
+
"data": result.data,
|
|
927
|
+
"execution_time": result.execution_time,
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
@mcp.tool()
|
|
931
|
+
async def list_drawing_views() -> dict[str, Any]:
|
|
932
|
+
"""List the views on the active drawing.
|
|
933
|
+
|
|
934
|
+
Read-only. Use it to find an existing view's name before targeting it
|
|
935
|
+
(e.g. with ``auto_center_marks``). Errors when the active document is
|
|
936
|
+
not a drawing.
|
|
937
|
+
|
|
938
|
+
Returns:
|
|
939
|
+
dict[str, Any]: ``status``, ``views`` (view names, sheet formats
|
|
940
|
+
excluded) and ``count``.
|
|
941
|
+
|
|
942
|
+
Example:
|
|
943
|
+
```python
|
|
944
|
+
await list_drawing_views()
|
|
945
|
+
```
|
|
946
|
+
"""
|
|
947
|
+
result = await adapter.list_drawing_views()
|
|
948
|
+
require_success(result, context="Failed to list drawing views")
|
|
949
|
+
views = list(result.data or [])
|
|
950
|
+
return {
|
|
951
|
+
"status": "success",
|
|
952
|
+
"message": (
|
|
953
|
+
f"{len(views)} view(s): {', '.join(views)}"
|
|
954
|
+
if views
|
|
955
|
+
else "The drawing has no views"
|
|
956
|
+
),
|
|
957
|
+
"views": views,
|
|
958
|
+
"count": len(views),
|
|
959
|
+
"execution_time": result.execution_time,
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
@mcp.tool()
|
|
963
|
+
async def auto_center_marks(
|
|
964
|
+
input_data: AutoCenterMarksInput,
|
|
965
|
+
) -> dict[str, Any]:
|
|
966
|
+
"""Auto-insert centre marks on circular features in a drawing view.
|
|
967
|
+
|
|
968
|
+
Runs SolidWorks' automatic centre-mark insertion for the named view.
|
|
969
|
+
The API does not report how many marks it added, so the response
|
|
970
|
+
gives the view's centre-mark count before and after and the delta.
|
|
971
|
+
A run that added nothing is still a success — the view may have no
|
|
972
|
+
un-marked holes.
|
|
973
|
+
|
|
974
|
+
Args:
|
|
975
|
+
input_data (AutoCenterMarksInput): The view and which feature
|
|
976
|
+
types to mark.
|
|
977
|
+
|
|
978
|
+
Returns:
|
|
979
|
+
dict[str, Any]: Status plus ``center_marks_before`` /
|
|
980
|
+
``center_marks_after`` / ``center_marks_added``.
|
|
981
|
+
|
|
982
|
+
Example:
|
|
983
|
+
```python
|
|
984
|
+
await auto_center_marks({"view_name": "Drawing View1"})
|
|
985
|
+
```
|
|
986
|
+
"""
|
|
987
|
+
require_capability(
|
|
988
|
+
adapter,
|
|
989
|
+
"auto_center_marks",
|
|
990
|
+
"Active adapter does not support auto_center_marks; "
|
|
991
|
+
"no centre marks were inserted.",
|
|
992
|
+
)
|
|
993
|
+
input_data = normalize_input(input_data, AutoCenterMarksInput)
|
|
994
|
+
result = await adapter.auto_center_marks(
|
|
995
|
+
input_data.view_name,
|
|
996
|
+
input_data.mark_holes,
|
|
997
|
+
input_data.mark_fillets,
|
|
998
|
+
input_data.mark_slots,
|
|
999
|
+
)
|
|
1000
|
+
require_success(result, context="Failed to insert centre marks")
|
|
1001
|
+
data = result.data if isinstance(result.data, dict) else {}
|
|
1002
|
+
added = data.get("center_marks_added")
|
|
1003
|
+
return {
|
|
1004
|
+
"status": "success",
|
|
1005
|
+
"message": (
|
|
1006
|
+
f"Inserted {added} centre mark(s) on {input_data.view_name}"
|
|
1007
|
+
if isinstance(added, int)
|
|
1008
|
+
else f"Ran centre-mark insertion on {input_data.view_name}"
|
|
1009
|
+
),
|
|
1010
|
+
"data": data,
|
|
1011
|
+
"execution_time": result.execution_time,
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
tool_count = 14 # Number of tools registered
|
|
1015
|
+
return tool_count
|