-
Notifications
You must be signed in to change notification settings - Fork 321
Add Bugzilla quicksearch to MCP server #5580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
loganrosen
wants to merge
1
commit into
mozilla:master
Choose a base branch
from
loganrosen:bugzilla-quicksearch
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+264
−4
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,3 +49,6 @@ node_modules/ | |
| *.log | ||
| # Desktop Service Store | ||
| *.DS_Store | ||
|
|
||
| # VSCode settings | ||
| .vscode/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| """Tests for Bugzilla MCP tools.""" | ||
|
|
||
| from unittest.mock import MagicMock | ||
|
|
||
| import pytest | ||
| from fastmcp.client import Client | ||
| from fastmcp.client.transports import FastMCPTransport | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| async def mcp_client(): | ||
| """Create an MCP client for testing.""" | ||
| from bugbug_mcp.server import mcp | ||
|
|
||
| async with Client(mcp) as client: | ||
| yield client | ||
|
|
||
|
|
||
| def setup_bugzilla_mock(mocker, bugs): | ||
| """Helper to setup Bugzilla mock with given bugs.""" | ||
| mock_bugzilla_class = mocker.patch("libmozdata.bugzilla.Bugzilla") | ||
| mock_instance = MagicMock() | ||
|
|
||
| # Store bugs to be returned | ||
| mock_instance._bugs = bugs | ||
|
|
||
| # When Bugzilla is initialized, capture the bughandler | ||
| def mock_init(params, include_fields, bughandler): | ||
| mock_instance._bughandler = bughandler | ||
| return mock_instance | ||
|
|
||
| # When get_data().wait() is called, invoke the handler with bugs | ||
| def mock_get_data(): | ||
| for bug in mock_instance._bugs: | ||
| mock_instance._bughandler(bug) | ||
| return mock_instance | ||
|
|
||
| mock_instance.get_data = mock_get_data | ||
| mock_instance.wait = MagicMock() | ||
| mock_bugzilla_class.side_effect = mock_init | ||
|
|
||
| return mock_bugzilla_class | ||
|
|
||
|
|
||
| class TestBugzillaQuickSearch: | ||
| """Test the bugzilla_quick_search tool.""" | ||
|
|
||
| async def test_quick_search_basic( | ||
| self, mocker, mcp_client: Client[FastMCPTransport] | ||
| ): | ||
| """Test basic quick search functionality.""" | ||
| mock_bugs = [ | ||
| { | ||
| "id": 123456, | ||
| "status": "NEW", | ||
| "summary": "Test bug 1", | ||
| "product": "Firefox", | ||
| "component": "General", | ||
| "priority": "P1", | ||
| "severity": "S2", | ||
| }, | ||
| { | ||
| "id": 789012, | ||
| "status": "ASSIGNED", | ||
| "summary": "Test bug 2", | ||
| "product": "Core", | ||
| "component": "DOM", | ||
| "priority": "P2", | ||
| "severity": "S3", | ||
| }, | ||
| ] | ||
|
|
||
| mock_bugzilla = setup_bugzilla_mock(mocker, mock_bugs) | ||
|
|
||
| result = await mcp_client.call_tool( | ||
| name="bugzilla_quick_search", | ||
| arguments={"search_query": "firefox crash", "limit": 2}, | ||
| ) | ||
|
|
||
| # Verify API call | ||
| mock_bugzilla.assert_called_once() | ||
| call_args = mock_bugzilla.call_args[0][0] | ||
| assert call_args["quicksearch"] == "firefox crash" | ||
| assert call_args["limit"] == 2 | ||
|
|
||
| # Verify result | ||
| result_text = result.content[0].text | ||
| assert "Found 2 bug(s)" in result_text | ||
| assert "Bug 123456 [NEW]" in result_text | ||
| assert "Bug 789012 [ASSIGNED]" in result_text | ||
| assert "Test bug 1" in result_text | ||
| assert "Firefox::General" in result_text | ||
| assert "Core::DOM" in result_text | ||
|
|
||
| async def test_quick_search_no_results( | ||
| self, mocker, mcp_client: Client[FastMCPTransport] | ||
| ): | ||
| """Test quick search with no results.""" | ||
| setup_bugzilla_mock(mocker, []) | ||
|
|
||
| result = await mcp_client.call_tool( | ||
| name="bugzilla_quick_search", | ||
| arguments={"search_query": "nonexistent query"}, | ||
| ) | ||
|
|
||
| result_text = result.content[0].text | ||
| assert "No bugs found matching: nonexistent query" in result_text | ||
|
|
||
| async def test_quick_search_custom_limit( | ||
| self, mocker, mcp_client: Client[FastMCPTransport] | ||
| ): | ||
| """Test quick search with custom limit.""" | ||
| mock_bugzilla = setup_bugzilla_mock(mocker, []) | ||
|
|
||
| await mcp_client.call_tool( | ||
| name="bugzilla_quick_search", | ||
| arguments={"search_query": "test", "limit": 50}, | ||
| ) | ||
|
|
||
| call_args = mock_bugzilla.call_args[0][0] | ||
| assert call_args["limit"] == 50 | ||
|
|
||
| async def test_quick_search_handles_missing_fields( | ||
| self, mocker, mcp_client: Client[FastMCPTransport] | ||
| ): | ||
| """Test that missing fields are handled gracefully.""" | ||
| mock_bugs = [{"id": 123456, "summary": "Test bug"}] | ||
| setup_bugzilla_mock(mocker, mock_bugs) | ||
|
|
||
| result = await mcp_client.call_tool( | ||
| name="bugzilla_quick_search", arguments={"search_query": "test"} | ||
| ) | ||
|
|
||
| result_text = result.content[0].text | ||
| assert "Bug 123456" in result_text | ||
| assert "Test bug" in result_text | ||
| assert "N/A" in result_text |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Quick Search does not really support natural-language search. The Quick Search enables shortcuts, e.g,
Status:RESOLVED(without space after:), which get converted to an advanced search.Here is how to use it: https://bugzilla.mozilla.org/page.cgi?id=quicksearch.html
I think something like a Skill would be more suitable for this, since explaining it in the tool description would be overkill.
I'm curious to learn about your use case for this tool.