import z from "zod"; import { ToolDef } from "../types" import { isValidHost } from "../utils/logged"; import { exec } from "node:child_process"; import { promisify } from "node:util"; const execAsync = promisify(exec); export const pingTool: ToolDef = { title: "ping", config: { description: "ICMP-ping a host or IP address and return the result.", inputSchema: { host: z.string().describe("Hostname or IP address to ping"), count: z.number().int().min(1).max(10).default(4).describe("Echo requests to send"), }, }, handler: async ({ host, count }) => { if (!isValidHost(host)) { return { isError: true, content: [{ type: "text", text: `Invalid host: ${host}` }], }; } try { // -c count, -w deadline(s) so we never hang the request const { stdout } = await execAsync(`ping -r ${count} ${host}`, { timeout: 12_000, }); return { content: [{ type: "text", text: stdout.trim() }] }; } catch (err: unknown) { const message = err instanceof Error ? err.message : typeof err === "object" && err !== null && "stdout" in err ? String((err as { stdout?: unknown }).stdout) : String(err); return { isError: true, content: [{ type: "text", text: `ping failed:\n${message}` }], }; } }, };