Skip to main content
Glama
ibm-ecm

Core Content Services MCP Server

Official
by ibm-ecm

update_folder

Update an existing folder in the content repository by specifying its identifier and new properties to modify its metadata or class.

Instructions

PREREQUISITES IN ORDER: To use this tool, you MUST call two other tools first in a specific sequence.

  1. determine_class tool to get the class_identifier.

  2. get_class_property_descriptions to get a list of valid properties for the given class_identifier

Description: Updates an existing folder in the content repository with specified properties.

:param identifier: String The folder identifier or path (required). This can be either the folder's ID (GUID) or its path in the repository (e.g., "/Folder1/folder123"). :param class_identifier: String Optional. The class identifier for the folder. If provided, allows changing the folder's class. :param folder_properties: FolderPropertiesInput Properties to update for the folder including name, etc

:returns: If successful, returns a Folder object with its updated properties. If unsuccessful, returns a ToolError with details about the failure.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
identifierYes
class_identifierNo
folder_propertiesNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler for the update_folder tool. Defines the @mcp.tool-decorated async function that accepts identifier, class_identifier, and folder_properties, builds a GraphQL mutation (with or without class_identifier), executes it via the GraphQL client, and returns a Folder object or ToolError.
    @mcp.tool(
        name="update_folder",
    )
    async def update_folder(
        identifier: str,
        class_identifier: Optional[str] = None,
        folder_properties: Optional[FolderPropertiesInput] = None,
    ) -> Union[Folder, ToolError]:
        """
        **PREREQUISITES IN ORDER**: To use this tool, you MUST call two other tools first in a specific sequence.
        1. determine_class tool to get the class_identifier.
        2. get_class_property_descriptions to get a list of valid properties for the given class_identifier
    
        Description:
        Updates an existing folder in the content repository with specified properties.
    
        :param identifier: String The folder identifier or path (required). This can be either the folder's ID (GUID) or its path in the repository (e.g., "/Folder1/folder123").
        :param class_identifier: String Optional. The class identifier for the folder. If provided, allows changing the folder's class.
        :param folder_properties: FolderPropertiesInput Properties to update for the folder including name, etc
    
        :returns: If successful, returns a Folder object with its updated properties.
                 If unsuccessful, returns a ToolError with details about the failure.
        """
        method_name = "update_folder"
        try:
            # Prepare the mutation
            if class_identifier:
                mutation = """
                mutation ($object_store_name: String!, $identifier: String!, $class_identifier: String,
                        $folder_properties: FolderPropertiesInput) {
                updateFolder(
                    repositoryIdentifier: $object_store_name
                    identifier: $identifier
                    classIdentifier: $class_identifier
                    folderProperties: $folder_properties
                ) {
                    id
                    className
                    properties {
                    id
                    value
                    }
                }
                }
                """
            else:
                mutation = """
                mutation ($object_store_name: String!, $identifier: String!, 
                        $folder_properties: FolderPropertiesInput) {
                updateFolder(
                    repositoryIdentifier: $object_store_name
                    identifier: $identifier
                    
                    folderProperties: $folder_properties
                ) {
                    id
                    className
                    properties {
                    id
                    value
                    }
                }
                }
            """
    
            # Prepare variables for the GraphQL query
            variables = {
                "object_store_name": graphql_client.object_store,  # Always use the default object store
                "identifier": identifier,
                # "class_identifier": class_identifier if class_identifier else NULL_VALUE,
                "folder_properties": None,
            }
            if class_identifier:
                variables["class_identifier"] = class_identifier
            # Process folder properties if provided
            if folder_properties:
                try:
                    folder_properties.eval()
                    transformed_props = folder_properties.transform_properties_dict(
                        exclude_none=True
                    )
    
                    variables["folder_properties"] = transformed_props
                except Exception as e:
                    logger.error("Error transforming folder properties: %s", str(e))
                    logger.error(traceback.format_exc())
                    return ToolError(
                        message=f"{method_name} failed: {str(e)}. Trace available in server logs."
                    )
    
            # Execute the GraphQL mutation
            logger.info("Executing folder update")
            response: Union[ToolError, Dict[str, Any]] = (
                await graphql_client_execute_async_wrapper(
                    logger,
                    method_name,
                    graphql_client,
                    query=mutation,
                    variables=variables,
                )
            )
            # handling exception
            if isinstance(response, ToolError):
                return response
    
            # Create and return a folder instance from the response
            return Folder.create_an_instance(
                graphQL_changed_object_dict=response["data"]["updateFolder"],
                class_identifier=(
                    class_identifier if class_identifier else DEFAULT_FOLDER_CLASS
                ),
            )
    
        except Exception as e:
            logger.error("%s failed: %s", method_name, str(e))
            logger.error(traceback.format_exc())
            return ToolError(
                message=f"{method_name} failed: {str(e)}. Trace available in server logs."
            )
  • FolderPropertiesInput schema used by update_folder. Extends CustomInputBase with properties (list of PropertyIdentifierAndScalarValue), name, and owner fields.
    class FolderPropertiesInput(CustomInputBase):
        """Input for folder properties."""
    
        properties: Optional[List[PropertyIdentifierAndScalarValue]] = Field(
            default=None, description="Properties for Folder"
        )
        name: Optional[str] = Field(
            default=None,
            description="Name sets folder name or whatever property is configured as the Name property",
        )
        owner: Optional[str] = Field(default=None, description="Owner")
  • PropertyIdentifierAndScalarValue used within FolderPropertiesInput to represent an individual property identifier and its scalar value.
    class PropertyIdentifierAndScalarValue(BaseModel):
        """Represents a property with an identifier and scalar value."""
    
        identifier: str = Field(description="Property identifier")
        value: Optional[Union[str, int, float, bool, object]] = Field(
            default=None, description="Property value"
        )
  • Folder model returned by update_folder. Includes create_an_instance classmethod that parses GraphQL response data into a Folder instance.
    class Folder(BaseModel):
        """Folder class for the MCP server."""
    
        class_identifier: str = Field(
            default="Folder", description="Class identifier for the folder"
        )
        id: str = Field(description="The id of the folder")
        name: Optional[str] = Field(default=None, description="The name of the folder")
        parent_folder_id: Optional[str] = Field(
            default=None, description="The id of the parent folder"
        )
        creator: Optional[str] = Field(
            default=None, description="The creator of the folder"
        )
        properties: Optional[List[dict]] = Field(
            default=None, description="Folder properties"
        )
        dateCreated: Optional[datetime] = Field(
            default=None, description="Date when folder was created"
        )
        lastModifier: Optional[str] = Field(
            default=None, description="The last modifier of the folder"
        )
        dateLastModified: Optional[datetime] = Field(
            default=None, description="Date when folder was last modified"
        )
        owner: Optional[str] = Field(default=None, description="The owner of the folder")
    
        @classmethod
        def create_an_instance(
            cls, graphQL_changed_object_dict: dict, class_identifier: str = "Folder"
        ):
            "create a Folder instance from a GraphQL Folder"
            folder_data = {"className": class_identifier, "id": None, "properties": []}
    
            if "id" in graphQL_changed_object_dict:
                folder_data["id"] = graphQL_changed_object_dict["id"]
    
            if "properties" in graphQL_changed_object_dict:
                properties = graphQL_changed_object_dict["properties"]
                folder_data["properties"] = properties
    
                for prop in properties:
                    if prop["id"] == "FolderName":
                        folder_data["name"] = prop["value"]
                    elif prop["id"] == "Parent":
                        folder_data["parent_folder_id"] = prop["value"]["identifier"]
                    elif prop["id"] == "Creator":
                        folder_data["creator"] = prop["value"]
                    elif prop["id"] == "DateCreated" and prop["value"]:
                        folder_data["dateCreated"] = prop["value"]
                    elif prop["id"] == "LastModifier":
                        folder_data["lastModifier"] = prop["value"]
                    elif prop["id"] == "DateLastModified" and prop["value"]:
                        folder_data["dateLastModified"] = prop["value"]
                    elif prop["id"] == "Owner":
                        folder_data["owner"] = prop["value"]
    
            return cls(**folder_data)
  • The register_folder_tools function registers all folder-related tools on the MCP server. Called from mcp_server_main.py (lines 271 and 294) for CORE and FULL server types.
    def register_folder_tools(mcp: FastMCP, graphql_client: GraphQLClient) -> None:
        @mcp.tool(
            name="create_folder",
        )
        def create_folder(
            name: str,
Behavior3/5

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

With no annotations, the description must disclose behavioral traits. It states the tool updates a folder (a mutation) and returns a Folder object or ToolError. However, it does not mention side effects, authorization needs, rate limits, or whether the operation is reversible. More context on the impact of updates would improve transparency.

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 moderately concise but includes a block of prerequisites in all-caps that could be streamlined. The parameter list is clear but repeats some information from the schema. Overall, it is not overly verbose but could be more efficiently structured.

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?

The description provides return values and prerequisites, but lacks details on error scenarios beyond ToolError, permissions, or potential side effects. Given the complexity of a mutation tool with 3 parameters and an object input, it is minimally complete but leaves gaps.

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?

Schema description coverage is 0%, so the description must compensate. It explains that 'identifier' can be a GUID or path, 'class_identifier' is optional for changing class, and 'folder_properties' includes name and other properties. This adds meaning beyond the schema, especially for the identifier parameter.

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 'Updates an existing folder in the content repository with specified properties.' This provides a specific verb ('Update') and resource ('folder'), distinguishing it from creation or deletion. However, it does not explicitly differentiate from similar tools like 'update_document_properties' or 'create_folder'.

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

Usage Guidelines5/5

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

The description explicitly lists prerequisites in order: 'you MUST call two other tools first... determine_class... get_class_property_descriptions.' This provides strong guidance on when and how to use the tool, including a necessary sequence, which is above and beyond typical usage guidance.

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/ibm-ecm/cs-mcp-server'

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