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-08-18 16:37:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mcp-bugzilla (Old)
 and      /work/SRC/openSUSE:Factory/.mcp-bugzilla.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mcp-bugzilla"

Tue Aug 18 16:37:37 2026 rev:3 rq:1371682 version:0.20.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/mcp-bugzilla/mcp-bugzilla.changes        
2026-08-12 16:12:02.933309713 +0200
+++ /work/SRC/openSUSE:Factory/.mcp-bugzilla.new.1258/mcp-bugzilla.changes      
2026-08-18 16:38:23.001010767 +0200
@@ -1,0 +2,15 @@
+Tue Aug 18 07:40:07 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to version 0.20.0:
+  * Add get_component_defaults tool to look up a component's
+    default assignee and QA contact, either by product/component
+    or resolved from a bug id
+  * update_bug_fields gained reset_qa_contact and
+    reset_assigned_to to reset those fields to the component's
+    defaults
+  * Add --tool-search flag (MCP_TOOL_SEARCH env) to collapse all
+    tools into search_tools + call_tool meta-tools using BM25
+    relevance ranking
+  * Bump fastmcp requirement accordingly
+
+-------------------------------------------------------------------

Old:
----
  mcp_bugzilla-0.19.0.tar.gz

New:
----
  mcp_bugzilla-0.20.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mcp-bugzilla.spec ++++++
--- /var/tmp/diff_new_pack.54Kz57/_old  2026-08-18 16:38:23.944044512 +0200
+++ /var/tmp/diff_new_pack.54Kz57/_new  2026-08-18 16:38:23.945044548 +0200
@@ -21,20 +21,20 @@
 # not a multi-flavour module.
 %define pythons %{primary_python}
 Name:           mcp-bugzilla
-Version:        0.19.0
+Version:        0.20.0
 Release:        0
 Summary:        Model Context Protocol server for Bugzilla
 License:        Apache-2.0
 URL:            https://github.com/openSUSE/mcp-bugzilla
 Source:         
https://files.pythonhosted.org/packages/source/m/mcp_bugzilla/mcp_bugzilla-%{version}.tar.gz
-BuildRequires:  %{primary_python}-fastmcp >= 3.4.6
+BuildRequires:  %{primary_python}-fastmcp >= 3.4.7
 BuildRequires:  %{primary_python}-httpx-retries >= 0.5.0
 BuildRequires:  %{primary_python}-pip
 BuildRequires:  %{primary_python}-uv-build
 BuildRequires:  %{primary_python}-wheel
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-Requires:       %{primary_python}-fastmcp >= 3.4.6
+Requires:       %{primary_python}-fastmcp >= 3.4.7
 Requires:       %{primary_python}-httpx-retries >= 0.5.0
 Provides:       bugzilla-mcp = %{version}-%{release}
 Obsoletes:      bugzilla-mcp < %{version}

++++++ mcp_bugzilla-0.19.0.tar.gz -> mcp_bugzilla-0.20.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp_bugzilla-0.19.0/PKG-INFO 
new/mcp_bugzilla-0.20.0/PKG-INFO
--- old/mcp_bugzilla-0.19.0/PKG-INFO    1970-01-01 01:00:00.000000000 +0100
+++ new/mcp_bugzilla-0.20.0/PKG-INFO    1970-01-01 01:00:00.000000000 +0100
@@ -1,8 +1,8 @@
 Metadata-Version: 2.3
 Name: mcp-bugzilla
-Version: 0.19.0
+Version: 0.20.0
 Summary: MCP server for Bugzilla
-Requires-Dist: fastmcp==3.4.6
+Requires-Dist: fastmcp==3.4.7
 Requires-Dist: httpx-retries>=0.5.0
 Requires-Dist: pytest ; extra == 'dev'
 Requires-Dist: pytest-asyncio ; extra == 'dev'
@@ -70,6 +70,14 @@
   - **Note on Bugzilla API parity**: `new_since` and `include_fields` mirror 
Bugzilla's own API parameters of the same names (`include_fields` is applied 
client-side here). `exclude_creators` and `limit` have no server-side Bugzilla 
equivalent — this server applies them client-side, as post-processing over the 
standard `Bug.comments` response; the underlying Bugzilla request is unmodified.
   - **Example**: `bug_comments(12345, 
exclude_creators="upstream-release-monitoring", limit=5)` returns the 5 most 
recent comments that aren't from the release-monitoring bot
 
