Skip to main content
Glama
jupiterbak

AYX-MCP-Wrapper

by jupiterbak

get_workflow_tool_list

Retrieve all tools used in an Alteryx workflow by providing the workflow ID. This helps users analyze and manage workflow components.

Instructions

Get the list of tools in a workflow by the workflow ID

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
workflow_idYes

Implementation Reference

  • The core handler function in the Tools class that implements the logic for get_workflow_tool_list. It retrieves the workflow, downloads and unzips it, parses the XML, extracts tool nodes, cleans properties, and returns a pretty-formatted dictionary of tools.
    def get_workflow_tool_list(self, workflow_id: str):
        """Get the list of the workflow tools and the tool properties by the workflow ID"""
        try:
            api_response = self.workflows_api.workflows_get_workflow(workflow_id)
            if api_response is None:
                return "Error: Workflow not found"
            
            # Download the workflow file
            api_response = self.workflows_api.workflows_download_workflow(workflow_id)
            if api_response is None:
                return "Error: Failed to download workflow"
                
            temp_directory = self.configuration.temp_directory
            # normalize the temp directory
            temp_directory = os.path.normpath(temp_directory)
            if not os.path.exists(temp_directory):
                os.makedirs(temp_directory)
            
            with open(
                f"{temp_directory}/{workflow_id}.yxzp",
                "wb" if not os.path.exists(f"{temp_directory}/{workflow_id}.yxzp") else "wb+",
            ) as f:
                f.write(api_response)
    
            new_directory = f"{temp_directory}/{workflow_id}"
            if os.path.exists(new_directory):
                shutil.rmtree(new_directory)
            os.makedirs(new_directory)
            
            with zipfile.ZipFile(f"{temp_directory}/{workflow_id}.yxzp", "r") as zip_ref:
                zip_ref.extractall(new_directory)
            
            yxmd_files = [file for file in os.listdir(new_directory) if file.endswith(".yxmd") or file.endswith(".yxwz")]
            if len(yxmd_files) == 0:
                return "Error: Workflow XML file not found after unzipping"
            
            yxmd_file = yxmd_files[0]
    
            # Read as binary first, then decode as UTF-8
            with open(f"{new_directory}/{yxmd_file}", "rb") as f:
                binary_content = f.read()
                try:
                    # Try to decode as UTF-8
                    xml_content = binary_content.decode('utf-8')
                except UnicodeDecodeError:
                    # If UTF-8 fails, return the binary content as a string representation
                    xml_content = binary_content
    
            # Parse the XML content using xmltodict
            xml_dict = xmltodict.parse(xml_content)
    
            # extract the tools list
            tools_list = xml_dict['AlteryxDocument']['Nodes']['Node']
            # if tools_list is a list, then we need to iterate through it
            tools_dict = {}
            if isinstance(tools_list, list):
                for tool in tools_list:
                    tool_id = tool['@ToolID']
                    tool_type = tool['GuiSettings']['@Plugin']
                    tool_dict = tool['Properties']['Configuration']
                    # Add the tool type to the tool dictionary
                    tool_dict['ToolType'] = tool_type
    
                    # Remove all properties BG_Image, Font, TextColor, FillColor, Justification, TextSize
                    tool_dict.pop('BG_Image', None)
                    tool_dict.pop('Font', None)
                    tool_dict.pop('TextColor', None)
                    tool_dict.pop('FillColor', None)
                    tool_dict.pop('Justification', None)
                    tool_dict.pop('TextSize', None)
    
                    # Remove the data encoded in the tool
                    tool_dict.pop('Data', None)
    
                    tools_dict[tool_id] = tool_dict
            else:
                tool_id = tools_list['@ToolID']
                tool_type = tools_list['GuiSettings']['@Plugin']
                tool_dict = tools_list['Properties']['Configuration']
                # Add the tool type to the tool dictionary
                tool_dict['ToolType'] = tool_type
    
                # Remove all properties BG_Image, Font, TextColor, FillColor, Justification, TextSize
                tool_dict.pop('BG_Image', None)
                tool_dict.pop('Font', None)
                tool_dict.pop('TextColor', None)
                tool_dict.pop('FillColor', None)
                tool_dict.pop('Justification', None)
                tool_dict.pop('TextSize', None)
    
                # Remove the data encoded in the tool
                tool_dict.pop('Data', None)
    
                # Add the tool dictionary to the tools dictionary
                tools_dict[tool_id] = tool_dict
            return pprint.pformat(tools_dict)
                    
        except Exception as e:
            return f"Error: {str(e)}"
  • The MCP tool registration in register_tools method using @self.app.tool() decorator, which defines the tool schema implicitly from the function signature and delegates execution to the Tools instance.
    @self.app.tool()
    def get_workflow_tool_list(workflow_id: str):
        """Get the list of tools in a workflow by the workflow ID"""
        return self.tools.get_workflow_tool_list(workflow_id)
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It mentions 'Get the list' which implies a read-only operation, but doesn't disclose behavioral traits such as permissions required, rate limits, pagination, error handling, or what format the list is returned in (e.g., JSON array, plain text). This leaves significant gaps for an agent to understand how to interact with the tool effectively.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence that front-loads the key action and resource. It wastes no words and is appropriately sized for a simple tool, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (a read operation with one parameter), lack of annotations, and no output schema, the description is incomplete. It doesn't cover what the output looks like (e.g., list structure, tool details), error cases, or any prerequisites. This makes it inadequate for an agent to fully understand the tool's behavior and integration needs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds minimal semantics beyond the input schema. It specifies that the parameter 'workflow_id' is used to identify the workflow, which is implied by the schema's property name. With 0% schema description coverage, the description doesn't compensate by explaining the format or constraints of 'workflow_id' (e.g., UUID, string pattern). However, since there's only one parameter, the baseline is higher, but it lacks enrichment.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Get') and resource ('list of tools in a workflow'), making the purpose understandable. It distinguishes from siblings like 'get_workflow_by_id' or 'get_workflow_jobs' by specifying tools rather than workflow details or jobs. However, it lacks specificity about what 'tools' means in this context (e.g., tool names, IDs, configurations).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. For example, it doesn't mention if this is for auditing, debugging, or integration purposes, or how it differs from 'get_workflow_by_id' which might include tool information. The description only states what it does, not when or why to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/jupiterbak/AYX-MCP-Wrapper'

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