Fetch PVPC Prices
fetch_pricesRetrieve Spanish electricity price data (PVPC) for specific dates and regions to analyze energy costs and consumption patterns.
Instructions
Fetches the Voluntary Price for the Small Consumer (PVPC) prices for a given date range and geographical area.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| locale | No | Get translations for sources. Accepted values: `es`, `en`. Defaults to `es`. | es |
| startDate | No | Beginning of the date range to filter indicator values in iso8601 format. E.g. 2025-06-29T00:00:00.000+02:00. Defaults to the start of today. | 2026-01-03T00:00:00.000Z |
| endDate | No | End of the date range to filter indicator values in iso8601 format. E.g. 2025-06-29T23:59:59.999+02:00. Defaults to the end of today. | 2026-01-03T23:59:59.999Z |
| timeAggregation | No | How to aggregate indicator values when grouping them by time. Accepted values: `sum`, `average`. Defaults to `sum`. | sum |
| timeTruncation | No | Tells how to truncate data time series. Accepted values: `hour`, `day`, `month`, `year`. | |
| geographicalAggregation | No | How to aggregate indicator values when grouping them by geographical ID. Accepted values: `sum`, `average`. Defaults to `sum`. | sum |
| geographicalIds | No | Tells the geographical IDs to filter indicator values. Accepted values: `3` (España), `8741` (Península), `8742` (Canarias), `8743` (Baleares), `8744` (Ceuta), `8745` (Melilla). Defaults to `8741`, `8742`, `8743`, `8744`, `8745`. | |
| geographicalTruncation | No | Tells how to group data at geographical level when the geographical aggregation is informed. Accepted values: `country`, `electric_system`. |
Output Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prices | Yes |
Implementation Reference
- src/mcp.ts:110-166 (handler)MCP tool handler for 'fetch_prices'. Delegates to PvpcApiClient.fetchPrices, formats output as structured content with JSON text, and handles PvpcErrors.
async ({ locale, startDate, endDate, timeAggregation, timeTruncation, geographicalAggregation, geographicalIds, geographicalTruncation, }) => { try { const prices = await this.apiClient.fetchPrices({ locale, startDate, endDate, timeAggregation, timeTruncation, geographicalAggregation, geographicalIds, geographicalTruncation, }); return { content: [ { type: "text", text: JSON.stringify({ prices }, null, 2), }, ], structuredContent: { prices, }, }; } catch (error) { if (error instanceof PvpcError) { return { content: [ { type: "text", text: `Failed to fetch prices: ${error.name} - ${error.message}\nStatus: ${error.status}`, }, ], isError: true, }; } return { content: [ { type: "text", text: "Failed to fetch prices: Unknown error", }, ], isError: true, }; } }, - src/pvpc.ts:79-118 (helper)Core implementation in PvpcApiClient that constructs query params, fetches from REE ESIOS API, and transforms response into PvpcPrice array.
async fetchPrices(params: FetchPricesParams): Promise<PvpcPrice[]> { const queryParams = { locale: params.locale, start_date: params.startDate, end_date: params.endDate, time_agg: params.timeAggregation, time_trunc: params.timeTruncation, geo_agg: params.geographicalAggregation, geo_ids: params.geographicalIds, geo_trunc: params.geographicalTruncation, }; const stringQueryParams = QueryString.stringify(queryParams, { arrayFormat: "brackets", encode: false, skipNulls: true, }); const response = await this.get<FetchPricesResponse>( `?${stringQueryParams}`, ); const currencyCode = "EUR"; const currencySymbol = "€"; const magnitude = "€/MWh"; return response.indicator.values.map((v) => ({ price: { amount: v.value, currencyCode, currencySymbol, }, magnitude, datetime: v.datetime, datetimeUtc: v.datetime_utc, geographicalId: v.geo_id, geographicalName: v.geo_name, updatedAt: response.indicator.values_updated_at, })); } - src/mcp.ts:38-109 (schema)Zod-based inputSchema and outputSchema for the 'fetch_prices' tool, defining parameters like dates, locale, geo_ids with defaults and descriptions.
{ title: "Fetch PVPC Prices", description: "Fetches the Voluntary Price for the Small Consumer (PVPC) prices for a given date range and geographical area.", inputSchema: { locale: z .enum(["es", "en"]) .default("es") .describe( "Get translations for sources. Accepted values: `es`, `en`. Defaults to `es`.", ), startDate: z .string() .default(startOfToday().toISOString()) .describe( "Beginning of the date range to filter indicator values in iso8601 format. E.g. 2025-06-29T00:00:00.000+02:00. Defaults to the start of today.", ), endDate: z .string() .default(endOfToday().toISOString()) .describe( "End of the date range to filter indicator values in iso8601 format. E.g. 2025-06-29T23:59:59.999+02:00. Defaults to the end of today.", ), timeAggregation: z .enum(["sum", "average"]) .default("sum") .describe( "How to aggregate indicator values when grouping them by time. Accepted values: `sum`, `average`. Defaults to `sum`.", ), timeTruncation: z .enum(["hour", "day", "month", "year"]) .optional() .describe( "Tells how to truncate data time series. Accepted values: `hour`, `day`, `month`, `year`.", ), geographicalAggregation: z .enum(["sum", "average"]) .default("sum") .describe( "How to aggregate indicator values when grouping them by geographical ID. Accepted values: `sum`, `average`. Defaults to `sum`.", ), geographicalIds: z .array(z.number()) .default([8741, 8742, 8743, 8744, 8745]) .describe( "Tells the geographical IDs to filter indicator values. Accepted values: `3` (España), `8741` (Península), `8742` (Canarias), `8743` (Baleares), `8744` (Ceuta), `8745` (Melilla). Defaults to `8741`, `8742`, `8743`, `8744`, `8745`.", ), geographicalTruncation: z .enum(["country", "electric_system"]) .optional() .describe( "Tells how to group data at geographical level when the geographical aggregation is informed. Accepted values: `country`, `electric_system`.", ), }, outputSchema: { prices: z.array( z.object({ price: z.object({ amount: z.number(), currencyCode: z.string(), currencySymbol: z.string(), }), magnitude: z.string(), datetime: z.string(), datetimeUtc: z.string(), geographicalId: z.number(), geographicalName: z.string(), updatedAt: z.string(), }), ), }, }, - src/mcp.ts:36-167 (registration)Registers the 'fetch_prices' tool with the MCP server using registerTool, providing name, schema, and handler.
this.server.registerTool( "fetch_prices", { title: "Fetch PVPC Prices", description: "Fetches the Voluntary Price for the Small Consumer (PVPC) prices for a given date range and geographical area.", inputSchema: { locale: z .enum(["es", "en"]) .default("es") .describe( "Get translations for sources. Accepted values: `es`, `en`. Defaults to `es`.", ), startDate: z .string() .default(startOfToday().toISOString()) .describe( "Beginning of the date range to filter indicator values in iso8601 format. E.g. 2025-06-29T00:00:00.000+02:00. Defaults to the start of today.", ), endDate: z .string() .default(endOfToday().toISOString()) .describe( "End of the date range to filter indicator values in iso8601 format. E.g. 2025-06-29T23:59:59.999+02:00. Defaults to the end of today.", ), timeAggregation: z .enum(["sum", "average"]) .default("sum") .describe( "How to aggregate indicator values when grouping them by time. Accepted values: `sum`, `average`. Defaults to `sum`.", ), timeTruncation: z .enum(["hour", "day", "month", "year"]) .optional() .describe( "Tells how to truncate data time series. Accepted values: `hour`, `day`, `month`, `year`.", ), geographicalAggregation: z .enum(["sum", "average"]) .default("sum") .describe( "How to aggregate indicator values when grouping them by geographical ID. Accepted values: `sum`, `average`. Defaults to `sum`.", ), geographicalIds: z .array(z.number()) .default([8741, 8742, 8743, 8744, 8745]) .describe( "Tells the geographical IDs to filter indicator values. Accepted values: `3` (España), `8741` (Península), `8742` (Canarias), `8743` (Baleares), `8744` (Ceuta), `8745` (Melilla). Defaults to `8741`, `8742`, `8743`, `8744`, `8745`.", ), geographicalTruncation: z .enum(["country", "electric_system"]) .optional() .describe( "Tells how to group data at geographical level when the geographical aggregation is informed. Accepted values: `country`, `electric_system`.", ), }, outputSchema: { prices: z.array( z.object({ price: z.object({ amount: z.number(), currencyCode: z.string(), currencySymbol: z.string(), }), magnitude: z.string(), datetime: z.string(), datetimeUtc: z.string(), geographicalId: z.number(), geographicalName: z.string(), updatedAt: z.string(), }), ), }, }, async ({ locale, startDate, endDate, timeAggregation, timeTruncation, geographicalAggregation, geographicalIds, geographicalTruncation, }) => { try { const prices = await this.apiClient.fetchPrices({ locale, startDate, endDate, timeAggregation, timeTruncation, geographicalAggregation, geographicalIds, geographicalTruncation, }); return { content: [ { type: "text", text: JSON.stringify({ prices }, null, 2), }, ], structuredContent: { prices, }, }; } catch (error) { if (error instanceof PvpcError) { return { content: [ { type: "text", text: `Failed to fetch prices: ${error.name} - ${error.message}\nStatus: ${error.status}`, }, ], isError: true, }; } return { content: [ { type: "text", text: "Failed to fetch prices: Unknown error", }, ], isError: true, }; } }, ); - src/interfaces.ts:1-37 (schema)TypeScript interfaces for FetchPricesParams, FetchPricesResponse, and PvpcPrice used by the API client and tool output.
export interface PvpcPrice { price: { amount: number; currencyCode: string; currencySymbol: string; }; magnitude: string; datetime: string; datetimeUtc: string; geographicalId: number; geographicalName: string; updatedAt: string; } export interface FetchPricesResponse { indicator: { values: { value: number; datetime: string; datetime_utc: string; geo_id: number; geo_name: string; }[]; values_updated_at: string; }; } export interface FetchPricesParams { locale: string; startDate: string; endDate: string; timeAggregation: string; timeTruncation?: string; geographicalAggregation: string; geographicalIds: number[]; geographicalTruncation?: string; }