Skip to main content
Glama
Noosbai
by Noosbai

check_printability

Analyze 3D models (STL/3MF) to detect printing issues like thin walls, long bridges, overhangs, and mesh problems. Provides a printability score and recommendations for successful prints.

Instructions

Analyse un modèle 3D (STL/3MF) pour détecter les problèmes d'impression : murs trop fins, ponts trop longs, overhangs, mesh non-manifold, stabilité, etc. Retourne un score de printabilité et des recommandations.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
file_pathYesChemin absolu vers le fichier STL ou 3MF
nozzle_diameterNoDiamètre de buse en mm (pour calibrer les seuils)

Implementation Reference

  • The main handler function that executes the check_printability tool. It validates the file exists, parses the 3D model, analyzes the mesh, detects print issues, and returns a formatted report with printability score, issues categorized by severity (error/warning/info), and Bible FDM diagnostic hints.
    async ({ file_path, nozzle_diameter }) => {
      try {
        if (!existsSync(file_path)) {
          return {
            isError: true,
            content: [{ type: "text" as const, text: `Fichier non trouvé : ${file_path}` }],
          };
        }
    
        console.error(`[check_printability] Analyzing ${file_path}...`);
        const mesh = await parseModel(file_path);
        const analysis = analyzeMesh(mesh);
        const report = detectPrintIssues(mesh.triangles, analysis, nozzle_diameter);
    
        const lines: string[] = [
          `## Rapport de printabilité`,
          `**Score** : ${report.score}/100`,
          `**Verdict** : ${report.summary}`,
          `**Buse** : ${nozzle_diameter}mm`,
          "",
        ];
    
        if (report.issues.length === 0) {
          lines.push("Aucun problème détecté. La pièce est prête à imprimer.");
        } else {
          // Group by severity
          const errors = report.issues.filter((i) => i.severity === "error");
          const warnings = report.issues.filter((i) => i.severity === "warning");
          const infos = report.issues.filter((i) => i.severity === "info");
    
          if (errors.length > 0) {
            lines.push("### Erreurs critiques");
            for (const issue of errors) {
              lines.push(`- **[${issue.category}]** ${issue.message}`);
              if (issue.detail) lines.push(`  _${issue.detail}_`);
            }
            lines.push("");
          }
    
          if (warnings.length > 0) {
            lines.push("### Avertissements");
            for (const issue of warnings) {
              lines.push(`- **[${issue.category}]** ${issue.message}`);
              if (issue.detail) lines.push(`  _${issue.detail}_`);
            }
            lines.push("");
          }
    
          if (infos.length > 0) {
            lines.push("### Informations");
            for (const issue of infos) {
              lines.push(`- **[${issue.category}]** ${issue.message}`);
              if (issue.detail) lines.push(`  _${issue.detail}_`);
              if (issue.bibleFdmRef) lines.push(`  _Bible FDM: ${issue.bibleFdmRef}_`);
            }
          }
        }
    
        // Bible FDM diagnostic hints
        if (report.diagnosticHints && report.diagnosticHints.length > 0) {
          lines.push("");
          lines.push("### Diagnostic Bible FDM");
          for (const hint of report.diagnosticHints) {
            lines.push(`**${hint.defect}**`);
            lines.push(`  Causes probables : ${hint.causes.join(", ")}`);
            lines.push(`  Actions recommandées :`);
            for (const fix of hint.fixes) {
              lines.push(`  - ${fix}`);
            }
            lines.push("");
          }
        }
    
        return {
          content: [{ type: "text" as const, text: lines.join("\n") }],
        };
      } catch (error) {
        return {
          isError: true,
          content: [{
            type: "text" as const,
            text: `Erreur : ${error instanceof Error ? error.message : String(error)}`,
          }],
        };
      }
    },
  • Input schema definition using Zod. Defines two parameters: 'file_path' (string, absolute path to STL/3MF file) and 'nozzle_diameter' (number, defaults to 0.4mm) used to calibrate detection thresholds.
    inputSchema: {
      file_path: z.string().describe("Chemin absolu vers le fichier STL ou 3MF"),
      nozzle_diameter: z
        .number()
        .default(0.4)
        .describe("Diamètre de buse en mm (pour calibrer les seuils)"),
    },
  • The registerCheckPrintability function that registers the tool with the MCP server. Includes tool metadata (title, description), input schema, and the handler function.
    export function registerCheckPrintability(server: McpServer) {
      server.registerTool(
        "check_printability",
        {
          title: "Vérifier la printabilité d'un modèle",
          description:
            "Analyse un modèle 3D (STL/3MF) pour détecter les problèmes d'impression : " +
            "murs trop fins, ponts trop longs, overhangs, mesh non-manifold, stabilité, etc. " +
            "Retourne un score de printabilité et des recommandations.",
          inputSchema: {
            file_path: z.string().describe("Chemin absolu vers le fichier STL ou 3MF"),
            nozzle_diameter: z
              .number()
              .default(0.4)
              .describe("Diamètre de buse en mm (pour calibrer les seuils)"),
          },
        },
        async ({ file_path, nozzle_diameter }) => {
          try {
            if (!existsSync(file_path)) {
              return {
                isError: true,
                content: [{ type: "text" as const, text: `Fichier non trouvé : ${file_path}` }],
              };
            }
    
            console.error(`[check_printability] Analyzing ${file_path}...`);
            const mesh = await parseModel(file_path);
            const analysis = analyzeMesh(mesh);
            const report = detectPrintIssues(mesh.triangles, analysis, nozzle_diameter);
    
            const lines: string[] = [
              `## Rapport de printabilité`,
              `**Score** : ${report.score}/100`,
              `**Verdict** : ${report.summary}`,
              `**Buse** : ${nozzle_diameter}mm`,
              "",
            ];
    
            if (report.issues.length === 0) {
              lines.push("Aucun problème détecté. La pièce est prête à imprimer.");
            } else {
              // Group by severity
              const errors = report.issues.filter((i) => i.severity === "error");
              const warnings = report.issues.filter((i) => i.severity === "warning");
              const infos = report.issues.filter((i) => i.severity === "info");
    
              if (errors.length > 0) {
                lines.push("### Erreurs critiques");
                for (const issue of errors) {
                  lines.push(`- **[${issue.category}]** ${issue.message}`);
                  if (issue.detail) lines.push(`  _${issue.detail}_`);
                }
                lines.push("");
              }
    
              if (warnings.length > 0) {
                lines.push("### Avertissements");
                for (const issue of warnings) {
                  lines.push(`- **[${issue.category}]** ${issue.message}`);
                  if (issue.detail) lines.push(`  _${issue.detail}_`);
                }
                lines.push("");
              }
    
              if (infos.length > 0) {
                lines.push("### Informations");
                for (const issue of infos) {
                  lines.push(`- **[${issue.category}]** ${issue.message}`);
                  if (issue.detail) lines.push(`  _${issue.detail}_`);
                  if (issue.bibleFdmRef) lines.push(`  _Bible FDM: ${issue.bibleFdmRef}_`);
                }
              }
            }
    
            // Bible FDM diagnostic hints
            if (report.diagnosticHints && report.diagnosticHints.length > 0) {
              lines.push("");
              lines.push("### Diagnostic Bible FDM");
              for (const hint of report.diagnosticHints) {
                lines.push(`**${hint.defect}**`);
                lines.push(`  Causes probables : ${hint.causes.join(", ")}`);
                lines.push(`  Actions recommandées :`);
                for (const fix of hint.fixes) {
                  lines.push(`  - ${fix}`);
                }
                lines.push("");
              }
            }
    
            return {
              content: [{ type: "text" as const, text: lines.join("\n") }],
            };
          } catch (error) {
            return {
              isError: true,
              content: [{
                type: "text" as const,
                text: `Erreur : ${error instanceof Error ? error.message : String(error)}`,
              }],
            };
          }
        },
      );
    }
  • src/index.ts:14-14 (registration)
    Import statement for registerCheckPrintability in the main server file.
    import { registerCheckPrintability } from "./tools/check-printability.js";
  • src/index.ts:43-43 (registration)
    Registration call that activates the check_printability tool on the MCP server instance.
    registerCheckPrintability(server);

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/Noosbai/PrusaMCP'

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