get_sessions
Retrieve website session data filtered by date range, search query, pagination, and sorting parameters.
Instructions
Get session data for a website
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| websiteId | Yes | Website UUID | |
| startAt | Yes | Start timestamp in milliseconds | |
| endAt | Yes | End timestamp in milliseconds | |
| query | No | Search query | |
| page | No | Page number (1-based) | |
| pageSize | No | Results per page | |
| orderBy | No | Field to order by |
Implementation Reference
- src/tools/stats.ts:117-140 (handler)The 'get_sessions' tool handler function that calls the Umami API to retrieve session data for a website. It accepts websiteId, startAt, endAt, and optional query, page, pageSize, and orderBy parameters, then makes a GET request to /api/websites/{websiteId}/sessions.
server.tool( "get_sessions", "Get session data for a website", { websiteId: z.string().describe("Website UUID"), ...dateRange, query: z.string().optional().describe("Search query"), page: z.number().optional().describe("Page number (1-based)"), pageSize: z.number().optional().describe("Results per page"), orderBy: z.string().optional().describe("Field to order by"), }, async ({ websiteId, startAt, endAt, query, page, pageSize, orderBy }) => { const data = await client.call("GET", `/api/websites/${websiteId}/sessions`, undefined, { startAt, endAt, query, page, pageSize, orderBy, }); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); - src/tools/stats.ts:121-128 (schema)The Zod schema defining the input parameters for the 'get_sessions' tool: websiteId (required string), startAt/endAt (required numbers from dateRange spread), and optional query, page, pageSize, orderBy.
{ websiteId: z.string().describe("Website UUID"), ...dateRange, query: z.string().optional().describe("Search query"), page: z.number().optional().describe("Page number (1-based)"), pageSize: z.number().optional().describe("Results per page"), orderBy: z.string().optional().describe("Field to order by"), }, - src/tools/stats.ts:118-140 (registration)The tool is registered via server.tool() call inside registerStatsTools(), which is exported and called from src/index.ts on line 30.
server.tool( "get_sessions", "Get session data for a website", { websiteId: z.string().describe("Website UUID"), ...dateRange, query: z.string().optional().describe("Search query"), page: z.number().optional().describe("Page number (1-based)"), pageSize: z.number().optional().describe("Results per page"), orderBy: z.string().optional().describe("Field to order by"), }, async ({ websiteId, startAt, endAt, query, page, pageSize, orderBy }) => { const data = await client.call("GET", `/api/websites/${websiteId}/sessions`, undefined, { startAt, endAt, query, page, pageSize, orderBy, }); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); - src/tools/stats.ts:5-8 (helper)The dateRange helper object spread into the schema to provide startAt and endAt timestamp parameters. Also used by other tools in this file.
const dateRange = { startAt: z.number().describe("Start timestamp in milliseconds"), endAt: z.number().describe("End timestamp in milliseconds"), }; - src/client.ts:68-117 (helper)The UmamiClient.call() method that actually executes the HTTP request to the Umami API, handling authentication, query parameters, and JSON serialization.
async call( method: string, path: string, body?: Record<string, unknown>, query?: Record<string, string | number | boolean | undefined> ): Promise<unknown> { this.ensureConfigured(); const token = await this.getToken(); let url = `${this.config.baseUrl}${path}`; if (query) { const params = new URLSearchParams(); for (const [k, v] of Object.entries(query)) { if (v !== undefined && v !== null && v !== "") { params.set(k, String(v)); } } const qs = params.toString(); if (qs) url += `?${qs}`; } const headers: Record<string, string> = { Authorization: `Bearer ${token}`, }; if (body) { headers["Content-Type"] = "application/json"; } const res = await fetch(url, { method, headers, body: body ? JSON.stringify(body) : undefined, signal: AbortSignal.timeout(30_000), }); if (!res.ok) { const text = await res.text().catch(() => ""); throw new Error(`Umami API error ${method} ${path} (${res.status}): ${text}`); } // Some endpoints return 200 with no body (e.g. DELETE) const contentType = res.headers.get("content-type") || ""; if (contentType.includes("application/json")) { return res.json(); } const text = await res.text(); return text || { success: true }; } }