+- **`get_component_defaults(component: str = None, product: str = None, 
bug_id: int = None)`**: Looks up a component's default assignee and QA contact, 
read from the parent product since Bugzilla has no component endpoint.
+  - **Parameters**:
+    - `component`: Component name (resolved from `bug_id` if omitted)
+    - `product`: Product the component belongs to (resolved from `bug_id` if 
omitted)
+    - `bug_id`: Resolve product/component from this bug instead of passing them
+  - **Returns**: A dictionary with `product`, `component`, `default_assignee`, 
`default_qa_contact`, `is_active`
+  - **Example**: `get_component_defaults(bug_id=12345)` returns the defaults 
for that bug's component. To reset a bug *to* these defaults, use 
`update_bug_fields(..., reset_qa_contact=True)`.
+
 
 - **`add_comment(bug_id: int, comment: str, is_private: bool = False)`**: Adds 
a new comment to a specified bug.
   - **Parameters**:
@@ -126,16 +134,20 @@
   + **Returns**: A dictionary containing the updated bug fields
   + **Example**: `assign_bug(12345, "[email protected]", comment="You're 
the expert on this component")`
 
-* **`update_bug_fields(bug_id: int, priority: str = None, severity: str = 
None, resolution: str = None, comment: str = "")`**: Updates various bug fields.
+* **`update_bug_fields(bug_id: int, priority: str = None, severity: str = 
None, resolution: str = None, custom_fields: dict = None, reset_qa_contact: 
bool = False, reset_assigned_to: bool = False, comment: str = "")`**: Updates 
various bug fields.
 
   + **Parameters**:
     - `bug_id`: The bug ID to update
     - `priority`: Priority level (e.g., `urgent`, `high`, `medium`, `low`, 
`unspecified`)
     - `severity`: Severity level (e.g., `urgent`, `high`, `medium`, `low`, 
`unspecified`)
     - `resolution`: Resolution (only for closed bugs)
+    - `custom_fields`: Dict of custom fields, e.g. `{"cf_fixed_in": "1.2.3"}`
+    - `reset_qa_contact`: If `True`, reset the QA contact to the component's 
default
+    - `reset_assigned_to`: If `True`, reset the assignee to the component's 
default
     - `comment`: Optional comment explaining the changes
   + **Returns**: A dictionary containing the updated bug fields
   + **Example**: `update_bug_fields(12345, priority="high", severity="urgent", 
comment="Escalating due to customer impact")`
+  + **Example**: `update_bug_fields(12345, reset_qa_contact=True)` resets the 
QA contact to the component default
 
 * **`add_cc_to_bug(bug_id: int, cc_email: str)`**: Adds an email address to 
the CC list of a bug.
 
@@ -330,6 +342,7 @@
 | `--bugzilla-api-key <KEY>` | `BUGZILLA_API_KEY` | *none* | Static Bugzilla 
API key. Optional: if omitted and not provided per-request via 
`--mcp-auth-header` (http), access is **anonymous**. For `--transport stdio` 
this is the only source of the key |
 | `--bugzilla-auth-mode {query,bearer}` | `BUGZILLA_AUTH_MODE` | `query` | How 
to authenticate with Bugzilla: `query` sends `?api_key=<KEY>` (default, works 
with most instances); `bearer` sends `Authorization: Bearer <KEY>` header 
(required for Red Hat Bugzilla and similar) |
 | `--read-only` | `MCP_READ_ONLY` | `False` | Disables all tools which can 
modify a bug. Works well in conjunction with `MCP_BUGZILLA_DISABLED_METHODS` |
+| `--tool-search` | `MCP_TOOL_SEARCH` | `False` | Collapse all tools into 
`search_tools` + `call_tool` meta-tools using BM25 relevance ranking. The LLM 
searches for tools by natural language query and calls them directly. Reduces 
context overhead when many tools are available |
 | `--download-dir <DIR>` | `BUGZILLA_DOWNLOAD_DIR` | `<tmpdir>/mcp-bugzilla` | 
Directory where `download_attachment` writes binary/oversized attachments. The 
default directory is created on first use and restricted to the owner 
(`0o700`); an explicit `output_dir` keeps its own permissions |
 
 **Note**: `--host` and `--port` are rejected with an error when used together 
