inspect_contam_project
Analyze CONTAM project files to provide structural summaries before editing or simulation runs, enabling informed airflow and contaminant transport modeling decisions.
Instructions
Use this when you want a quick structural summary of a CONTAM .prj file before editing or running it.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| projectPath | Yes |
Implementation Reference
- contam-mcp/src/server.js:2123-2138 (handler)Tool registration and handler for "inspect_contam_project"
server.tool( "inspect_contam_project", "Use this when you want a quick structural summary of a CONTAM .prj file before editing or running it.", { projectPath: z.string() }, async ({ projectPath }) => { const resolvedProjectPath = asAbsolutePath(projectPath); if (!(await fileExists(resolvedProjectPath))) { throw new Error(`Project file not found: ${resolvedProjectPath}`); } const inspection = await inspectContamProject(resolvedProjectPath); return toolResponse("Parsed CONTAM project metadata.", inspection); } ); - contam-mcp/src/server.js:443-450 (helper)The main logic function for inspecting a CONTAM project, which reads the file and calls parsing logic.
async function inspectContamProject(projectPath) { const lines = await readProjectLines(projectPath); return { projectPath, projectDirectory: path.dirname(projectPath), ...inspectContamProjectLines(lines) }; } - contam-mcp/src/server.js:394-441 (helper)Helper function that parses the contents (lines) of a project file.
function inspectContamProjectLines(lines) { const references = {}; for (const descriptor of projectReferenceDescriptors) { references[descriptor.key] = { value: null, comment: null, lineNumber: null }; } for (let index = 0; index < lines.length; index += 1) { const line = lines[index]; const { valuePart, commentPart } = splitCommentLine(line); const normalizedComment = commentPart.toLowerCase(); for (const descriptor of projectReferenceDescriptors) { const expected = descriptor.commentLabel; if ( normalizedComment === expected || normalizedComment === `no ${expected}` ) { references[descriptor.key] = { value: valuePart && valuePart.toLowerCase() !== "null" ? valuePart : null, comment: commentPart, lineNumber: index + 1 }; } } } return { formatLine: lines[0]?.trim() || null, title: lines[1]?.trim() || null, totalLines: lines.length, references, dateRange: parseDateRange(lines), counts: { contaminants: parseSectionCount(lines, "contaminants"), species: parseSectionCount(lines, "species"), levels: parseSectionCount(lines, "levels plus icon data"), daySchedules: parseSectionCount(lines, "day-schedules"), weekSchedules: parseSectionCount(lines, "week-schedules"), windPressureProfiles: parseSectionCount(lines, "wind pressure profiles") }, preview: lines.slice(0, 20) }; }