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.
Files changed (115) hide show
  1. solidworks_mcp/__init__.py +57 -0
  2. solidworks_mcp/adapters/__init__.py +40 -0
  3. solidworks_mcp/adapters/base.py +1882 -0
  4. solidworks_mcp/adapters/circuit_breaker.py +2052 -0
  5. solidworks_mcp/adapters/com_executor.py +252 -0
  6. solidworks_mcp/adapters/complexity_analyzer.py +272 -0
  7. solidworks_mcp/adapters/connection_pool.py +1884 -0
  8. solidworks_mcp/adapters/factory.py +366 -0
  9. solidworks_mcp/adapters/intelligent_router.py +218 -0
  10. solidworks_mcp/adapters/mock_adapter.py +4016 -0
  11. solidworks_mcp/adapters/pywin32_adapter.py +2842 -0
  12. solidworks_mcp/adapters/solidworks/__init__.py +17 -0
  13. solidworks_mcp/adapters/solidworks/bitmap.py +180 -0
  14. solidworks_mcp/adapters/solidworks/com_utils.py +56 -0
  15. solidworks_mcp/adapters/solidworks/dimension_layout.py +753 -0
  16. solidworks_mcp/adapters/solidworks/documentation.py +1476 -0
  17. solidworks_mcp/adapters/solidworks/drawing_standard.py +1993 -0
  18. solidworks_mcp/adapters/solidworks/face_selection.py +392 -0
  19. solidworks_mcp/adapters/solidworks/features.py +3362 -0
  20. solidworks_mcp/adapters/solidworks/io.py +3649 -0
  21. solidworks_mcp/adapters/solidworks/rebuild_diagnostics.py +269 -0
  22. solidworks_mcp/adapters/solidworks/rebuild_inspector.py +146 -0
  23. solidworks_mcp/adapters/solidworks/selection.py +308 -0
  24. solidworks_mcp/adapters/solidworks/sketch.py +2545 -0
  25. solidworks_mcp/adapters/sw_feature_errors.py +66 -0
  26. solidworks_mcp/adapters/sw_type_info.py +317 -0
  27. solidworks_mcp/adapters/vba_adapter.py +318 -0
  28. solidworks_mcp/adapters/vba_macro_executor.py +215 -0
  29. solidworks_mcp/agents/__init__.py +68 -0
  30. solidworks_mcp/agents/design_knowledge/assembly_patterns.md +127 -0
  31. solidworks_mcp/agents/design_knowledge/hinges.md +118 -0
  32. solidworks_mcp/agents/design_knowledge/snap_fits.md +93 -0
  33. solidworks_mcp/agents/design_knowledge/solidworks_basics.md +3 -0
  34. solidworks_mcp/agents/design_knowledge/tolerancing.md +128 -0
  35. solidworks_mcp/agents/harness.py +216 -0
  36. solidworks_mcp/agents/history_db.py +1508 -0
  37. solidworks_mcp/agents/retrieval_index.py +164 -0
  38. solidworks_mcp/agents/schemas.py +165 -0
  39. solidworks_mcp/agents/smoke_test.py +285 -0
  40. solidworks_mcp/agents/soc_exporter.py +650 -0
  41. solidworks_mcp/agents/soc_pickup.py +332 -0
  42. solidworks_mcp/agents/soc_rewind.py +221 -0
  43. solidworks_mcp/agents/vector_rag.py +665 -0
  44. solidworks_mcp/cache/__init__.py +5 -0
  45. solidworks_mcp/cache/response_cache.py +164 -0
  46. solidworks_mcp/config.py +729 -0
  47. solidworks_mcp/exceptions.py +37 -0
  48. solidworks_mcp/security/__init__.py +68 -0
  49. solidworks_mcp/security/auth.py +128 -0
  50. solidworks_mcp/security/cors.py +27 -0
  51. solidworks_mcp/security/rate_limiting.py +90 -0
  52. solidworks_mcp/security/runtime.py +155 -0
  53. solidworks_mcp/server.py +777 -0
  54. solidworks_mcp/server_cli_fixed.py +120 -0
  55. solidworks_mcp/setup/__init__.py +1 -0
  56. solidworks_mcp/setup/cli.py +399 -0
  57. solidworks_mcp/setup/clients.py +157 -0
  58. solidworks_mcp/setup/config_file.py +230 -0
  59. solidworks_mcp/setup/handshake.py +202 -0
  60. solidworks_mcp/setup/launcher.py +102 -0
  61. solidworks_mcp/setup/legacy.py +100 -0
  62. solidworks_mcp/setup/registration.py +193 -0
  63. solidworks_mcp/setup/solidworks.py +49 -0
  64. solidworks_mcp/tools/__init__.py +64 -0
  65. solidworks_mcp/tools/analysis.py +723 -0
  66. solidworks_mcp/tools/automation.py +578 -0
  67. solidworks_mcp/tools/docs_discovery.py +1476 -0
  68. solidworks_mcp/tools/drawing.py +1015 -0
  69. solidworks_mcp/tools/drawing_analysis.py +456 -0
  70. solidworks_mcp/tools/drawing_automation.py +627 -0
  71. solidworks_mcp/tools/engineering_data.py +466 -0
  72. solidworks_mcp/tools/error_classifier.py +232 -0
  73. solidworks_mcp/tools/export.py +833 -0
  74. solidworks_mcp/tools/file_facts.py +40 -0
  75. solidworks_mcp/tools/file_management.py +1473 -0
  76. solidworks_mcp/tools/input_compat.py +17 -0
  77. solidworks_mcp/tools/macro_recording.py +464 -0
  78. solidworks_mcp/tools/modeling.py +2360 -0
  79. solidworks_mcp/tools/sketching.py +1422 -0
  80. solidworks_mcp/tools/template_management.py +367 -0
  81. solidworks_mcp/tools/tool_boundary.py +280 -0
  82. solidworks_mcp/tools/vba_generation.py +1145 -0
  83. solidworks_mcp/ui/__init__.py +9 -0
  84. solidworks_mcp/ui/local_llm.py +725 -0
  85. solidworks_mcp/ui/routers/__init__.py +10 -0
  86. solidworks_mcp/ui/routers/checkpoint.py +24 -0
  87. solidworks_mcp/ui/routers/docs.py +47 -0
  88. solidworks_mcp/ui/routers/llm.py +83 -0
  89. solidworks_mcp/ui/routers/local_model.py +69 -0
  90. solidworks_mcp/ui/routers/model.py +75 -0
  91. solidworks_mcp/ui/routers/preview.py +38 -0
  92. solidworks_mcp/ui/routers/session.py +161 -0
  93. solidworks_mcp/ui/routers/viewer.py +154 -0
  94. solidworks_mcp/ui/schemas.py +502 -0
  95. solidworks_mcp/ui/server.py +298 -0
  96. solidworks_mcp/ui/service.py +481 -0
  97. solidworks_mcp/ui/services/__init__.py +136 -0
  98. solidworks_mcp/ui/services/_utils.py +958 -0
  99. solidworks_mcp/ui/services/checkpoint_service.py +1110 -0
  100. solidworks_mcp/ui/services/docs_service.py +282 -0
  101. solidworks_mcp/ui/services/llm_service.py +956 -0
  102. solidworks_mcp/ui/services/model_service.py +459 -0
  103. solidworks_mcp/ui/services/parameter_repair_service.py +314 -0
  104. solidworks_mcp/ui/services/preview_service.py +489 -0
  105. solidworks_mcp/ui/services/session_service.py +1389 -0
  106. solidworks_mcp/utils/__init__.py +9 -0
  107. solidworks_mcp/utils/feature_tree_classifier.py +342 -0
  108. solidworks_mcp/utils/logging.py +76 -0
  109. solidworks_mcp/utils/validation.py +77 -0
  110. solidworks_mcp/version.py +8 -0
  111. solidworks_mcp_python-1.5.0.dist-info/METADATA +410 -0
  112. solidworks_mcp_python-1.5.0.dist-info/RECORD +115 -0
  113. solidworks_mcp_python-1.5.0.dist-info/WHEEL +4 -0
  114. solidworks_mcp_python-1.5.0.dist-info/entry_points.txt +3 -0
  115. solidworks_mcp_python-1.5.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,193 @@
