Skip to main content
Glama
ibm-ecm

IBM Core Content Services MCP Server

Official
by ibm-ecm

checkout_document

Check out documents from IBM Content Manager to enable editing, update properties, and optionally download content for offline work.

Instructions

Checks out a document in the content repository.

:param identifier: The document id or path (required). This can be either the document's ID (GUID) or its path in the repository (e.g., "/Folder1/document.pdf"). :param document_properties: Properties to update for the document during check-out. :param checkout_action: Check-out action parameters for the document. :param download_folder_path: Optional path to a folder where the document content will be downloaded. If not provided but content download is needed, the user will be prompted to provide it.

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

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
identifierYes
document_propertiesNo
checkout_actionNo
download_folder_pathNo

Implementation Reference

  • Executes the checkout_document tool: sends GraphQL mutation to checkout the document, handles properties and actions, creates Document instance, and optionally downloads content elements to the specified folder.
    async def checkout_document( identifier: str, document_properties: Optional[DocumentPropertiesInput] = None, checkout_action: Optional[SubCheckoutActionInput] = None, download_folder_path: Optional[str] = None, ) -> Union[Document, ToolError]: """ Checks out a document in the content repository. :param identifier: The document id or path (required). This can be either the document's ID (GUID) or its path in the repository (e.g., "/Folder1/document.pdf"). :param document_properties: Properties to update for the document during check-out. :param checkout_action: Check-out action parameters for the document. :param download_folder_path: Optional path to a folder where the document content will be downloaded. If not provided but content download is needed, the user will be prompted to provide it. :returns: If successful, returns a Document object with its updated properties. If unsuccessful, returns a ToolError with details about the failure. """ method_name = "checkout_document" try: # Prepare the mutation mutation = """ mutation ($object_store_name: String!, $identifier: String!, $document_properties: DocumentPropertiesInput, $checkout_action: SubCheckoutActionInput) { checkoutDocument( repositoryIdentifier: $object_store_name identifier: $identifier documentProperties: $document_properties checkoutAction: $checkout_action ) { id className reservation{ isReserved id } currentVersion{ contentElements{ ... on ContentTransferType { retrievalName contentType contentSize downloadUrl } } } properties { id value } } } """ # Prepare variables for the GraphQL query variables = { "object_store_name": graphql_client.object_store, "identifier": identifier, "document_properties": None, "checkout_action": None, } # Process document properties if provided if document_properties: try: transformed_props = document_properties.transform_properties_dict( exclude_none=True ) variables["document_properties"] = transformed_props except Exception as e: logger.error("Error transforming document properties: %s", str(e)) logger.error(traceback.format_exc()) return ToolError( message=f"{method_name} failed: {str(e)}. Trace available in server logs." ) # Handle checkout action if provided if checkout_action: # Use model_dump with exclude_none for cleaner code variables["checkout_action"] = checkout_action.model_dump( exclude_none=True ) # Execute the GraphQL mutation logger.info("Executing document check-out") response = await graphql_client.execute_async( query=mutation, variables=variables ) # Handle errors if "errors" in response: logger.error("GraphQL error: %s", response["errors"]) return ToolError(message=f"{method_name} failed: {response['errors']}") # Create a Document instance from the response document = Document.create_an_instance( graphQL_changed_object_dict=response["data"]["checkoutDocument"], class_identifier=DEFAULT_DOCUMENT_CLASS, ) # Check if we need to download content if ( download_folder_path and "currentVersion" in response["data"]["checkoutDocument"] ): content_elements = response["data"]["checkoutDocument"][ "currentVersion" ]["contentElements"] if content_elements and len(content_elements) > 0: logger.info( "Found %s content elements to download", len(content_elements) ) download_results = [] download_errors = [] for idx, element in enumerate(content_elements): if "downloadUrl" in element and element["downloadUrl"]: download_url = element["downloadUrl"] logger.info( "Downloading content element %s/%s: %s", idx + 1, len(content_elements), element["retrievalName"], ) download_result = ( await graphql_client.download_content_async( download_url=download_url, download_folder_path=download_folder_path, ) ) if download_result["success"]: download_results.append(download_result) logger.info( "Content element %s downloaded to %s", idx + 1, download_result["file_path"], ) else: error_msg = ( "Failed to download content element %s: %s" % ( idx + 1, download_result["error"], ) ) download_errors.append(error_msg) logger.warning(error_msg) if download_errors: error_message = ( "Document checkout was successful, but %s content downloads failed: %s" % (len(download_errors), "; ".join(download_errors)) ) logger.warning(error_message) return ToolError( message=error_message, suggestions=[ "Check if the download folder exists and is writable", "Verify network connectivity to the content server", "Try downloading the files without checking out the document", ], ) elif download_results: logger.info( "Successfully downloaded %s content elements", len(download_results), ) return document 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." )
  • Registers the checkout_document tool using the MCP @mcp.tool decorator with name 'checkout_document'. Schema is inferred from function signature.
    @mcp.tool( name="checkout_document", )
  • Pydantic model defining the input schema for the 'checkout_action' parameter of checkout_document tool.
    class SubCheckoutActionInput(BaseModel): """Input for document check-out action.""" reservationId: Optional[str] = Field( default=None, description="ID for the reservation" ) reservationType: Optional[ReservationType] = Field( default=None, description="Type of reservation (COLLABORATIVE, EXCLUSIVE, or OBJECT_STORE_DEFAULT)", ) reservationClass: Optional[str] = Field( default=None, description="Class for the reservation" ) reservationProperties: Optional[List[PropertyIdentifierAndScalarValue]] = Field( default=None, description="Properties for the reservation" ) reservationObjectProperties: Optional[List[ObjectPropertyInput]] = Field( default=None, description="Object properties for the reservation" )
  • Pydantic model defining the input schema for the 'document_properties' parameter of checkout_document tool.
    class DocumentPropertiesInput(CustomInputBase): """Input for document properties.""" properties: Optional[List[PropertyIdentifierAndScalarValue]] = Field( default=None, description="Properties for Document" ) name: Optional[str] = Field( default=None, description="Name sets DocumentTitle or whatever property is configured as the Name property", ) owner: Optional[str] = Field(default=None, description="Owner") content: Optional[str] = Field( default=None, description="Content can be specified if this represents a Reservation document or document creation", ) mimeType: Optional[str] = Field(default=None, description="Mime type") compoundDocumentState: Optional[str] = Field( default=None, description="Compound document state" ) cmRetentionDate: Optional[datetime] = Field( default=None, description="Retention date" ) # contentElements field removed from the model to prevent agents from interpreting and creating this field # Instead, we use the methods from CustomInputBase to add content elements programmatically # Commented out references to ObjectReferenceInput, PermissionListInput, ObjectPropertyInput """ objectProperties: Optional[List[ObjectPropertyInput]] = Field( default=None, description="Object properties" ) replicationGroup: Optional[ObjectReferenceInput] = Field( default=None, description="Replication group" ) permissions: Optional[PermissionListInput] = Field( default=None, description="Permissions" ) securityPolicy: Optional[ObjectReferenceInput] = Field( default=None, description="Security policy" ) securityFolder: Optional[ObjectReferenceInput] = Field( default=None, description="Security folder" ) storagePolicy: Optional[ObjectReferenceInput] = Field( default=None, description="Storage policy" ) documentLifecyclePolicy: Optional[ObjectReferenceInput] = Field( default=None, description="Document lifecycle policy" ) storageArea: Optional[ObjectReferenceInput] = Field( default=None, description="Storage area" ) """

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