server.py•4.04 kB
import os
import subprocess
from fastmcp import FastMCP
import pyvista as pv
from run_heat_transfer import run_single_heat_transfer
mcp = FastMCP(name="Hardware Directory")
@mcp.tool
def create_box(x_length: float, y_length: float, z_length: float) -> str:
"""Create a cube with dimensions x_length, y_length and z_length"""
if not os.path.exists("run_cadquery.py"):
with open("run_cadquery.py", "w") as cfile:
cfile.write("import cadquery as cq\n")
cfile.write("from cadquery import exporters\n")
cfile.close()
with open("run_cadquery.py", "a") as cfile:
cfile.write(
f"part = cq.Workplane('XY').box({x_length}, {y_length}, {z_length})\n"
)
cfile.close()
return "Part created"
@mcp.tool
def add_through_hole(diameter) -> str:
"""Add a through hole with diameter"""
with open("run_cadquery.py", "a") as cfile:
cfile.write(f'part = part.faces(">Z").workplane().hole({diameter})\n')
cfile.close()
return "Hole added"
@mcp.tool
def export_part() -> str:
"""Export part to .stl file. This tool call should be called as the last tool call in a chain of tool calls."""
if os.path.exists("run_cadquery.py"):
with open("run_cadquery.py", "a") as cfile:
cfile.write("exporters.export(part, 'part.stl')\n")
cfile.close()
result = subprocess.run(["uv", "run", "run_cadquery.py"])
return "Part exported to part.stl"
else:
return "No part created yet"
@mcp.tool
def visualize_stl_file() -> str:
mesh = pv.read("part.stl")
mesh.plot()
return "Part visualized"
@mcp.tool
def run_heat_transfer_tool_call() -> str:
return run_single_heat_transfer()
@mcp.tool
def add_rectangle_extrusion_outward(center_x, center_y, x_length, y_length, depth):
"""
Add a rectangle extrusion at (center_x, center_y) with size x_length x y_length x depth
"""
code = f"""
# Add a rectangle extrusion at ({center_x}, {center_y}) with size {x_length} times {y_length}
part = (
part
.faces(">Z") # pick top face
.workplane() # start sketch
.center({center_x}, {center_y}) # move sketch origin
.rect({x_length}, {y_length}, centered=True) # rectangle width=8, height=4
.extrude({depth}) # extrude upward
)
"""
with open("run_cadquery.py", "a") as cfile:
cfile.write(code)
cfile.close()
return "Extrusion added"
@mcp.tool
def add_rectangle_extrusion_inward(center_x, center_y, x_length, y_length, depth):
"""
Add a rectangle extrusion at (center_x, center_y) with size x_length x y_length x depth
"""
code = f"""
# Cut a smaller rectangle at ({center_x}, {center_y}) with size {x_length}×{y_length}
part = (
part
.faces(">Z")
.workplane()
.center({center_x}, {center_y}) # new location
.rect({x_length}, {y_length}, centered=True) # width=6, height=3
.cutBlind(-{depth}) # cut downward
)
"""
with open("run_cadquery.py", "a") as cfile:
cfile.write(code)
cfile.close()
return "Extrusion added"
@mcp.tool
def read_cadquery_file() -> str:
"""Reads the python file where the cadquery code is stored"""
with open("run_cadquery.py", "r") as cfile:
return cfile.read()
@mcp.tool
def rewrite_cadquery_file(new_file_content: str) -> str:
"""Overwrite the existing CAD query file."""
with open("run_cadquery.py", "w") as cfile:
cfile.write(new_file_content)
cfile.close()
return "File overwritten"
# @mcp.tool
# def update_part(part_id: int, description: str) -> str:
# """Update the description of the given part."""
# return f"Part {part_id} updated: {description}"
# @mcp.tool
# def delete_part(part_id: int) -> str:
# """Delete the given part."""
# return f"Part {part_id} deleted"
if __name__ == "__main__":
mcp.run(transport="http", port=8000)