list_websites
List all websites tracked in Umami, with pagination, search query, and ordering by name or domain.
Instructions
List all websites tracked in Umami
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based) | |
| pageSize | No | Results per page (default 10) | |
| query | No | Search query to filter websites | |
| orderBy | No | Field to order by (e.g. 'name', 'domain') |
Implementation Reference
- src/tools/websites.ts:15-23 (handler)Handler function for the 'list_websites' tool. Makes a GET request to /api/websites with optional query params (page, pageSize, query, orderBy) and returns JSON-formatted results.
async ({ page, pageSize, query, orderBy }) => { const data = await client.call("GET", "/api/websites", undefined, { page: page, pageSize: pageSize, query, orderBy, }); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } - src/tools/websites.ts:9-14 (schema)Zod schema defining the optional input parameters for the 'list_websites' tool: page (number), pageSize (number), query (string), orderBy (string).
{ page: z.number().optional().describe("Page number (1-based)"), pageSize: z.number().optional().describe("Results per page (default 10)"), query: z.string().optional().describe("Search query to filter websites"), orderBy: z.string().optional().describe("Field to order by (e.g. 'name', 'domain')"), }, - src/tools/websites.ts:6-24 (registration)Registration of the 'list_websites' tool on the McpServer via server.tool(), with description, Zod input schema, and the async handler function.
server.tool( "list_websites", "List all websites tracked in Umami", { page: z.number().optional().describe("Page number (1-based)"), pageSize: z.number().optional().describe("Results per page (default 10)"), query: z.string().optional().describe("Search query to filter websites"), orderBy: z.string().optional().describe("Field to order by (e.g. 'name', 'domain')"), }, async ({ page, pageSize, query, orderBy }) => { const data = await client.call("GET", "/api/websites", undefined, { page: page, pageSize: pageSize, query, orderBy, }); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); - src/client.ts:68-117 (helper)UmamiClient.call() helper method used by the handler to make authenticated HTTP requests to the Umami API.
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 }; } }