list_articles
Retrieve knowledge articles from ServiceNow instances using filters like knowledge base, category, query, and workflow state. Supports pagination with limit and offset.
Instructions
List knowledge articles
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Filter by category | |
| knowledge_base | No | Filter by knowledge base | |
| limit | No | Maximum number of articles to return | |
| offset | No | Offset for pagination | |
| query | No | Search query for articles | |
| workflow_state | No | Filter by workflow state |
Implementation Reference
- The core handler function for the 'list_articles' tool. It queries the ServiceNow 'kb_knowledge' table using GET with filters for knowledge_base, category, workflow_state, and query, transforms the results into a structured list of articles, and returns a dictionary with success status, message, articles list, and pagination info.def list_articles( config: ServerConfig, auth_manager: AuthManager, params: ListArticlesParams, ) -> Dict[str, Any]: """ List knowledge articles with filtering options. Args: config: Server configuration. auth_manager: Authentication manager. params: Parameters for listing articles. Returns: Dictionary with list of articles and metadata. """ api_url = f"{config.api_url}/table/kb_knowledge" # Build query parameters query_params = { "sysparm_limit": params.limit, "sysparm_offset": params.offset, "sysparm_display_value": "all", } # Build query string query_parts = [] if params.knowledge_base: query_parts.append(f"kb_knowledge_base.sys_id={params.knowledge_base}") if params.category: query_parts.append(f"kb_category.sys_id={params.category}") if params.workflow_state: query_parts.append(f"workflow_state={params.workflow_state}") if params.query: query_parts.append(f"short_descriptionLIKE{params.query}^ORtextLIKE{params.query}") if query_parts: query_string = "^".join(query_parts) logger.debug(f"Constructed article query string: {query_string}") query_params["sysparm_query"] = query_string # Log the query parameters for debugging logger.debug(f"Listing articles with query params: {query_params}") # Make request try: response = requests.get( api_url, params=query_params, headers=auth_manager.get_headers(), timeout=config.timeout, ) response.raise_for_status() # Get the JSON response json_response = response.json() logger.debug(f"Article listing raw response: {json_response}") # Safely extract the result if isinstance(json_response, dict) and "result" in json_response: result = json_response.get("result", []) else: logger.error("Unexpected response format: %s", json_response) return { "success": False, "message": f"Unexpected response format", "articles": [], "count": 0, "limit": params.limit, "offset": params.offset, } # Transform the results articles = [] # Handle either string or list if isinstance(result, list): for article_item in result: if not isinstance(article_item, dict): logger.warning("Skipping non-dictionary article item: %s", article_item) continue # Safely extract values article_id = article_item.get("sys_id", "") title = article_item.get("short_description", "") # Extract nested values safely knowledge_base = "" if isinstance(article_item.get("kb_knowledge_base"), dict): knowledge_base = article_item["kb_knowledge_base"].get("display_value", "") category = "" if isinstance(article_item.get("kb_category"), dict): category = article_item["kb_category"].get("display_value", "") workflow_state = "" if isinstance(article_item.get("workflow_state"), dict): workflow_state = article_item["workflow_state"].get("display_value", "") created = article_item.get("sys_created_on", "") updated = article_item.get("sys_updated_on", "") articles.append({ "id": article_id, "title": title, "knowledge_base": knowledge_base, "category": category, "workflow_state": workflow_state, "created": created, "updated": updated, }) else: logger.warning("Result is not a list: %s", result) return { "success": True, "message": f"Found {len(articles)} articles", "articles": articles, "count": len(articles), "limit": params.limit, "offset": params.offset, } except requests.RequestException as e: logger.error(f"Failed to list articles: {e}") return { "success": False, "message": f"Failed to list articles: {str(e)}", "articles": [], "count": 0, "limit": params.limit, "offset": params.offset, }
- Pydantic BaseModel defining the input parameters for the list_articles tool, including pagination (limit, offset) and filters (knowledge_base, category, query, workflow_state).class ListArticlesParams(BaseModel): """Parameters for listing knowledge articles.""" limit: int = Field(10, description="Maximum number of articles to return") offset: int = Field(0, description="Offset for pagination") knowledge_base: Optional[str] = Field(None, description="Filter by knowledge base") category: Optional[str] = Field(None, description="Filter by category") query: Optional[str] = Field(None, description="Search query for articles") workflow_state: Optional[str] = Field(None, description="Filter by workflow state")
- src/servicenow_mcp/utils/tool_utils.py:704-710 (registration)Registration of the 'list_articles' tool in the central tool_definitions dictionary. Maps the tool name to its handler (list_articles_tool), input schema (ListArticlesParams), return type hint, description, and serialization method ('raw_dict'). This is used by the MCP server to expose the tool."list_articles": ( list_articles_tool, ListArticlesParams, Dict[str, Any], # Expects dict "List knowledge articles", "raw_dict", # Tool returns raw dict ),
- src/servicenow_mcp/tools/__init__.py:54-54 (registration)Import and export of the list_articles function from knowledge_base.py in the tools package __init__.py, making it available for import in other modules like tool_utils.py.list_articles,