get_user
Retrieve details of a specific user by UUID. Requires admin authentication to access user information.
Instructions
Get details of a specific user (admin only)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| userId | Yes | User UUID |
Implementation Reference
- src/tools/users.ts:42-52 (handler)Handler for the 'get_user' tool - calls Umami API GET /api/users/:userId to retrieve a specific user's details.
server.tool( "get_user", "Get details of a specific user (admin only)", { userId: z.string().describe("User UUID"), }, async ({ userId }) => { const data = await client.call("GET", `/api/users/${userId}`); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); - src/tools/users.ts:45-47 (schema)Input schema for 'get_user' tool - requires a single 'userId' string parameter.
{ userId: z.string().describe("User UUID"), }, - src/tools/users.ts:5-139 (registration)The 'get_user' tool is registered via server.tool() inside the registerUserTools() function.
export function registerUserTools(server: McpServer, client: UmamiClient) { server.tool( "list_users", "List all users (admin only)", { 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 users"), orderBy: z.string().optional().describe("Field to order by (e.g. 'username', 'createdAt')"), }, async ({ page, pageSize, query, orderBy }) => { const data = await client.call("GET", "/api/users", undefined, { page, pageSize, query, orderBy, }); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); server.tool( "create_user", "Create a new user (admin only)", { username: z.string().describe("Username for the new user"), password: z.string().describe("Password for the new user"), role: z.string().optional().describe("User role: 'admin' or 'user' (default: 'user')"), }, async ({ username, password, role }) => { const body: Record<string, unknown> = { username, password }; if (role) body.role = role; const data = await client.call("POST", "/api/users", body); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); server.tool( "get_user", "Get details of a specific user (admin only)", { userId: z.string().describe("User UUID"), }, async ({ userId }) => { const data = await client.call("GET", `/api/users/${userId}`); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); server.tool( "update_user", "Update a user's username, password, or role (admin only)", { userId: z.string().describe("User UUID"), username: z.string().optional().describe("New username"), password: z.string().optional().describe("New password"), role: z.string().optional().describe("New role: 'admin' or 'user'"), }, async ({ userId, username, password, role }) => { const body: Record<string, unknown> = {}; if (username !== undefined) body.username = username; if (password !== undefined) body.password = password; if (role !== undefined) body.role = role; const data = await client.call("POST", `/api/users/${userId}`, body); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); server.tool( "delete_user", "Delete a user (admin only)", { userId: z.string().describe("User UUID to delete"), }, async ({ userId }) => { await client.call("DELETE", `/api/users/${userId}`); return { content: [{ type: "text", text: `User ${userId} deleted successfully.` }] }; } ); server.tool( "get_user_websites", "Get the list of websites a user has access to (admin only)", { userId: z.string().describe("User UUID"), page: z.number().optional().describe("Page number (1-based)"), pageSize: z.number().optional().describe("Results per page"), query: z.string().optional().describe("Search query to filter websites"), }, async ({ userId, page, pageSize, query }) => { const data = await client.call("GET", `/api/users/${userId}/websites`, undefined, { page, pageSize, query, }); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); server.tool( "get_user_usage", "Get usage statistics for a specific user (admin only)", { userId: z.string().describe("User UUID"), startAt: z.number().optional().describe("Start timestamp in milliseconds"), endAt: z.number().optional().describe("End timestamp in milliseconds"), }, async ({ userId, startAt, endAt }) => { const data = await client.call("GET", `/api/users/${userId}/usage`, undefined, { startAt, endAt, }); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); server.tool( "get_user_teams", "Get the list of teams a user belongs to (admin only)", { userId: z.string().describe("User UUID"), page: z.number().optional().describe("Page number (1-based)"), pageSize: z.number().optional().describe("Results per page"), query: z.string().optional().describe("Search query to filter teams"), }, async ({ userId, page, pageSize, query }) => { const data = await client.call("GET", `/api/users/${userId}/teams`, undefined, { page, pageSize, query, }); return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } ); } - src/index.ts:12-34 (registration)The registerUserTools function is imported and called from the main server entry point, registering all user tools including 'get_user'.
import { registerUserTools } from "./tools/users.js"; import { registerTeamTools } from "./tools/teams.js"; import { registerRealtimeTools } from "./tools/realtime.js"; import { registerAccountTools } from "./tools/account.js"; import { registerWebsiteResources } from "./resources/websites.js"; import { registerAccountResources } from "./resources/account.js"; import { registerPrompts } from "./prompts/index.js"; const server = new McpServer({ name: "umami-mcp", version: "1.2.0", }); const config = loadConfig(); const client = new UmamiClient(config); // Register all tools registerWebsiteTools(server, client); registerStatsTools(server, client); registerSessionTools(server, client); registerEventTools(server, client); registerReportTools(server, client); registerUserTools(server, client); - src/client.ts:68-117 (helper)UmamiClient.call() is the helper that executes the HTTP request for 'get_user' - it sends a GET request to /api/users/:userId with Bearer token auth.
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 }; } }