33## Architecture
44
55- ** Dual-mode** : Connected (Windows+CST) and Offline (any OS, generates VBA scripts)
6- - ** VBA Builder pattern** : All VBA generated via ` vba_builder.py ` — never use raw f-strings
6+ - ** VBA Builder pattern** : All VBA generated via ` vba_builder.py ` — never use raw f-strings for VBA
77- ** Modular tools** : Each ` tools/*.py ` exports ` TOOLS ` list + ` handle() ` function + ` register_*_tools() `
8- - ** ToolRegistry** : ` tools/__init__.py ` collects all tools and wires single ` list_tools ` /` call_tool ` handlers
8+ - ** ToolRegistry** : ` tools/__init__.py ` collects all tools via ` _registry.add_module(TOOLS, handle, client) ` and wires single ` list_tools ` /` call_tool ` handlers
9+ - ** Offline-first** : Server works fully on Linux/macOS. VBA scripts generated for manual execution in CST
910
1011## Key Files
1112
12- - ` types.py ` — Enums and dataclasses (ProjectType, SolverType, etc.)
13- - ` config.py ` — Env vars, CST path auto-detection
14- - ` validators.py ` — Input validation, VBA injection prevention
15- - ` vba_builder.py ` — Safe VBA code generation (builder pattern)
16- - ` cst_client.py ` — Session manager (connected/offline modes)
17- - ` server.py ` — MCP entry point
18- - ` tools/ ` — 16 tool modules (~ 107 tools total)
19- - ` data/ ` — JSON material databases, antenna templates, VBA reference
20-
21- ## Adding New Tools
22-
23- 1 . Add Tool definition to the module's ` TOOLS ` list
24- 2 . Add handler in the module's ` handle() ` function
25- 3 . Use ` VBABuilder ` for all VBA generation
26- 4 . Validate all inputs via ` validators.py `
13+ | File | Purpose |
14+ | ------| ---------|
15+ | ` types.py ` | Enums and dataclasses (ProjectType, SolverType, MeshType, etc.) |
16+ | ` config.py ` | Env vars, CST path auto-detection |
17+ | ` validators.py ` | Input validation, VBA injection prevention |
18+ | ` vba_builder.py ` | Safe VBA code generation (VBABuilder + VBAScript classes) |
19+ | ` cst_client.py ` | Session manager (connected/offline modes) |
20+ | ` server.py ` | MCP entry point, stdio transport |
21+ | ` tools/__init__.py ` | ToolRegistry aggregator, register_all_tools() |
22+ | ` data/ ` | JSON material databases, antenna templates, VBA reference |
23+
24+ ## Tool Categories (~ 107 tools)
25+
26+ | Module | Tools | Description |
27+ | --------| -------| -------------|
28+ | project.py | 8 | Create, open, save, close, export, status |
29+ | geometry.py | 13 | Brick, cylinder, sphere, cone, torus, extrude, loft, wire, polygon |
30+ | boolean.py | 4 | Add, subtract, intersect, insert |
31+ | transforms.py | 4 | Translate, rotate, mirror, scale |
32+ | materials.py | 8 | Create, load, list, assign, lossy metal, anisotropic |
33+ | ports.py | 7 | Waveguide, discrete, lumped, plane wave, Floquet, list, delete |
34+ | boundaries.py | 4 | Boundary conditions, background, symmetry, frequency range |
35+ | mesh.py | 5 | Mesh type, density, refinement, adaptive, info |
36+ | solvers.py | 5 | Time domain, frequency domain, eigenmode, integral equation, info |
37+ | simulation.py | 6 | Run, run_async, status, pause, resume, stop |
38+ | results.py | 10 | S-params, farfield, field monitor, impedance, VSWR, gain, efficiency |
39+ | import_export.py | 5 | CAD import/export, Touchstone, farfield |
40+ | parameters.py | 6 | Set, get, list, delete, sweep, optimize |
41+ | antenna_templates.py | 13 | Parametric designs: patch, dipole, monopole, horn, Yagi, helix, etc. |
42+ | pcb.py | 6 | Stackup, traces, vias, ground planes, Gerber import |
43+ | vba.py | 3 | Raw VBA execution, help reference, object listing |
44+
45+ ## Adding a New Tool
46+
47+ 1 . Add ` Tool() ` definition to the module's ` TOOLS ` list with proper inputSchema
48+ 2 . Add handler in the module's ` handle() ` function (inside the try/except)
49+ 3 . Use ` VBABuilder ` for all VBA generation — never raw f-strings
50+ 4 . Validate all inputs via ` validators.py ` functions
27515 . Return ` list[TextContent] ` with JSON response
52+ 6 . Register in ` tools/__init__.py ` via ` register_*_tools() `
53+
54+ ### Adding a New Tool Module
55+
56+ 1 . Create ` tools/new_category.py ` with ` TOOLS ` , ` handle() ` , and ` register_*_tools() `
57+ 2 . Follow the pattern: try/except in handle(), error format ` {"status": "error", "message": "..."} `
58+ 3 . Import and call ` register_*_tools() ` in ` tools/__init__.py:register_all_tools() `
59+ 4 . Add tests in ` tests/test_tools_new_category.py `
60+
61+ ## Error Handling Contract
62+
63+ All ` handle() ` functions return consistent error format:
64+ ``` json
65+ {"status" : " error" , "message" : " Human-readable error description" }
66+ ```
67+
68+ - Every ` handle() ` must wrap its body in ` try/except Exception as e `
69+ - Internal validation errors (e.g., bad enum value) return the same format
70+ - Never raise exceptions from handle() — always return TextContent with error JSON
71+
72+ ## Security Rules
73+
74+ - All VBA passes through ` validate_vba_input() ` — blocks Shell, CreateObject, file I/O, Declare, SendKeys
75+ - All file paths checked for traversal (` .. ` ) via ` validate_file_path() `
76+ - All names restricted to ` [A-Za-z_][A-Za-z0-9_ .-]* ` via ` validate_name() `
77+ - Component paths validated via ` validate_component_path() `
78+ - VBA strings escaped via ` _escape_vba_string() ` — blocks concatenation injection
79+ - No hardcoded paths — everything via env vars or auto-detection
2880
2981## Testing
3082
@@ -33,14 +85,26 @@ pip install -e ".[dev]"
3385pytest tests/ -v
3486```
3587
36- Tests run in offline mode — no CST installation needed.
88+ Tests run in offline mode — no CST installation needed. The offline client returns ` {"status": "offline", "vba": code} ` for all execute_vba calls.
3789
38- ## Security Rules
90+ ### Test Pattern
91+ ``` python
92+ @pytest.mark.asyncio
93+ async def test_tool (client : CSTClient):
94+ from mcp_cst_studio.tools.module import handle
95+ result = await handle(" cst_tool_name" , {args}, client)
96+ data = json.loads(result[0 ].text)
97+ assert " vba" in data or " status" in data
98+ ```
3999
40- - All VBA passes through ` validate_vba_input() ` — blocks Shell, CreateObject, file I/O
41- - All file paths checked for traversal (` .. ` )
42- - All names restricted to alphanumeric + underscore + space + dot + hyphen
43- - No hardcoded paths — everything via env vars or auto-detection
100+ ## RF Engineering References
101+
102+ - Patch antenna dimensions: Balanis Ch. 14, Hammerstad-Jensen effective permittivity (Eq. 14-1)
103+ - Microstrip impedance: Wheeler synthesis (narrow/wide strip regimes)
104+ - Stripline impedance: Cohn formula (Z0 = 94.25/sqrt(eps_r) * ...)
105+ - Yagi design: reflector 0.20λ spacing, directors 0.25λ spacing
106+ - Helix gain: Kraus formula (C²NS/λ³)
107+ - Horn gain: aperture efficiency formula
44108
45109## Build & Run
46110
@@ -50,6 +114,6 @@ mcp-cst-studio # runs stdio server
50114```
51115
52116Environment variables:
53- - ` CST_PATH ` — CST installation directory
54- - ` CST_WORK_DIR ` — Working directory for projects
55- - ` CST_VERSION ` — CST version (default: 2026)
117+ - ` CST_PATH ` — CST installation directory (auto-detected on Windows)
118+ - ` CST_WORK_DIR ` — Working directory for projects (default: ~ /cst_projects)
119+ - ` CST_VERSION ` — CST version year (default: 2026)
0 commit comments