UNPKG

open-meteo-mcp-server

Version:

Model Context Protocol server for Open-Meteo weather APIs

190 lines 7.93 kB
import axios from 'axios'; export class OpenMeteoClient { client; airQualityClient; marineClient; archiveClient; seasonalClient; ensembleClient; geocodingClient; floodClient; climateClient; constructor(baseURL = process.env.OPEN_METEO_API_URL || 'https://api.open-meteo.com', version = 'unknown') { const config = { timeout: 30000, headers: { Accept: 'application/json', 'User-Agent': `Open-Meteo-MCP-Server/${version}`, }, }; // Utilisation des variables d'environnement avec des valeurs par défaut const airQualityURL = process.env.OPEN_METEO_AIR_QUALITY_API_URL || 'https://air-quality-api.open-meteo.com'; const marineURL = process.env.OPEN_METEO_MARINE_API_URL || 'https://marine-api.open-meteo.com'; const archiveURL = process.env.OPEN_METEO_ARCHIVE_API_URL || 'https://archive-api.open-meteo.com'; const seasonalURL = process.env.OPEN_METEO_SEASONAL_API_URL || 'https://seasonal-api.open-meteo.com'; const ensembleURL = process.env.OPEN_METEO_ENSEMBLE_API_URL || 'https://ensemble-api.open-meteo.com'; const geocodingURL = process.env.OPEN_METEO_GEOCODING_API_URL || 'https://geocoding-api.open-meteo.com'; const floodURL = process.env.OPEN_METEO_FLOOD_API_URL || 'https://flood-api.open-meteo.com'; const climateURL = process.env.OPEN_METEO_CLIMATE_API_URL || 'https://climate-api.open-meteo.com'; this.client = axios.create({ baseURL, ...config }); this.airQualityClient = axios.create({ baseURL: airQualityURL, ...config }); this.marineClient = axios.create({ baseURL: marineURL, ...config }); this.archiveClient = axios.create({ baseURL: archiveURL, ...config }); this.seasonalClient = axios.create({ baseURL: seasonalURL, ...config }); this.ensembleClient = axios.create({ baseURL: ensembleURL, ...config }); this.geocodingClient = axios.create({ baseURL: geocodingURL, ...config }); this.floodClient = axios.create({ baseURL: floodURL, ...config }); this.climateClient = axios.create({ baseURL: climateURL, ...config }); this.setupErrorInterceptors(); } setupErrorInterceptors() { for (const instance of [ this.client, this.airQualityClient, this.marineClient, this.archiveClient, this.seasonalClient, this.ensembleClient, this.geocodingClient, this.floodClient, this.climateClient, ]) { instance.interceptors.response.use(undefined, OpenMeteoClient.mapHttpError); } } static mapHttpError(error) { if (axios.isAxiosError(error)) { const status = error.response?.status; const data = error.response?.data; const apiMessage = data?.reason ?? data?.error ?? error.message; if (status === 400) throw new Error(`Invalid request parameters: ${apiMessage}`); if (status === 422) throw new Error(`Invalid parameter value: ${apiMessage}`); if (status === 429) throw new Error('Open-Meteo rate limit reached. Please retry later.'); if (status !== undefined && status >= 500) throw new Error(`Open-Meteo server error (${status}): ${apiMessage}`); } throw error; } buildParams(params) { const result = {}; for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null) { if (Array.isArray(value)) { result[key] = value.join(','); } else { result[key] = String(value); } } } return result; } async getForecast(params) { const response = await this.client .get('/v1/forecast', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getArchive(params) { const response = await this.archiveClient .get('/v1/archive', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getDwdIcon(params) { const response = await this.client .get('/v1/dwd-icon', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getGfs(params) { const response = await this.client .get('/v1/gfs', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getMeteoFrance(params) { const response = await this.client .get('/v1/meteofrance', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getEcmwf(params) { const response = await this.client .get('/v1/ecmwf', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getJma(params) { const response = await this.client .get('/v1/jma', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getMetno(params) { const response = await this.client .get('/v1/metno', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getGem(params) { const response = await this.client .get('/v1/gem', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getAirQuality(params) { const response = await this.airQualityClient .get('/v1/air-quality', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getMarine(params) { const response = await this.marineClient .get('/v1/marine', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getEnsemble(params) { const response = await this.ensembleClient .get('/v1/ensemble', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getElevation(params) { const response = await this.client .get('/v1/elevation', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getFlood(params) { const response = await this.floodClient .get('/v1/flood', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getSeasonal(params) { const response = await this.seasonalClient .get('/v1/seasonal', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getClimate(params) { const response = await this.climateClient .get('/v1/climate', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } async getGeocoding(params) { const response = await this.geocodingClient .get('/v1/search', { params: this.buildParams(params) }) .catch(OpenMeteoClient.mapHttpError); return response.data; } } //# sourceMappingURL=client.js.map