Skip to main content
Glama
stringtheoryaccelerator

Maine Burn Permit MCP Server

check_fire_danger

Check current fire danger ratings for Maine towns to determine if burning is permitted, using real-time data from official fire weather systems.

Instructions

Checks the current fire danger rating for a specific town in Maine to see if burning is allowed.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
townYesThe name of the town to check fire danger for

Implementation Reference

  • Handler function that launches a headless Puppeteer browser, scrapes the Maine Fire Weather website to find the station for the given town, retrieves fire danger and weather data, and returns a structured response with text summary and data object.
    async (args) => {
        const { town } = args;
    
    let browser;
    try {
        browser = await puppeteer.launch({
            headless: true,
            args: ["--no-sandbox", "--disable-setuid-sandbox"],
        });
        const page = await browser.newPage();
        await page.goto(FIRE_DANGER_URL, { waitUntil: "networkidle0" });
    
        // Extract the STA object from the page script
        const staData = await page.evaluate(() => {
            // @ts-ignore
            return typeof STA !== 'undefined' ? STA : null;
        });
    
        if (!staData || !staData.stations) {
            return {
                content: [
                    {
                        type: "text",
                        text: "Could not retrieve station data from Maine Fire Weather website.",
                    },
                ],
                isError: true,
            };
        }
    
        // Find station by name (case-insensitive partial match)
        const stations = Object.values(staData.stations) as any[];
        const station = stations.find((s: any) =>
            s.station_name.toLowerCase().includes(town.toLowerCase())
        );
    
        if (!station) {
            const availableStations = stations.map((s: any) => s.station_name).join(", ");
            return {
                content: [
                    {
                        type: "text",
                        text: `Could not find a weather station matching "${town}". Available stations: ${availableStations}. Please try one of these locations.`,
                    },
                ],
            };
        }
    
        // Navigate to specific station page
        const stationUrl = `${FIRE_DANGER_URL}?station=${station.source_id}`;
        await page.goto(stationUrl, { waitUntil: "networkidle0" });
    
        const currentStationData = await page.evaluate(() => {
            // @ts-ignore
            return typeof STA !== 'undefined' ? STA.currentStation : null;
        });
    
        if (!currentStationData || !currentStationData.firedanger) {
            return {
                content: [
                    {
                        type: "text",
                        text: `Could not retrieve fire danger data for ${station.station_name}.`,
                    },
                ],
                isError: true,
            };
        }
    
        const fd = currentStationData.firedanger;
        const weather = currentStationData.weather;
    
        const output = {
            stationName: station.station_name,
            zoneId: station.zoneid.toString(),
            burningIndex: fd.bi.toString(),
            fireMoisture1hr: fd.fm1.toString(),
            fireMoisture10hr: fd.fm10.toString(),
            fireMoisture100hr: fd.fm100.toString(),
            temperature: `${weather.dry_temp}°F`,
            humidity: `${weather.rh}%`,
            windSpeed: `${weather.wind_sp} mph`,
            note: `Please verify the official Class Day (Low/Moderate/High) on the main map at ${FIRE_DANGER_URL} before burning.`,
        };
    
        return {
            content: [
                {
                    type: "text",
                    text: `Fire Weather Data for ${output.stationName} (Zone ${output.zoneId}):\n` +
                        `Burning Index: ${output.burningIndex}\n` +
                        `Fire Moisture (1-hr): ${output.fireMoisture1hr}\n` +
                        `Fire Moisture (10-hr): ${output.fireMoisture10hr}\n` +
                        `Fire Moisture (100-hr): ${output.fireMoisture100hr}\n` +
                        `Weather: ${output.temperature}, RH ${output.humidity}, Wind ${output.windSpeed}\n` +
                        `\nNote: ${output.note}`,
                },
            ],
            structuredContent: output,
        };
    
    } catch (error: any) {
        return {
            content: [
                {
                    type: "text",
                    text: `Error checking fire danger: ${error.message}`,
                },
            ],
            isError: true,
        };
    } finally {
        if (browser) {
            await browser.close();
        }
    }
  • Zod schemas defining the input (town name) and output (station details, fire indices, weather data, note) for the tool.
    inputSchema: {
        town: z.string().describe("The name of the town to check fire danger for"),
    },
    outputSchema: {
        stationName: z.string(),
        zoneId: z.string(),
        burningIndex: z.string(),
        fireMoisture1hr: z.string(),
        fireMoisture10hr: z.string(),
        fireMoisture100hr: z.string(),
        temperature: z.string(),
        humidity: z.string(),
        windSpeed: z.string(),
        note: z.string(),
    },
  • Function to register the 'check_fire_danger' tool on the MCP server, including schema and handler.
    export function registerFireDangerTool(server: McpServer) {
        server.registerTool(
            "check_fire_danger",
            {
                title: "Check Fire Danger",
                description: "Checks the current fire danger rating for a specific town in Maine to see if burning is allowed.",
                inputSchema: {
                    town: z.string().describe("The name of the town to check fire danger for"),
                },
                outputSchema: {
                    stationName: z.string(),
                    zoneId: z.string(),
                    burningIndex: z.string(),
                    fireMoisture1hr: z.string(),
                    fireMoisture10hr: z.string(),
                    fireMoisture100hr: z.string(),
                    temperature: z.string(),
                    humidity: z.string(),
                    windSpeed: z.string(),
                    note: z.string(),
                },
            },
            async (args) => {
                const { town } = args;
    
            let browser;
            try {
                browser = await puppeteer.launch({
                    headless: true,
                    args: ["--no-sandbox", "--disable-setuid-sandbox"],
                });
                const page = await browser.newPage();
                await page.goto(FIRE_DANGER_URL, { waitUntil: "networkidle0" });
    
                // Extract the STA object from the page script
                const staData = await page.evaluate(() => {
                    // @ts-ignore
                    return typeof STA !== 'undefined' ? STA : null;
                });
    
                if (!staData || !staData.stations) {
                    return {
                        content: [
                            {
                                type: "text",
                                text: "Could not retrieve station data from Maine Fire Weather website.",
                            },
                        ],
                        isError: true,
                    };
                }
    
                // Find station by name (case-insensitive partial match)
                const stations = Object.values(staData.stations) as any[];
                const station = stations.find((s: any) =>
                    s.station_name.toLowerCase().includes(town.toLowerCase())
                );
    
                if (!station) {
                    const availableStations = stations.map((s: any) => s.station_name).join(", ");
                    return {
                        content: [
                            {
                                type: "text",
                                text: `Could not find a weather station matching "${town}". Available stations: ${availableStations}. Please try one of these locations.`,
                            },
                        ],
                    };
                }
    
                // Navigate to specific station page
                const stationUrl = `${FIRE_DANGER_URL}?station=${station.source_id}`;
                await page.goto(stationUrl, { waitUntil: "networkidle0" });
    
                const currentStationData = await page.evaluate(() => {
                    // @ts-ignore
                    return typeof STA !== 'undefined' ? STA.currentStation : null;
                });
    
                if (!currentStationData || !currentStationData.firedanger) {
                    return {
                        content: [
                            {
                                type: "text",
                                text: `Could not retrieve fire danger data for ${station.station_name}.`,
                            },
                        ],
                        isError: true,
                    };
                }
    
                const fd = currentStationData.firedanger;
                const weather = currentStationData.weather;
    
                const output = {
                    stationName: station.station_name,
                    zoneId: station.zoneid.toString(),
                    burningIndex: fd.bi.toString(),
                    fireMoisture1hr: fd.fm1.toString(),
                    fireMoisture10hr: fd.fm10.toString(),
                    fireMoisture100hr: fd.fm100.toString(),
                    temperature: `${weather.dry_temp}°F`,
                    humidity: `${weather.rh}%`,
                    windSpeed: `${weather.wind_sp} mph`,
                    note: `Please verify the official Class Day (Low/Moderate/High) on the main map at ${FIRE_DANGER_URL} before burning.`,
                };
    
                return {
                    content: [
                        {
                            type: "text",
                            text: `Fire Weather Data for ${output.stationName} (Zone ${output.zoneId}):\n` +
                                `Burning Index: ${output.burningIndex}\n` +
                                `Fire Moisture (1-hr): ${output.fireMoisture1hr}\n` +
                                `Fire Moisture (10-hr): ${output.fireMoisture10hr}\n` +
                                `Fire Moisture (100-hr): ${output.fireMoisture100hr}\n` +
                                `Weather: ${output.temperature}, RH ${output.humidity}, Wind ${output.windSpeed}\n` +
                                `\nNote: ${output.note}`,
                        },
                    ],
                    structuredContent: output,
                };
    
            } catch (error: any) {
                return {
                    content: [
                        {
                            type: "text",
                            text: `Error checking fire danger: ${error.message}`,
                        },
                    ],
                    isError: true,
                };
            } finally {
                if (browser) {
                    await browser.close();
                }
            }
        });
    }
  • src/index.ts:14-14 (registration)
    Call to register the fire danger tool on the main MCP server instance.
    registerFireDangerTool(server);
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/stringtheoryaccelerator/publicmcp'

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