Skip to main content
Glama

manage_exit_nodes

Control and configure Tailscale exit nodes for routing operations. List, set, clear, advertise, or stop advertising routes like 0.0.0.0/0 or ::/0 using device IDs for precise network management.

Instructions

Manage Tailscale exit nodes and routing

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
deviceIdNoDevice ID for exit node operations
operationYesExit node operation to perform
routesYesRoutes to advertise (e.g., ["0.0.0.0/0", "::/0"] for full exit node)

Implementation Reference

  • The main handler function implementing manage_exit_nodes tool logic for listing, advertising, setting, and clearing exit nodes.
    async function manageExitNodes( args: z.infer<typeof ExitNodeSchema>, context: ToolContext, ): Promise<CallToolResult> { try { logger.debug("Managing exit nodes:", args); switch (args.operation) { case "list": { const devicesResult = await context.api.listDevices(); if (!devicesResult.success) { return returnToolError(devicesResult.error); } const devices = devicesResult.data || []; const exitNodes = devices.filter( (device) => device.advertisedRoutes?.includes("0.0.0.0/0") || device.advertisedRoutes?.includes("::/0"), ); if (exitNodes.length === 0) { return returnToolSuccess("No exit nodes found in the network"); } const exitNodeList = exitNodes .map((node) => { return `**${node.name}** (${node.hostname}) - ID: ${node.id} - OS: ${node.os} - Routes: ${node.advertisedRoutes?.join(", ") || "None"} - Status: ${node.authorized ? "Authorized" : "Unauthorized"}`; }) .join("\n\n"); return returnToolSuccess( `Exit Nodes (${exitNodes.length}):\n\n${exitNodeList}`, ); } case "advertise": { if (!args.deviceId || !args.routes) { return returnToolError( "Device ID and routes are required for advertise operation", ); } const result = await context.api.setDeviceExitNode( args.deviceId, args.routes, ); if (!result.success) { return returnToolError(result.error); } return returnToolSuccess( `Device ${ args.deviceId } is now advertising routes: ${args.routes.join(", ")}`, ); } case "set": { const nodeId = args.deviceId ?? ""; const cliResult = await context.cli.setExitNode(nodeId); if (!cliResult.success) { return returnToolError(cliResult.error); } return returnToolSuccess( `Exit node set to: ${args.deviceId || "auto"}`, ); } case "clear": { const cliResult = await context.cli.setExitNode(); if (!cliResult.success) { return returnToolError(cliResult.error); } return returnToolSuccess("Exit node cleared successfully"); } default: return returnToolError( "Invalid exit node operation. Use: list, set, clear, advertise", ); } } catch (error) { logger.error("Error managing exit nodes:", error); return returnToolError(error); } }
  • Zod input schema defining parameters for the manage_exit_nodes tool (operation, deviceId, routes).
    const ExitNodeSchema = z.object({ operation: z .enum(["list", "set", "clear", "advertise", "stop_advertising"]) .describe("Exit node operation to perform"), deviceId: z .string() .optional() .describe("Device ID for exit node operations"), routes: z .array(z.string()) .min(1, "At least one route must be specified") .describe( 'Routes to advertise (e.g., ["0.0.0.0/0", "::/0"] for full exit node)', ), });
  • Registration of the manage_exit_nodes tool in the adminTools ToolModule, linking name, schema, and handler.
    { name: "manage_exit_nodes", description: "Manage Tailscale exit nodes and routing", inputSchema: ExitNodeSchema, handler: manageExitNodes, },

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/HexSleeves/tailscale-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server