opa_get_forecasts
Get short-term energy price forecasts for crude oil, natural gas, and other key commodities from the EIA STEO and additional sources.
Instructions
Get energy price forecasts from EIA Short-Term Energy Outlook (STEO) and other sources. Use when the user asks about price predictions, outlooks, or where oil/gas prices are heading. Returns forecast data for key commodities. Requires a paid plan with energy intelligence access.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/index.ts:1266-1288 (handler)The actual handler/logic for the 'opa_get_forecasts' tool. It calls makeApiRequest to '/v1/ei/forecasts/latest', checks for success, formats the response as JSON in a markdown block, and returns a text result.
server.tool( "opa_get_forecasts", "Get energy price forecasts from EIA Short-Term Energy Outlook (STEO) and other sources. Use when the user asks about price predictions, outlooks, or where oil/gas prices are heading. Returns forecast data for key commodities. Requires a paid plan with energy intelligence access.", {}, async () => { const response = await makeApiRequest<ApiResponse<Record<string, unknown>>>( "/v1/ei/forecasts/latest", ); if (!response || response.status !== "success") { return errorResult( "Forecast data not available. This requires a paid plan with energy intelligence access.", ); } let text = "# Energy Price Forecasts\n\n"; text += "```json\n" + JSON.stringify(response.data, null, 2) + "\n```\n"; text += "\n_Source: EIA STEO | Data from [OilPriceAPI](https://oilpriceapi.com)_"; return textResult(text); }, ); - src/index.ts:1266-1288 (registration)The tool is registered via server.tool() with the name 'opa_get_forecasts', a description, an empty schema object (no inputs), and the handler function.
server.tool( "opa_get_forecasts", "Get energy price forecasts from EIA Short-Term Energy Outlook (STEO) and other sources. Use when the user asks about price predictions, outlooks, or where oil/gas prices are heading. Returns forecast data for key commodities. Requires a paid plan with energy intelligence access.", {}, async () => { const response = await makeApiRequest<ApiResponse<Record<string, unknown>>>( "/v1/ei/forecasts/latest", ); if (!response || response.status !== "success") { return errorResult( "Forecast data not available. This requires a paid plan with energy intelligence access.", ); } let text = "# Energy Price Forecasts\n\n"; text += "```json\n" + JSON.stringify(response.data, null, 2) + "\n```\n"; text += "\n_Source: EIA STEO | Data from [OilPriceAPI](https://oilpriceapi.com)_"; return textResult(text); }, ); - src/index.ts:396-400 (helper)The textResult helper function used by the handler to construct the successful response.
function textResult(text: string) { return { content: [{ type: "text" as const, text }], }; } - src/index.ts:386-391 (helper)The errorResult helper function used by the handler when the API request fails.
function errorResult(message: string) { return { content: [{ type: "text" as const, text: message }], isError: true, }; } - src/index.ts:457-518 (helper)The makeApiRequest helper function that performs the API call with retry logic and exponential backoff. Called by the handler to fetch forecast data from '/v1/ei/forecasts/latest'.
export async function makeApiRequest<T>( endpoint: string, fetchFn: typeof fetch = fetch, ): Promise<T | null> { const headers: Record<string, string> = { "User-Agent": USER_AGENT, Accept: "application/json", }; if (API_KEY) { headers["Authorization"] = `Bearer ${API_KEY}`; } const maxRetries = 3; for (let attempt = 0; attempt <= maxRetries; attempt++) { try { const response = await fetchFn(`${API_BASE}${endpoint}`, { headers }); if (response.ok) { return (await response.json()) as T; } if (response.status === 401) { console.error( "Authentication failed. Set OILPRICEAPI_KEY environment variable. Get a free key at https://oilpriceapi.com/signup", ); return null; } // Retry on 429 and 5xx if ( (response.status === 429 || response.status >= 500) && attempt < maxRetries ) { const retryAfter = response.headers.get("Retry-After"); const delay = retryAfter ? Math.min(parseInt(retryAfter, 10), 60) * 1000 : Math.pow(2, attempt) * 1000; await new Promise((resolve) => setTimeout(resolve, delay)); continue; } console.error( `HTTP ${response.status}: ${response.statusText} for ${endpoint}`, ); return null; } catch (error) { if (attempt === maxRetries) { console.error( `API request failed after ${maxRetries + 1} attempts: ${endpoint}`, error, ); return null; } const delay = Math.pow(2, attempt) * 1000; await new Promise((resolve) => setTimeout(resolve, delay)); } } return null; }