Skip to main content
Glama

reboot_node

Restart a specific node within a CloudLab experiment to resolve issues or apply configuration changes. Specify the experiment ID and node identifier to initiate the reboot process.

Instructions

Reboot a specific node in an experiment

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
experiment_idYesExperiment UUID (from list_experiments)
nodeYesNode client_id (e.g., 'node0')

Implementation Reference

  • The handler function for the 'reboot_node' tool. It extracts experiment_id and node from arguments, makes a POST request to the CloudLab API endpoint `/experiments/{experiment_id}/node/{node}/reboot`, and returns the result.
    case "reboot_node": {
      const { experiment_id, node } = args as {
        experiment_id: string;
        node: string;
      };
      const result = await cloudlabRequest(
        `/experiments/${experiment_id}/node/${node}/reboot`,
        "POST"
      );
      return {
        content: [
          {
            type: "text",
            text: `Reboot initiated for node ${node}: ${JSON.stringify(result, null, 2)}`,
          },
        ],
      };
    }
  • The input schema definition for the 'reboot_node' tool, returned in the list_tools response. Requires experiment_id and node.
    {
      name: "reboot_node",
      description: "Reboot a specific node in an experiment",
      inputSchema: {
        type: "object",
        properties: {
          experiment_id: {
            type: "string",
            description: "Experiment UUID (from list_experiments)",
          },
          node: {
            type: "string",
            description: "Node client_id (e.g., 'node0')",
          },
        },
        required: ["experiment_id", "node"],
      },
    },
  • src/index.ts:97-255 (registration)
    The ListToolsRequestHandler registers all tools including 'reboot_node' by returning their schemas.
    server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: "list_experiments",
            description: "List all your CloudLab experiments",
            inputSchema: {
              type: "object",
              properties: {},
              required: [],
            },
          },
          {
            name: "create_experiment",
            description: "Create a new CloudLab experiment from a profile",
            inputSchema: {
              type: "object",
              properties: {
                project: {
                  type: "string",
                  description: "Project name (e.g., 'UCY-CS499-DC')",
                },
                profile_name: {
                  type: "string",
                  description: "Profile name (e.g., 'small-lan')",
                },
                profile_project: {
                  type: "string",
                  description: "Project that owns the profile (e.g., 'PortalProfiles')",
                },
                name: {
                  type: "string",
                  description: "Optional experiment name (auto-generated if not provided)",
                },
                bindings: {
                  type: "object",
                  description: "Optional profile parameter bindings (e.g., {nodeCount: '2', phystype: 'c220g1'})",
                },
              },
              required: ["project", "profile_name", "profile_project"],
            },
          },
          {
            name: "get_experiment",
            description: "Get detailed status of a specific experiment including node states",
            inputSchema: {
              type: "object",
              properties: {
                experiment_id: {
                  type: "string",
                  description: "Experiment UUID (from list_experiments)",
                },
              },
              required: ["experiment_id"],
            },
          },
          {
            name: "reboot_node",
            description: "Reboot a specific node in an experiment",
            inputSchema: {
              type: "object",
              properties: {
                experiment_id: {
                  type: "string",
                  description: "Experiment UUID (from list_experiments)",
                },
                node: {
                  type: "string",
                  description: "Node client_id (e.g., 'node0')",
                },
              },
              required: ["experiment_id", "node"],
            },
          },
          {
            name: "reboot_all_nodes",
            description: "Reboot all nodes in an experiment",
            inputSchema: {
              type: "object",
              properties: {
                experiment_id: {
                  type: "string",
                  description: "Experiment UUID (from list_experiments)",
                },
              },
              required: ["experiment_id"],
            },
          },
          {
            name: "reload_node",
            description: "Reload/reimage a node with its disk image",
            inputSchema: {
              type: "object",
              properties: {
                experiment_id: {
                  type: "string",
                  description: "Experiment UUID (from list_experiments)",
                },
                node: {
                  type: "string",
                  description: "Node client_id",
                },
              },
              required: ["experiment_id", "node"],
            },
          },
          {
            name: "powercycle_node",
            description: "Power cycle a node (hard reboot)",
            inputSchema: {
              type: "object",
              properties: {
                experiment_id: {
                  type: "string",
                  description: "Experiment UUID (from list_experiments)",
                },
                node: {
                  type: "string",
                  description: "Node client_id",
                },
              },
              required: ["experiment_id", "node"],
            },
          },
          {
            name: "extend_experiment",
            description: "Extend the expiration time of an experiment",
            inputSchema: {
              type: "object",
              properties: {
                experiment_id: {
                  type: "string",
                  description: "Experiment UUID (from list_experiments)",
                },
                hours: {
                  type: "number",
                  description: "Number of hours to extend",
                },
              },
              required: ["experiment_id", "hours"],
            },
          },
          {
            name: "terminate_experiment",
            description: "Terminate an experiment (WARNING: destroys all data)",
            inputSchema: {
              type: "object",
              properties: {
                experiment_id: {
                  type: "string",
                  description: "Experiment UUID (from list_experiments)",
                },
              },
              required: ["experiment_id"],
            },
          },
        ],
      };
    });
  • src/index.ts:258-438 (registration)
    The CallToolRequestHandler registers the execution logic for all tools via the switch statement on tool name.
    server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;
    
      try {
        switch (name) {
          case "list_experiments": {
            const result = await cloudlabRequest("/experiments");
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify(result, null, 2),
                },
              ],
            };
          }
    
          case "create_experiment": {
            const { project, profile_name, profile_project, name, bindings } = args as {
              project: string;
              profile_name: string;
              profile_project: string;
              name?: string;
              bindings?: Record<string, string>;
            };
            const body: Record<string, any> = {
              project,
              profile_name,
              profile_project,
            };
            if (name) body.name = name;
            if (bindings) body.bindings = bindings;
    
            const result = await cloudlabRequest("/experiments", "POST", body);
            return {
              content: [
                {
                  type: "text",
                  text: `Experiment created: ${JSON.stringify(result, null, 2)}`,
                },
              ],
            };
          }
    
          case "get_experiment": {
            const { experiment_id } = args as { experiment_id: string };
            const result = await cloudlabRequest(`/experiments/${experiment_id}`);
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify(result, null, 2),
                },
              ],
            };
          }
    
          case "reboot_node": {
            const { experiment_id, node } = args as {
              experiment_id: string;
              node: string;
            };
            const result = await cloudlabRequest(
              `/experiments/${experiment_id}/node/${node}/reboot`,
              "POST"
            );
            return {
              content: [
                {
                  type: "text",
                  text: `Reboot initiated for node ${node}: ${JSON.stringify(result, null, 2)}`,
                },
              ],
            };
          }
    
          case "reboot_all_nodes": {
            const { experiment_id } = args as { experiment_id: string };
            const result = await cloudlabRequest(
              `/experiments/${experiment_id}/nodes/reboot`,
              "POST"
            );
            return {
              content: [
                {
                  type: "text",
                  text: `Reboot initiated for all nodes: ${JSON.stringify(result, null, 2)}`,
                },
              ],
            };
          }
    
          case "reload_node": {
            const { experiment_id, node } = args as {
              experiment_id: string;
              node: string;
            };
            const result = await cloudlabRequest(
              `/experiments/${experiment_id}/node/${node}/reload`,
              "POST"
            );
            return {
              content: [
                {
                  type: "text",
                  text: `Reload initiated for node ${node}: ${JSON.stringify(result, null, 2)}`,
                },
              ],
            };
          }
    
          case "powercycle_node": {
            const { experiment_id, node } = args as {
              experiment_id: string;
              node: string;
            };
            const result = await cloudlabRequest(
              `/experiments/${experiment_id}/node/${node}/powercycle`,
              "POST"
            );
            return {
              content: [
                {
                  type: "text",
                  text: `Power cycle initiated for node ${node}: ${JSON.stringify(result, null, 2)}`,
                },
              ],
            };
          }
    
          case "extend_experiment": {
            const { experiment_id, hours } = args as {
              experiment_id: string;
              hours: number;
            };
            const result = await cloudlabRequest(
              `/experiments/${experiment_id}`,
              "PUT",
              { extend_by: hours }
            );
            return {
              content: [
                {
                  type: "text",
                  text: `Extension requested: ${JSON.stringify(result, null, 2)}`,
                },
              ],
            };
          }
    
          case "terminate_experiment": {
            const { experiment_id } = args as { experiment_id: string };
            const result = await cloudlabRequest(
              `/experiments/${experiment_id}`,
              "DELETE"
            );
            return {
              content: [
                {
                  type: "text",
                  text: `Experiment termination initiated: ${JSON.stringify(result, null, 2)}`,
                },
              ],
            };
          }
    
          default:
            throw new Error(`Unknown tool: ${name}`);
        }
      } catch (error) {
        return {
          content: [
            {
              type: "text",
              text: `Error: ${error instanceof Error ? error.message : String(error)}`,
            },
          ],
          isError: true,
        };
      }
    });
  • Helper function used by all tools, including reboot_node, to make authenticated requests to the CloudLab API.
    async function cloudlabRequest(
      endpoint: string,
      method: string = "GET",
      body?: object
    ): Promise<any> {
      const token = loadToken();
      const url = `${CLOUDLAB_API_BASE}${endpoint}`;
    
      const headers: Record<string, string> = {
        "X-Api-Token": token,
        "Accept": "application/json",
      };
    
      if (body) {
        headers["Content-Type"] = "application/json";
      }
    
      const response = await fetch(url, {
        method,
        headers,
        body: body ? JSON.stringify(body) : undefined,
        redirect: "follow",
      });
    
      if (!response.ok) {
        const text = await response.text();
        throw new Error(`CloudLab API error (${response.status}): ${text}`);
      }
    
      const contentType = response.headers.get("content-type");
      if (contentType?.includes("application/json")) {
        return response.json();
      }
      return response.text();
    }

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/ArdaGurcan/cloudlab-mcp'

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