list_articles
Retrieve knowledge articles from ServiceNow with filtering options for knowledge base, category, workflow state, and search queries.
Instructions
List knowledge articles
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of articles to return | |
| offset | No | Offset for pagination | |
| knowledge_base | No | Filter by knowledge base | |
| category | No | Filter by category | |
| query | No | Search query for articles | |
| workflow_state | No | Filter by workflow state |
Implementation Reference
- Implements the list_articles tool by querying ServiceNow's kb_knowledge table API with pagination and filters, transforming results into a structured list.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 model defining input parameters for the list_articles tool, including pagination, filters for knowledge base, category, query, and 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:750-756 (registration)Registers the list_articles tool in the central tool_definitions dictionary used by the MCP server, mapping name to handler function, input schema, return type, description, and serialization method."list_articles": ( list_articles_tool, ListArticlesParams, Dict[str, Any], # Expects dict "List knowledge articles", "raw_dict", # Tool returns raw dict ),
- src/servicenow_mcp/utils/tool_utils.py:167-168 (registration)Imports the list_articles function from knowledge_base.py with alias list_articles_tool for use in tool registration.list_articles as list_articles_tool, )
- src/servicenow_mcp/tools/__init__.py:54-54 (registration)Exposes the list_articles function in the tools package __init__ for easy import.list_articles,