Skip to main content
Glama

add_bounds_restriction

Apply numeric constraints to parameters in IDS specifications by defining minimum and maximum values for validation.

Instructions

Add numeric bounds restriction.

Args: spec_id: Specification identifier or name facet_index: Index of facet in location (0-based) parameter_name: Which parameter to restrict (e.g., "value") base_type: XSD base type (e.g., "xs:double", "xs:integer") ctx: FastMCP Context (auto-injected) location: "applicability" or "requirements" (default: "requirements") min_inclusive: Minimum value (inclusive) max_inclusive: Maximum value (inclusive) min_exclusive: Minimum value (exclusive) max_exclusive: Maximum value (exclusive)

Returns: {"status": "added", "restriction_type": "bounds", "spec_id": "S1"}

Example: Add bounds to property value: Height must be between 2.4 and 3.0 meters

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
spec_idYes
facet_indexYes
parameter_nameYes
base_typeYes
locationNorequirements
min_inclusiveNo
max_inclusiveNo
min_exclusiveNo
max_exclusiveNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Implements the core logic for adding numeric bounds restrictions (min/max inclusive/exclusive) to a specified parameter in an IDS facet using IfcTester's Restriction API.
    async def add_bounds_restriction(
        spec_id: str,
        facet_index: int,
        parameter_name: str,
        base_type: str,
        ctx: Context,
        location: str = "requirements",
        min_inclusive: Optional[float] = None,
        max_inclusive: Optional[float] = None,
        min_exclusive: Optional[float] = None,
        max_exclusive: Optional[float] = None
    ) -> Dict[str, Any]:
        """
        Add numeric bounds restriction.
    
        Args:
            spec_id: Specification identifier or name
            facet_index: Index of facet in location (0-based)
            parameter_name: Which parameter to restrict (e.g., "value")
            base_type: XSD base type (e.g., "xs:double", "xs:integer")
            ctx: FastMCP Context (auto-injected)
            location: "applicability" or "requirements" (default: "requirements")
            min_inclusive: Minimum value (inclusive)
            max_inclusive: Maximum value (inclusive)
            min_exclusive: Minimum value (exclusive)
            max_exclusive: Maximum value (exclusive)
    
        Returns:
            {"status": "added", "restriction_type": "bounds", "spec_id": "S1"}
    
        Example:
            Add bounds to property value: Height must be between 2.4 and 3.0 meters
        """
        try:
            ids_obj = await get_or_create_session(ctx)
            spec = _find_specification(ids_obj, spec_id)
    
            await ctx.info(f"Adding bounds restriction to {spec_id}, facet {facet_index}")
    
            # Get the facet
            facet = _get_facet_from_spec(spec, location, facet_index)
    
            # Build bounds parameters
            bounds_params = {}
            if min_inclusive is not None:
                bounds_params["minInclusive"] = min_inclusive
            if max_inclusive is not None:
                bounds_params["maxInclusive"] = max_inclusive
            if min_exclusive is not None:
                bounds_params["minExclusive"] = min_exclusive
            if max_exclusive is not None:
                bounds_params["maxExclusive"] = max_exclusive
    
            # Create bounds restriction using IfcTester
            # Normalize base type (remove 'xs:' prefix if present)
            normalized_base = _normalize_base_type(base_type)
            restriction = ids.Restriction(
                base=normalized_base,
                options=bounds_params
            )
    
            # Apply restriction to the parameter
            _apply_restriction_to_facet(facet, parameter_name, restriction)
    
            await ctx.info(f"Bounds restriction added: {bounds_params}")
    
            return {
                "status": "added",
                "restriction_type": "bounds",
                "spec_id": spec_id,
                "facet_index": facet_index,
                "parameter": parameter_name,
                "bounds": bounds_params
            }
    
        except ToolError:
            raise
        except Exception as e:
            await ctx.error(f"Failed to add bounds restriction: {str(e)}")
            raise ToolError(f"Failed to add bounds restriction: {str(e)}")
  • Registers the add_bounds_restriction tool function with the FastMCP server instance.
    mcp_server.tool(restrictions.add_bounds_restriction)
  • Helper function that applies a Restriction object to a specific parameter on a facet object, used by add_bounds_restriction and other restriction tools.
    def _apply_restriction_to_facet(
        facet: Any,
        parameter_name: str,
        restriction: ids.Restriction
    ) -> None:
        """
        Apply restriction to a facet parameter.
    
        Args:
            facet: Facet object (Entity, Property, Attribute, etc.)
            parameter_name: Parameter to restrict (e.g., "value", "propertySet", "baseName")
            restriction: Restriction object to apply
    
        Raises:
            ToolError: If parameter doesn't exist on facet
        """
        # Check if parameter exists
        if not hasattr(facet, parameter_name):
            raise ToolError(
                f"Parameter '{parameter_name}' not found on facet type {type(facet).__name__}"
            )
    
        # Set the restriction on the parameter
        setattr(facet, parameter_name, restriction)
  • Helper function to retrieve a specific facet from an IDS specification by location ('applicability' or 'requirements') and index, used by all restriction tools.
    def _get_facet_from_spec(
        spec: ids.Specification,
        location: str,
        facet_index: int
    ) -> Any:
        """
        Get facet from specification by location and index.
    
        Args:
            spec: Specification object
            location: "applicability" or "requirements"
            facet_index: Index of facet in location (0-based)
    
        Returns:
            Facet object
    
        Raises:
            ToolError: If location invalid or index out of range
        """
        if location == "applicability":
            facets = spec.applicability
        elif location == "requirements":
            facets = spec.requirements
        else:
            raise ToolError(f"Invalid location: {location}. Must be 'applicability' or 'requirements'")
    
        if facet_index < 0 or facet_index >= len(facets):
            raise ToolError(
                f"Facet index {facet_index} out of range. "
                f"Location '{location}' has {len(facets)} facet(s)"
            )
    
        return facets[facet_index]
  • Helper function to normalize XSD base types by removing 'xs:' prefix, used when creating Restriction objects.
    def _normalize_base_type(base_type: str) -> str:
        """
        Normalize XML Schema base type for IfcTester.
    
        IfcTester adds 'xs:' prefix automatically, so we need to remove it if present.
    
        Args:
            base_type: Base type (e.g., "xs:string" or "string")
    
        Returns:
            Normalized base type without 'xs:' prefix (e.g., "string")
        """
        if base_type.startswith("xs:"):
            return base_type[3:]  # Remove 'xs:' prefix
        return base_type
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It states what the tool does and shows a return format, but doesn't explain important behavioral aspects: whether this is a mutation operation, what permissions are needed, whether the restriction replaces existing ones, error handling, or side effects. The example helps but doesn't cover behavioral traits comprehensively.

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

