Query Economic Surprises
query_surprisesCompare actual economic releases to consensus forecasts. Analyze beat/miss magnitude, historical surprise patterns, and market impact.
Instructions
Get actual vs consensus comparison for recent economic releases. Shows beat/miss magnitude, historical surprise patterns, and market impact. Cost: $0.02 per query. Source: FRED, BLS, BEA.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| series | No | FRED series ID to filter by | |
| days | No | Lookback period in days (default 30) | |
| limit | No | Maximum results (default 25) |
Implementation Reference
- src/tools/econ.ts:156-213 (registration)The registration of the 'query_surprises' tool via server.registerTool, including inputSchema definition and the async handler function.
server.registerTool( "query_surprises", { title: "Query Economic Surprises", description: "Get actual vs consensus comparison for recent economic releases. Shows beat/miss " + "magnitude, historical surprise patterns, and market impact. " + "Cost: $0.02 per query. Source: FRED, BLS, BEA.", inputSchema: { series: z .string() .optional() .describe("FRED series ID to filter by"), days: z .number() .int() .min(1) .max(365) .optional() .describe("Lookback period in days (default 30)"), limit: z .number() .int() .min(1) .max(100) .optional() .describe("Maximum results (default 25)"), }, }, async ({ series, days, limit }) => { const res = await apiGet<EconQueryResponse>("/api/v1/econ/surprise", { series, days: days ?? 30, limit: limit ?? 25, }); if (!res.ok) { return { content: [ { type: "text" as const, text: `API error (${res.status}): ${JSON.stringify(res.data)}`, }, ], isError: true, }; } const { count, data } = res.data; const warn = stalenessWarning(res); const summary = `${warn}Found ${count} economic surprise(s).`; const json = JSON.stringify(data, null, 2); return { content: [{ type: "text" as const, text: `${summary}\n\n${json}` }], }; }, ); - src/tools/econ.ts:185-212 (handler)The async handler function for 'query_surprises'. Delegates to the API at /api/v1/econ/surprise with optional series, days (default 30), and limit (default 25) parameters. Formats response with count and JSON data.
async ({ series, days, limit }) => { const res = await apiGet<EconQueryResponse>("/api/v1/econ/surprise", { series, days: days ?? 30, limit: limit ?? 25, }); if (!res.ok) { return { content: [ { type: "text" as const, text: `API error (${res.status}): ${JSON.stringify(res.data)}`, }, ], isError: true, }; } const { count, data } = res.data; const warn = stalenessWarning(res); const summary = `${warn}Found ${count} economic surprise(s).`; const json = JSON.stringify(data, null, 2); return { content: [{ type: "text" as const, text: `${summary}\n\n${json}` }], }; }, - src/tools/econ.ts:164-183 (schema)Input schema for 'query_surprises' defining optional parameters: series (FRED series ID), days (1-365 lookback, default 30), and limit (1-100, default 25).
inputSchema: { series: z .string() .optional() .describe("FRED series ID to filter by"), days: z .number() .int() .min(1) .max(365) .optional() .describe("Lookback period in days (default 30)"), limit: z .number() .int() .min(1) .max(100) .optional() .describe("Maximum results (default 25)"), }, - src/index.ts:57-57 (registration)Registration call: registerEconTools(server) which adds 'query_surprises' (among other econ tools) to the MCP server.
registerEconTools(server); - src/client.ts:44-76 (helper)The apiGet helper used by the handler to make HTTP GET requests to the Verilex API, including staleness tracking.
export async function apiGet<T = unknown>( path: string, params?: Record<string, string | number | undefined>, ): Promise<ApiResponse<T>> { const url = buildUrl(path, params); const headers: Record<string, string> = { Accept: "application/json", "User-Agent": "verilex-mcp-server/0.1.0", }; // Forward x402 payment token if present in env (for paid endpoints) const paymentToken = process.env.VERILEX_PAYMENT_TOKEN; if (paymentToken) { headers["X-Payment-Token"] = paymentToken; } const res = await fetch(url, { headers }); const data = (await res.json()) as T; const stale = res.headers.get("X-Data-Stale"); const lastUpdated = res.headers.get("X-Data-Last-Updated"); const ageSeconds = res.headers.get("X-Data-Age-Seconds"); return { ok: res.ok, status: res.status, data, stale: stale === "true", lastUpdated: lastUpdated ?? undefined, ageSeconds: ageSeconds ? Number(ageSeconds) : undefined, }; }