Skip to main content
Glama
ibm-ecm

IBM Core Content Services MCP Server

Official
by ibm-ecm

unfile_document

Remove a document from a folder in IBM Content Manager using folder and document identifiers to manage document organization.

Instructions

Unfile a document from a folder in the content repository. This tool interfaces with the GraphQL API to unfile document from folder with the provided ids.

:param folder_id_or_path string Yes The unique identifier or path for the folder. If not provided, an error will be returned. :param document_id string Yes The unique identifier for the document. If not provided, an error will be returned.

:returns: If successful, return the folder id. Else, return a ToolError instance that describes the error.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
folder_id_or_pathYes
document_idYes

Implementation Reference

  • MCP tool registration decorator for unfile_document.
    @mcp.tool(
        name="unfile_document",
    )
  • Core implementation of the unfile_document tool: validates inputs, resolves folder ID if path, queries for ReferentialContainmentRelationship (RCR) between folder and document, deletes the RCR if found and unique.
    async def unfile_document(
        folder_id_or_path: str, document_id: str
    ) -> Union[str, ToolError]:
        """
        Unfile a document from a folder in the content repository. This tool interfaces with the GraphQL API
        to unfile document from folder with the provided ids.
    
    
        :param folder_id_or_path	string	Yes	The unique identifier or path for the folder. If not provided, an error will be returned.
        :param document_id	string	Yes	The unique identifier for the document. If not provided, an error will be returned.
    
        :returns: If successful, return the folder id.
         Else, return a ToolError instance that describes the error.
        """
        method_name = "unfile_document"
        try:
            # check folder id or path and documetn id
            if not folder_id_or_path:
                return ToolError(
                    message=f"unfile_document failed: folder id or path is a required input.",
                )
            if not document_id:
                return ToolError(
                    message=f"unfile_document failed: document id is a required input.",
                )
    
            mutation = """
            query rcr($repo:String!,$where_clause: String!)
                {
                repositoryObjects(repositoryIdentifier:$repo
                from: "ReferentialContainmentRelationship"
                where : $where_clause)
                {
                    independentObjects
                    {
                    ... on ReferentialContainmentRelationship
                    {
                        id
                        tail {
                        id
                        }
                        head
                        {
                        id
                        }
                    }
                    }
                }
                }
                    
            """
    
            formatted_folder_value = ""
            if is_guid_with_braces(folder_id_or_path):
                formatted_folder_value = f"({folder_id_or_path})"
            else:
                formatted_folder_value = lookup_folder_id(
                    folder_name=folder_id_or_path, graphql_client=graphql_client
                )
            if type(formatted_folder_value) is ToolError:
                return formatted_folder_value
            formatted_document_value = f"({document_id})"
            condition_string = (
                f"tail = {formatted_folder_value} and head = {formatted_document_value}"
            )
            var = {
                "repo": graphql_client.object_store,
                "where_clause": condition_string,
            }
            response = graphql_client.execute(query=mutation, variables=var)
            # handling exception
            if "errors" in response:
                return ToolError(
                    message=f"unfile_document failed: got err {response}.",
                )
    
            return_rcr = response["data"]["repositoryObjects"]["independentObjects"]
            return_id = ""
            if len(return_rcr) > 0:
                if len(return_rcr) > 1:
                    return ToolError(
                        message=f"unfile_document failed: this document has been filed more than once in the folder.",
                    )
                return_id = return_rcr[0]["id"]
            else:
                return ToolError(
                    message=f"unfile_document failed: no such document in the folder.",
                )
    
            mutation = """
                mutation deleteRcr($repo:String!,
                    $id:String!)
                    {
                    deleteReferentialContainmentRelationship(repositoryIdentifier: $repo, 
                        identifier:$id
                    )
                    {
                    
                    id
                    }                 
                    }
            """
            var = {"repo": graphql_client.object_store, "id": return_id}
            response = await graphql_client.execute_async(query=mutation, variables=var)
            if "errors" in response:
                return ToolError(
                    message=f"unfile_document failed: got err {response}.",
                )
            return response["data"]["deleteReferentialContainmentRelationship"]["id"]
    
        except Exception as e:
            error_traceback = traceback.format_exc(limit=TRACEBACK_LIMIT)
            logger.error(
                f"{method_name} failed: {e.__class__.__name__} - {str(e)}\n{error_traceback}"
            )
    
            return ToolError(
                message=f"{method_name} failed: got err {e}. Trace available in server logs.",
            )
  • Docstring providing input/output schema and description for the unfile_document tool.
    """
    Unfile a document from a folder in the content repository. This tool interfaces with the GraphQL API
    to unfile document from folder with the provided ids.
    
    
    :param folder_id_or_path	string	Yes	The unique identifier or path for the folder. If not provided, an error will be returned.
    :param document_id	string	Yes	The unique identifier for the document. If not provided, an error will be returned.
    
    :returns: If successful, return the folder id.
     Else, return a ToolError instance that describes the error.
    """
  • Helper function used to resolve folder path/name to ID via GraphQL query.
    def lookup_folder_id(
        folder_name: str, graphql_client: GraphQLClient
    ) -> Union[str, ToolError]:
        """
        Retrieves the folder id for the given folder name.
        """
        query = """ 
                        query folder($repo:String!, $folder_name: String!)   
            {
            folder(repositoryIdentifier:$repo
            identifier:$folder_name)
            {
                id
            }
            } 
        """
    
        vars = {"repo": graphql_client.object_store, "folder_name": folder_name}
        response = graphql_client.execute(
            query, vars
        )  # Changed from execute_graphql to execute
    
        if "errors" in response:
            return ToolError(
                message=f"lookup_folder_id failed: got err {response}.",
            )
        else:
            return response["data"]["folder"]["id"]
  • Helper function to check if folder_id_or_path is a GUID with braces, used to decide whether to lookup ID.
    def is_guid_with_braces(input_string):
        """
        Check if a string is a valid GUID/UUID with curly braces.
    
        Args:
            input_string (str): The string to check
    
        Returns:
            bool: True if the string is a valid GUID with curly braces, False otherwise
        """
        # Check if string starts with '{' and ends with '}'
        if not (input_string.startswith("{") and input_string.endswith("}")):
            return False
    
        # Remove the curly braces
        guid_string = input_string[1:-1]
    
        # Pattern for UUID: 8-4-4-4-12 hexadecimal digits
        pattern = r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
    
        # Case-insensitive match
        if re.match(pattern, guid_string, re.IGNORECASE):
            return True
    
        # Alternative validation using uuid module
        try:
            uuid_obj = uuid.UUID(guid_string)
            return str(uuid_obj) == guid_string.lower()
        except ValueError:
            return False

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/ibm-content-services-mcp-server'

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