ras_sessions_list
Monitor active remote desktop sessions to check user connectivity, identify idle or disconnected sessions, and troubleshoot access issues across the Parallels RAS farm.
Instructions
List all active remote desktop sessions across the RAS farm, including username, client IP address, device name, session state, screen resolution, and connected server. Use this to monitor active users, check session counts, troubleshoot user connectivity, or identify idle/disconnected sessions.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/rd-sessions.ts:31-38 (handler)The ras_sessions_list handler function that executes the tool logic. It calls rasClient.get('/api/rd-sessions') to retrieve all active remote desktop sessions and returns the data as formatted JSON text, with error handling using sanitiseError.
async () => { try { const data = await rasClient.get("/api/rd-sessions"); return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] }; } catch (err) { return { content: [{ type: "text" as const, text: sanitiseError(err, "Failed to retrieve RD sessions") }], isError: true }; } } - src/tools/rd-sessions.ts:18-40 (registration)Tool registration for ras_sessions_list using server.registerTool(). Includes the tool name, title, description, read-only annotations, empty input schema (no parameters required), and the handler function.
export function register(server: McpServer): void { server.registerTool( "ras_sessions_list", { title: "Active RD Sessions", description: "List all active remote desktop sessions across the RAS farm, including " + "username, client IP address, device name, session state, screen resolution, " + "and connected server. Use this to monitor active users, check session counts, " + "troubleshoot user connectivity, or identify idle/disconnected sessions.", annotations: READ_ONLY_ANNOTATIONS, inputSchema: {}, }, async () => { try { const data = await rasClient.get("/api/rd-sessions"); return { content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }] }; } catch (err) { return { content: [{ type: "text" as const, text: sanitiseError(err, "Failed to retrieve RD sessions") }], isError: true }; } } ); } - src/tools/rd-sessions.ts:11-16 (schema)READ_ONLY_ANNOTATIONS constant defining shared annotations for read-only session tools: readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=true.
const READ_ONLY_ANNOTATIONS = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, } as const; - src/client.ts:128-166 (helper)The rasClient.get() method used by the handler to make authenticated GET requests to the RAS API. Handles lazy authentication, automatic retry on 401 token expiry, and request timeouts.
async get(path: string): Promise<unknown> { // Ensure we have a valid session if (!this.authToken) { await this.login(); } const fetchOptions = { method: "GET" as const, headers: { ...this.headers, auth_token: this.authToken!, }, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), }; let response = await fetch(`${this.baseUrl}${path}`, fetchOptions); // Token may have expired — re-authenticate once and retry if (response.status === 401) { await this.login(); response = await fetch(`${this.baseUrl}${path}`, { ...fetchOptions, headers: { ...this.headers, auth_token: this.authToken!, }, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), }); } if (!response.ok) { const body = await response.text(); throw new Error( `RAS API error (HTTP ${response.status}) on ${path}: ${body.substring(0, 300)}` ); } return response.json(); } - src/client.ts:43-54 (helper)The sanitiseError() function used by the handler to sanitize error messages by removing auth tokens, passwords, and truncating excessively long API response bodies to avoid leaking sensitive information.
function sanitiseError(err: unknown, context: string): string { const raw = err instanceof Error ? err.message : String(err); // Remove anything that looks like a token or password value let sanitised = raw .replace(/auth_token[=:]\s*\S+/gi, "auth_token=[REDACTED]") .replace(/password[=:]\s*\S+/gi, "password=[REDACTED]"); // Truncate excessively long API response bodies if (sanitised.length > 500) { sanitised = sanitised.substring(0, 500) + "... (truncated)"; } return `${context}: ${sanitised}`; }