search_tickets
Search Zendesk tickets using query syntax with filters for status, priority, assignee, requester, tags, custom fields, and date ranges to find specific support requests.
Instructions
Search Zendesk tickets using query syntax. Supports text search, filters, custom fields, and date ranges.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Text to search in subject/description | |
| status | No | Filter by status: new, open, pending, hold, solved, closed | |
| priority | No | Filter by priority: low, normal, high, urgent | |
| assignee | No | Filter by assignee email | |
| requester | No | Filter by requester email | |
| tags | No | Filter by tags | |
| custom_field_id | No | Custom field ID to search | |
| custom_field_value | No | Value to match in custom field | |
| created_after | No | ISO date - tickets created after this date | |
| created_before | No | ISO date - tickets created before this date | |
| sort_by | No | Field to sort by (created_at, updated_at, priority, status) | updated_at |
| sort_order | No | Sort order (asc or desc) | desc |
| limit | No | Max results (up to 100) |
Implementation Reference
- Actual implementation of search_tickets logic that performs the Zendesk API request and processes results.
def search_tickets( self, query: str | None = None, status: str | None = None, priority: str | None = None, assignee: str | None = None, requester: str | None = None, tags: List[str] | None = None, custom_field_id: int | None = None, custom_field_value: str | None = None, created_after: str | None = None, created_before: str | None = None, sort_by: str = "updated_at", sort_order: str = "desc", limit: int = 25, ) -> Dict[str, Any]: """ Search Zendesk tickets using query syntax. Args: query: Text to search in subject/description status: Filter by status (new, open, pending, hold, solved, closed) priority: Filter by priority (low, normal, high, urgent) assignee: Filter by assignee email requester: Filter by requester email tags: Filter by tags custom_field_id: Custom field ID to search custom_field_value: Value to match in custom field created_after: ISO date - tickets created after created_before: ISO date - tickets created before sort_by: Field to sort by (created_at, updated_at, priority, status) sort_order: Sort order (asc or desc) limit: Max results (up to 100) Returns: Dict containing tickets and search metadata """ try: # Cap limit at 100 limit = min(limit, 100) # Build query parts query_parts = [] # Always search for tickets (not users, organizations, etc.) query_parts.append("type:ticket") # Text search (searches subject and description) if query: query_parts.append(query) # Standard filters if status: query_parts.append(f"status:{status}") if priority: query_parts.append(f"priority:{priority}") if assignee: query_parts.append(f"assignee:{assignee}") if requester: query_parts.append(f"requester:{requester}") # Tags if tags: for tag in tags: query_parts.append(f"tags:{tag}") # Custom field search if custom_field_id and custom_field_value: query_parts.append(f"custom_field_{custom_field_id}:{custom_field_value}") # Date filters if created_after: query_parts.append(f"created>{created_after}") if created_before: query_parts.append(f"created<{created_before}") # Build the full query string full_query = " ".join(query_parts) # Determine sort parameter for API sort_param = sort_by if sort_order == "desc": sort_param = f"-{sort_by}" if not sort_by.startswith("-") else sort_by # URL encode the query and build URL params = { "query": full_query, "sort_by": sort_param, "per_page": str(limit), } query_string = urllib.parse.urlencode(params) url = f"{self.base_url}/search.json?{query_string}" # Create request with auth header req = urllib.request.Request(url) req.add_header("Authorization", self.auth_header) req.add_header("Content-Type", "application/json") # Make the API request with urllib.request.urlopen(req) as response: data = json.loads(response.read().decode()) results = data.get("results", []) # Process tickets to return only essential fields ticket_list = [] for ticket in results: ticket_list.append({ "id": ticket.get("id"), "subject": ticket.get("subject"), "status": ticket.get("status"), "priority": ticket.get("priority"), "description": ticket.get("description"), "created_at": ticket.get("created_at"), "updated_at": ticket.get("updated_at"), "requester_id": ticket.get("requester_id"), "assignee_id": ticket.get("assignee_id"), "tags": ticket.get("tags", []), }) return { "tickets": ticket_list, "query": full_query, "count": len(ticket_list), "total_count": data.get("count", len(ticket_list)), "sort_by": sort_by, "sort_order": sort_order, } - src/zendesk_mcp_server/server.py:248-313 (registration)Tool definition and registration of search_tickets in the MCP server.
types.Tool( name="search_tickets", description="Search Zendesk tickets using query syntax. Supports text search, filters, custom fields, and date ranges.", inputSchema={ "type": "object", "properties": { "query": { "type": "string", "description": "Text to search in subject/description" }, "status": { "type": "string", "description": "Filter by status: new, open, pending, hold, solved, closed" }, "priority": { "type": "string", "description": "Filter by priority: low, normal, high, urgent" }, "assignee": { "type": "string", "description": "Filter by assignee email" }, "requester": { "type": "string", "description": "Filter by requester email" }, "tags": { "type": "array", "items": {"type": "string"}, "description": "Filter by tags" }, "custom_field_id": { "type": "integer", "description": "Custom field ID to search" }, "custom_field_value": { "type": "string", "description": "Value to match in custom field" }, "created_after": { "type": "string", "description": "ISO date - tickets created after this date" }, "created_before": { "type": "string", "description": "ISO date - tickets created before this date" }, "sort_by": { "type": "string", "description": "Field to sort by (created_at, updated_at, priority, status)", "default": "updated_at" }, "sort_order": { "type": "string", "description": "Sort order (asc or desc)", "default": "desc" }, "limit": { "type": "integer", "description": "Max results (up to 100)", "default": 25 } }, "required": [] } ) - src/zendesk_mcp_server/server.py:405-424 (handler)MCP handler branch for search_tickets that calls the zendesk_client method.
elif name == "search_tickets": results = zendesk_client.search_tickets( query=arguments.get("query") if arguments else None, status=arguments.get("status") if arguments else None, priority=arguments.get("priority") if arguments else None, assignee=arguments.get("assignee") if arguments else None, requester=arguments.get("requester") if arguments else None, tags=arguments.get("tags") if arguments else None, custom_field_id=arguments.get("custom_field_id") if arguments else None, custom_field_value=arguments.get("custom_field_value") if arguments else None, created_after=arguments.get("created_after") if arguments else None, created_before=arguments.get("created_before") if arguments else None, sort_by=arguments.get("sort_by", "updated_at") if arguments else "updated_at", sort_order=arguments.get("sort_order", "desc") if arguments else "desc", limit=arguments.get("limit", 25) if arguments else 25, ) return [types.TextContent( type="text", text=json.dumps(results, indent=2) )]