list_changesets
Retrieve and filter ServiceNow changesets to monitor application updates, track developer contributions, and review recent modifications with customizable parameters.
Instructions
List changesets from ServiceNow
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of records to return | |
| offset | No | Offset to start from | |
| state | No | Filter by state | |
| application | No | Filter by application | |
| developer | No | Filter by developer | |
| timeframe | No | Filter by timeframe (recent, last_week, last_month) | |
| query | No | Additional query string |
Implementation Reference
- The handler function that executes the tool logic: validates params, builds ServiceNow API query for sys_update_set table, fetches and returns changesets.def list_changesets( auth_manager: AuthManager, server_config: ServerConfig, params: Union[Dict[str, Any], ListChangesetsParams], ) -> Dict[str, Any]: """ List changesets from ServiceNow. Args: auth_manager: The authentication manager. server_config: The server configuration. params: The parameters for listing changesets. Can be a dictionary or a ListChangesetsParams object. Returns: A list of changesets. """ # Unwrap and validate parameters result = _unwrap_and_validate_params(params, ListChangesetsParams) if not result["success"]: return result validated_params = result["params"] # Get the instance URL instance_url = _get_instance_url(auth_manager, server_config) if not instance_url: return { "success": False, "message": "Cannot find instance_url in either server_config or auth_manager", } # Get the headers headers = _get_headers(auth_manager, server_config) if not headers: return { "success": False, "message": "Cannot find get_headers method in either auth_manager or server_config", } # Build query parameters query_params = { "sysparm_limit": validated_params.limit, "sysparm_offset": validated_params.offset, } # Build sysparm_query query_parts = [] if validated_params.state: query_parts.append(f"state={validated_params.state}") if validated_params.application: query_parts.append(f"application={validated_params.application}") if validated_params.developer: query_parts.append(f"developer={validated_params.developer}") if validated_params.timeframe: if validated_params.timeframe == "recent": query_parts.append("sys_created_onONLast 7 days@javascript:gs.beginningOfLast7Days()@javascript:gs.endOfToday()") elif validated_params.timeframe == "last_week": query_parts.append("sys_created_onONLast week@javascript:gs.beginningOfLastWeek()@javascript:gs.endOfLastWeek()") elif validated_params.timeframe == "last_month": query_parts.append("sys_created_onONLast month@javascript:gs.beginningOfLastMonth()@javascript:gs.endOfLastMonth()") if validated_params.query: query_parts.append(validated_params.query) if query_parts: query_params["sysparm_query"] = "^".join(query_parts) # Make the API request url = f"{instance_url}/api/now/table/sys_update_set" try: response = requests.get(url, params=query_params, headers=headers) response.raise_for_status() result = response.json() return { "success": True, "changesets": result.get("result", []), "count": len(result.get("result", [])), } except requests.exceptions.RequestException as e: logger.error(f"Error listing changesets: {e}") return { "success": False, "message": f"Error listing changesets: {str(e)}", }
- Pydantic BaseModel defining the input schema/parameters for the list_changesets tool, used to generate MCP inputSchema.class ListChangesetsParams(BaseModel): """Parameters for listing changesets.""" limit: Optional[int] = Field(10, description="Maximum number of records to return") offset: Optional[int] = Field(0, description="Offset to start from") state: Optional[str] = Field(None, description="Filter by state") application: Optional[str] = Field(None, description="Filter by application") developer: Optional[str] = Field(None, description="Filter by developer") timeframe: Optional[str] = Field(None, description="Filter by timeframe (recent, last_week, last_month)") query: Optional[str] = Field(None, description="Additional query string")
- src/servicenow_mcp/utils/tool_utils.py:621-627 (registration)MCP tool registration: maps 'list_changesets' to its handler (list_changesets_tool), schema (ListChangesetsParams), description, etc., in the tool_definitions dict loaded by the server."list_changesets": ( list_changesets_tool, ListChangesetsParams, str, # Expects JSON string "List changesets from ServiceNow", "json", # Tool returns list/dict ),
- src/servicenow_mcp/tools/__init__.py:33-41 (registration)Imports list_changesets from changeset_tools.py into the tools package namespace, enabling its use in tool_utils.py.from servicenow_mcp.tools.changeset_tools import ( add_file_to_changeset, commit_changeset, create_changeset, get_changeset_details, list_changesets, publish_changeset, update_changeset, )
- Helper function to unwrap dictionary or Pydantic model params, validate against schema, and check required fields. Used by list_changesets.def _unwrap_and_validate_params( params: Union[Dict[str, Any], BaseModel], model_class: Type[T], required_fields: Optional[List[str]] = None ) -> Dict[str, Any]: """ Unwrap and validate parameters. Args: params: The parameters to unwrap and validate. Can be a dictionary or a Pydantic model. model_class: The Pydantic model class to validate against. required_fields: List of fields that must be present. Returns: A dictionary with success status and validated parameters or error message. """ try: # Handle case where params is already a Pydantic model if isinstance(params, BaseModel): # If it's already the correct model class, use it directly if isinstance(params, model_class): model_instance = params # Otherwise, convert to dict and create new instance else: model_instance = model_class(**params.dict()) # Handle dictionary case else: # Create model instance model_instance = model_class(**params) # Check required fields if required_fields: missing_fields = [] for field in required_fields: if getattr(model_instance, field, None) is None: missing_fields.append(field) if missing_fields: return { "success": False, "message": f"Missing required fields: {', '.join(missing_fields)}", } return { "success": True, "params": model_instance, } except Exception as e: return { "success": False, "message": f"Invalid parameters: {str(e)}", }