with `--transport stdio`.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp_bugzilla-0.19.0/README.md 
new/mcp_bugzilla-0.20.0/README.md
--- old/mcp_bugzilla-0.19.0/README.md   1970-01-01 01:00:00.000000000 +0100
+++ new/mcp_bugzilla-0.20.0/README.md   1970-01-01 01:00:00.000000000 +0100
@@ -57,6 +57,14 @@
   - **Note on Bugzilla API parity**: `new_since` and `include_fields` mirror 
Bugzilla's own API parameters of the same names (`include_fields` is applied 
client-side here). `exclude_creators` and `limit` have no server-side Bugzilla 
equivalent — this server applies them client-side, as post-processing over the 
standard `Bug.comments` response; the underlying Bugzilla request is unmodified.
   - **Example**: `bug_comments(12345, 
exclude_creators="upstream-release-monitoring", limit=5)` returns the 5 most 
recent comments that aren't from the release-monitoring bot
 
+- **`get_component_defaults(component: str = None, product: str = None, 
bug_id: int = None)`**: Looks up a component's default assignee and QA contact, 
read from the parent product since Bugzilla has no component endpoint.
+  - **Parameters**:
+    - `component`: Component name (resolved from `bug_id` if omitted)
+    - `product`: Product the component belongs to (resolved from `bug_id` if 
omitted)
+    - `bug_id`: Resolve product/component from this bug instead of passing them
+  - **Returns**: A dictionary with `product`, `component`, `default_assignee`, 
`default_qa_contact`, `is_active`
+  - **Example**: `get_component_defaults(bug_id=12345)` returns the defaults 
for that bug's component. To reset a bug *to* these defaults, use 
`update_bug_fields(..., reset_qa_contact=True)`.
+
 
 - **`add_comment(bug_id: int, comment: str, is_private: bool = False)`**: Adds 
a new comment to a specified bug.
   - **Parameters**:
@@ -113,16 +121,20 @@
   + **Returns**: A dictionary containing the updated bug fields
   + **Example**: `assign_bug(12345, "[email protected]", comment="You're 
the expert on this component")`
 
-* **`update_bug_fields(bug_id: int, priority: str = None, severity: str = 
None, resolution: str = None, comment: str = "")`**: Updates various bug fields.
+* **`update_bug_fields(bug_id: int, priority: str = None, severity: str = 
None, resolution: str = None, custom_fields: dict = None, reset_qa_contact: 
bool = False, reset_assigned_to: bool = False, comment: str = "")`**: Updates 
various bug fields.
 
   + **Parameters**:
     - `bug_id`: The bug ID to update
     - `priority`: Priority level (e.g., `urgent`, `high`, `medium`, `low`, 
`unspecified`)
     - `severity`: Severity level (e.g., `urgent`, `high`, `medium`, `low`, 
`unspecified`)
     - `resolution`: Resolution (only for closed bugs)
+    - `custom_fields`: Dict of custom fields, e.g. `{"cf_fixed_in": "1.2.3"}`
+    - `reset_qa_contact`: If `True`, reset the QA contact to the component's 
default
+    - `reset_assigned_to`: If `True`, reset the assignee to the component's 
default
     - `comment`: Optional comment explaining the changes
   + **Returns**: A dictionary containing the updated bug fields
   + **Example**: `update_bug_fields(12345, priority="high", severity="urgent", 
comment="Escalating due to customer impact")`
+  + **Example**: `update_bug_fields(12345, reset_qa_contact=True)` resets the 
QA contact to the component default
 
 * **`add_cc_to_bug(bug_id: int, cc_email: str)`**: Adds an email address to 
the CC list of a bug.
 
@@ -317,6 +329,7 @@
 | `--bugzilla-api-key <KEY>` | `BUGZILLA_API_KEY` | *none* | Static Bugzilla 
API key. Optional: if omitted and not provided per-request via 
`--mcp-auth-header` (http), access is **anonymous**. For `--transport stdio` 
this is the only source of the key |
 | `--bugzilla-auth-mode {query,bearer}` | `BUGZILLA_AUTH_MODE` | `query` | How 
