mcp-ticketer 0.1.22__py3-none-any.whl → 0.1.24__py3-none-any.whl
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.
Potentially problematic release.
This version of mcp-ticketer might be problematic. Click here for more details.
- mcp_ticketer/__init__.py +10 -10
- mcp_ticketer/__version__.py +1 -1
- mcp_ticketer/adapters/aitrackdown.py +15 -14
- mcp_ticketer/adapters/github.py +21 -20
- mcp_ticketer/adapters/hybrid.py +13 -12
- mcp_ticketer/adapters/jira.py +32 -27
- mcp_ticketer/adapters/linear.py +29 -26
- mcp_ticketer/cache/memory.py +2 -2
- mcp_ticketer/cli/auggie_configure.py +237 -0
- mcp_ticketer/cli/codex_configure.py +257 -0
- mcp_ticketer/cli/gemini_configure.py +261 -0
- mcp_ticketer/cli/main.py +171 -10
- mcp_ticketer/cli/migrate_config.py +3 -7
- mcp_ticketer/cli/utils.py +8 -8
- mcp_ticketer/core/adapter.py +12 -11
- mcp_ticketer/core/config.py +17 -17
- mcp_ticketer/core/env_discovery.py +24 -24
- mcp_ticketer/core/http_client.py +13 -13
- mcp_ticketer/core/mappers.py +25 -25
- mcp_ticketer/core/models.py +10 -10
- mcp_ticketer/core/project_config.py +25 -22
- mcp_ticketer/core/registry.py +7 -7
- mcp_ticketer/mcp/server.py +18 -18
- mcp_ticketer/queue/manager.py +2 -2
- mcp_ticketer/queue/queue.py +7 -7
- mcp_ticketer/queue/worker.py +8 -8
- {mcp_ticketer-0.1.22.dist-info → mcp_ticketer-0.1.24.dist-info}/METADATA +58 -8
- mcp_ticketer-0.1.24.dist-info/RECORD +45 -0
- mcp_ticketer-0.1.22.dist-info/RECORD +0 -42
- {mcp_ticketer-0.1.22.dist-info → mcp_ticketer-0.1.24.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.1.22.dist-info → mcp_ticketer-0.1.24.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.1.22.dist-info → mcp_ticketer-0.1.24.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.1.22.dist-info → mcp_ticketer-0.1.24.dist-info}/top_level.txt +0 -0
mcp_ticketer/core/registry.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Adapter registry for dynamic adapter management."""
|
|
2
2
|
|
|
3
|
-
from typing import Any,
|
|
3
|
+
from typing import Any, Optional
|
|
4
4
|
|
|
5
5
|
from .adapter import BaseAdapter
|
|
6
6
|
|
|
@@ -8,11 +8,11 @@ from .adapter import BaseAdapter
|
|
|
8
8
|
class AdapterRegistry:
|
|
9
9
|
"""Registry for managing ticket system adapters."""
|
|
10
10
|
|
|
11
|
-
_adapters:
|
|
12
|
-
_instances:
|
|
11
|
+
_adapters: dict[str, type[BaseAdapter]] = {}
|
|
12
|
+
_instances: dict[str, BaseAdapter] = {}
|
|
13
13
|
|
|
14
14
|
@classmethod
|
|
15
|
-
def register(cls, name: str, adapter_class:
|
|
15
|
+
def register(cls, name: str, adapter_class: type[BaseAdapter]) -> None:
|
|
16
16
|
"""Register an adapter class.
|
|
17
17
|
|
|
18
18
|
Args:
|
|
@@ -37,7 +37,7 @@ class AdapterRegistry:
|
|
|
37
37
|
|
|
38
38
|
@classmethod
|
|
39
39
|
def get_adapter(
|
|
40
|
-
cls, name: str, config: Optional[
|
|
40
|
+
cls, name: str, config: Optional[dict[str, Any]] = None, force_new: bool = False
|
|
41
41
|
) -> BaseAdapter:
|
|
42
42
|
"""Get or create an adapter instance.
|
|
43
43
|
|
|
@@ -75,7 +75,7 @@ class AdapterRegistry:
|
|
|
75
75
|
return instance
|
|
76
76
|
|
|
77
77
|
@classmethod
|
|
78
|
-
def list_adapters(cls) ->
|
|
78
|
+
def list_adapters(cls) -> dict[str, type[BaseAdapter]]:
|
|
79
79
|
"""List all registered adapters.
|
|
80
80
|
|
|
81
81
|
Returns:
|
|
@@ -114,7 +114,7 @@ class AdapterRegistry:
|
|
|
114
114
|
cls._instances.clear()
|
|
115
115
|
|
|
116
116
|
|
|
117
|
-
def adapter_factory(adapter_type: str, config:
|
|
117
|
+
def adapter_factory(adapter_type: str, config: dict[str, Any]) -> BaseAdapter:
|
|
118
118
|
"""Factory function for creating adapters.
|
|
119
119
|
|
|
120
120
|
Args:
|
mcp_ticketer/mcp/server.py
CHANGED
|
@@ -4,7 +4,7 @@ import asyncio
|
|
|
4
4
|
import json
|
|
5
5
|
import sys
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Any,
|
|
7
|
+
from typing import Any, Optional
|
|
8
8
|
|
|
9
9
|
from dotenv import load_dotenv
|
|
10
10
|
|
|
@@ -34,7 +34,7 @@ class MCPTicketServer:
|
|
|
34
34
|
"""MCP server for ticket operations over stdio."""
|
|
35
35
|
|
|
36
36
|
def __init__(
|
|
37
|
-
self, adapter_type: str = "aitrackdown", config: Optional[
|
|
37
|
+
self, adapter_type: str = "aitrackdown", config: Optional[dict[str, Any]] = None
|
|
38
38
|
):
|
|
39
39
|
"""Initialize MCP server.
|
|
40
40
|
|
|
@@ -48,7 +48,7 @@ class MCPTicketServer:
|
|
|
48
48
|
)
|
|
49
49
|
self.running = False
|
|
50
50
|
|
|
51
|
-
async def handle_request(self, request:
|
|
51
|
+
async def handle_request(self, request: dict[str, Any]) -> dict[str, Any]:
|
|
52
52
|
"""Handle JSON-RPC request.
|
|
53
53
|
|
|
54
54
|
Args:
|
|
@@ -105,7 +105,7 @@ class MCPTicketServer:
|
|
|
105
105
|
|
|
106
106
|
def _error_response(
|
|
107
107
|
self, request_id: Any, code: int, message: str
|
|
108
|
-
) ->
|
|
108
|
+
) -> dict[str, Any]:
|
|
109
109
|
"""Create error response.
|
|
110
110
|
|
|
111
111
|
Args:
|
|
@@ -123,7 +123,7 @@ class MCPTicketServer:
|
|
|
123
123
|
"id": request_id,
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
async def _handle_create(self, params:
|
|
126
|
+
async def _handle_create(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
127
127
|
"""Handle ticket creation."""
|
|
128
128
|
# Queue the operation instead of direct execution
|
|
129
129
|
queue = Queue()
|
|
@@ -216,12 +216,12 @@ class MCPTicketServer:
|
|
|
216
216
|
# Wait before next poll
|
|
217
217
|
await asyncio.sleep(poll_interval)
|
|
218
218
|
|
|
219
|
-
async def _handle_read(self, params:
|
|
219
|
+
async def _handle_read(self, params: dict[str, Any]) -> Optional[dict[str, Any]]:
|
|
220
220
|
"""Handle ticket read."""
|
|
221
221
|
ticket = await self.adapter.read(params["ticket_id"])
|
|
222
222
|
return ticket.model_dump() if ticket else None
|
|
223
223
|
|
|
224
|
-
async def _handle_update(self, params:
|
|
224
|
+
async def _handle_update(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
225
225
|
"""Handle ticket update."""
|
|
226
226
|
# Queue the operation
|
|
227
227
|
queue = Queue()
|
|
@@ -295,7 +295,7 @@ class MCPTicketServer:
|
|
|
295
295
|
# Wait before next poll
|
|
296
296
|
await asyncio.sleep(poll_interval)
|
|
297
297
|
|
|
298
|
-
async def _handle_delete(self, params:
|
|
298
|
+
async def _handle_delete(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
299
299
|
"""Handle ticket deletion."""
|
|
300
300
|
# Queue the operation
|
|
301
301
|
queue = Queue()
|
|
@@ -315,7 +315,7 @@ class MCPTicketServer:
|
|
|
315
315
|
"message": f"Ticket deletion queued with ID: {queue_id}",
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
async def _handle_list(self, params:
|
|
318
|
+
async def _handle_list(self, params: dict[str, Any]) -> list[dict[str, Any]]:
|
|
319
319
|
"""Handle ticket listing."""
|
|
320
320
|
tickets = await self.adapter.list(
|
|
321
321
|
limit=params.get("limit", 10),
|
|
@@ -324,13 +324,13 @@ class MCPTicketServer:
|
|
|
324
324
|
)
|
|
325
325
|
return [ticket.model_dump() for ticket in tickets]
|
|
326
326
|
|
|
327
|
-
async def _handle_search(self, params:
|
|
327
|
+
async def _handle_search(self, params: dict[str, Any]) -> list[dict[str, Any]]:
|
|
328
328
|
"""Handle ticket search."""
|
|
329
329
|
query = SearchQuery(**params)
|
|
330
330
|
tickets = await self.adapter.search(query)
|
|
331
331
|
return [ticket.model_dump() for ticket in tickets]
|
|
332
332
|
|
|
333
|
-
async def _handle_transition(self, params:
|
|
333
|
+
async def _handle_transition(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
334
334
|
"""Handle state transition."""
|
|
335
335
|
# Queue the operation
|
|
336
336
|
queue = Queue()
|
|
@@ -405,7 +405,7 @@ class MCPTicketServer:
|
|
|
405
405
|
# Wait before next poll
|
|
406
406
|
await asyncio.sleep(poll_interval)
|
|
407
407
|
|
|
408
|
-
async def _handle_comment(self, params:
|
|
408
|
+
async def _handle_comment(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
409
409
|
"""Handle comment operations."""
|
|
410
410
|
operation = params.get("operation", "add")
|
|
411
411
|
|
|
@@ -444,7 +444,7 @@ class MCPTicketServer:
|
|
|
444
444
|
else:
|
|
445
445
|
raise ValueError(f"Unknown comment operation: {operation}")
|
|
446
446
|
|
|
447
|
-
async def _handle_queue_status(self, params:
|
|
447
|
+
async def _handle_queue_status(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
448
448
|
"""Check status of queued operation."""
|
|
449
449
|
queue_id = params.get("queue_id")
|
|
450
450
|
if not queue_id:
|
|
@@ -475,7 +475,7 @@ class MCPTicketServer:
|
|
|
475
475
|
|
|
476
476
|
return response
|
|
477
477
|
|
|
478
|
-
async def _handle_create_pr(self, params:
|
|
478
|
+
async def _handle_create_pr(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
479
479
|
"""Handle PR creation for a ticket."""
|
|
480
480
|
ticket_id = params.get("ticket_id")
|
|
481
481
|
if not ticket_id:
|
|
@@ -563,7 +563,7 @@ class MCPTicketServer:
|
|
|
563
563
|
"ticket_id": ticket_id,
|
|
564
564
|
}
|
|
565
565
|
|
|
566
|
-
async def _handle_link_pr(self, params:
|
|
566
|
+
async def _handle_link_pr(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
567
567
|
"""Handle linking an existing PR to a ticket."""
|
|
568
568
|
ticket_id = params.get("ticket_id")
|
|
569
569
|
pr_url = params.get("pr_url")
|
|
@@ -617,7 +617,7 @@ class MCPTicketServer:
|
|
|
617
617
|
"pr_url": pr_url,
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
-
async def _handle_initialize(self, params:
|
|
620
|
+
async def _handle_initialize(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
621
621
|
"""Handle initialize request from MCP client.
|
|
622
622
|
|
|
623
623
|
Args:
|
|
@@ -633,7 +633,7 @@ class MCPTicketServer:
|
|
|
633
633
|
"capabilities": {"tools": {"listChanged": False}},
|
|
634
634
|
}
|
|
635
635
|
|
|
636
|
-
async def _handle_tools_list(self) ->
|
|
636
|
+
async def _handle_tools_list(self) -> dict[str, Any]:
|
|
637
637
|
"""List available MCP tools."""
|
|
638
638
|
return {
|
|
639
639
|
"tools": [
|
|
@@ -781,7 +781,7 @@ class MCPTicketServer:
|
|
|
781
781
|
]
|
|
782
782
|
}
|
|
783
783
|
|
|
784
|
-
async def _handle_tools_call(self, params:
|
|
784
|
+
async def _handle_tools_call(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
785
785
|
"""Handle tool invocation from MCP client.
|
|
786
786
|
|
|
787
787
|
Args:
|
mcp_ticketer/queue/manager.py
CHANGED
|
@@ -7,7 +7,7 @@ import subprocess
|
|
|
7
7
|
import sys
|
|
8
8
|
import time
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any,
|
|
10
|
+
from typing import Any, Optional
|
|
11
11
|
|
|
12
12
|
import psutil
|
|
13
13
|
|
|
@@ -207,7 +207,7 @@ class WorkerManager:
|
|
|
207
207
|
|
|
208
208
|
return False
|
|
209
209
|
|
|
210
|
-
def get_status(self) ->
|
|
210
|
+
def get_status(self) -> dict[str, Any]:
|
|
211
211
|
"""Get detailed worker status.
|
|
212
212
|
|
|
213
213
|
Returns:
|
mcp_ticketer/queue/queue.py
CHANGED
|
@@ -8,7 +8,7 @@ from dataclasses import asdict, dataclass
|
|
|
8
8
|
from datetime import datetime, timedelta
|
|
9
9
|
from enum import Enum
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Any,
|
|
11
|
+
from typing import Any, Optional
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class QueueStatus(str, Enum):
|
|
@@ -25,7 +25,7 @@ class QueueItem:
|
|
|
25
25
|
"""Represents a queued operation."""
|
|
26
26
|
|
|
27
27
|
id: str
|
|
28
|
-
ticket_data:
|
|
28
|
+
ticket_data: dict[str, Any]
|
|
29
29
|
adapter: str
|
|
30
30
|
operation: str
|
|
31
31
|
status: QueueStatus
|
|
@@ -33,7 +33,7 @@ class QueueItem:
|
|
|
33
33
|
processed_at: Optional[datetime] = None
|
|
34
34
|
error_message: Optional[str] = None
|
|
35
35
|
retry_count: int = 0
|
|
36
|
-
result: Optional[
|
|
36
|
+
result: Optional[dict[str, Any]] = None
|
|
37
37
|
project_dir: Optional[str] = None
|
|
38
38
|
|
|
39
39
|
def to_dict(self) -> dict:
|
|
@@ -132,7 +132,7 @@ class Queue:
|
|
|
132
132
|
|
|
133
133
|
def add(
|
|
134
134
|
self,
|
|
135
|
-
ticket_data:
|
|
135
|
+
ticket_data: dict[str, Any],
|
|
136
136
|
adapter: str,
|
|
137
137
|
operation: str,
|
|
138
138
|
project_dir: Optional[str] = None,
|
|
@@ -224,7 +224,7 @@ class Queue:
|
|
|
224
224
|
queue_id: str,
|
|
225
225
|
status: QueueStatus,
|
|
226
226
|
error_message: Optional[str] = None,
|
|
227
|
-
result: Optional[
|
|
227
|
+
result: Optional[dict[str, Any]] = None,
|
|
228
228
|
):
|
|
229
229
|
"""Update queue item status.
|
|
230
230
|
|
|
@@ -310,7 +310,7 @@ class Queue:
|
|
|
310
310
|
|
|
311
311
|
def list_items(
|
|
312
312
|
self, status: Optional[QueueStatus] = None, limit: int = 50
|
|
313
|
-
) ->
|
|
313
|
+
) -> list[QueueItem]:
|
|
314
314
|
"""List queue items.
|
|
315
315
|
|
|
316
316
|
Args:
|
|
@@ -414,7 +414,7 @@ class Queue:
|
|
|
414
414
|
)
|
|
415
415
|
conn.commit()
|
|
416
416
|
|
|
417
|
-
def get_stats(self) ->
|
|
417
|
+
def get_stats(self) -> dict[str, int]:
|
|
418
418
|
"""Get queue statistics.
|
|
419
419
|
|
|
420
420
|
Returns:
|
mcp_ticketer/queue/worker.py
CHANGED
|
@@ -7,7 +7,7 @@ import threading
|
|
|
7
7
|
import time
|
|
8
8
|
from datetime import datetime
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any,
|
|
10
|
+
from typing import Any, Optional
|
|
11
11
|
|
|
12
12
|
from dotenv import load_dotenv
|
|
13
13
|
|
|
@@ -73,8 +73,8 @@ class Worker:
|
|
|
73
73
|
self.max_concurrent = max_concurrent
|
|
74
74
|
|
|
75
75
|
# Track rate limits per adapter
|
|
76
|
-
self.last_request_times:
|
|
77
|
-
self.adapter_semaphores:
|
|
76
|
+
self.last_request_times: dict[str, datetime] = {}
|
|
77
|
+
self.adapter_semaphores: dict[str, asyncio.Semaphore] = {}
|
|
78
78
|
|
|
79
79
|
# Statistics
|
|
80
80
|
self.stats = {
|
|
@@ -153,7 +153,7 @@ class Worker:
|
|
|
153
153
|
|
|
154
154
|
logger.info("Worker loop stopped")
|
|
155
155
|
|
|
156
|
-
def _get_batch(self) ->
|
|
156
|
+
def _get_batch(self) -> list[QueueItem]:
|
|
157
157
|
"""Get a batch of pending items from the queue.
|
|
158
158
|
|
|
159
159
|
Returns:
|
|
@@ -169,7 +169,7 @@ class Worker:
|
|
|
169
169
|
break
|
|
170
170
|
return batch
|
|
171
171
|
|
|
172
|
-
async def _process_batch(self, batch:
|
|
172
|
+
async def _process_batch(self, batch: list[QueueItem]):
|
|
173
173
|
"""Process a batch of queue items with concurrency control.
|
|
174
174
|
|
|
175
175
|
Args:
|
|
@@ -194,7 +194,7 @@ class Worker:
|
|
|
194
194
|
# Wait for all adapter groups to complete
|
|
195
195
|
await asyncio.gather(*tasks, return_exceptions=True)
|
|
196
196
|
|
|
197
|
-
async def _process_adapter_group(self, adapter: str, items:
|
|
197
|
+
async def _process_adapter_group(self, adapter: str, items: list[QueueItem]):
|
|
198
198
|
"""Process items for a specific adapter with concurrency control.
|
|
199
199
|
|
|
200
200
|
Args:
|
|
@@ -342,7 +342,7 @@ class Worker:
|
|
|
342
342
|
|
|
343
343
|
return AdapterRegistry.get_adapter(item.adapter, adapter_config)
|
|
344
344
|
|
|
345
|
-
async def _execute_operation(self, adapter, item: QueueItem) ->
|
|
345
|
+
async def _execute_operation(self, adapter, item: QueueItem) -> dict[str, Any]:
|
|
346
346
|
"""Execute the queued operation.
|
|
347
347
|
|
|
348
348
|
Args:
|
|
@@ -390,7 +390,7 @@ class Worker:
|
|
|
390
390
|
else:
|
|
391
391
|
raise ValueError(f"Unknown operation: {operation}")
|
|
392
392
|
|
|
393
|
-
def get_status(self) ->
|
|
393
|
+
def get_status(self) -> dict[str, Any]:
|
|
394
394
|
"""Get worker status.
|
|
395
395
|
|
|
396
396
|
Returns:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-ticketer
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.24
|
|
4
4
|
Summary: Universal ticket management interface for AI agents with MCP support
|
|
5
5
|
Author-email: MCP Ticketer Team <support@mcp-ticketer.io>
|
|
6
6
|
Maintainer-email: MCP Ticketer Team <support@mcp-ticketer.io>
|
|
@@ -39,6 +39,8 @@ Requires-Dist: psutil>=5.9.0
|
|
|
39
39
|
Requires-Dist: pydantic>=2.0
|
|
40
40
|
Requires-Dist: python-dotenv>=1.0.0
|
|
41
41
|
Requires-Dist: rich>=13.0.0
|
|
42
|
+
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
|
|
43
|
+
Requires-Dist: tomli-w>=1.0.0
|
|
42
44
|
Requires-Dist: typer>=0.9.0
|
|
43
45
|
Requires-Dist: typing-extensions>=4.8.0
|
|
44
46
|
Provides-Extra: all
|
|
@@ -129,6 +131,39 @@ pip install -e .
|
|
|
129
131
|
- Python 3.9+
|
|
130
132
|
- Virtual environment (recommended)
|
|
131
133
|
|
|
134
|
+
## 🤖 Supported AI Clients
|
|
135
|
+
|
|
136
|
+
MCP Ticketer integrates with multiple AI clients via the Model Context Protocol (MCP):
|
|
137
|
+
|
|
138
|
+
| AI Client | Support | Config Type | Project-Level | Setup Command |
|
|
139
|
+
|-----------|---------|-------------|---------------|---------------|
|
|
140
|
+
| **Claude Code** | ✅ Native | JSON | ✅ Yes | `mcp-ticketer mcp claude` |
|
|
141
|
+
| **Gemini CLI** | ✅ Full | JSON | ✅ Yes | `mcp-ticketer mcp gemini` |
|
|
142
|
+
| **Codex CLI** | ✅ Full | TOML | ❌ Global only | `mcp-ticketer mcp codex` |
|
|
143
|
+
| **Auggie** | ✅ Full | JSON | ❌ Global only | `mcp-ticketer mcp auggie` |
|
|
144
|
+
|
|
145
|
+
### Quick MCP Setup
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Claude Code (recommended for project-specific workflows)
|
|
149
|
+
mcp-ticketer init --adapter aitrackdown # First, initialize an adapter
|
|
150
|
+
mcp-ticketer mcp claude # Then configure MCP
|
|
151
|
+
|
|
152
|
+
# Gemini CLI (Google's AI client)
|
|
153
|
+
mcp-ticketer init --adapter aitrackdown
|
|
154
|
+
mcp-ticketer mcp gemini --scope project
|
|
155
|
+
|
|
156
|
+
# Codex CLI (global configuration, requires restart)
|
|
157
|
+
mcp-ticketer init --adapter aitrackdown
|
|
158
|
+
mcp-ticketer mcp codex
|
|
159
|
+
|
|
160
|
+
# Auggie (simple global setup)
|
|
161
|
+
mcp-ticketer init --adapter aitrackdown
|
|
162
|
+
mcp-ticketer mcp auggie
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**See [AI Client Integration Guide](docs/AI_CLIENT_INTEGRATION.md) for detailed setup instructions.**
|
|
166
|
+
|
|
132
167
|
## 🚀 Quick Start
|
|
133
168
|
|
|
134
169
|
### 1. Initialize Configuration
|
|
@@ -179,28 +214,43 @@ mcp-ticketer search "login bug" --state open
|
|
|
179
214
|
|
|
180
215
|
## 🤖 MCP Server Integration
|
|
181
216
|
|
|
182
|
-
|
|
217
|
+
MCP Ticketer provides seamless integration with AI clients through automatic configuration:
|
|
183
218
|
|
|
184
219
|
```bash
|
|
185
|
-
|
|
220
|
+
# Run MCP server manually (for testing)
|
|
221
|
+
mcp-ticketer serve
|
|
222
|
+
|
|
223
|
+
# Or configure your AI client automatically (recommended)
|
|
224
|
+
mcp-ticketer mcp claude # For Claude Code
|
|
225
|
+
mcp-ticketer mcp gemini # For Gemini CLI
|
|
226
|
+
mcp-ticketer mcp codex # For Codex CLI
|
|
227
|
+
mcp-ticketer mcp auggie # For Auggie
|
|
186
228
|
```
|
|
187
229
|
|
|
188
|
-
|
|
230
|
+
**Configuration is automatic** - the commands above will:
|
|
231
|
+
1. Detect your mcp-ticketer installation
|
|
232
|
+
2. Read your adapter configuration
|
|
233
|
+
3. Generate the appropriate MCP server config
|
|
234
|
+
4. Save it to the correct location for your AI client
|
|
235
|
+
|
|
236
|
+
**Manual Configuration Example** (Claude Code):
|
|
189
237
|
|
|
190
238
|
```json
|
|
191
239
|
{
|
|
192
240
|
"mcpServers": {
|
|
193
|
-
"ticketer": {
|
|
194
|
-
"command": "mcp-ticketer
|
|
195
|
-
"args": [],
|
|
241
|
+
"mcp-ticketer": {
|
|
242
|
+
"command": "/path/to/mcp-ticketer",
|
|
243
|
+
"args": ["serve"],
|
|
196
244
|
"env": {
|
|
197
|
-
"MCP_TICKETER_ADAPTER": "
|
|
245
|
+
"MCP_TICKETER_ADAPTER": "aitrackdown"
|
|
198
246
|
}
|
|
199
247
|
}
|
|
200
248
|
}
|
|
201
249
|
}
|
|
202
250
|
```
|
|
203
251
|
|
|
252
|
+
**See [AI Client Integration Guide](docs/AI_CLIENT_INTEGRATION.md) for client-specific details.**
|
|
253
|
+
|
|
204
254
|
## 📚 Documentation
|
|
205
255
|
|
|
206
256
|
Full documentation is available at [https://mcp-ticketerer.readthedocs.io](https://mcp-ticketerer.readthedocs.io)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
mcp_ticketer/__init__.py,sha256=Xx4WaprO5PXhVPbYi1L6tBmwmJMkYS-lMyG4ieN6QP0,717
|
|
2
|
+
mcp_ticketer/__version__.py,sha256=jSY7C2Ap-dss0EXCJjKddzTwqfO8125m1PW4jz1lXkU,1118
|
|
3
|
+
mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
mcp_ticketer/adapters/__init__.py,sha256=B5DFllWn23hkhmrLykNO5uMMSdcFuuPHXyLw_jyFzuE,358
|
|
5
|
+
mcp_ticketer/adapters/aitrackdown.py,sha256=24h3UqMj5CltCl271kmqnDFOicCVp9w7yMTKK8s_dTA,16283
|
|
6
|
+
mcp_ticketer/adapters/github.py,sha256=X0lEWBCfy-vztX2vauuVSYsOCa9_ezt9hGa5BsCQTu8,46663
|
|
7
|
+
mcp_ticketer/adapters/hybrid.py,sha256=XFqHtWTLguE61ZGuZ156gxoz-wMr21AxLSADI1QVxcU,19025
|
|
8
|
+
mcp_ticketer/adapters/jira.py,sha256=W2pU-YxrSqgjm1gVt2eGc8We-G0MbRMSggQ2gWkThME,30602
|
|
9
|
+
mcp_ticketer/adapters/linear.py,sha256=C6rHIxRaWvOBjX6ue2Nt-IPTcwFAwBkksstb7zV3YJw,71484
|
|
10
|
+
mcp_ticketer/cache/__init__.py,sha256=Xcd-cKnt-Cx7jBzvfzUUUPaGkmyXFi5XUFWw3Z4b7d4,138
|
|
11
|
+
mcp_ticketer/cache/memory.py,sha256=2yBqGi9i0SanlUhJoOC7nijWjoMa3_ntPe-V-AV-LfU,5042
|
|
12
|
+
mcp_ticketer/cli/__init__.py,sha256=l9Q8iKmfGkTu0cssHBVqNZTsL4eAtFzOB25AED_0G6g,89
|
|
13
|
+
mcp_ticketer/cli/auggie_configure.py,sha256=MXKzLtqe3K_UTQ2GacHAWbvf_B0779KL325smiAKE0Q,8212
|
|
14
|
+
mcp_ticketer/cli/codex_configure.py,sha256=xDppHouT6_-cYXswyAggoPX5bSlRXMvCoM_x9PQ-42A,9086
|
|
15
|
+
mcp_ticketer/cli/configure.py,sha256=BsA_pSHQMQS0t1bJO_wMM8LWsd5sWJDASjEPRHvwC18,16198
|
|
16
|
+
mcp_ticketer/cli/discover.py,sha256=AF_qlQc1Oo0UkWayoF5pmRChS5J3fJjH6f2YZzd_k8w,13188
|
|
17
|
+
mcp_ticketer/cli/gemini_configure.py,sha256=ZNSA1lBW-itVToza-JxW95Po7daVXKiZAh7lp6pmXMU,9343
|
|
18
|
+
mcp_ticketer/cli/main.py,sha256=AvWLtlKrAtgWv6cfXNRzESqJE7CRhHdKeDuNWOxj5GM,47111
|
|
19
|
+
mcp_ticketer/cli/mcp_configure.py,sha256=RzV50UjXgOmvMp-9S0zS39psuvjffVByaMrqrUaAGAM,9594
|
|
20
|
+
mcp_ticketer/cli/migrate_config.py,sha256=MYsr_C5ZxsGg0P13etWTWNrJ_lc6ElRCkzfQADYr3DM,5956
|
|
21
|
+
mcp_ticketer/cli/queue_commands.py,sha256=mm-3H6jmkUGJDyU_E46o9iRpek8tvFCm77F19OtHiZI,7884
|
|
22
|
+
mcp_ticketer/cli/utils.py,sha256=2ptUrp2ELZsox0kSxAI5DFrHonOU999qh4MxbLv6VBQ,21155
|
|
23
|
+
mcp_ticketer/core/__init__.py,sha256=eXovsaJymQRP2AwOBuOy6mFtI3I68D7gGenZ5V-IMqo,349
|
|
24
|
+
mcp_ticketer/core/adapter.py,sha256=q64LxOInIno7EIbmuxItf8KEsd-g9grCs__Z4uwZHto,10273
|
|
25
|
+
mcp_ticketer/core/config.py,sha256=QlWMJmxz4HsoZ4e2DZQdgKy0YHlL6UebbDVxw1CD3jI,15117
|
|
26
|
+
mcp_ticketer/core/env_discovery.py,sha256=wKp2Pi5vQMGOTrM1690IBv_eoABly-pD8ah7n1zSWDc,17710
|
|
27
|
+
mcp_ticketer/core/http_client.py,sha256=s5ikMiwEJ8TJjNn73wu3gv3OdAtyBEpAqPnSroRMW2k,13971
|
|
28
|
+
mcp_ticketer/core/mappers.py,sha256=1aG1jFsHTCwmGRVgOlXW-VOSTGzc86gv7qjDfiR1ups,17462
|
|
29
|
+
mcp_ticketer/core/models.py,sha256=DRuJoYbjp9fcPV9GwQfhVcNUB0XmwQB3vuqW8hQWZ_k,6491
|
|
30
|
+
mcp_ticketer/core/project_config.py,sha256=yYxlgxjcEPeOwx-b-SXFpe0k9pW9xzBRAK72PsItG-o,23346
|
|
31
|
+
mcp_ticketer/core/registry.py,sha256=ShYLDPE62KFJpB0kj_zFyQzRxSH3LkQEEuo1jaakb1k,3483
|
|
32
|
+
mcp_ticketer/mcp/__init__.py,sha256=Y05eTzsPk0wH8yKNIM-ekpGjgSDO0bQr0EME-vOP4GE,123
|
|
33
|
+
mcp_ticketer/mcp/server.py,sha256=U0bkHYe_DGa7wNPtuawsA8i_llHmpADgtq-OkYMjoBo,37041
|
|
34
|
+
mcp_ticketer/queue/__init__.py,sha256=1YIaCpZpFqPcqvDEQXiEvDLiw94DXRdCJkBaVIFQrms,231
|
|
35
|
+
mcp_ticketer/queue/__main__.py,sha256=gc_tE9NUdK07OJfTZuD4t6KeBD_vxFQIhknGTQUG_jk,109
|
|
36
|
+
mcp_ticketer/queue/manager.py,sha256=qqUqq_JtH8jfg-MDfc-UIgFaa7gYsA1eBaR2KsCw48c,7513
|
|
37
|
+
mcp_ticketer/queue/queue.py,sha256=zD7SRDP7zfGm4gokqzgL0CLuPUPxbBNmddsOqLMCbjQ,13162
|
|
38
|
+
mcp_ticketer/queue/run_worker.py,sha256=_IBezjvhbJJ7gn0evTBIMbSPjvfFZwxEdT-1DLo_bRk,799
|
|
39
|
+
mcp_ticketer/queue/worker.py,sha256=2wusez3Wxmun6qAmup3WsGjBD-vNgtLwxygYviXdECQ,14634
|
|
40
|
+
mcp_ticketer-0.1.24.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
|
|
41
|
+
mcp_ticketer-0.1.24.dist-info/METADATA,sha256=wpkFwzRgF21v3TfGDLmF0ZCJbFwCXYi1Ft6Ikh1-Bu8,13191
|
|
42
|
+
mcp_ticketer-0.1.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
43
|
+
mcp_ticketer-0.1.24.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
|
|
44
|
+
mcp_ticketer-0.1.24.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
|
|
45
|
+
mcp_ticketer-0.1.24.dist-info/RECORD,,
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
mcp_ticketer/__init__.py,sha256=701DkKv4mtXRwbG6GjYhryb-aV8FVmq3RMF-qD_V3I8,497
|
|
2
|
-
mcp_ticketer/__version__.py,sha256=2pZOWOjMxfiDnLidx4HMlRttVUeptHpsEh1V-KVEYmo,1118
|
|
3
|
-
mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
mcp_ticketer/adapters/__init__.py,sha256=B5DFllWn23hkhmrLykNO5uMMSdcFuuPHXyLw_jyFzuE,358
|
|
5
|
-
mcp_ticketer/adapters/aitrackdown.py,sha256=vEeapedlX5EpNjPpv2lcjb_R8lKP7oG50aYQWXWQRVs,16261
|
|
6
|
-
mcp_ticketer/adapters/github.py,sha256=M3x0Qv8yr47gLVzdekWNjjfvlck0sYDfn4T_rbU-Of4,46632
|
|
7
|
-
mcp_ticketer/adapters/hybrid.py,sha256=yGLFzCdvSza1cXeoG_jc_uYm5_aJGVHp4aErgGbvMAM,19003
|
|
8
|
-
mcp_ticketer/adapters/jira.py,sha256=c60Hcf4yNkz1cGPDgQRCC8LLbt8LqqjvdSsBHXHuyxw,30534
|
|
9
|
-
mcp_ticketer/adapters/linear.py,sha256=7nlhKL4BLpSOeFEyZ9d7yL39BAjBiraxclc2w6Zq0cM,71402
|
|
10
|
-
mcp_ticketer/cache/__init__.py,sha256=Xcd-cKnt-Cx7jBzvfzUUUPaGkmyXFi5XUFWw3Z4b7d4,138
|
|
11
|
-
mcp_ticketer/cache/memory.py,sha256=fBMpnPw91XApD7sEnpQmzpzCc_H_K-55N9kIHo1RXOc,5048
|
|
12
|
-
mcp_ticketer/cli/__init__.py,sha256=l9Q8iKmfGkTu0cssHBVqNZTsL4eAtFzOB25AED_0G6g,89
|
|
13
|
-
mcp_ticketer/cli/configure.py,sha256=BsA_pSHQMQS0t1bJO_wMM8LWsd5sWJDASjEPRHvwC18,16198
|
|
14
|
-
mcp_ticketer/cli/discover.py,sha256=AF_qlQc1Oo0UkWayoF5pmRChS5J3fJjH6f2YZzd_k8w,13188
|
|
15
|
-
mcp_ticketer/cli/main.py,sha256=RUia93L7UQChxuM-ENetX0oZlSuQb1L-WSYSrOW6D8c,42107
|
|
16
|
-
mcp_ticketer/cli/mcp_configure.py,sha256=RzV50UjXgOmvMp-9S0zS39psuvjffVByaMrqrUaAGAM,9594
|
|
17
|
-
mcp_ticketer/cli/migrate_config.py,sha256=bI4yO7ED4_d3_3Y0Q0E2X4jA7ltjC4Bsk09OxXUje-A,5979
|
|
18
|
-
mcp_ticketer/cli/queue_commands.py,sha256=mm-3H6jmkUGJDyU_E46o9iRpek8tvFCm77F19OtHiZI,7884
|
|
19
|
-
mcp_ticketer/cli/utils.py,sha256=T_kuCKCciFfOKg1jTRc7IK0LN4lVrEC7DtrDSXK8E0A,21167
|
|
20
|
-
mcp_ticketer/core/__init__.py,sha256=eXovsaJymQRP2AwOBuOy6mFtI3I68D7gGenZ5V-IMqo,349
|
|
21
|
-
mcp_ticketer/core/adapter.py,sha256=AC5kHZD_7PtVonGWDQomVxhTl75SHdSx5L0ANNxVETM,10224
|
|
22
|
-
mcp_ticketer/core/config.py,sha256=M1XQqwU2KfifBvhVXS9RKWKjUmuCb-x2jkAqZo-9GOo,15121
|
|
23
|
-
mcp_ticketer/core/env_discovery.py,sha256=uJX1wLryKvsCxbmoEHlLbAeAYXY2u4gZm98v0uQnQ-M,17722
|
|
24
|
-
mcp_ticketer/core/http_client.py,sha256=nnvAmB-Yh_ciJJW9yEiJhiYJu_uy9vtvGG_3Uqro8tk,13983
|
|
25
|
-
mcp_ticketer/core/mappers.py,sha256=DwNB7nv4GUt4RJQNzMcvWMeN7Uf9lXSJC6ZogZjmCJA,17482
|
|
26
|
-
mcp_ticketer/core/models.py,sha256=e4NsGstTzT4iUhirpbqF9SDtWwVkJs2g1NJKHBJdWNI,6503
|
|
27
|
-
mcp_ticketer/core/project_config.py,sha256=jWGNqe6eA5SZ-09AIqXDyZAb2GdIxjO0nSbFfmxaBuo,23277
|
|
28
|
-
mcp_ticketer/core/registry.py,sha256=Hz616t82tiZITMExz1cUTlbW_6u6Hzi-faECTvkUEG8,3495
|
|
29
|
-
mcp_ticketer/mcp/__init__.py,sha256=Y05eTzsPk0wH8yKNIM-ekpGjgSDO0bQr0EME-vOP4GE,123
|
|
30
|
-
mcp_ticketer/mcp/server.py,sha256=3EiPy65fjHBXG66S6IzWxIjfSJ-ZsF2xYvAiM8t_flo,37053
|
|
31
|
-
mcp_ticketer/queue/__init__.py,sha256=1YIaCpZpFqPcqvDEQXiEvDLiw94DXRdCJkBaVIFQrms,231
|
|
32
|
-
mcp_ticketer/queue/__main__.py,sha256=gc_tE9NUdK07OJfTZuD4t6KeBD_vxFQIhknGTQUG_jk,109
|
|
33
|
-
mcp_ticketer/queue/manager.py,sha256=Xk_v0LZgcg1fjqnrD4bOF4PEarGuhbBdK0kUvn3FoiQ,7519
|
|
34
|
-
mcp_ticketer/queue/queue.py,sha256=hUx5meIHczjA4b-zhLrJQvFjqNrB9F9bLtaMLZCPPoU,13174
|
|
35
|
-
mcp_ticketer/queue/run_worker.py,sha256=_IBezjvhbJJ7gn0evTBIMbSPjvfFZwxEdT-1DLo_bRk,799
|
|
36
|
-
mcp_ticketer/queue/worker.py,sha256=X6Uwx7H9S9HB3tZK965G4KIbP4t2oT8wvSw8RGnEvJ0,14646
|
|
37
|
-
mcp_ticketer-0.1.22.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
|
|
38
|
-
mcp_ticketer-0.1.22.dist-info/METADATA,sha256=DRxE3hR8YRBt-j1JkyuyPTwmMwKpY4tjV8LEazVogTE,11211
|
|
39
|
-
mcp_ticketer-0.1.22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
40
|
-
mcp_ticketer-0.1.22.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
|
|
41
|
-
mcp_ticketer-0.1.22.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
|
|
42
|
-
mcp_ticketer-0.1.22.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|