Skip to main content
Glama

openvsp.modify

Apply scripted parameter edits to an OpenVSP model, adjusting geometry with set commands and returning the generated script path.

Instructions

Apply scripted parameter edits to an OpenVSP model without running VSPAero. Use set_commands to adjust geometry; returns the generated script path.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
requestYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
result_pathNoPath to the generated VSPAero .adb file (if run_vspaero=True)
script_pathYesAbsolute path to the temporary script file

Implementation Reference

  • MCP handler function for openvsp.modify tool, registered with @app.tool and delegates to execute_openvsp with run_vspaero=False.
    @app.tool(
        name="openvsp.modify",
        description=(
            "Apply scripted parameter edits to an OpenVSP model without running VSPAero. "
            "Use set_commands to adjust geometry; returns the generated script path."),
        meta={"version": "0.1.0", "categories": ["geometry"]},
    )
    def modify(request: OpenVSPRequest) -> OpenVSPResponse:
        return execute_openvsp(request.model_copy(update={"run_vspaero": False}))
  • Core execution logic for OpenVSP modifications and optional VSPAero run, invoked by the tool handler.
    def execute_openvsp(request: OpenVSPRequest) -> OpenVSPResponse:
        """Run OpenVSP (and optionally VSPAero) using the provided request."""
    
        with tempfile.TemporaryDirectory(prefix="openvsp_mcp_") as tmpdir:
            workdir = Path(tmpdir)
            script_path = _write_script(request, workdir)
    
            try:
                result = subprocess.run(
                    [OPENVSP_BIN, "-script", str(script_path)],
                    check=False,
                    capture_output=True,
                )
            except FileNotFoundError as exc:  # pragma: no cover
                raise RuntimeError("OpenVSP binary not found") from exc
    
            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() or "OpenVSP script execution failed"
                raise RuntimeError(message)
    
            vspaero_output: str | None = None
            if request.run_vspaero:
                try:
                    aero = subprocess.run(
                        [VSPAERO_BIN, request.geometry_file, request.case_name],
                        check=False,
                        capture_output=True,
                    )
                except FileNotFoundError as exc:  # pragma: no cover
                    raise RuntimeError("VSPAero binary not found") from exc
    
                if aero.returncode != 0:
                    message = aero.stderr.decode("utf-8", errors="ignore").strip()
                    if not message:
                        message = aero.stdout.decode("utf-8", errors="ignore").strip() or "VSPAero execution failed"
                    raise RuntimeError(message)
                vspaero_output = str(Path(request.case_name).with_suffix(".adb"))
    
            return OpenVSPResponse(script_path=str(script_path), result_path=vspaero_output)
  • Pydantic input model (OpenVSPRequest) defining parameters for openvsp.modify tool calls.
    class OpenVSPRequest(BaseModel):
        """Parameters controlling geometry edits and optional VSPAero run."""
    
        geometry_file: str = Field(..., description="Path to the .vsp3 file")
        set_commands: list[VSPCommand] = Field(default_factory=list, description="Commands to run")
        run_vspaero: bool = Field(True, description="Execute VSPAero after editing geometry")
        case_name: str = Field("case", description="Base name for generated results")
  • Pydantic output model (OpenVSPResponse) for openvsp.modify tool responses.
    class OpenVSPResponse(BaseModel):
        """Response object capturing generated paths."""
    
        script_path: str = Field(..., description="Absolute path to the temporary script file")
        result_path: str | None = Field(
            None,
            description="Path to the generated VSPAero .adb file (if run_vspaero=True)",
        )
  • Generates the OpenVSP script file from set_commands and model path, used in execute_openvsp.
    def _write_script(request: OpenVSPRequest, working_dir: Path) -> Path:
        script_path = working_dir / "automation.vspscript"
        commands: Iterable[VSPCommand] = request.set_commands or []
    
        script_lines = [
            "// Auto-generated by openvsp-mcp",
            "void main() {",
            "    ClearVSPModel();",
            f"    ReadVSPFile(\"{request.geometry_file}\");",
        ]
    
        for command in commands:
            script_lines.append(f"    {_ensure_statement(command.command)}")
    
        script_lines.extend(
            [
                "    Update();",
                f"    SetVSP3FileName(\"{request.geometry_file}\");",
                f"    WriteVSPFile(\"{request.geometry_file}\", SET_ALL);",
                "}",
            ]
        )
    
        script_path.write_text("\n".join(script_lines) + "\n", encoding="utf-8")
        return script_path

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed2 schema fields changedv1.0.0
    • addedInput schema / $defs
      Added value: +{
      +  "OpenVSPRequest": {
      +    "description": "Parameters controlling geometry edits and optional VSPAero run.",
      +    "properties": {
      +      "case_name": {
      +        "default": "case",
      +        "description": "Base name for generated results",
      +        "title": "Case Name",
      +        "type": "string"
      +      },
      +      "geometry_file": {
      +        "description": "Path to the .vsp3 file",
      +        "title": "Geometry File",
      +        "type": "string"
      +      },
      +      "run_vspaero": {
      +        "default": true,
      +        "description": "Execute VSPAero after editing geometry",
      +        "title": "Run Vspaero",
      +        "type": "boolean"
      +      },
      +      "set_commands": {
      +        "description": "Commands to run",
      +        "items": {
      +          "$ref": "#/$defs/VSPCommand"
      +        },
      +        "title": "Set Commands",
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "geometry_file"
      +    ],
      +    "title": "OpenVSPRequest",
      +    "type": "object"
      +  },
      +  "VSPCommand": {
      +    "description": "Single OpenVSP script command.",
      +    "properties": {
      +      "command": {
      +        "description": "Literal line inserted into the VSP script",
      +        "title": "Command",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "command"
      +    ],
      +    "title": "VSPCommand",
      +    "type": "object"
      +  }
      +}
    • addedInput schema / title
      Added value: +"modifyArguments"
  2. First observed

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It mentions that the tool 'returns the generated script path,' which adds some behavioral context about the output. However, it lacks details on permissions needed, whether edits are destructive or reversible, error handling, or how the script interacts with the model. For a mutation tool with zero annotation coverage, this is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two sentences that are front-loaded with key information: the tool's purpose and a usage hint. There's no wasted text, though it could be slightly more structured to separate purpose from guidelines.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (mutation with 1 parameter but nested objects), no annotations, and an output schema (which reduces the need to describe returns), the description is partially complete. It covers the main action and output but misses critical behavioral details like safety, prerequisites, and parameter explanations, leaving gaps for an AI agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It references 'set_commands' to adjust geometry, which aligns with one parameter, but doesn't explain other parameters like 'geometry_file' or 'run_vspaero' (which seems contradictory to the description's 'without running VSPAero'). The description adds minimal value beyond the schema, resulting in a baseline score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Apply scripted parameter edits to an OpenVSP model without running VSPAero.' It specifies the action (apply edits), resource (OpenVSP model), and constraint (without VSPAero). However, it doesn't explicitly differentiate from sibling tools like 'openvsp.run_vspaero' beyond mentioning the VSPAero exclusion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides some usage context: 'Use set_commands to adjust geometry' and distinguishes it from VSPAero execution. However, it doesn't explicitly state when to use this tool versus alternatives like 'openvsp.inspect' or 'openvsp.run_vspaero', nor does it mention prerequisites or exclusions beyond the VSPAero aspect.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Three-Little-Birds/openvsp-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server