Skip to main content
Glama

get_instances_based_on_template

Retrieve paginated template instances from CEDAR repository using a template ID to manage large datasets and avoid token limits.

Instructions

Get template instances that belong to the input template ID with pagination support.

This tool searches for instances of a given template and fetches their complete content in paginated chunks to avoid token limit issues.

Args: template_id: The template ID or full URL from CEDAR repository (e.g., "https://repo.metadatacenter.org/templates/e019284e-48d1-4494-bc83-ddefd28dfbac") limit: Number of instances to return per page (min: 1, max: 100, default: 10) offset: Starting position for pagination (default: 0)

Returns: Dictionary containing: - instances: List of template instances for this page - pagination: Pagination metadata (total_count, current_page, etc.) - errors: List of any errors encountered during fetching

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
template_idYes
limitNo
offsetNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main MCP tool handler for get_instances_based_on_template, including registration via @mcp.tool(). Validates params, searches instance IDs, fetches and cleans each instance, handles pagination and errors.
    @mcp.tool()
    def get_instances_based_on_template(
        template_id: str, limit: int = 10, offset: int = 0
    ) -> Dict[str, Any]:
        """
        Get template instances that belong to the input template ID with pagination support.
    
        This tool searches for instances of a given template and fetches their complete content
        in paginated chunks to avoid token limit issues.
    
        Args:
            template_id: The template ID or full URL from CEDAR repository
                        (e.g., "https://repo.metadatacenter.org/templates/e019284e-48d1-4494-bc83-ddefd28dfbac")
            limit: Number of instances to return per page (min: 1, max: 100, default: 10)
            offset: Starting position for pagination (default: 0)
    
        Returns:
            Dictionary containing:
            - instances: List of template instances for this page
            - pagination: Pagination metadata (total_count, current_page, etc.)
            - errors: List of any errors encountered during fetching
        """
        # Validate pagination parameters
        if limit < 1 or limit > 100:
            return {
                "error": "Invalid limit parameter. Must be between 1 and 100.",
                "instances": [],
                "pagination": None,
            }
    
        if offset < 0:
            return {
                "error": "Invalid offset parameter. Must be 0 or greater.",
                "instances": [],
                "pagination": None,
            }
    
        # Step 1: Search for instance IDs with pagination
        search_result = search_instance_ids(
            template_id=template_id,
            cedar_api_key=CEDAR_API_KEY,
            limit=limit,
            offset=offset,
        )
    
        # Check if search failed
        if "error" in search_result:
            return {
                "error": f"Failed to search for template instances: {search_result['error']}",
                "instances": [],
                "pagination": None,
            }
    
        instance_ids = search_result.get("instance_ids", [])
        pagination_metadata = search_result.get("pagination", {})
    
        # If no instances found, return empty result with pagination metadata
        if not instance_ids:
            return {"instances": [], "pagination": pagination_metadata, "errors": None}
    
        # Step 2: Fetch content for each instance in this page
        instances = []
        failed_instances = []
    
        for instance_id in instance_ids:
            instance_content = get_instance(instance_id, CEDAR_API_KEY)
    
            # Check if this instance fetch failed
            if "error" in instance_content:
                failed_instances.append(
                    {"instance_id": instance_id, "error": instance_content["error"]}
                )
            else:
                # Clean the instance content before adding to results
                try:
                    cleaned_instance = clean_template_instance_response(
                        instance_content
                    )
                    instances.append(cleaned_instance)
                except Exception as e:
                    failed_instances.append(
                        {
                            "instance_id": instance_id,
                            "error": f"Failed to clean instance response: {str(e)}",
                        }
                    )
    
        # Step 3: Prepare response
        response = {"instances": instances, "pagination": pagination_metadata}
    
        # Include error information if any instances failed to fetch
        if failed_instances:
            response["errors"] = failed_instances
    
        return response
  • Helper function that performs the paginated search on CEDAR API to find instance IDs based on template_id.
    def search_instance_ids(
        template_id: str, cedar_api_key: str, limit: int = 10, offset: int = 0
    ) -> Dict[str, Any]:
        """
        Search for template instances with pagination support.
    
        Args:
            template_id: Template ID (UUID or full URL)
            cedar_api_key: CEDAR API key for authentication
            limit: Number of instances to fetch
            offset: Starting position
    
        Returns:
            Dictionary containing:
            - instance_ids: List of instance IDs for this page
            - pagination: Pagination metadata
            - error: Error message if failed
        """
        try:
            # Convert template ID to full URL format if needed
            if not template_id.startswith("https://"):
                template_url = f"https://repo.metadatacenter.org/templates/{template_id}"
            else:
                template_url = template_id
    
            headers = {
                "Accept": "application/json",
                "Authorization": f"apiKey {cedar_api_key}",
            }
    
            # Build the search API URL
            base_url = "https://resource.metadatacenter.org/search"
            params = {
                "version": "latest",
                "limit": limit,
                "is_based_on": template_url,
                "offset": offset,
            }
    
            # Make the API request
            response = requests.get(
                base_url, headers=headers, params=cast(Any, params), timeout=30
            )
            response.raise_for_status()
            search_data = response.json()
    
            # Extract information
            total_count = search_data.get("totalCount", 0)
            resources = search_data.get("resources", [])
    
            # Extract instance IDs from current page
            instance_ids = []
            for resource in resources:
                instance_id = resource.get("@id")
                if instance_id:
                    instance_ids.append(instance_id)
    
            # Calculate pagination metadata
            current_page = (offset // limit) + 1
            total_pages = (
                (total_count + limit - 1) // limit if limit > 0 else 0
            )  # Ceiling division
            has_next = offset + limit < total_count
    
            pagination_metadata = {
                "limit": limit,
                "offset": offset,
                "total_count": total_count,
                "current_page": current_page,
                "total_pages": total_pages,
                "has_next": has_next,
            }
    
            return {"instance_ids": instance_ids, "pagination": pagination_metadata}
    
        except requests.exceptions.RequestException as e:
            return {"error": f"Failed to search CEDAR instances: {str(e)}"}
        except (KeyError, ValueError) as e:
            return {"error": f"Failed to parse CEDAR search response: {str(e)}"}
  • Helper function that fetches the full content of a single template instance by its ID.
    def get_instance(instance_id: str, cedar_api_key: str) -> Dict[str, Any]:
        """
        Fetch the full content of a CEDAR template instance.
    
        Args:
            instance_id: Full instance URL (e.g., "https://repo.metadatacenter.org/template-instances/{uuid}")
            cedar_api_key: CEDAR API key for authentication
    
        Returns:
            Dictionary containing instance content or error information
        """
        try:
            # URL encode the instance ID for safe inclusion in URL
            encoded_instance_id = quote(instance_id, safe="")
    
            # Build the instance API URL
            base_url = f"https://resource.metadatacenter.org/template-instances/{encoded_instance_id}"
    
            # Set authorization header
            headers = {
                "Accept": "application/json",
                "Authorization": f"apiKey {cedar_api_key}",
            }
    
            # Make the API request with timeout
            response = requests.get(base_url, headers=headers, timeout=30)
            response.raise_for_status()
    
            # Return the raw JSON response from CEDAR
            return response.json()
    
        except requests.exceptions.RequestException as e:
            return {"error": f"Failed to fetch CEDAR instance content: {str(e)}"}
        except (KeyError, ValueError) as e:
            return {"error": f"Failed to parse CEDAR instance response: {str(e)}"}
  • Helper function that cleans and simplifies the raw JSON-LD response from a template instance.
    def clean_template_instance_response(instance_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        Clean and transform CEDAR template instance JSON-LD to simplified structure.
    
        Removes metadata fields and transforms JSON-LD specific attributes:
        - Removes: '@context', 'schema:isBasedOn', 'schema:name', 'schema:description',
                   'pav:createdOn', 'pav:createdBy', 'pav:derivedFrom', 'oslc:modifiedBy', '@id' from root
        - Transforms: '@id' → 'iri', 'rdfs:label' → 'label' throughout
        - Flattens: '@value' objects to their direct values
    
        Args:
            instance_data: Raw instance data from CEDAR (JSON-LD format)
    
        Returns:
            Cleaned and transformed instance data as dictionary
        """
        # Remove metadata fields from root level
        metadata_fields = {
            "@context",
            "schema:isBasedOn",
            "schema:name",
            "schema:description",
            "pav:createdOn",
            "pav:createdBy",
            "pav:derivedFrom",
            "oslc:modifiedBy",
            "@id",
        }
    
        # Create cleaned copy
        cleaned_data = {}
        for key, value in instance_data.items():
            if key not in metadata_fields:
                cleaned_data[key] = value
    
        # Recursively transform the entire structure
        return _transform_jsonld_structure(cleaned_data)
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: pagination support, chunking to avoid token limits, error handling (returns errors list), and the structure of the return value. However, it doesn't mention rate limits, authentication requirements, or performance characteristics.

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 well-structured and front-loaded with the core purpose. Every sentence adds value: first states the action, second explains the pagination rationale, then clearly documents parameters and return structure. No wasted words or redundant information.

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

Completeness5/5

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

Given the tool's moderate complexity (3 parameters, pagination logic) and the presence of an output schema (implied by the Returns section), the description is complete. It covers purpose, parameters, return structure, and behavioral context adequately without needing to duplicate what the output schema would provide.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must fully compensate. It provides excellent parameter semantics: explains what template_id represents (ID or full URL) with an example, defines limit with min/max/default values, and explains offset's role in pagination. This adds substantial meaning beyond the bare schema.

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

Purpose5/5

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

The description clearly states the verb ('Get', 'searches for', 'fetches') and resource ('template instances') with specific scope ('that belong to the input template ID'). It distinguishes from the sibling tool 'get_template' by focusing on instances rather than templates themselves. The purpose is specific and unambiguous.

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

Usage Guidelines3/5

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

The description implies usage context ('to avoid token limit issues') and mentions pagination, but doesn't explicitly state when to use this tool versus alternatives or when not to use it. No direct comparison with the sibling 'get_template' is provided, leaving some ambiguity about tool selection.

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/BACH-AI-Tools/cedar-mcp'

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