Conciseness3/5

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

The description is reasonably structured with sections for Args, Returns, and Example. However, it includes redundant information (ctx parameter is auto-injected but listed) and could be more front-loaded. The example is helpful but the overall text could be more efficiently organized, with some sentences not earning their place in terms of clarity.

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

Completeness3/5

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

Given the tool's complexity (9 parameters, no annotations, schema coverage 0%), the description provides basic functionality explanation and parameter listing. The output schema exists (Returns section), so return values are documented. However, for a mutation tool with many parameters, it lacks crucial context about behavior, constraints, and integration with the broader system of sibling tools.

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

Parameters4/5

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

With 0% schema description coverage, the description compensates well by listing all 9 parameters with brief explanations. It clarifies parameter meanings like 'facet_index: Index of facet in location (0-based)' and 'location: "applicability" or "requirements" (default: "requirements")'. The description adds significant value beyond the bare schema, though some parameter details remain unclear (e.g., how min_inclusive and min_exclusive interact).

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 tool's purpose: 'Add numeric bounds restriction' with an example showing it restricts values to a range. It distinguishes from siblings like 'add_enumeration_restriction' and 'add_pattern_restriction' by focusing on numeric bounds. However, it doesn't explicitly contrast with all sibling tools in the description text itself.

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 minimal usage guidance. The example mentions 'Add bounds to property value' which gives some context, but there's no explicit guidance on when to use this tool versus alternatives like 'add_enumeration_restriction' or 'add_length_restriction'. No prerequisites, error conditions, or when-not-to-use information is provided.

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/vinnividivicci/ifc-ids-mcp'

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