Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mcp-bugzilla for openSUSE:Factory checked in at 2026-11-06 19:58:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mcp-bugzilla (Old) and /work/SRC/openSUSE:Factory/.mcp-bugzilla.new.3759290 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mcp-bugzilla" Fri Nov 6 19:58:20 2026 rev:5 rq:1395830 version:0.22.0 Changes: -------- --- /work/SRC/openSUSE:Factory/mcp-bugzilla/mcp-bugzilla.changes 2026-09-28 10:46:38.871443304 +0200 +++ /work/SRC/openSUSE:Factory/.mcp-bugzilla.new.3759290/mcp-bugzilla.changes 2026-11-06 20:05:00.780935936 +0100 @@ -1,0 +2,10 @@ +Fri Nov 6 07:48:31 UTC 2026 - Martin Pluskal <[email protected]> + +- Update to version 0.22.0: + * Expose sort order parameter in bugs_quicksearch + * Ship the quicksearch syntax reference with the server + * Handle partial endpoint failures gracefully in bug_info +- Keep fastmcp as a versioned floor instead of upstream's exact + pin on 4.1.4; the fastmcp API the server uses is unchanged + +------------------------------------------------------------------- Old: ---- mcp_bugzilla-0.21.0.tar.gz New: ---- mcp_bugzilla-0.22.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mcp-bugzilla.spec ++++++ --- /var/tmp/diff_new_pack.wxHdEU/_old 2026-11-06 20:05:01.667973083 +0100 +++ /var/tmp/diff_new_pack.wxHdEU/_new 2026-11-06 20:05:01.671973251 +0100 @@ -21,7 +21,7 @@ # not a multi-flavour module. %define pythons %{primary_python} Name: mcp-bugzilla -Version: 0.21.0 +Version: 0.22.0 Release: 0 Summary: Model Context Protocol server for Bugzilla License: Apache-2.0 ++++++ mcp_bugzilla-0.21.0.tar.gz -> mcp_bugzilla-0.22.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mcp_bugzilla-0.21.0/PKG-INFO new/mcp_bugzilla-0.22.0/PKG-INFO --- old/mcp_bugzilla-0.21.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/mcp_bugzilla-0.22.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,8 +1,8 @@ Metadata-Version: 2.3 Name: mcp-bugzilla -Version: 0.21.0 +Version: 0.22.0 Summary: MCP server for Bugzilla -Requires-Dist: fastmcp==4.0.3 +Requires-Dist: fastmcp==4.1.4 Requires-Dist: httpx-retries>=0.5.0 Requires-Dist: pytest ; extra == 'dev' Requires-Dist: pytest-asyncio ; extra == 'dev' @@ -193,17 +193,18 @@ #### Bug Search -- **`bugs_quicksearch(query: str, include_fields: str = "...", limit: int = 50, offset: int = 0)`**: Executes a search for bugs using Bugzilla's powerful [quicksearch syntax](https://bugzilla.readthedocs.io/en/latest/using/finding.html#quicksearch). +- **`bugs_quicksearch(query: str, include_fields: str = "...", limit: int = 50, offset: int = 0, order: str = "relevance")`**: Executes a search for bugs using Bugzilla's powerful [quicksearch syntax](https://bugzilla.readthedocs.io/en/latest/using/finding.html#quicksearch). - **Parameters**: - `query`: A quicksearch query string (e.g., `"product:Firefox"`) - `include_fields`: Comma-separated list of fields to return (default: `"id,product,component,assigned_to,status,resolution,summary,last_change_time"`) - `limit`: Maximum number of results to return (default: `50`) - `offset`: Number of results to skip for pagination (default: `0`) + - `order`: Sort order (default: `"relevance"`). For field searches, use `"bug_id DESC"` to sort newest bugs first, or `"changeddate DESC"` to sort by recently modified. - **Returns**: A list of dictionaries, each containing essential bug fields - - **Example**: `bugs_quicksearch("product:Firefox status:NEW", limit=10)` + - **Example**: `bugs_quicksearch("product:Firefox status:NEW", limit=10, order="bug_id DESC")` - **`quicksearch_syntax_resource()`**: Returns documentation on Bugzilla's quicksearch syntax. - - **Returns**: A string containing HTML documentation. + - **Returns**: A string containing Markdown documentation. - **`summarize_bug_prompt(bug_id: int)`**: Returns a detailed summary prompt for all comments of a given bug ID. - **Returns**: A well-structured summary of the bug's comments including usernames (bold italic) and dates (bold). @@ -213,8 +214,19 @@ - **`bug_url(bug_id: int)`**: Constructs and returns the direct URL to a specific bug on the Bugzilla server. - **Returns**: A string representing the bug's URL (e.g., `"https://bugzilla.example.com/show_bug.cgi?id=12345"`) -- **`bugzilla_server_info()`**: Returns comprehensive Bugzilla server information. - - **Returns**: A dictionary containing `url`, `version`, `extensions`, `timezone`, `time`, and `parameters`. +- **`bugzilla_version()`**: Returns the version of the Bugzilla server. + - **Returns**: A string representing the Bugzilla version (e.g., `"5.0.4"`). + +- **`bugzilla_extensions()`**: Returns the extensions installed on the Bugzilla server. + - **Returns**: A dictionary containing installed Bugzilla extensions and their metadata. + +- **`bugzilla_time()`**: Returns the current time and timezone of the Bugzilla server. + - **Returns**: A dictionary containing server time (`db_time`, `web_time`, `web_time_utc`) and timezone details (`tz_name`, `tz_offset`, `tz_short_name`). + +- **`bugzilla_parameters(names: list[str] = None)`**: Returns the configuration parameters of the Bugzilla server. + - **Parameters**: + - `names`: Optional list of parameter names to filter results + - **Returns**: A dictionary containing Bugzilla configuration parameters. - **`mcp_server_info_resource()`**: Returns the configuration arguments being used by the current server instance (version, host, port, etc.). - **Returns**: A dictionary containing server configuration. @@ -603,6 +615,10 @@ # Use pagination page1 = bugs_quicksearch("status:NEW", limit=50, offset=0) page2 = bugs_quicksearch("status:NEW", limit=50, offset=50) + +# Sort by newest bugs first or recently updated +recent_bugs = bugs_quicksearch("product:Firefox status:NEW", order="bug_id DESC") +recently_updated = bugs_quicksearch("product:Firefox", order="changeddate DESC") ``` ### Example 6: Using with Red Hat Bugzilla diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mcp_bugzilla-0.21.0/README.md new/mcp_bugzilla-0.22.0/README.md --- old/mcp_bugzilla-0.21.0/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/mcp_bugzilla-0.22.0/README.md 1970-01-01 01:00:00.000000000 +0100 @@ -180,17 +180,18 @@ #### Bug Search -- **`bugs_quicksearch(query: str, include_fields: str = "...", limit: int = 50, offset: int = 0)`**: Executes a search for bugs using Bugzilla's powerful [quicksearch syntax](https://bugzilla.readthedocs.io/en/latest/using/finding.html#quicksearch). +- **`bugs_quicksearch(query: str, include_fields: str = "...", limit: int = 50, offset: int = 0, order: str = "relevance")`**: Executes a search for bugs using Bugzilla's powerful [quicksearch syntax](https://bugzilla.readthedocs.io/en/latest/using/finding.html#quicksearch). - **Parameters**: - `query`: A quicksearch query string (e.g., `"product:Firefox"`) - `include_fields`: Comma-separated list of fields to return (default: `"id,product,component,assigned_to,status,resolution,summary,last_change_time"`) - `limit`: Maximum number of results to return (default: `50`) - `offset`: Number of results to skip for pagination (default: `0`) + - `order`: Sort order (default: `"relevance"`). For field searches, use `"bug_id DESC"` to sort newest bugs first, or `"changeddate DESC"` to sort by recently modified. - **Returns**: A list of dictionaries, each containing essential bug fields - - **Example**: `bugs_quicksearch("product:Firefox status:NEW", limit=10)` + - **Example**: `bugs_quicksearch("product:Firefox status:NEW", limit=10, order="bug_id DESC")` - **`quicksearch_syntax_resource()`**: Returns documentation on Bugzilla's quicksearch syntax. - - **Returns**: A string containing HTML documentation. + - **Returns**: A string containing Markdown documentation. - **`summarize_bug_prompt(bug_id: int)`**: Returns a detailed summary prompt for all comments of a given bug ID. - **Returns**: A well-structured summary of the bug's comments including usernames (bold italic) and dates (bold). @@ -200,8 +201,19 @@ - **`bug_url(bug_id: int)`**: Constructs and returns the direct URL to a specific bug on the Bugzilla server. - **Returns**: A string representing the bug's URL (e.g., `"https://bugzilla.example.com/show_bug.cgi?id=12345"`) -- **`bugzilla_server_info()`**: Returns comprehensive Bugzilla server information. - - **Returns**: A dictionary containing `url`, `version`, `extensions`, `timezone`, `time`, and `parameters`. +- **`bugzilla_version()`**: Returns the version of the Bugzilla server. + - **Returns**: A string representing the Bugzilla version (e.g., `"5.0.4"`). + +- **`bugzilla_extensions()`**: Returns the extensions installed on the Bugzilla server. + - **Returns**: A dictionary containing installed Bugzilla extensions and their metadata. + +- **`bugzilla_time()`**: Returns the current time and timezone of the Bugzilla server. + - **Returns**: A dictionary containing server time (`db_time`, `web_time`, `web_time_utc`) and timezone details (`tz_name`, `tz_offset`, `tz_short_name`). + +- **`bugzilla_parameters(names: list[str] = None)`**: Returns the configuration parameters of the Bugzilla server. + - **Parameters**: + - `names`: Optional list of parameter names to filter results + - **Returns**: A dictionary containing Bugzilla configuration parameters. - **`mcp_server_info_resource()`**: Returns the configuration arguments being used by the current server instance (version, host, port, etc.). - **Returns**: A dictionary containing server configuration. @@ -590,6 +602,10 @@ # Use pagination page1 = bugs_quicksearch("status:NEW", limit=50, offset=0) page2 = bugs_quicksearch("status:NEW", limit=50, offset=50) + +# Sort by newest bugs first or recently updated +recent_bugs = bugs_quicksearch("product:Firefox status:NEW", order="bug_id DESC") +recently_updated = bugs_quicksearch("product:Firefox", order="changeddate DESC") ``` ### Example 6: Using with Red Hat Bugzilla diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mcp_bugzilla-0.21.0/pyproject.toml new/mcp_bugzilla-0.22.0/pyproject.toml --- old/mcp_bugzilla-0.21.0/pyproject.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/mcp_bugzilla-0.22.0/pyproject.toml 1970-01-01 01:00:00.000000000 +0100 @@ -1,11 +1,11 @@ [project] name = "mcp-bugzilla" -version = "0.21.0" +version = "0.22.0" description = "MCP server for Bugzilla" readme = "README.md" requires-python = ">=3.13" dependencies = [ - "fastmcp==4.0.3", + "fastmcp==4.1.4", "httpx-retries>=0.5.0", ] @@ -26,5 +26,5 @@ ] [build-system] -requires = ["uv_build>=0.11.16,<0.13.0"] +requires = ["uv_build>=0.11.16,<0.14.0"] build-backend = "uv_build" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mcp_bugzilla-0.21.0/pyproject.toml.orig new/mcp_bugzilla-0.22.0/pyproject.toml.orig --- old/mcp_bugzilla-0.21.0/pyproject.toml.orig 1970-01-01 01:00:00.000000000 +0100 +++ new/mcp_bugzilla-0.22.0/pyproject.toml.orig 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +1,12 @@ [project] name = "mcp-bugzilla" -version = "0.21.0" +version = "0.22.0" description = "MCP server for Bugzilla" readme = "README.md" requires-python = ">=3.13" dependencies = [ - "fastmcp==4.0.3", + "fastmcp==4.1.4", "httpx-retries>=0.5.0", ] @@ -24,5 +24,5 @@ py-modules = ["mcp_utils", "server"] [build-system] -requires = ["uv_build>=0.11.16,<0.13.0"] +requires = ["uv_build>=0.11.16,<0.14.0"] build-backend = "uv_build" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mcp_bugzilla-0.21.0/src/mcp_bugzilla/lib_bugzilla.py new/mcp_bugzilla-0.22.0/src/mcp_bugzilla/lib_bugzilla.py --- old/mcp_bugzilla-0.21.0/src/mcp_bugzilla/lib_bugzilla.py 1970-01-01 01:00:00.000000000 +0100 +++ new/mcp_bugzilla-0.22.0/src/mcp_bugzilla/lib_bugzilla.py 1970-01-01 01:00:00.000000000 +0100 @@ -3,7 +3,6 @@ Moved from mcp_utils.py for better modularity. """ -import asyncio from datetime import datetime from typing import Any @@ -123,50 +122,25 @@ r = await self._request("GET", "/version") return _json_or_raise(r)["version"] - async def bugzilla_info(self) -> dict[str, Any]: - """Fetch comprehensive bugzilla server information: - it returns url, version, extensions, timezone, time and parameters for the current user in a dictionary - """ - try: - # Fetch everything concurrently - version_r, extensions_r, time_r, parameters_r = await asyncio.gather( - self.client.get("/version"), - self.client.get("/extensions"), - self.client.get("/time"), - self.client.get("/parameters"), - ) - - # Raise for status on all - for r in [version_r, extensions_r, time_r, parameters_r]: - r.raise_for_status() - - # Combine results - version_data = _json_or_raise(version_r) - extensions_data = _json_or_raise(extensions_r) - time_data = _json_or_raise(time_r) - parameters_data = _json_or_raise(parameters_r) - - result = { - "url": self.base_url, - "version": version_data.get("version"), - "extensions": extensions_data.get("extensions", {}), - "timezone": time_data.get("tz_name"), - "time": time_data.get("web_time"), - "parameters": parameters_data.get("parameters", {}), - } - mcp_log.info( - f"[BZ-RES] Retrieved bugzilla server info from {self.base_url}" - ) - return result + async def server_extensions(self) -> dict[str, Any]: + """Fetch bugzilla extensions installed on the server""" + r = await self._request("GET", "/extensions") + envelope = _json_or_raise(r) + return envelope.get("extensions", envelope) - except httpx.HTTPStatusError as e: - mcp_log.error( - f"[BZ-RES] Failed: {e.response.status_code} {e.response.text}" - ) - raise - except httpx.RequestError as e: - mcp_log.error(f"[BZ-RES] Network Error: {e}") - raise + async def server_time(self) -> dict[str, Any]: + """Fetch bugzilla server time and timezone information""" + r = await self._request("GET", "/time") + return _json_or_raise(r) + + async def server_parameters(self, names: list[str] | None = None) -> dict[str, Any]: + """Fetch bugzilla server configuration parameters""" + r = await self._request("GET", "/parameters") + envelope = _json_or_raise(r) + params = envelope.get("parameters", envelope) + if names: + return {k: v for k, v in params.items() if k in names} + return params async def bug_info( self, @@ -294,7 +268,12 @@ return data async def quicksearch( - self, query: str, include_fields: str, limit: int, offset: int + self, + query: str, + include_fields: str, + limit: int, + offset: int, + order: str = "relevance", ) -> dict[str, Any]: """Perform a quicksearch""" # Quicksearch isn't a direct REST endpoint usually, but /bug with quicksearch param works @@ -304,7 +283,7 @@ "include_fields": include_fields, "limit": limit, "offset": offset, - "order": "relevance", + "order": order, } mcp_log.info(f"[BZ-REQ] GET {self.api_url}/bug params={params}") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mcp_bugzilla-0.21.0/src/mcp_bugzilla/quicksearch_syntax.py new/mcp_bugzilla-0.22.0/src/mcp_bugzilla/quicksearch_syntax.py --- old/mcp_bugzilla-0.21.0/src/mcp_bugzilla/quicksearch_syntax.py 1970-01-01 01:00:00.000000000 +0100 +++ new/mcp_bugzilla-0.22.0/src/mcp_bugzilla/quicksearch_syntax.py 1970-01-01 01:00:00.000000000 +0100 @@ -0,0 +1,61 @@ +"""Bugzilla Quicksearch syntax reference documentation.""" + +QUICKSEARCH_SYNTAX_DOC = """# Bugzilla Quicksearch Syntax Reference + +Bugzilla Quicksearch provides a concise, search-box syntax for querying bugs. +By default, queries match only **open bugs** (e.g., UNCONFIRMED, NEW, ASSIGNED, REOPENED) and searches are case-insensitive. + +## Basic Text Search +- **Words**: Entering words searches across `summary`, `product`, `component`, `keywords`, `whiteboard`, and `comments`. + - Example: `crash bluetooth` (searches for open bugs matching both words) +- **Substring matching**: Plain text words match partial words (e.g., `cat` matches `catch` or `certificate`). +- **Quotes**: Use double quotes for exact multi-word phrases. + - Example: `"kernel panic"` +- **Bug Number / Alias**: Entering a bug number (or comma-separated numbers) searches directly by ID. + - Example: `123456` or `123456,123457` + +## Status Shortcuts +- **ALL**: Include both open and closed bugs (default is open bugs only). + - Example: `ALL product:openSUSE crash` +- **OPEN**: Explicitly search open bugs only. +- **CLOSED**: Search closed/resolved bugs only. +- Specific statuses can also be specified with `status:<STATUS>` (e.g., `status:NEW,ASSIGNED` or `status:RESOLVED`). + +## Field Searches (`field:value`) +Search specific fields using `field:value`. Multiple values separated by commas act as a logical **OR**. + +| Field Prefix | Description | Example | +| :--- | :--- | :--- | +| `product:` | Filter by product name | `product:openSUSE` or `product:"SUSE Linux Enterprise Server"` | +| `component:` | Filter by component name | `component:Kernel` or `component:"Security Tools"` | +| `status:` | Bug status (`NEW`, `ASSIGNED`, `RESOLVED`, etc.) | `status:RESOLVED,CLOSED` | +| `resolution:` | Resolution reason (`FIXED`, `DUPLICATE`, `WONTFIX`, etc.) | `resolution:FIXED` | +| `assigned_to:` / `assignee:` | Assignee login or email | `assigned_to:[email protected]` | +| `reporter:` | Reporter login or email | `reporter:[email protected]` | +| `cc:` | User in the CC list | `cc:[email protected]` | +| `priority:` | Priority level | `priority:P1,P2` | +| `severity:` | Severity level | `severity:critical,blocker` | +| `keywords:` | Keywords attached to bug | `keywords:regression` | +| `whiteboard:` | Status whiteboard text | `whiteboard:"needs-triage"` | +| `flag:` | Flags set on the bug | `flag:needinfo?` | + +## Operators & Modifiers +- **Multiple terms (AND)**: Separate terms with spaces. + - Example: `product:openSUSE component:Kernel status:NEW` +- **Comma (OR)**: Separate values within a field with commas. + - Example: `severity:blocker,critical` +- **Negation (`-`)**: Prefix a term or field filter with `-` to negate it. + - Example: `-status:RESOLVED` or `-product:Test` +- **OR Operator (`|`)**: Matches either term in summary and status whiteboard. + - Example: `gnome|kde` + +## Common Query Examples +- Search recent or open regressions in a product: + `product:Firefox keywords:regression` +- Search all bugs reported by a user including closed ones: + `ALL reporter:[email protected]` +- Search critical or blocker bugs in a specific component: + `component:Networking severity:blocker,critical` +- Search open bugs excluding resolved: + `product:openSUSE -status:RESOLVED` +""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mcp_bugzilla-0.21.0/src/mcp_bugzilla/server.py new/mcp_bugzilla-0.22.0/src/mcp_bugzilla/server.py --- old/mcp_bugzilla-0.21.0/src/mcp_bugzilla/server.py 1970-01-01 01:00:00.000000000 +0100 +++ new/mcp_bugzilla-0.22.0/src/mcp_bugzilla/server.py 1970-01-01 01:00:00.000000000 +0100 @@ -17,7 +17,7 @@ from fastmcp import FastMCP from fastmcp.dependencies import CurrentHeaders, Depends -from fastmcp.exceptions import PromptError, ResourceError, ToolError +from fastmcp.exceptions import PromptError, ToolError from .lib_bugzilla import Bugzilla from .mcp_utils import ( @@ -30,6 +30,7 @@ mcp_log, safe_filename, ) +from .quicksearch_syntax import QUICKSEARCH_SYNTAX_DOC # The FastMCP instance mcp = FastMCP("Bugzilla") @@ -382,17 +383,26 @@ | None = "id,product,component,assigned_to,status,resolution,summary,last_change_time", limit: int | None = 50, offset: int | None = 0, + order: str | None = "relevance", bz: Bugzilla = _get_bz, ) -> dict[str, Any]: """Search bugs using Bugzilla's Quicksearch syntax. - To reduce the token limit & response time, this only returns a subset of fields for each bug. + Results are capped to `limit` bugs (default: 50). Use `offset` for pagination. + To reduce token limit and response time, this only returns a subset of fields for each bug. The user can query full details of each bug using the `bug_info` tool. Returns the top-level bug data envelope containing the matched bugs. + + Sorting (`order`): + - "relevance" (default): Relevance ranking for text searches. Note: for pure field searches + (e.g., `product:openSUSE`), Bugzilla ignores "relevance" and sorts by bug ID ascending (oldest first). + - "bug_id DESC": Sort by newest bugs first. Recommended when searching for recent bugs! + - "changeddate DESC": Sort by most recently modified bugs first. + - "opendate DESC": Sort by most recently created bugs first. """ mcp_log.info( - f"[LLM-REQ] bugs_quicksearch(query='{query}', include_fields='{include_fields}', limit={limit}, offset={offset})" + f"[LLM-REQ] bugs_quicksearch(query='{query}', include_fields='{include_fields}', limit={limit}, offset={offset}, order='{order}')" ) try: @@ -403,6 +413,7 @@ or "id,product,component,assigned_to,status,resolution,summary,last_change_time", limit or 50, offset or 0, + order or "relevance", ) mcp_log.info("[LLM-RES] Returning quicksearch envelope") @@ -414,37 +425,55 @@ @mcp.tool(annotations={"readOnlyHint": True, "openWorldHint": True}, tags={"read"}) async def quicksearch_syntax_resource(bz: Bugzilla = _get_bz) -> str: - """Access the documentation of the Bugzilla Quicksearch syntax. Use this to learn how to construct advanced search queries. Response is in HTML.""" + """Access the documentation of the Bugzilla Quicksearch syntax. Use this to learn how to construct advanced search queries. Response is in Markdown.""" mcp_log.info("[LLM-REQ] quicksearch_syntax_resource()") + mcp_log.info( + f"[LLM-RES] Returned {len(QUICKSEARCH_SYNTAX_DOC)} chars of documentation" + ) + return QUICKSEARCH_SYNTAX_DOC + [email protected](annotations={"readOnlyHint": True, "openWorldHint": True}, tags={"read"}) +async def bugzilla_version(bz: Bugzilla = _get_bz) -> str: + """Returns the version of the Bugzilla server.""" + mcp_log.info("[LLM-REQ] bugzilla_version()") try: - # We can use the client to fetch this page too, though it's not a rest API - # Using the underlying client for convenience - url = f"{bz.base_url}/page.cgi" - r = await bz.client.get( - url, params={"id": "quicksearch.html"} - ) # Use absolute URL since base_url of client is /rest - - if r.status_code != 200: - raise ResourceError( - f"Failed to fetch bugzilla quicksearch_syntax with status code {r.status_code}" - ) + return await bz.server_version() + except Exception as e: # noqa: BLE001 + raise ToolError(f"Failed to fetch bugzilla version\nReason: {e}") + - mcp_log.info(f"[LLM-RES] Fetched {len(r.text)} chars of documentation") - return r.text [email protected](annotations={"readOnlyHint": True, "openWorldHint": True}, tags={"read"}) +async def bugzilla_extensions(bz: Bugzilla = _get_bz) -> dict[str, Any]: + """Returns the extensions installed on the Bugzilla server.""" + mcp_log.info("[LLM-REQ] bugzilla_extensions()") + try: + return await bz.server_extensions() + except Exception as e: # noqa: BLE001 + raise ToolError(f"Failed to fetch bugzilla extensions\nReason: {e}") + + [email protected](annotations={"readOnlyHint": True, "openWorldHint": True}, tags={"read"}) +async def bugzilla_time(bz: Bugzilla = _get_bz) -> dict[str, Any]: + """Returns the current time and timezone of the Bugzilla server.""" + mcp_log.info("[LLM-REQ] bugzilla_time()") + try: + return await bz.server_time() except Exception as e: # noqa: BLE001 - raise ResourceError(f"Failed to fetch quicksearch documentation: {e}") + raise ToolError(f"Failed to fetch bugzilla time\nReason: {e}") @mcp.tool(annotations={"readOnlyHint": True, "openWorldHint": True}, tags={"read"}) -async def bugzilla_server_info(bz: Bugzilla = _get_bz) -> dict[str, Any]: - """Returns comprehensive Bugzilla server information (url, version, extensions, timezone, time, parameters).""" - mcp_log.info("[LLM-REQ] bugzilla_server_info()") +async def bugzilla_parameters( + names: list[str] | None = None, bz: Bugzilla = _get_bz +) -> dict[str, Any]: + """Returns the configuration parameters of the Bugzilla server. Optionally filter by parameter names.""" + mcp_log.info(f"[LLM-REQ] bugzilla_parameters(names={names})") try: - return await bz.bugzilla_info() + return await bz.server_parameters(names=names) except Exception as e: # noqa: BLE001 - raise ToolError(f"Failed to fetch bugzilla server info\nReason: {e}") + raise ToolError(f"Failed to fetch bugzilla parameters\nReason: {e}") @mcp.tool(annotations={"readOnlyHint": True, "openWorldHint": False}, tags={"read"})
