Skip to main content
Glama

create_protocol

Create new scientific protocols on protocols.io by defining titles and descriptions, after researching existing protocols for reference.

Instructions

Create a new protocol with the given title and description.

Before creating a new protocol, ensure you have searched for at least 2 relevant public protocols using search_public_protocols and reviewed their detailed steps with get_protocol_steps for reference when adding steps.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
titleYesTitle of the new protocol (plain text only)
descriptionYesDescription of the new protocol (plain text only)

Implementation Reference

  • The primary handler function for the 'create_protocol' tool, decorated with @mcp.tool() for automatic registration. It creates a blank protocol, updates title and description via API calls, and returns the resulting Protocol or an ErrorMessage.
    @mcp.tool() async def create_protocol( title: Annotated[str, Field(description="Title of the new protocol (plain text only)")], description: Annotated[str, Field(description="Description of the new protocol (plain text only)")], ) -> Protocol | ErrorMessage: """ Create a new protocol with the given title and description. Before creating a new protocol, ensure you have searched for at least 2 relevant public protocols using search_public_protocols and reviewed their detailed steps with get_protocol_steps for reference when adding steps. """ response_create_blank_protocol = await helpers.access_protocols_io_resource("POST", f"/v3/protocols/{uuid.uuid4().hex}", {"type_id": 1}) if response_create_blank_protocol["status_code"] != 0: return ErrorMessage.from_string(response_create_blank_protocol["error_message"]) protocol = await Protocol.from_protocol_id(response_create_blank_protocol["protocol"]["id"]) data = {"title": title, "description": description} response_update_protocol = await helpers.access_protocols_io_resource("PUT", f"/v4/protocols/{protocol.id}", data) if response_update_protocol["status_code"] != 0: return ErrorMessage.from_string(response_update_protocol["status_text"]) response_get_protocol = await helpers.access_protocols_io_resource("GET", f"/v4/protocols/{protocol.id}") if response_get_protocol["status_code"] != 0: return ErrorMessage.from_string(response_get_protocol["status_text"]) protocol = await Protocol.from_protocol_id(response_get_protocol["payload"]["id"]) return protocol
  • Pydantic schema for Protocol output type used by create_protocol.
    class Protocol(BaseModel): id: Annotated[int, Field(description="Unique identifier for the protocol")] title: Annotated[str, Field(description="Title of the protocol")] description: Annotated[str, Field(description="Description of the protocol")] doi: Annotated[str | None, Field(description="DOI of the protocol, if the protocol is private, this will be null")] = None url: Annotated[str, Field(description="URL link to the protocol on protocols.io ")] created_on: Annotated[datetime, Field(description="Date and time the protocol was created")] published_on: Annotated[datetime | None, Field(description="Date and time the protocol was published, if the protocol is private, this will be null")] = None @classmethod async def from_protocol_id(cls, protocol_id: int) -> "Protocol": response = await helpers.access_protocols_io_resource("GET", f"/v4/protocols/{protocol_id}?content_format=markdown") protocol = response["payload"] return cls( id=protocol_id, title=protocol["title"], description=protocol.get("description") or "", doi=protocol.get("doi") or None, url=protocol.get("url"), created_on=datetime.fromtimestamp(protocol.get("created_on"), tz=timezone.utc), published_on=datetime.fromtimestamp(protocol.get("published_on"), tz=timezone.utc) if protocol.get("published_on") else None )
  • Pydantic schema for ErrorMessage output type used by create_protocol.
    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)
  • Key helper utility for making authenticated API requests to protocols.io, heavily used in the create_protocol handler.
    async def access_protocols_io_resource(method: Literal["GET", "POST", "PUT", "DELETE"], path: str, data: dict = None) -> dict[str, Any]: """Access protocols.io API with specified method and path.""" headers = { "Authorization": f"Bearer {PROTOCOLS_IO_CLIENT_ACCESS_TOKEN}" } async with httpx.AsyncClient(timeout=30.0) as client: response = await client.request(method, f"{PROTOCOLS_IO_API_URL}{path}", json=data, headers=headers) return response.json()
  • The import statement that loads the tools module, triggering registration of all @mcp.tool()-decorated functions including create_protocol.
    importlib.import_module('protocols_io_mcp.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/hqn21/protocols-io-mcp-server'

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