workflowy_update_node
Modify an existing WorkFlowy node by updating its name, note content, layout style, or completion status to keep your outlines current.
Instructions
Update an existing WorkFlowy node
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| node_id | Yes | ||
| name | No | ||
| note | No | ||
| layout_mode | No | ||
| _completed | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ch | No | Child nodes | |
| cp | No | Completion status (for tests) | |
| id | Yes | Unique identifier for the node | |
| data | No | Node data including layoutMode | |
| name | No | Text content of the node | |
| note | No | Note content attached to the node | |
| parentId | No | Parent node ID | |
| priority | No | Sort order | |
| createdAt | No | Creation timestamp (Unix timestamp) | |
| modifiedAt | No | Last modification timestamp | |
| completedAt | No | Completion timestamp (null if not completed) |
Implementation Reference
- src/workflowy_mcp/server.py:124-163 (handler)The primary handler function for the 'workflowy_update_node' MCP tool. It validates inputs via type hints and NodeUpdateRequest model, manages rate limiting, delegates to WorkFlowyClient.update_node, and returns the updated WorkFlowyNode.
@mcp.tool(name="workflowy_update_node", description="Update an existing WorkFlowy node") async def update_node( node_id: str, name: str | None = None, note: str | None = None, layout_mode: Literal["bullets", "todo", "h1", "h2", "h3"] | None = None, _completed: bool | None = None, ) -> WorkFlowyNode: """Update an existing WorkFlowy node. Args: node_id: The ID of the node to update name: New text content for the node (optional) note: New note/description (optional) layout_mode: New layout mode for the node (bullets, todo, h1, h2, h3) (optional) _completed: New completion status (not used - use complete_node/uncomplete_node) Returns: The updated WorkFlowy node """ client = get_client() request = NodeUpdateRequest( # type: ignore[call-arg] name=name, note=note, layoutMode=layout_mode, ) if _rate_limiter: await _rate_limiter.acquire() try: node = await client.update_node(node_id, request) if _rate_limiter: _rate_limiter.on_success() return node except Exception as e: if _rate_limiter and hasattr(e, "__class__") and e.__class__.__name__ == "RateLimitError": _rate_limiter.on_rate_limit(getattr(e, "retry_after", None)) raise - Pydantic BaseModel defining the input schema (optional name, note, layoutMode) used in the tool handler for node updates.
class NodeUpdateRequest(BaseModel): """Request payload for updating an existing node.""" name: str | None = Field(None, description="New text content") note: str | None = Field(None, description="New note content") layoutMode: Literal["bullets", "todo", "h1", "h2", "h3"] | None = Field( None, description="New display mode (bullets, todo, h1, h2, h3)" ) def has_updates(self) -> bool: """Check if at least one field is provided for update.""" return any(getattr(self, field) is not None for field in self.model_fields) - Core API client method that executes the HTTP POST request to update the node via the WorkFlowy API endpoint /nodes/{node_id}, parses response into WorkFlowyNode, and handles errors including rate limits.
async def update_node(self, node_id: str, request: NodeUpdateRequest) -> WorkFlowyNode: """Update an existing node.""" try: response = await self.client.post( f"/nodes/{node_id}", json=request.model_dump(exclude_none=True) ) data = await self._handle_response(response) # API returns the full node object return WorkFlowyNode(**data) except httpx.TimeoutException as err: raise TimeoutError("update_node") from err except httpx.NetworkError as e: raise NetworkError(f"Network error: {str(e)}") from e - src/workflowy_mcp/server.py:124-124 (registration)The @mcp.tool decorator registers the update_node function as the MCP tool with the specified name and description.
@mcp.tool(name="workflowy_update_node", description="Update an existing WorkFlowy node")