Skip to main content
Glama
TAgents

Planning System MCP Server

by TAgents

get_plan_structure

Retrieve the complete hierarchical structure of a plan to understand its phases, tasks, and milestones. Use this tool to analyze project organization and dependencies.

Instructions

Get the complete hierarchical structure of a plan

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
plan_idYesPlan ID
include_detailsNoInclude full node details

Implementation Reference

  • src/tools.js:401-416 (registration)
    Registers the get_plan_structure tool including its description and input schema in the MCP tools list.
    {
      name: "get_plan_structure",
      description: "Get the complete hierarchical structure of a plan",
      inputSchema: {
        type: "object",
        properties: {
          plan_id: { type: "string", description: "Plan ID" },
          include_details: { 
            type: "boolean", 
            description: "Include full node details",
            default: false
          }
        },
        required: ["plan_id"]
      }
    },
  • Handler function that executes the get_plan_structure tool: fetches plan details and nodes, constructs hierarchical structure using buildNodeHierarchy if needed, and returns formatted JSON response.
    if (name === "get_plan_structure") {
      const { plan_id, include_details = false } = args;
      
      const plan = await apiClient.plans.getPlan(plan_id);
      const nodes = await apiClient.nodes.getNodes(plan_id);
      
      // The API already returns a tree structure, not a flat list
      // If it's already hierarchical, use it directly
      let structure;
      if (Array.isArray(nodes) && nodes.length > 0 && nodes[0].children !== undefined) {
        // Already hierarchical - use directly
        structure = nodes;
      } else {
        // Flat list - build hierarchy
        structure = buildNodeHierarchy(nodes, include_details);
      }
      
      return formatResponse({
        plan: {
          id: plan.id,
          title: plan.title,
          status: plan.status,
          description: plan.description
        },
        structure
      });
    }
  • buildNodeHierarchy helper function constructs a hierarchical tree structure from a flat list of nodes, handling parent-child relationships, sorting by order_index, and optionally including full node details. Called by the tool handler.
     */
    function buildNodeHierarchy(nodes, includeDetails = false) {
      if (!nodes || nodes.length === 0) {
        return [];
      }
      
      // Debug logging to understand the structure
      if (process.env.NODE_ENV === 'development') {
        console.error('Building hierarchy for nodes:', nodes.length);
        if (nodes[0]) {
          console.error('Sample node:', {
            id: nodes[0].id,
            parent_id: nodes[0].parent_id,
            node_type: nodes[0].node_type
          });
        }
      }
      
      const nodeMap = new Map();
      const rootNodes = [];
      
      // First pass: create all nodes in the map
      nodes.forEach(node => {
        const nodeData = includeDetails ? { ...node } : {
          id: node.id,
          title: node.title,
          node_type: node.node_type,
          status: node.status,
          parent_id: node.parent_id,
          order_index: node.order_index
        };
        
        // Initialize with empty children array
        nodeMap.set(node.id, {
          ...nodeData,
          children: []
        });
      });
      
      // Second pass: build parent-child relationships
      nodes.forEach(node => {
        const currentNode = nodeMap.get(node.id);
        
        if (node.parent_id) {
          const parent = nodeMap.get(node.parent_id);
          if (parent) {
            // Add as child to parent
            parent.children.push(currentNode);
          } else {
            // Parent not found, treat as root
            if (process.env.NODE_ENV === 'development') {
              console.error(`Parent ${node.parent_id} not found for node ${node.id}`);
            }
            rootNodes.push(currentNode);
          }
        } else {
          // No parent_id means it's a root node
          rootNodes.push(currentNode);
        }
      });
      
      // Special case: if we have a single root node of type 'root', return its children
      if (rootNodes.length === 1 && rootNodes[0].node_type === 'root') {
        // Return the root node itself with its children
        const rootNode = rootNodes[0];
        
        // Sort children by order_index
        const sortNodes = (nodeArray) => {
          nodeArray.sort((a, b) => {
            const orderA = a.order_index ?? 999;
            const orderB = b.order_index ?? 999;
            return orderA - orderB;
          });
          
          nodeArray.forEach(node => {
            if (node.children && node.children.length > 0) {
              sortNodes(node.children);
            }
          });
        };
        
        sortNodes(rootNode.children);
        return [rootNode]; // Return root with its properly sorted children
      }
      
      // Sort all root nodes and their children
      const sortNodes = (nodeArray) => {
        nodeArray.sort((a, b) => {
          const orderA = a.order_index ?? 999;
          const orderB = b.order_index ?? 999;
          return orderA - orderB;
        });
        
        nodeArray.forEach(node => {
          if (node.children && node.children.length > 0) {
            sortNodes(node.children);
          }
        });
      };
      
      sortNodes(rootNodes);
      
      return rootNodes;
    }

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/TAgents/agent-planner-mcp'

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