1
+ """Add or remove the server entry for one client, by that client's own means.
2
+
3
+ Most clients read a JSON file (:class:`JsonFileRegistrar`); Claude Code is
4
+ configured through its ``claude mcp`` command (:class:`ClaudeCliRegistrar`).
5
+ :func:`registrar_for` picks one, so the setup wizard never needs to know
6
+ which kind of client it is talking to.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import subprocess
12
+ from collections.abc import Callable
13
+ from typing import Any, Protocol, runtime_checkable
14
+
15
+ from .clients import SERVER_NAME, Client
16
+ from .config_file import ConfigFileError, EntryChange, server_entries, set_entry
17
+ from .legacy import launcher_name, old_entries
18
+
19
+ # subprocess.run's shape, so tests can pass a fake runner.
20
+ Runner = Callable[..., subprocess.CompletedProcess[str]]
21
+
22
+
23
+ class Registrar(Protocol):
24
+ """Changes a client's ``solidworks`` entry."""
25
+
26
+ def apply(self, entry: dict[str, Any] | None, *, dry_run: bool) -> EntryChange:
27
+ """Add or update ``entry``, or remove the entry when it is None.
28
+
29
+ Args:
30
+ entry: The entry to write, or ``None`` to remove it.
31
+ dry_run: Report what would change, and change nothing.
32
+
33
+ Returns:
34
+ What happened.
35
+ """
36
+ ...
37
+
38
+
39
+ @runtime_checkable
40
+ class OldEntryCleaner(Protocol):
41
+ """Finds and removes older entries that start this same server.
42
+
43
+ Only registrars that can read their client's entries implement this.
44
+ Claude Code's are held by its CLI, so it doesn't.
45
+ """
46
+
47
+ def old_entries(self) -> list[tuple[str, str]]:
48
+ """List the older entries for this server.
49
+
50
+ Returns:
51
+ ``(name, launcher file name)`` for each, safe to print.
52
+ """
53
+ ...
54
+
55
+ def remove_entry(self, name: str, *, dry_run: bool) -> EntryChange:
56
+ """Remove one entry by name.
57
+
58
+ Args:
59
+ name: The entry's key.
60
+ dry_run: Report what would change, and change nothing.
61
+
62
+ Returns:
63
+ What happened.
64
+ """
65
+ ...
66
+
67
+
68
+ class JsonFileRegistrar:
69
+ """Edits the ``solidworks`` entry in the client's JSON config file.
70
+
71
+ It also implements :class:`OldEntryCleaner`, since it can read the file.
72
+ """
73
+
74
+ def __init__(self, client: Client) -> None:
75
+ """Bind to a file-configured client.
76
+
77
+ Args:
78
+ client: A client whose ``config_path`` is set.
79
+ """
80
+ assert client.config_path is not None
81
+ self._path = client.config_path
82
+ self._section = client.section
83
+
84
+ def apply(self, entry: dict[str, Any] | None, *, dry_run: bool) -> EntryChange:
85
+ """Set or remove the entry in the file (see :func:`set_entry`).
86
+
87
+ Args:
88
+ entry: The entry to write, or ``None`` to remove it.
89
+ dry_run: Report what would change, and change nothing.
90
+
91
+ Returns:
92
+ What happened, with the backup made before writing.
93
+ """
94
+ return set_entry(self._path, self._section, SERVER_NAME, entry, dry_run=dry_run)
95
+
96
+ def old_entries(self) -> list[tuple[str, str]]:
97
+ """List the file's older entries that start this server.
98
+
99
+ Returns:
100
+ ``(name, launcher file name)`` for each (see :mod:`.legacy`).
101
+ """
102
+ servers = server_entries(self._path, self._section)
103
+ return [(name, launcher_name(servers[name])) for name in old_entries(servers)]
104
+
105
+ def remove_entry(self, name: str, *, dry_run: bool) -> EntryChange:
106
+ """Remove one entry from the file, with the same care as :meth:`apply`.
107
+
108
+ Args:
109
+ name: The entry's key.
110
+ dry_run: Report what would change, and change nothing.
111
+
112
+ Returns:
113
+ What happened, with the backup made before writing.
114
+ """
115
+ return set_entry(self._path, self._section, name, None, dry_run=dry_run)
116
+
117
+
118
+ class ClaudeCliRegistrar:
119
+ """Registers the server with ``claude mcp add --scope user``."""
120
+
121
+ def __init__(self, client: Client, run: Runner = subprocess.run) -> None:
122
+ """Bind to Claude Code.
123
+
124
+ Args:
125
+ client: The Claude Code client; ``found`` says if ``claude`` is on the PATH.
126
+ run: How to run a command (``subprocess.run``, or a fake in tests).
127
+ """
128
+ self._found = client.found
129
+ self._run = run
130
+
131
+ def apply(self, entry: dict[str, Any] | None, *, dry_run: bool) -> EntryChange:
132
+ """Run ``claude mcp`` to add or remove the server.
133
+
134
+ Without ``claude`` on the PATH, or with ``dry_run``, nothing runs and
135
+ the change reports the command for the user to run.
136
+
137
+ Args:
138
+ entry: The entry to register, or ``None`` to remove it.
139
+ dry_run: Report the command, and run nothing.
140
+
141
+ Returns:
142
+ What happened; ``location`` is the command line.
143
+
144
+ Raises:
145
+ ConfigFileError: ``claude mcp add`` failed.
146
+ """
147
+ remove = ["claude", "mcp", "remove", "--scope", "user", SERVER_NAME]
148
+ command = remove if entry is None else self._add_command(entry)
149
+ shown = subprocess.list2cmdline(command)
150
+ action = "removed" if entry is None else "added"
151
+ if dry_run or not self._found:
152
+ return EntryChange(shown, "not run" if not self._found else action)
153
+
154
+ # `add` fails if the name exists, so clear any old entry first; a
155
+ # failed remove only means there was nothing to remove.
156
+ self._run(remove, capture_output=True, text=True)
157
+ if entry is None:
158
+ return EntryChange(shown, action)
159
+ result = self._run(command, capture_output=True, text=True)
160
+ if result.returncode != 0:
161
+ raise ConfigFileError(
162
+ f"'claude mcp add' failed (exit {result.returncode}); run it yourself: {shown}"
163
+ )
164
+ return EntryChange(shown, action)
165
+
166
+ @staticmethod
167
+ def _add_command(entry: dict[str, Any]) -> list[str]:
168
+ """The ``claude mcp add`` command line for ``entry``.
169
+
170
+ Args:
171
+ entry: A ``{"command": ..., "args": [...]}`` server entry.
172
+
173
+ Returns:
174
+ The command, with the server's own command after ``--``.
175
+ """
176
+ return [
177
+ "claude", "mcp", "add", "--scope", "user", SERVER_NAME,
178
+ "--", entry["command"], *entry["args"],
179
+ ] # fmt: skip
180
+
181
+
182
+ def registrar_for(client: Client) -> Registrar:
183
+ """The registrar that knows how to configure ``client``.
184
+
185
+ Args:
186
+ client: A client from :func:`~.clients.find_clients`.
187
+
188
+ Returns:
189
+ A file registrar for file-configured clients, else the Claude CLI one.
190
+ """
191
+ if client.config_path is None:
192
+ return ClaudeCliRegistrar(client)
193
+ return JsonFileRegistrar(client)
@@ -0,0 +1,49 @@
1
+ """Which SolidWorks versions are installed, read from the Windows registry.
2
+
3
+ Each install leaves a key ``HKLM\\SOFTWARE\\SolidWorks\\SOLIDWORKS <year>``.
4
+ Setup only reports the years; the server finds the running SolidWorks itself.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import re
10
+ from types import ModuleType
11
+ from typing import Any
12
+
13
+ _VERSION_KEY = re.compile(r"^SOLIDWORKS (\d{4})$", re.IGNORECASE)
14
+
15
+
16
+ def installed_versions(registry: ModuleType | None = None) -> list[int]:
17
+ """List the installed SolidWorks years.
18
+
19
+ Args:
20
+ registry: A ``winreg``-like module; defaults to ``winreg`` (tests
21
+ pass a fake).
22
+
23
+ Returns:
24
+ The years, newest first; empty off Windows or with no install.
25
+ """
26
+ if registry is None:
27
+ try:
28
+ import winreg
29
+ except ImportError: # not Windows
30
+ return []
31
+ registry = winreg
32
+ reg: Any = registry # winreg and the test fakes share this shape
33
+ try:
34
+ root = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, r"SOFTWARE\SolidWorks")
35
+ except OSError: # no SolidWorks key at all
36
+ return []
37
+ years: set[int] = set()
38
+ with root:
39
+ index = 0
40
+ while True:
41
+ # EnumKey raises OSError past the last subkey; that ends the walk.
42
+ try:
43
+ name = reg.EnumKey(root, index)
44
+ except OSError:
45
+ break
46
+ if match := _VERSION_KEY.match(name):
47
+ years.add(int(match.group(1)))
48
+ index += 1
49
+ return sorted(years, reverse=True)
@@ -0,0 +1,64 @@
1
+ """Tools for SolidWorks MCP Server.
2
+
3
+ This module provides all the MCP tools for SolidWorks automation, organized by category.
4
+ """
5
+
6
+ from typing import Any
7
+
8
+ from fastmcp import FastMCP
9
+ from loguru import logger
10
+
11
+ from .analysis import register_analysis_tools
12
+ from .automation import register_automation_tools
13
+ from .docs_discovery import register_docs_discovery_tools
14
+ from .drawing import register_drawing_tools
15
+ from .drawing_analysis import register_drawing_analysis_tools
16
+ from .drawing_automation import register_drawing_automation_tools
17
+ from .engineering_data import register_engineering_data_tools
18
+ from .export import register_export_tools
19
+ from .file_management import register_file_management_tools
20
+ from .macro_recording import register_macro_recording_tools
21
+ from .modeling import register_modeling_tools
22
+ from .sketching import register_sketching_tools
23
+ from .template_management import register_template_management_tools
24
+ from .vba_generation import register_vba_generation_tools
25
+
26
+
27
+ async def register_tools(mcp: FastMCP, adapter: Any, config: Any) -> int:
28
+ """Register all SolidWorks MCP tools.
29
+
30
+ Args:
31
+ mcp (FastMCP): The mcp value.
32
+ adapter (Any): Adapter instance used for the operation.
33
+ config (Any): Configuration values for the operation.
34
+
35
+ Returns:
36
+ int: The computed numeric result.
37
+ """
38
+ logger.info("Registering SolidWorks MCP tools...")
39
+
40
+ # Register tool categories
41
+ await register_modeling_tools(mcp, adapter, config)
42
+ await register_sketching_tools(mcp, adapter, config)
43
+ await register_drawing_tools(mcp, adapter, config)
44
+ await register_drawing_analysis_tools(mcp, adapter, config)
45
+ await register_drawing_automation_tools(mcp, adapter, config)
46
+ await register_engineering_data_tools(mcp, adapter, config)
47
+ await register_analysis_tools(mcp, adapter, config)
48
+ await register_export_tools(mcp, adapter, config)
49
+ await register_automation_tools(mcp, adapter, config)
50
+ await register_file_management_tools(mcp, adapter, config)
51
+ await register_vba_generation_tools(mcp, adapter, config)
52
+ await register_template_management_tools(mcp, adapter, config)
53
+ await register_macro_recording_tools(mcp, adapter, config)
54
+ await register_docs_discovery_tools(mcp, adapter, config)
55
+
56
+ tool_count = len(await mcp.list_tools())
57
+
58
+ logger.info(f"Registered {tool_count} SolidWorks tools")
59
+ return tool_count
60
+
61
+
62
+ __all__ = [
63
+ "register_tools",
64
+ ]