to authenticate with Bugzilla: `query` sends `?api_key=<KEY>` (default, works 
with most instances); `bearer` sends `Authorization: Bearer <KEY>` header 
(required for Red Hat Bugzilla and similar) |
 | `--read-only` | `MCP_READ_ONLY` | `False` | Disables all tools which can 
modify a bug. Works well in conjunction with `MCP_BUGZILLA_DISABLED_METHODS` |
+| `--tool-search` | `MCP_TOOL_SEARCH` | `False` | Collapse all tools into 
`search_tools` + `call_tool` meta-tools using BM25 relevance ranking. The LLM 
searches for tools by natural language query and calls them directly. Reduces 
context overhead when many tools are available |
 | `--download-dir <DIR>` | `BUGZILLA_DOWNLOAD_DIR` | `<tmpdir>/mcp-bugzilla` | 
Directory where `download_attachment` writes binary/oversized attachments. The 
default directory is created on first use and restricted to the owner 
(`0o700`); an explicit `output_dir` keeps its own permissions |
 
 **Note**: `--host` and `--port` are rejected with an error when used together 
with `--transport stdio`.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp_bugzilla-0.19.0/pyproject.toml 
new/mcp_bugzilla-0.20.0/pyproject.toml
--- old/mcp_bugzilla-0.19.0/pyproject.toml      1970-01-01 01:00:00.000000000 
+0100
+++ new/mcp_bugzilla-0.20.0/pyproject.toml      1970-01-01 01:00:00.000000000 
+0100
@@ -1,11 +1,11 @@
 [project]
 name = "mcp-bugzilla"
-version = "0.19.0"
+version = "0.20.0"
 description = "MCP server for Bugzilla"
 readme = "README.md"
 requires-python = ">=3.13"
 dependencies = [
-    "fastmcp==3.4.6",
+    "fastmcp==3.4.7",
     "httpx-retries>=0.5.0",
 ]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp_bugzilla-0.19.0/pyproject.toml.orig 
new/mcp_bugzilla-0.20.0/pyproject.toml.orig
--- old/mcp_bugzilla-0.19.0/pyproject.toml.orig 1970-01-01 01:00:00.000000000 
+0100
+++ new/mcp_bugzilla-0.20.0/pyproject.toml.orig 1970-01-01 01:00:00.000000000 
+0100
@@ -1,12 +1,12 @@
 [project]
 name = "mcp-bugzilla"
-version = "0.19.0"
+version = "0.20.0"
 description = "MCP server for Bugzilla"
 readme = "README.md"
 requires-python = ">=3.13"
 
 dependencies = [
-    "fastmcp==3.4.6",
+    "fastmcp==3.4.7",
     "httpx-retries>=0.5.0",
 ]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp_bugzilla-0.19.0/src/mcp_bugzilla/__init__.py 
