openvsp.inspect
Analyze OpenVSP aircraft geometry to identify components and retrieve structural data without making modifications to the design.
Instructions
Describe an OpenVSP geometry without modifying it. Returns component IDs and raw info.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Implementation Reference
- src/openvsp_mcp/describe.py:14-62 (handler)Core handler logic for openvsp.inspect: generates a temporary script, executes OpenVSP to describe the model, checks exit code, parses .vsp3 XML to extract geometry IDs, wing names, and detailed info.def describe_geometry(geometry_file: str) -> OpenVSPInspectResponse: """Run OpenVSP in describe mode and parse high-level geometry information.""" with tempfile.TemporaryDirectory(prefix="openvsp_mcp_describe_") as tmpdir: temp_request = OpenVSPRequest( geometry_file=geometry_file, set_commands=[], run_vspaero=False, case_name="describe", ) script_path = _write_script(temp_request, Path(tmpdir)) result = subprocess.run( [OPENVSP_BIN, "-script", str(script_path)], check=False, capture_output=True, ) if result.returncode not in _OK_EXIT_CODES: message = result.stderr.decode("utf-8", errors="ignore").strip() if not message: message = result.stdout.decode("utf-8", errors="ignore").strip() raise RuntimeError(message or "OpenVSP describe run failed") tree = ET.parse(geometry_file) root = tree.getroot() geom_ids: list[str] = [] wing_names: list[str] = [] info_lines: list[str] = [] for geom in root.findall(".//Geom"): name_elem = geom.find("ParmContainer/Name") geom_name = name_elem.text if name_elem is not None else "" id_elem = geom.find("ParmContainer/ID") geom_id = id_elem.text if id_elem is not None else "" type_elem = geom.find("GeomBase/TypeName") geom_type = type_elem.text if type_elem is not None else "" if geom_id: geom_ids.append(geom_id) if geom_type.lower() == "wing" and geom_name: wing_names.append(geom_name) info_lines.append(f"{geom_id or 'UNKNOWN'}:{geom_name or 'Unnamed'}:{geom_type or 'Unknown'}") return OpenVSPInspectResponse( geom_ids=geom_ids, wing_names=wing_names, info_log="\n".join(info_lines), )
- src/openvsp_mcp/tool.py:20-28 (registration)Registers the openvsp.inspect tool on the FastMCP server instance within build_tool(), wiring the inspect handler which delegates to describe_geometry.@app.tool( name="openvsp.inspect", description=( "Describe an OpenVSP geometry without modifying it. Returns component IDs and raw info."), meta={"version": "0.1.0", "categories": ["geometry", "aero", "inspection"]}, ) def inspect(request: OpenVSPGeometryRequest) -> OpenVSPInspectResponse: return describe_geometry(request.geometry_file)
- src/openvsp_mcp/models.py:14-16 (schema)Pydantic input schema for openvsp.inspect tool: requires path to .vsp3 geometry file.class OpenVSPGeometryRequest(BaseModel): geometry_file: str = Field(..., description="Path to the .vsp3 file")
- src/openvsp_mcp/models.py:27-33 (schema)Pydantic output schema for openvsp.inspect: returns lists of geom IDs, wing names, and raw info log.class OpenVSPInspectResponse(BaseModel): """High-level summary of a geometry.""" geom_ids: list[str] = Field(..., description="Top-level geometry IDs discovered") wing_names: list[str] = Field(default_factory=list, description="Detected wing geometry names") info_log: str = Field(..., description="Raw output from OpenVSP describe command")
- src/openvsp_mcp/describe.py:10-28 (helper)Imports helpers from core (OpenVSP binary path, exit codes, script writer) and models used in describe_geometry.from .core import OPENVSP_BIN, _OK_EXIT_CODES, _write_script from .models import OpenVSPInspectResponse, OpenVSPRequest def describe_geometry(geometry_file: str) -> OpenVSPInspectResponse: """Run OpenVSP in describe mode and parse high-level geometry information.""" with tempfile.TemporaryDirectory(prefix="openvsp_mcp_describe_") as tmpdir: temp_request = OpenVSPRequest( geometry_file=geometry_file, set_commands=[], run_vspaero=False, case_name="describe", ) script_path = _write_script(temp_request, Path(tmpdir)) result = subprocess.run( [OPENVSP_BIN, "-script", str(script_path)], check=False,