mcp-bugzilla 0.13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,563 @@
1
+ Metadata-Version: 2.3
2
+ Name: mcp-bugzilla
3
+ Version: 0.13.0
4
+ Summary: MCP server for Bugzilla
5
+ Requires-Dist: fastmcp==3.3.1
6
+ Requires-Dist: httpx-retries>=0.5.0
7
+ Requires-Dist: uv ; extra == 'dev'
8
+ Requires-Dist: pytest ; extra == 'dev'
9
+ Requires-Dist: pytest-asyncio ; extra == 'dev'
10
+ Requires-Dist: respx ; extra == 'dev'
11
+ Requires-Python: ==3.13.*
12
+ Provides-Extra: dev
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Bugzilla Model Context Protocol (MCP) Server
16
+
17
+ [![Tests](https://github.com/openSUSE/mcp-bugzilla/actions/workflows/tests.yml/badge.svg)](https://github.com/openSUSE/mcp-bugzilla/actions/workflows/tests.yml)
18
+
19
+ A robust MCP server that provides seamless interaction with Bugzilla instances through the Model Context Protocol. This server exposes a comprehensive set of tools and prompts, enabling AI models and other MCP clients to efficiently query bug information, manage comments, and leverage Bugzilla's powerful quicksearch capabilities.
20
+
21
+ ## Table of Contents
22
+
23
+ - [Features](#features)
24
+ - [Requirements](#requirements)
25
+ - [Installation](#installation)
26
+ - [Configuration](#configuration)
27
+ - [Usage](#usage)
28
+ - [API Reference](#api-reference)
29
+ - [Examples](#examples)
30
+ - [Troubleshooting](#troubleshooting)
31
+ - [License](#license)
32
+
33
+ ## Features
34
+
35
+ ### Tools
36
+
37
+ The server provides the following tools for interacting with Bugzilla:
38
+
39
+ #### Bug Information
40
+
41
+ - **`bug_info(bug_ids: set[int])`**: Retrieves comprehensive details for specified Bugzilla bug IDs.
42
+ - **Parameters**:
43
+ - `bug_ids`: A set of bug IDs to fetch details for
44
+ - **Returns**: A dictionary containing the array `bugs` which lists all available information about the bugs (status, assignee, summary, description, extensions, etc.)
45
+ - **Example**: `bug_info({12345, 67890})` returns complete bug details for the specified IDs.
46
+
47
+ - **`bug_history(id: int, new_since: Optional[datetime] = None)`**: Fetches the history of changes for a given bug ID.
48
+ - **Parameters**:
49
+ - `id`: The bug ID to fetch history for
50
+ - `new_since`: Optional datetime object to only return history entries newer than this time.
51
+ - **Returns**: A list of history event dictionaries, each containing timestamp, author, and an array of changes.
52
+ - **Example**: `bug_history(12345, new_since=datetime.fromisoformat("2026-01-01T00:00:00"))` returns all history changes newer than Jan 1, 2026.
53
+
54
+ - **`bug_comments(id: int, include_private_comments: bool = False, new_since: Optional[datetime] = None)`**: Fetches all comments associated with a given bug ID.
55
+ - **Parameters**:
56
+ - `id`: The bug ID to fetch comments for
57
+ - `include_private_comments`: Whether to include private comments (default: `False`)
58
+ - `new_since`: Optional datetime object to only return comments newer than this time.
59
+ - **Returns**: A list of comment dictionaries, each containing author, timestamp, text, and privacy status
60
+ - **Example**: `bug_comments(12345, include_private_comments=True, new_since=datetime.fromisoformat("2026-01-01T00:00:00"))` returns all comments newer than Jan 1, 2026 including private ones
61
+
62
+
63
+
64
+ - **`add_comment(bug_id: int, comment: str, is_private: bool = False)`**: Adds a new comment to a specified bug.
65
+ - **Parameters**:
66
+ - `bug_id`: The bug ID to add a comment to
67
+ - `comment`: The comment text to add
68
+ - `is_private`: Whether the comment should be private (default: `False`)
69
+ - **Returns**: A dictionary containing the ID of the newly created comment
70
+ - **Example**: `add_comment(12345, "Fixed in version 2.0", is_private=False)`
71
+
72
+ #### Write Operations
73
+
74
+ **Note**: Write operations require appropriate Bugzilla permissions. These tools enable bug management and workflow automation.
75
+
76
+ * **`update_bug_status(bug_id: int, status: str, resolution: str = None, comment: str = "")`**: Updates the status of a bug with optional comment.
77
+
78
+ + **Parameters**:
79
+ - `bug_id`: The bug ID to update
80
+ - `status`: New status (e.g., `NEW`, `ASSIGNED`, `MODIFIED`, `ON_QA`, `VERIFIED`, `CLOSED`)
81
+ - `resolution`: Required when status is `CLOSED` (e.g., `FIXED`, `WONTFIX`, `NOTABUG`, `DUPLICATE`)
82
+ - `comment`: Optional comment explaining the status change
83
+ + **Returns**: A dictionary containing the updated bug fields
84
+ + **Example**: `update_bug_status(12345, "CLOSED", resolution="FIXED", comment="Fixed in version 2.0")`
85
+
86
+ * **`assign_bug(bug_id: int, assignee: str, comment: str = "")`**: Assigns a bug to a user.
87
+
88
+ + **Parameters**:
89
+ - `bug_id`: The bug ID to assign
90
+ - `assignee`: Email address of the assignee
91
+ - `comment`: Optional comment explaining the assignment
92
+ + **Returns**: A dictionary containing the updated bug fields
93
+ + **Example**: `assign_bug(12345, "developer@example.com", comment="You're the expert on this component")`
94
+
95
+ * **`update_bug_fields(bug_id: int, priority: str = None, severity: str = None, resolution: str = None, comment: str = "")`**: Updates various bug fields.
96
+
97
+ + **Parameters**:
98
+ - `bug_id`: The bug ID to update
99
+ - `priority`: Priority level (e.g., `urgent`, `high`, `medium`, `low`, `unspecified`)
100
+ - `severity`: Severity level (e.g., `urgent`, `high`, `medium`, `low`, `unspecified`)
101
+ - `resolution`: Resolution (only for closed bugs)
102
+ - `comment`: Optional comment explaining the changes
103
+ + **Returns**: A dictionary containing the updated bug fields
104
+ + **Example**: `update_bug_fields(12345, priority="high", severity="urgent", comment="Escalating due to customer impact")`
105
+
106
+ * **`add_cc_to_bug(bug_id: int, cc_email: str)`**: Adds an email address to the CC list of a bug.
107
+
108
+ + **Parameters**:
109
+ - `bug_id`: The bug ID
110
+ - `cc_email`: Email address to add to CC list
111
+ + **Returns**: A dictionary containing the updated bug fields
112
+ + **Example**: `add_cc_to_bug(12345, "manager@example.com")`
113
+
114
+ * **`mark_as_duplicate(bug_id: int, duplicate_of: int, comment: str = "")`**: Marks a bug as a duplicate of another bug and closes it.
115
+
116
+ + **Parameters**:
117
+ - `bug_id`: The bug ID to mark as duplicate
118
+ - `duplicate_of`: The bug ID this is a duplicate of
119
+ - `comment`: Optional comment (auto-generated if not provided)
120
+ + **Returns**: A dictionary containing the updated bug fields including status `CLOSED`, resolution `DUPLICATE`, and `dupe_of` reference
121
+ + **Example**: `mark_as_duplicate(12345, 789012, comment="Same root cause as the original report")`
122
+
123
+ #### Bug Search
124
+
125
+ - **`bugs_quicksearch(query: str, status: str = "ALL", 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).
126
+ - **Parameters**:
127
+ - `query`: A quicksearch query string (e.g., `"product:Firefox"`)
128
+ - `status`: Bug status to filter by (default: `"ALL"`)
129
+ - `include_fields`: Comma-separated list of fields to return (default: `"id,product,component,assigned_to,status,resolution,summary,last_change_time"`)
130
+ - `limit`: Maximum number of results to return (default: `50`)
131
+ - `offset`: Number of results to skip for pagination (default: `0`)
132
+ - **Returns**: A list of dictionaries, each containing essential bug fields
133
+ - **Example**: `bugs_quicksearch("product:Firefox", status="NEW", limit=10)`
134
+
135
+ - **`quicksearch_syntax_resource()`**: Returns documentation on Bugzilla's quicksearch syntax.
136
+ - **Returns**: A string containing HTML documentation.
137
+
138
+ - **`summarize_bug_prompt(id: int)`**: Returns a detailed summary prompt for all comments of a given bug ID.
139
+ - **Returns**: A well-structured summary of the bug's comments including usernames (bold italic) and dates (bold).
140
+
141
+ #### Utility Tools
142
+
143
+ - **`bug_url(bug_id: int)`**: Constructs and returns the direct URL to a specific bug on the Bugzilla server.
144
+ - **Returns**: A string representing the bug's URL (e.g., `"https://bugzilla.example.com/show_bug.cgi?id=12345"`)
145
+
146
+ - **`bugzilla_server_info()`**: Returns comprehensive Bugzilla server information.
147
+ - **Returns**: A dictionary containing `url`, `version`, `extensions`, `timezone`, `time`, and `parameters`.
148
+
149
+ - **`mcp_server_info_resource()`**: Returns the configuration arguments being used by the current server instance (version, host, port, etc.).
150
+ - **Returns**: A dictionary containing server configuration.
151
+
152
+ - **`get_current_headers_resource()`**: Returns the HTTP headers from the current request.
153
+ - **Returns**: A dictionary of HTTP headers.
154
+
155
+
156
+ ## Requirements
157
+
158
+ - Python 3.13
159
+ - A Bugzilla instance with REST API access
160
+ - A Bugzilla user account with an API key
161
+ - Network access to the Bugzilla server
162
+
163
+ ## Installation
164
+
165
+ ### Docker / Podman
166
+
167
+ The easiest way to run the server is using Docker or Podman:
168
+
169
+ ```bash
170
+ docker pull kskarthik/mcp-bugzilla
171
+ docker run -p 8000:8000 \
172
+ -e BUGZILLA_SERVER=https://bugzilla.example.com \
173
+ kskarthik/mcp-bugzilla \
174
+ --bugzilla-server https://bugzilla.example.com \
175
+ --host 0.0.0.0 \
176
+ --port 8000
177
+ ```
178
+
179
+ **Official Docker Hub repository**: https://hub.docker.com/r/kskarthik/mcp-bugzilla/
180
+
181
+ ### From Source
182
+
183
+ 1. **Clone the repository:**
184
+ ```bash
185
+ git clone <repository-url>
186
+ cd mcp-bugzilla
187
+ ```
188
+
189
+ 2. **Install dependencies:**
190
+ ```bash
191
+ uv sync
192
+ ```
193
+
194
+ 3. **Run the server:**
195
+ ```bash
196
+ uv run mcp-bugzilla --bugzilla-server https://bugzilla.example.com --host 127.0.0.1 --port 8000
197
+ ```
198
+
199
+ This will start the HTTP server at `http://127.0.0.1:8000/mcp/`.
200
+
201
+ ## Configuration
202
+
203
+ ### Command-Line Arguments
204
+
205
+ The `mcp-bugzilla` command supports the following options:
206
+
207
+ | Argument | Environment Variable | Default | Description |
208
+ |----------|---------------------|---------|-------------|
209
+ | `--bugzilla-server <URL>` | `BUGZILLA_SERVER` | *Required* | Base URL of the Bugzilla server (e.g., `https://bugzilla.example.com`) |
210
+ | `--host <ADDRESS>` | `MCP_HOST` | `127.0.0.1` | Host address for the MCP server to listen on |
211
+ | `--port <PORT>` | `MCP_PORT` | `8000` | Port for the MCP server to listen on |
212
+ | `--api-key-header <HEADER_NAME>` | `MCP_API_KEY_HEADER` | `ApiKey` | HTTP header name for the Bugzilla API key |
213
+ | `--use-auth-header` | `USE_AUTH_HEADER` | `False` | Use `Authorization: Bearer` header instead of `api_key` query parameter |
214
+ | `--read-only` | `MCP_READ_ONLY` | `False` | Disables all tools which can modify a bug. Works well in conjunction with `MCP_BUGZILLA_DISABLED_METHODS` |
215
+
216
+ **Note**: Command-line arguments take precedence over environment variables.
217
+
218
+ ### Environment Variables
219
+
220
+ You can configure the server using environment variables instead of command-line arguments:
221
+
222
+ ```bash
223
+ export BUGZILLA_SERVER=https://bugzilla.example.com
224
+ export MCP_HOST=127.0.0.1
225
+ export MCP_PORT=8000
226
+ export MCP_API_KEY_HEADER=ApiKey
227
+ export LOG_LEVEL=INFO # Optional: DEBUG, INFO, WARNING, ERROR, CRITICAL
228
+ export MCP_READ_ONLY=true # Optional: set to true to disable write operations
229
+ # Selective Disabling Tools (Optional)
230
+ # Works fine in conjunction with --read-only flag
231
+ export MCP_BUGZILLA_DISABLED_METHODS='bug_info,bug_comments'
232
+
233
+ mcp-bugzilla
234
+ ```
235
+
236
+ ### Methods Disabling
237
+
238
+ The server allows you to selectively disable specific tools or prompts using an environment variable. This is useful for restricting functionality based on security or resource requirements.
239
+
240
+ **Method**: `MCP_BUGZILLA_DISABLED_METHODS=tool1,tool2`
241
+
242
+
243
+ ## Usage
244
+
245
+ ### Starting the Server
246
+
247
+ Start the server with your Bugzilla instance URL:
248
+
249
+ ```bash
250
+ mcp-bugzilla --bugzilla-server https://bugzilla.opensuse.org
251
+ ```
252
+
253
+ The server will start listening on `http://127.0.0.1:8000/mcp/` by default.
254
+
255
+ ### Endpoint
256
+
257
+ The MCP server exposes an HTTP endpoint at:
258
+
259
+ ```
260
+ http://<host>:<port>/mcp/
261
+ ```
262
+
263
+ For example, with default settings:
264
+ ```
265
+ http://127.0.0.1:8000/mcp/
266
+ ```
267
+
268
+ ### Authentication
269
+
270
+ **Required**: All requests must include a Bugzilla API key in the HTTP headers.
271
+
272
+ 1. **Generate an API Key**:
273
+ - Log in to your Bugzilla instance
274
+ - Navigate to your user preferences
275
+ - Go to the "API Keys" section
276
+ - Generate a new API key
277
+ - Copy the API key
278
+
279
+ 2. **Send the API Key**:
280
+ Include the API key in the HTTP request header. By default, the header name is `ApiKey`:
281
+
282
+ ```http
283
+ POST /mcp/ HTTP/1.1
284
+ Host: 127.0.0.1:8000
285
+ ApiKey: YOUR_API_KEY_HERE
286
+ Content-Type: application/json
287
+ ```
288
+
289
+ You can customize the header name using the `--api-key-header` argument or `MCP_API_KEY_HEADER` environment variable.
290
+
291
+ 3. **Example with curl**:
292
+ ```bash
293
+ curl -X POST http://127.0.0.1:8000/mcp/ \
294
+ -H "ApiKey: YOUR_API_KEY_HERE" \
295
+ -H "Content-Type: application/json" \
296
+ -d '{"jsonrpc": "2.0", "method": "tools/call", "params": {"name": "server_url_resource"}, "id": 1}'
297
+ ```
298
+
299
+ ### Authentication Methods
300
+
301
+ This server supports two authentication methods for communicating with Bugzilla:
302
+
303
+ #### Method 1: Query Parameter (Default)
304
+
305
+ By default, the server sends the API key as a query parameter in the URL:
306
+ ```bash
307
+ mcp-bugzilla --bugzilla-server https://bugzilla.example.com
308
+ ```
309
+
310
+ This works with standard Bugzilla instances (Mozilla Bugzilla, openSUSE Bugzilla, etc.).
311
+
312
+ #### Method 2: Authorization Header (for enterprise instances)
313
+
314
+ Some Bugzilla instances (such as Red Hat Bugzilla) require the API key to be sent via the `Authorization: Bearer` header instead of as a query parameter. Use the `--use-auth-header` flag for these instances:
315
+ ```bash
316
+ mcp-bugzilla --bugzilla-server https://bugzilla.redhat.com --use-auth-header
317
+ ```
318
+
319
+ **When to use `--use-auth-header`:**
320
+ - Red Hat Bugzilla (bugzilla.redhat.com)
321
+ - Other enterprise Bugzilla instances that reject `api_key` query parameters
322
+ - Bugzilla instances with strict authentication requirements
323
+
324
+ **How it works:**
325
+ - **With `--use-auth-header`**: Sends `Authorization: Bearer YOUR_API_KEY` header to Bugzilla
326
+ - **Without `--use-auth-header`** (default): Sends `?api_key=YOUR_API_KEY` query parameter to Bugzilla
327
+
328
+ **Note**: The `--api-key-header` option controls which header name the *MCP server* expects from *clients*, while `--use-auth-header` controls how the *MCP server* authenticates with *Bugzilla*. These are independent settings.
329
+
330
+ ### MCP Client Integration
331
+
332
+ The server follows the [Model Context Protocol (MCP) specification](https://modelcontextprotocol.io/). It can be integrated with any MCP-compatible client.
333
+
334
+ **Example MCP client configuration** (format may vary by client):
335
+
336
+ ```json
337
+ {
338
+ "mcpServers": {
339
+ "bugzilla": {
340
+ "url": "http://127.0.0.1:8000/mcp/",
341
+ "headers": {
342
+ "ApiKey": "YOUR_API_KEY_HERE"
343
+ }
344
+ }
345
+ }
346
+ }
347
+ ```
348
+
349
+ ## API Reference
350
+
351
+ ### Tool Response Format
352
+
353
+ All tools return JSON responses following the MCP protocol. Successful responses include the tool's return value, while errors include detailed error messages.
354
+
355
+ ### Error Handling
356
+
357
+ The server provides detailed error messages for common issues:
358
+
359
+ - **Missing API Key**: Returns `ValidationError` if the required API key header is missing
360
+ - **Invalid Bug ID**: Returns `ToolError` with details if a bug ID doesn't exist
361
+ - **API Errors**: Returns `ToolError` with the HTTP status code and error message from Bugzilla
362
+ - **Network Errors**: Returns `ToolError` for connection or timeout issues
363
+
364
+ ### Logging
365
+
366
+ The server includes structured logging with color-coded output:
367
+
368
+ - **LLM Requests/Responses**: Cyan - Shows tool calls from MCP clients
369
+ - **Bugzilla API Requests/Responses**: Green - Shows HTTP requests to Bugzilla
370
+ - **Errors**: Red - Shows error messages
371
+
372
+ Set the log level using the `LOG_LEVEL` environment variable:
373
+ - `DEBUG`: Detailed debugging information
374
+ - `INFO`: General informational messages (default)
375
+ - `WARNING`: Warning messages
376
+ - `ERROR`: Error messages only
377
+ - `CRITICAL`: Critical errors only
378
+
379
+ ## Examples
380
+
381
+ ### Example 1: Get Bug Information
382
+
383
+ ```python
384
+ # MCP client call
385
+ result = client.call_tool("bug_info", {"bug_ids": [12345]})
386
+ print(result)
387
+ # Returns complete bug details including status, assignee, summary, etc.
388
+ ```
389
+
390
+ ### Example 2: Search for Bugs
391
+
392
+ ```python
393
+ # Search for new bugs in Firefox product
394
+ result = client.call_tool("bugs_quicksearch", {
395
+ "query": "product:Firefox status:NEW",
396
+ "limit": 10
397
+ })
398
+ # Returns list of bugs with essential fields
399
+ ```
400
+
401
+ ### Example 3: Add a Comment
402
+
403
+ ```python
404
+ # Add a public comment to a bug
405
+ result = client.call_tool("add_comment", {
406
+ "bug_id": 12345,
407
+ "comment": "This issue has been resolved in version 2.0",
408
+ "is_private": False
409
+ })
410
+ # Returns: {"id": 67890} - the new comment ID
411
+ ```
412
+
413
+ ### Example 4: Get Bug History and Comments
414
+
415
+ ```python
416
+ # Get the history of changes for a bug
417
+ history = client.call_tool("bug_history", {
418
+ "id": 12345,
419
+ "new_since": datetime.fromisoformat("2026-01-01T00:00:00")
420
+ })
421
+
422
+ # Get all public comments
423
+ public_comments = client.call_tool("bug_comments", {
424
+ "id": 12345,
425
+ "include_private_comments": False
426
+ })
427
+
428
+ # Get all comments including private ones
429
+ all_comments = client.call_tool("bug_comments", {
430
+ "id": 12345,
431
+ "include_private_comments": True
432
+ })
433
+ ```
434
+
435
+ ### Example 5: Quicksearch Syntax Examples
436
+
437
+ ```python
438
+ # Search by product and status
439
+ bugs_quicksearch("product:Firefox status:NEW")
440
+
441
+ # Search by assignee
442
+ bugs_quicksearch("assigned_to:user@example.com")
443
+
444
+ # Search by component
445
+ bugs_quicksearch("component:Core status:RESOLVED")
446
+
447
+ # Search with multiple criteria
448
+ bugs_quicksearch("product:Firefox component:JavaScript status:NEW priority:P1")
449
+
450
+ # Use pagination
451
+ page1 = bugs_quicksearch("status:NEW", limit=50, offset=0)
452
+ page2 = bugs_quicksearch("status:NEW", limit=50, offset=50)
453
+ ```
454
+
455
+ ### Example 6: Using with Red Hat Bugzilla
456
+
457
+ Red Hat Bugzilla requires Authorization header authentication:
458
+ ```bash
459
+ # Start the server with --use-auth-header flag
460
+ mcp-bugzilla \
461
+ --bugzilla-server https://bugzilla.redhat.com \
462
+ --use-auth-header \
463
+ --host 127.0.0.1 \
464
+ --port 8000
465
+
466
+ # Client connects normally - the flag only affects server-to-Bugzilla communication
467
+ curl -X POST http://127.0.0.1:8000/mcp/ \
468
+ -H "ApiKey: YOUR_API_KEY_HERE" \
469
+ -H "Content-Type: application/json" \
470
+ -d '{"jsonrpc": "2.0", "method": "tools/call", "params": {"name": "server_url"}, "id": 1}'
471
+ ```
472
+
473
+ ### Example 7: Update Bug Status
474
+ ```python
475
+ # Close a bug as fixed
476
+ result = client.call_tool("update_bug_status", {
477
+ "bug_id": 12345,
478
+ "status": "CLOSED",
479
+ "resolution": "FIXED",
480
+ "comment": "Fixed in commit abc123"
481
+ })
482
+ ```
483
+
484
+ ### Example 8: Assign a Bug
485
+ ```python
486
+ # Assign bug to a developer
487
+ result = client.call_tool("assign_bug", {
488
+ "bug_id": 12345,
489
+ "assignee": "developer@example.com",
490
+ "comment": "Please review this regression"
491
+ })
492
+ ```
493
+
494
+ ### Example 9: Mark as Duplicate
495
+ ```python
496
+ # Mark bug as duplicate and close it
497
+ result = client.call_tool("mark_as_duplicate", {
498
+ "bug_id": 12345,
499
+ "duplicate_of": 67890,
500
+ "comment": "This is a duplicate of the original report"
501
+ })
502
+ # Bug is automatically closed with resolution DUPLICATE
503
+ ```
504
+
505
+ ## Troubleshooting
506
+
507
+ ### Server Won't Start
508
+
509
+ **Issue**: Server fails to start with "bugzilla-server argument required"
510
+
511
+ **Solution**: Ensure you provide the `--bugzilla-server` argument or set the `BUGZILLA_SERVER` environment variable:
512
+ ```bash
513
+ mcp-bugzilla --bugzilla-server https://bugzilla.example.com
514
+ ```
515
+
516
+ ### Authentication Errors
517
+
518
+ **Issue**: Receiving `ValidationError: ApiKey header is required`
519
+
520
+ **Solution**:
521
+ 1. Ensure you're sending the API key in the correct HTTP header (default: `ApiKey`)
522
+ 2. Verify the API key is valid and not expired
523
+ 3. Check that the header name matches your server configuration
524
+
525
+ ### API Errors
526
+
527
+ **Issue**: Receiving `ToolError` with HTTP status codes
528
+
529
+ **Common causes**:
530
+ - **401 Unauthorized**: Invalid or expired API key
531
+ - **404 Not Found**: Bug ID doesn't exist or you don't have permission to view it
532
+ - **403 Forbidden**: Insufficient permissions for the requested operation
533
+ - **500 Internal Server Error**: Bugzilla server error
534
+
535
+ **Solution**: Check the error message for details and verify your API key permissions.
536
+
537
+ ### Connection Issues
538
+
539
+ **Issue**: Cannot connect to Bugzilla server
540
+
541
+ **Solution**:
542
+ 1. Verify the Bugzilla server URL is correct and accessible
543
+ 2. Check network connectivity
544
+ 3. Ensure the Bugzilla instance has REST API enabled
545
+ 4. Verify firewall rules allow outbound connections
546
+
547
+ ### Logging Issues
548
+
549
+ **Issue**: Not seeing enough (or too much) log output
550
+
551
+ **Solution**: Adjust the `LOG_LEVEL` environment variable:
552
+ ```bash
553
+ export LOG_LEVEL=DEBUG # For more verbose output
554
+ export LOG_LEVEL=ERROR # For minimal output
555
+ ```
556
+
557
+ ## License
558
+
559
+ This project is licensed under the Apache 2.0 License. See the [LICENSE](https://www.apache.org/licenses/LICENSE-2.0.txt) file for details.
560
+
561
+ **Author**: Sai Karthik <kskarthik@disroot.org>
562
+
563
+ **Contributors**: https://github.com/openSUSE/mcp-bugzilla/graphs/contributors