update_project_item_field
Modify field values for items in GitHub Projects to keep project data current and organized.
Instructions
Update a field value for a project item.
Args:
owner: The GitHub organization or user name
project_number: The project number
item_id: The ID of the item to update
field_id: The ID of the field to update
field_value: The new value for the field (text, date, or option ID for single select)
Returns:
A confirmation message
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| owner | Yes | ||
| project_number | Yes | ||
| item_id | Yes | ||
| field_id | Yes | ||
| field_value | Yes |
Implementation Reference
- The primary handler function for the 'update_project_item_field' MCP tool. Decorated with @mcp.tool() for automatic registration. Defines input schema via type annotations and docstring. Performs basic type inference on field_value and delegates to GitHubClient.update_project_item_field.@mcp.tool() async def update_project_item_field( owner: str, project_number: int, item_id: str, field_id: str, field_value: str ) -> str: """Update a field value for a project item. Args: owner: The GitHub organization or user name project_number: The project number item_id: The ID of the item to update field_id: The ID of the field to update field_value: The new value for the field (text, date, or option ID for single select) Returns: A confirmation message """ try: # The GitHub client's update method expects the raw value, not just string # We might need a way to parse field_value based on field_id or context # For now, we pass the string directly, but this might fail for non-text fields. # A better implementation would fetch field info first to determine expected type. logger.warning( f"Attempting to update field {field_id} with value '{field_value}'. Type conversion might be needed." ) # Attempt basic type inference (example - needs improvement) parsed_value: Any = field_value try: parsed_value = float(field_value) if parsed_value.is_integer(): parsed_value = int(parsed_value) except ValueError: # Check if looks like a date? pass # Keep as string if not obviously numeric result = await github_client.update_project_item_field( owner, project_number, item_id, field_id, parsed_value, # Pass potentially parsed value ) return ( f"Successfully updated field for item in project #{project_number}!\n" f"Item ID: {item_id}\n" f"Field ID: {field_id}\n" f"Value Set: {field_value}" # Report the value as passed to the tool ) except GitHubClientError as e: logger.error(f"Error updating field {field_id} for item {item_id}: {e}") return f"Error: Could not update field value. Details: {e}"
- Supporting method in GitHubClient class that implements the core logic: fetches project ID, infers field value input format based on field ID prefixes for different field types, constructs and executes the GraphQL mutation to update the field value.async def update_project_item_field( self, owner: str, project_number: int, item_id: str, field_id: str, value: Any, # Value type depends on the field ) -> Dict[str, Any]: """Update a field value for an item in a GitHub Project V2. Args: owner: The GitHub organization or user name that owns the project project_number: The project number item_id: The project item ID field_id: The field ID to update value: The new value (type depends on field: string, number, date, boolean, iteration ID, single select option ID) Returns: The updated project item data (containing the item ID) Raises: GitHubClientError: If project not found or update fails. """ # Get project ID try: project_id = await self.get_project_node_id(owner, project_number) except GitHubClientError as e: logger.error(f"Cannot update item field: {e}") raise # Prepare value based on its type and field ID convention # This mapping might need refinement based on actual field types fetched separately field_value_input: Dict[str, Any] = {} # Heuristic based on ID prefix - A better approach would be to fetch field type first if field_id.startswith("PVTSSF_"): # Single Select Field (assumed prefix) if isinstance(value, str): field_value_input = {"singleSelectOptionId": value} else: raise GitHubClientError( f"Invalid value type for single select field {field_id}. Expected option ID string." ) elif field_id.startswith("PVTIF_"): # Iteration Field (assumed prefix) if isinstance(value, str): field_value_input = {"iterationId": value} else: raise GitHubClientError( f"Invalid value type for iteration field {field_id}. Expected iteration ID string." ) # Add more field types based on prefixes or fetched field info elif field_id.startswith("PVTF_"): # Text Field (assumed prefix) if isinstance(value, str): field_value_input = {"text": value} else: # Attempt to convert field_value_input = {"text": str(value)} elif field_id.startswith("PVTDF_"): # Date Field (assumed prefix) if isinstance(value, str): # Assuming date string like YYYY-MM-DD field_value_input = {"date": value} else: raise GitHubClientError( f"Invalid value type for date field {field_id}. Expected date string (YYYY-MM-DD)." ) elif field_id.startswith("PVTNU_"): # Number Field (assumed prefix) if isinstance(value, (int, float)): field_value_input = { "number": float(value) } # GraphQL uses Float for numbers else: raise GitHubClientError( f"Invalid value type for number field {field_id}. Expected int or float." ) else: # Default to text if type unknown logger.warning( f"Unknown field type for {field_id}. Attempting to set as text." ) field_value_input = {"text": str(value)} # Update field value update_query = """ mutation UpdateProjectFieldValue($projectId: ID!, $itemId: ID!, $fieldId: ID!, $value: ProjectV2FieldValue!) { updateProjectV2ItemFieldValue(input: { projectId: $projectId, itemId: $itemId, fieldId: $fieldId, value: $value }) { projectV2Item { id } } } """ variables = { "projectId": project_id, "itemId": item_id, "fieldId": field_id, "value": field_value_input, } try: result = await self.execute_query(update_query, variables) if not result.get("updateProjectV2ItemFieldValue") or not result[ "updateProjectV2ItemFieldValue" ].get("projectV2Item"): raise GitHubClientError( f"Failed to update field value for item {item_id}" ) return result["updateProjectV2ItemFieldValue"]["projectV2Item"] except GitHubClientError as e: logger.error(f"Failed to update field {field_id} for item {item_id}: {e}") raise