Skip to main content
Glama
hqn21

protocols-io-mcp-server

delete_protocol_step

Remove a specific step from a protocols.io protocol by providing both the protocol ID and step ID to delete unwanted or outdated protocol components.

Instructions

Delete a specific step from a protocol by providing both the protocol ID and step ID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
protocol_idYesUnique identifier for the protocol
step_idYesUnique identifier for the step to be deleted

Implementation Reference

  • The main handler function for the 'delete_protocol_step' tool. It is decorated with @mcp.tool(), which registers it as an MCP tool. The function deletes a specific step from a protocol using the Protocols.io API and returns the updated list of steps.
    @mcp.tool()
    async def delete_protocol_step(
        protocol_id: Annotated[int, Field(description="Unique identifier for the protocol")],
        step_id: Annotated[str, Field(description="Unique identifier for the step to be deleted")]
    ) -> list[ProtocolStep] | ErrorMessage:
        """
        Delete a specific step from a protocol by providing both the protocol ID and step ID.
        """
        response_delete_protocol_step = await helpers.access_protocols_io_resource("DELETE", f"/v4/protocols/{protocol_id}/steps", {"steps": [step_id]})
        if response_delete_protocol_step["status_code"] != 0:
            return ErrorMessage.from_string(response_delete_protocol_step["status_text"])
        response_get_protocol_steps = await helpers.access_protocols_io_resource("GET", f"/v4/protocols/{protocol_id}/steps?content_format=markdown")
        if response_get_protocol_steps["status_code"] != 0:
            return ErrorMessage.from_string(response_get_protocol_steps["status_text"])
        steps = [ProtocolStep.from_api_response(step) for step in response_get_protocol_steps.get("payload", [])]
        return steps
  • The @mcp.tool() decorator registers the delete_protocol_step function as an MCP tool.
    @mcp.tool()
  • Input schema defined via Annotated types in the function signature: protocol_id (int), step_id (str). Output is list[ProtocolStep] or ErrorMessage.
    async def delete_protocol_step(
        protocol_id: Annotated[int, Field(description="Unique identifier for the protocol")],
        step_id: Annotated[str, Field(description="Unique identifier for the step to be deleted")]
    ) -> list[ProtocolStep] | ErrorMessage:
        """
        Delete a specific step from a protocol by providing both the protocol ID and step ID.
        """
        response_delete_protocol_step = await helpers.access_protocols_io_resource("DELETE", f"/v4/protocols/{protocol_id}/steps", {"steps": [step_id]})
        if response_delete_protocol_step["status_code"] != 0:
            return ErrorMessage.from_string(response_delete_protocol_step["status_text"])
        response_get_protocol_steps = await helpers.access_protocols_io_resource("GET", f"/v4/protocols/{protocol_id}/steps?content_format=markdown")
        if response_get_protocol_steps["status_code"] != 0:
            return ErrorMessage.from_string(response_get_protocol_steps["status_text"])
        steps = [ProtocolStep.from_api_response(step) for step in response_get_protocol_steps.get("payload", [])]
        return steps
  • ProtocolStep model used for parsing and returning steps in the tool's output.
    class ProtocolStep(BaseModel):
        id: Annotated[str, Field(description="Unique identifier for the step")]
        description: Annotated[str, Field(description="Description of the step")]
        materials: Annotated[list[Material], Field(description="Materials required for this step. Empty if no materials are needed or if source data could not be parsed")] = Field(default_factory=list)
        reference_protocol_ids: Annotated[list[int], Field(description="Protocol IDs referenced by this step. Empty if no references exist or if source data could not be parsed")] = Field(default_factory=list)
    
        @staticmethod
        def parse(step: str) -> dict:
            description = []
            materials = []
            reference_protocol_ids = []
            material_flag = False
            reference_flag = False
            for line in step.splitlines():
                if material_flag is False and reference_flag is False:
                    if line == "[Materials]":
                        material_flag = True
                        reference_flag = False
                    elif line == "[Protocol References]":
                        reference_flag = True
                        material_flag = False
                    elif len(line) > 0:
                        description.append(line)
                elif material_flag:
                    if len(line) == 0 or line[0] != '-':
                        material_flag = False
                        continue
                    data = line.split()
                    materials.append(Material(
                        name=data[1],
                        quantity=float(data[2]),
                        unit=data[3]
                    ))
                elif reference_flag:
                    if len(line) == 0 or line[0] != '-':
                        reference_flag = False
                        continue
                    data = line.split("[")[1].split("]")[0]
                    reference_protocol_ids.append(int(data))
            description = "\n".join(description)
            return {
                "description": description,
                "materials": materials,
                "reference_protocol_ids": reference_protocol_ids
            }
    
        @classmethod
        def from_api_response(cls, data: dict) -> "ProtocolStep":
            parsed_step = ProtocolStep.parse(data["step"])
            return cls(
                id=data["guid"],
                description=parsed_step["description"],
                materials=parsed_step["materials"],
                reference_protocol_ids=parsed_step["reference_protocol_ids"]
            )
  • ErrorMessage model used for error responses in the tool.
    class ErrorMessage(BaseModel):
        error_message: Annotated[str, Field(description="Error message describing the issue encountered")]
    
        @classmethod
        def from_string(cls, message: str) -> "ErrorMessage":
            return cls(error_message=message)

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/hqn21/protocols-io-mcp-server'

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