new/mcp_bugzilla-0.20.0/src/mcp_bugzilla/__init__.py
--- old/mcp_bugzilla-0.19.0/src/mcp_bugzilla/__init__.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/mcp_bugzilla-0.20.0/src/mcp_bugzilla/__init__.py        1970-01-01 
01:00:00.000000000 +0100
@@ -82,6 +82,13 @@
     )
 
     parser.add_argument(
+        "--tool-search",
+        action="store_true",
+        default=os.getenv("MCP_TOOL_SEARCH", "false").lower() == "true",
+        help="Collapse all tools into search_tools + call_tool meta-tools 
using BM25 relevance ranking. Environment variable MCP_TOOL_SEARCH=true can 
also be used.",
+    )
+
+    parser.add_argument(
         "--transport",
         type=str,
         choices=["http", "stdio"],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp_bugzilla-0.19.0/src/mcp_bugzilla/lib_bugzilla.py 
new/mcp_bugzilla-0.20.0/src/mcp_bugzilla/lib_bugzilla.py
--- old/mcp_bugzilla-0.19.0/src/mcp_bugzilla/lib_bugzilla.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/mcp_bugzilla-0.20.0/src/mcp_bugzilla/lib_bugzilla.py    1970-01-01 
01:00:00.000000000 +0100
@@ -197,6 +197,46 @@
         mcp_log.debug(f"[BZ-RES] {envelope}")
         return envelope
 
+    async def get_product(
+        self, name: str, include_fields: str | None = None
+    ) -> dict[str, Any]:
+        """Fetch a product by name, with its components and their defaults.
+
+        Bugzilla has no component endpoint: component defaults (assignee, QA
+        contact) are only exposed nested under the parent product. The full
+        payload is large, so pass ``include_fields`` (dotted paths work, e.g.
+        ``components.default_assigned_to``) to keep only what is needed.
+        """
+        params = {"names": name}
+        if include_fields:
+            params["include_fields"] = include_fields
+        mcp_log.info(f"[BZ-REQ] GET {self.api_url}/product params={params}")
+
+        try:
+            r = await self.client.get("/product", params=params)
+            r.raise_for_status()
+        except httpx.HTTPStatusError as e:
+            bz_error = _bugzilla_error_body(e.response)
+            if bz_error is not None:
+                mcp_log.error(
+                    f"[BZ-RES] Failed: {e.response.status_code} "
+                    f"code={bz_error.get('code')} {bz_error['message']}"
+                )
+                raise BugzillaAPIError(e.response.status_code, bz_error) from 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
+
+        envelope = _json_or_raise(r)
+        products = envelope.get("products", [])
+        mcp_log.info(f"[BZ-RES] Retrieved {len(products)} products")
+        mcp_log.debug(f"[BZ-RES] {envelope}")
+        return envelope
+
     async def bug_flags(self, bug_id: int) -> list[dict[str, Any]]:
         """Return the flags currently set on a bug, with their instance ids.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mcp_bugzilla-0.19.0/src/mcp_bugzilla/server.py 
new/mcp_bugzilla-0.20.0/src/mcp_bugzilla/server.py
--- old/mcp_bugzilla-0.19.0/src/mcp_bugzilla/server.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/mcp_bugzilla-0.20.0/src/mcp_bugzilla/server.py  1970-01-01 
01:00:00.000000000 +0100
@@ -18,9 +18,9 @@
 from fastmcp import FastMCP
 from fastmcp.dependencies import CurrentHeaders, Depends
 from fastmcp.exceptions import PromptError, ResourceError, ToolError
+from .mcp_utils import is_textual, mcp_log, safe_filename
 
 from .lib_bugzilla import Bugzilla
-from .mcp_utils import is_textual, mcp_log, safe_filename
 
 # The FastMCP instance
 mcp = FastMCP("Bugzilla")
@@ -144,6 +144,107 @@
         raise ToolError(f"Failed to fetch bug info\nReason: {e}")
 
 
+class ComponentDefaults(TypedDict):
+    """A component's default assignee and QA contact.
+
+    ``default_assignee`` / ``default_qa_contact`` are ``None`` both when the
+    component has none set and when the API key cannot see them. Bugzilla
+    reports an unset contact as an empty string; that is normalised to ``None``
+    so the two cases read alike.
+    """
+
+    product: str
+    component: str
+    default_assignee: str | None
+    default_qa_contact: str | None
+    is_active: bool | None
+
+
[email protected](annotations={"readOnlyHint": True, "openWorldHint": True}, 
tags={"read"})
+async def get_component_defaults(
+    component: str | None = None,
+    product: str | None = None,
+    bug_id: int | None = None,
+    bz: Bugzilla = _get_bz,
+) -> ComponentDefaults:
+    """Look up a component's default assignee and QA contact.
+
+    Bugzilla has no component endpoint, so the defaults come from the parent
+    product. Pass ``product`` and ``component``, or a ``bug_id`` to resolve 
them
+    from that bug; explicit values win. To reset a bug *to* these defaults, use
+    ``update_bug_fields`` with ``reset_qa_contact`` / ``reset_assigned_to``.
+
+    Args:
+        component: Component name (resolved from bug_id if omitted)
+        product: Product the component belongs to (resolved from bug_id if 
omitted)
+        bug_id: Resolve product/component from this bug instead of passing them
+    """
+    mcp_log.info(
+        f"[LLM-REQ] get_component_defaults(component={component!r}, "
+        f"product={product!r}, bug_id={bug_id})"
+    )
+
+    try:
+        resolved_from_bug = False
+        if bug_id is not None and (not product or not component):
+            envelope = await bz.bug_info({bug_id}, 
include_fields="product,component")
+            bugs = envelope.get("bugs", [])
+            if not bugs:
+                raise ToolError(f"Bug {bug_id} not found")
+            product = product or bugs[0].get("product")
+            component = component or bugs[0].get("component")
+            resolved_from_bug = True
+
+        if not product:
+            raise ToolError(
+                f"Bug {bug_id} returned no product field"
+                if resolved_from_bug
+                else "Either `product` or `bug_id` must be supplied"
+            )
+        if not component:
+            raise ToolError(
+                f"Bug {bug_id} returned no component field; pass `component` 
explicitly"
+                if resolved_from_bug
+                else "Either `component` or `bug_id` must be supplied"
+            )
+
+        # The full product payload is ~10x larger and carries flag_types,
+        # milestones and versions this tool never reads.
+        envelope = await bz.get_product(
+            product,
+            include_fields=(
+                "name,components.name,components.default_assigned_to,"
+                "components.default_qa_contact,components.is_active"
+            ),
+        )
+        products = envelope.get("products", [])
+        if not products:
+            raise ToolError(f"Product {product!r} not found")
+
+        components = products[0].get("components", [])
+        for comp in components:
+            if comp.get("name") == component:
+                return ComponentDefaults(
+                    product=product,
+                    component=component,
+                    # Bugzilla's key is default_assigned_to, not 
default_assignee,
+                    # and an unset contact comes back as "" rather than null.
+                    default_assignee=comp.get("default_assigned_to") or None,
+                    default_qa_contact=comp.get("default_qa_contact") or None,
+                    is_active=comp.get("is_active"),
+                )
+
+        available = ", ".join(c.get("name", "?") for c in components)
+        raise ToolError(
+            f"Component {component!r} not found in product {product!r}. "
+            f"Available components: {available}"
+        )
+    except ToolError:
+        raise
+    except Exception as e:  # noqa: BLE001
+        raise ToolError(f"Failed to fetch component defaults\n{e}")
+
+
 @mcp.tool(annotations={"readOnlyHint": True, "openWorldHint": True}, 
tags={"read"})
 async def bug_history(
     id: int,
@@ -520,6 +621,8 @@
     severity: str | None = None,
     resolution: str | None = None,
     custom_fields: dict[str, Any] | None = None,
+    reset_qa_contact: bool = False,
+    reset_assigned_to: bool = False,
     comment: str = "",
     bz: Bugzilla = _get_bz,
 ) -> dict[str, Any]:
@@ -531,10 +634,13 @@
         severity: Severity (e.g., urgent, high, medium, low, unspecified)
         resolution: Resolution (e.g., FIXED, WONTFIX, NOTABUG, DUPLICATE) - 
only for closed bugs
         custom_fields: Dict of custom fields e.g. {"cf_fixed_in": "1.2.3"}
+        reset_qa_contact: Reset the QA contact to the component's default
+        reset_assigned_to: Reset the assignee to the component's default
         comment: Optional comment explaining the changes
     """
     mcp_log.info(
-        f"[LLM-REQ] update_bug_fields(bug_id={bug_id}, priority={priority}, 
severity={severity}, resolution={resolution})"
+        f"[LLM-REQ] update_bug_fields(bug_id={bug_id}, priority={priority}, 
severity={severity}, "
+        f"resolution={resolution}, reset_qa_contact={reset_qa_contact}, 
reset_assigned_to={reset_assigned_to})"
     )
 
     updates = {}
@@ -546,6 +652,10 @@
         updates["resolution"] = resolution
     if custom_fields:
         updates.update(custom_fields)
+    if reset_qa_contact:
+        updates["reset_qa_contact"] = True
+    if reset_assigned_to:
+        updates["reset_assigned_to"] = True
 
     if not updates:
         raise ToolError("At least one field must be specified")
@@ -1153,6 +1263,15 @@
     # Ensure base_url doesn't have trailing slash for consistency
     base_url = base_url.removesuffix("/")
 
+    # Optionally enable BM25 search transform
+    if getattr(cli_args, "tool_search", False):
+        from fastmcp.server.transforms.search import BM25SearchTransform
+
+        mcp.add_transform(BM25SearchTransform())
+        mcp_log.info(
+            "BM25 search transform enabled — tools collapsed into search_tools 
and call_tool"
+        )
+
     # Seletively disable components before running the server
     disable_components_selectively()
     disable_write_components()

Reply via email to