Skip to main content
Glama
AgentWong

IAC Memory MCP Server

by AgentWong

get_module_version_compatibility

Check if a specific Ansible module works with a target collection version to prevent compatibility issues in IaC deployments.

Instructions

Check module compatibility across collection versions

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
collection_nameYesName of the Ansible collection
module_nameYesName of the module to check
versionYesTarget collection version to check compatibility against

Implementation Reference

  • Main handler function executing the tool: logs input, fetches compatibility data from DB helper, formats detailed output including issues, breaking changes, and version history as TextContent.
    async def handle_get_module_version_compatibility(
        db: Any, arguments: Dict[str, Any], operation_id: str
    ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
        """Handle get_module_version_compatibility tool."""
        try:
            logger.info(
                "Getting module version compatibility",
                extra={
                    "collection_name": arguments["collection_name"],
                    "module_name": arguments["module_name"],
                    "version": arguments["version"],
                    "operation_id": operation_id,
                },
            )
    
            try:
                # Get compatibility info
                result = get_module_compatibility(
                    db,
                    arguments["collection_name"],
                    arguments["module_name"],
                    arguments["version"],
                )
            except Exception as db_error:
                error_msg = str(db_error)
                logger.error(error_msg, extra={"operation_id": operation_id})
                return [TextContent(type="text", text=error_msg)]
    
            # Format output
            output = [
                "Module Compatibility Check:",
                f"Module: {result['module_name']}",
                f"Collection: {result['collection_name']}",
                f"Target Version: {result['target_version']}",
                f"Current Version: {result['current_version']}",
                f"Is Compatible: {'Yes' if result['is_compatible'] else 'No'}",
                "\nCompatibility Issues:",
            ]
    
            if not result["compatibility_issues"]:
                output.append("- No issues found")
            else:
                for issue in result["compatibility_issues"]:
                    output.append(f"- {issue}")
    
            if result["breaking_changes"]:
                output.extend(
                    [
                        "\nBreaking Changes:",
                        *[f"- {change}" for change in result["breaking_changes"]],
                    ]
                )
    
            output.extend(
                [
                    "\nVersion History:",
                    *[
                        f"- {v['collection_version']} (Module v{v['module_version']}) - {v['released']}"
                        for v in result["version_history"]
                    ],
                ]
            )
    
            return [TextContent(type="text", text="\n".join(output))]
    
        except Exception as e:
            error_msg = f"Failed to check module version compatibility: {str(e)}"
            logger.error(error_msg, extra={"operation_id": operation_id})
            raise McpError(
                types.ErrorData(
                    code=types.INTERNAL_ERROR,
                    message=error_msg,
                    data={
                        "tool": "get_module_version_compatibility",
                        "operation_id": operation_id,
                    },
                )
            )
  • JSON schema defining input parameters: collection_name, module_name, version (all required strings). Used for validation.
    "get_module_version_compatibility": {
        "type": "object",
        "description": "Check module compatibility across collection versions",
        "required": ["collection_name", "module_name", "version"],
        "properties": {
            "collection_name": {
                "type": "string",
                "description": "Name of the Ansible collection",
            },
            "module_name": {
                "type": "string",
                "description": "Name of the module to check",
            },
            "version": {
                "type": "string",
                "description": "Target collection version to check compatibility against",
            },
        },
    },
  • Registration dictionary mapping tool name 'get_module_version_compatibility' to its handler function, alongside other Ansible tools.
    ansible_tool_handlers = {
        "get_ansible_collection_info": handle_get_ansible_collection_info,
        "list_ansible_collections": handle_list_ansible_collections,
        "get_collection_version_history": handle_get_collection_version_history,
        "get_ansible_module_info": handle_get_ansible_module_info,
        "list_collection_modules": handle_list_collection_modules,
        "get_module_version_compatibility": handle_get_module_version_compatibility,
        "add_ansible_collection": handle_add_ansible_collection,
        "add_ansible_module": handle_add_ansible_module,
        "update_collection_version": handle_update_collection_version,
        "update_module_version": handle_update_module_version,
    }
  • Database helper function that performs SQL queries to retrieve module data and history, compares schemas for compatibility (e.g., new required fields, removed properties), and computes results used by the handler.
    def get_module_compatibility(
        db: DatabaseManager, collection_name: str, module_name: str, version: str
    ) -> Dict:
        """Check module compatibility across collection versions.
    
        Args:
            db: Database manager instance
            collection_name: Name of the collection
            module_name: Name of the module
            version: Target version to check compatibility against
    
        Returns:
            Dict containing compatibility status and any potential issues
        """
        logger.info(
            "Getting module compatibility info",
            extra={
                "collection_name": collection_name,
                "module_name": module_name,
                "version": version,
                "operation": "get_module_compatibility",
            },
        )
    
        try:
            with db.get_connection() as conn:
                conn.execute("PRAGMA busy_timeout = 5000")  # 5 second timeout
    
                # Get latest version of the module
                current = conn.execute(
                    """
                    SELECT m.*, c.name as collection_name, c.version as collection_version
                    FROM ansible_modules m
                    JOIN ansible_collections c ON m.collection_id = c.id
                    WHERE c.name = ? AND m.name = ?
                    ORDER BY m.version DESC
                    LIMIT 1
                    """,
                    (collection_name, module_name),
                ).fetchone()
    
                if not current:
                    raise DatabaseError(
                        f"Module '{module_name}' not found in collection '{collection_name}'"
                    )
    
                # Get version history
                history = conn.execute(
                    """
                    SELECT m.version as module_version,
                           c.version as collection_version,
                           m.schema,
                           c.updated_at as released
                    FROM ansible_modules m
                    JOIN ansible_collections c ON m.collection_id = c.id
                    WHERE c.name = ? AND m.name = ?
                    ORDER BY c.updated_at DESC
                    """,
                    (collection_name, module_name),
                ).fetchall()
    
                # Check compatibility
                result = {
                    "module_name": module_name,
                    "collection_name": collection_name,
                    "target_version": version,
                    "current_version": current["version"],
                    "is_compatible": True,
                    "compatibility_issues": [],
                    "breaking_changes": [],
                    "version_history": [],
                }
    
                # Add version history
                for h in history:
                    result["version_history"].append(
                        {
                            "module_version": h["module_version"],
                            "collection_version": h["collection_version"],
                            "released": h["released"],
                        }
                    )
    
                # Compare schemas to detect breaking changes
                target = None
                for h in history:
                    if h["collection_version"] == version:
                        target = h
                        break
    
                if not target:
                    result["is_compatible"] = False
                    result["compatibility_issues"].append(
                        f"Target version {version} not found in module history"
                    )
                    return result
    
                # Basic schema comparison
                try:
                    import json
    
                    current_schema = json.loads(current["schema"])
                    target_schema = json.loads(target["schema"])
    
                    # Check for required fields in current that weren't required in target
                    if "required" in target_schema or "required" in current_schema:
                        current_required = set(current_schema.get("required", []))
                        target_required = set(target_schema.get("required", []))
                        
                        new_required = current_required - target_required
                        if new_required:
                            result["is_compatible"] = False
                            result["breaking_changes"].append(
                                f"Required fields added: {', '.join(new_required)}"
                            )
    
                    # Check for removed properties
                    if "properties" in current_schema and "properties" in target_schema:
                        removed_props = set(current_schema["properties"].keys()) - set(
                            target_schema["properties"].keys()
                        )
                        if removed_props:
                            result["breaking_changes"].append(
                                f"Properties removed: {', '.join(removed_props)}"
                            )
    
                    # Add compatibility notes
                    if result["breaking_changes"]:
                        result["compatibility_issues"].extend(result["breaking_changes"])
                    else:
                        result["compatibility_issues"].append(
                            "No breaking changes detected"
                        )
    
                except json.JSONDecodeError:
                    result["compatibility_issues"].append(
                        "Unable to compare schemas - invalid JSON format"
                    )
    
                return result
Behavior2/5

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

No annotations are provided, so the description carries full burden for behavioral disclosure. It only states the action ('Check') without detailing what the check entails (e.g., returns compatibility status, errors, or metadata), permissions required, rate limits, or output format. This is inadequate for a tool with no annotation coverage.

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, efficient sentence that directly states the tool's purpose without unnecessary words. It is appropriately sized and front-loaded, 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 tool's complexity (3 required parameters, no output schema, and no annotations), the description is insufficient. It lacks details on behavior, output, or error handling, failing to provide a complete context for the agent to understand how to use the tool effectively beyond its basic purpose.

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?

Schema description coverage is 100%, with clear parameter descriptions in the schema. The description adds no additional meaning beyond the schema's documentation of 'collection_name', 'module_name', and 'version', so it meets the baseline of 3 without compensating or enhancing parameter understanding.

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 action ('Check') and resource ('module compatibility across collection versions'), providing a specific purpose. However, it doesn't explicitly differentiate from sibling tools like 'get_resource_version_compatibility' or 'get_collection_version_history', which reduces the score from a perfect 5.

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?

The description provides no guidance on when to use this tool versus alternatives. With sibling tools like 'get_resource_version_compatibility' and 'get_collection_version_history' available, there's no indication of context, prerequisites, or exclusions, leaving the agent to infer usage.

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/AgentWong/iac-memory-mcp-server'

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