Skip to main content
Glama

add_protocol_step

Add a new step to an existing scientific protocol on protocols.io by providing the protocol ID and step details including description, materials, and references.

Instructions

Add a step to the end of the steps list for a specific protocol by its protocol ID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
protocol_idYesUnique identifier for the protocol
stepYesStep to be added to the protocol

Implementation Reference

  • The handler function for the 'add_protocol_step' tool. It appends a new step to the protocol by linking it to the last existing step via previous_guid, formats the step content, posts to the API, and returns the updated steps list.
    @mcp.tool() async def add_protocol_step( protocol_id: Annotated[int, Field(description="Unique identifier for the protocol")], step: Annotated[ProtocolStepInput, Field(description="Step to be added to the protocol")] ) -> list[ProtocolStep] | ErrorMessage: """ Add a step to the end of the steps list for a specific protocol by its protocol ID. """ # get all existing steps response_get_steps = await helpers.access_protocols_io_resource("GET", f"/v4/protocols/{protocol_id}/steps?content_format=markdown") if response_get_steps["status_code"] != 0: return ErrorMessage.from_string(response_get_steps["status_text"]) step_existed = [ProtocolStep.from_api_response(step) for step in response_get_steps.get("payload", [])] # get last step ID previous_step_id = step_existed[-1].id if step_existed else None # add step step_content = await ProtocolStepInput.to_string(step) step_data = { "guid": uuid.uuid4().hex, "previous_guid": previous_step_id, "step": step_content } response_add_step = await helpers.access_protocols_io_resource("POST", f"/v4/protocols/{protocol_id}/steps", {"steps": [step_data]}) if response_add_step["status_code"] != 0: return ErrorMessage.from_string(response_add_step["status_text"]) # get updated steps response_get_steps = await helpers.access_protocols_io_resource("GET", f"/v4/protocols/{protocol_id}/steps?content_format=markdown") if response_get_steps["status_code"] != 0: return ErrorMessage.from_string(response_get_steps["status_text"]) protocol_steps = [ProtocolStep.from_api_response(step) for step in response_get_steps.get("payload", [])] return protocol_steps
  • Pydantic model defining the input structure for the step: description, list of materials (each with name, quantity, unit), and list of reference protocol IDs. Includes a to_string method to format the step content for API submission, embedding material lists and fetching details for referenced protocols.
    class ProtocolStepInput(BaseModel): description: Annotated[str, Field(description="Description of the step (plain text only)")] materials: Annotated[list[Material], Field(description="Materials required for this step. Empty if no materials are needed")] = Field(default_factory=list) reference_protocol_ids: Annotated[list[int], Field(description="Protocol IDs referenced by this step. Empty if no references exist. Strongly recommend using at least one reference to ensure credibility")] = Field(default_factory=list) @staticmethod async def to_string(step: "ProtocolStepInput") -> str: step_content = f"{step.description}\n" if len(step.materials) + len(step.reference_protocol_ids) > 0: step_content += "\n" # add materials to step content if len(step.materials) > 0: step_content += "[Materials]\n" for material in step.materials: step_content += f"- {material.name.replace(' ', '_')} {material.quantity} {material.unit.replace(' ', '_')}\n" # add reference protocols to step content if len(step.reference_protocol_ids) > 0: if len(step.materials) > 0: step_content += "\n" step_content += "[Protocol References]\n" for protocol_id in step.reference_protocol_ids: # get information about the referenced protocol response_get_protocol = await helpers.access_protocols_io_resource("GET", f"/v4/protocols/{protocol_id}") if response_get_protocol["status_code"] != 0: return response_get_protocol["status_text"] protocol = await Protocol.from_protocol_id(response_get_protocol["payload"]["id"]) step_content += f"- {protocol.title.replace('[', '<').replace(']', '>')}[{protocol.id}] {protocol.doi}\n" return step_content
  • Pydantic model for individual material used in protocol steps, with name, quantity (non-negative float), and unit.
    class Material(BaseModel): name: Annotated[str, Field(description="Name of the material")] quantity: Annotated[float, Field(description="Amount of material needed", ge=0.0)] unit: Annotated[str, Field(description="Unit of measurement for the material, e.g., 'mL', 'g', 'μL'")]

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