mcp-ticketer 0.1.8__py3-none-any.whl → 0.1.12__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.

@@ -63,6 +63,10 @@ class MCPTicketServer:
63
63
  result = await self._handle_comment(params)
64
64
  elif method == "ticket/status":
65
65
  result = await self._handle_queue_status(params)
66
+ elif method == "ticket/create_pr":
67
+ result = await self._handle_create_pr(params)
68
+ elif method == "ticket/link_pr":
69
+ result = await self._handle_link_pr(params)
66
70
  elif method == "tools/list":
67
71
  result = await self._handle_tools_list()
68
72
  elif method == "tools/call":
@@ -134,11 +138,72 @@ class MCPTicketServer:
134
138
  manager = WorkerManager()
135
139
  manager.start_if_needed()
136
140
 
137
- return {
138
- "queue_id": queue_id,
139
- "status": "queued",
140
- "message": f"Ticket creation queued with ID: {queue_id}"
141
- }
141
+ # Check if async mode is requested (for backward compatibility)
142
+ if params.get("async_mode", False):
143
+ return {
144
+ "queue_id": queue_id,
145
+ "status": "queued",
146
+ "message": f"Ticket creation queued with ID: {queue_id}"
147
+ }
148
+
149
+ # Poll for completion with timeout (default synchronous behavior)
150
+ max_wait_time = params.get("timeout", 30) # seconds, allow override
151
+ poll_interval = 0.5 # seconds
152
+ start_time = asyncio.get_event_loop().time()
153
+
154
+ while True:
155
+ # Check queue status
156
+ item = queue.get_item(queue_id)
157
+
158
+ if not item:
159
+ return {
160
+ "queue_id": queue_id,
161
+ "status": "error",
162
+ "error": f"Queue item {queue_id} not found"
163
+ }
164
+
165
+ # If completed, return with ticket ID
166
+ if item.status == QueueStatus.COMPLETED:
167
+ response = {
168
+ "queue_id": queue_id,
169
+ "status": "completed",
170
+ "title": params["title"]
171
+ }
172
+
173
+ # Add ticket ID and other result data if available
174
+ if item.result:
175
+ response["ticket_id"] = item.result.get("id")
176
+ if "state" in item.result:
177
+ response["state"] = item.result["state"]
178
+ # Try to construct URL if we have enough information
179
+ if response.get("ticket_id"):
180
+ # This is adapter-specific, but we can add URL generation later
181
+ response["id"] = response["ticket_id"] # Also include as "id" for compatibility
182
+
183
+ response["message"] = f"Ticket created successfully: {response.get('ticket_id', queue_id)}"
184
+ return response
185
+
186
+ # If failed, return error
187
+ if item.status == QueueStatus.FAILED:
188
+ return {
189
+ "queue_id": queue_id,
190
+ "status": "failed",
191
+ "error": item.error_message or "Ticket creation failed",
192
+ "title": params["title"]
193
+ }
194
+
195
+ # Check timeout
196
+ elapsed = asyncio.get_event_loop().time() - start_time
197
+ if elapsed > max_wait_time:
198
+ return {
199
+ "queue_id": queue_id,
200
+ "status": "timeout",
201
+ "message": f"Ticket creation timed out after {max_wait_time} seconds. Use ticket_status with queue_id to check status.",
202
+ "title": params["title"]
203
+ }
204
+
205
+ # Wait before next poll
206
+ await asyncio.sleep(poll_interval)
142
207
 
143
208
  async def _handle_read(self, params: Dict[str, Any]) -> Optional[Dict[str, Any]]:
144
209
  """Handle ticket read."""
@@ -162,11 +227,60 @@ class MCPTicketServer:
162
227
  manager = WorkerManager()
163
228
  manager.start_if_needed()
164
229
 
165
- return {
166
- "queue_id": queue_id,
167
- "status": "queued",
168
- "message": f"Ticket update queued with ID: {queue_id}"
169
- }
230
+ # Poll for completion with timeout
231
+ max_wait_time = 30 # seconds
232
+ poll_interval = 0.5 # seconds
233
+ start_time = asyncio.get_event_loop().time()
234
+
235
+ while True:
236
+ # Check queue status
237
+ item = queue.get_item(queue_id)
238
+
239
+ if not item:
240
+ return {
241
+ "queue_id": queue_id,
242
+ "status": "error",
243
+ "error": f"Queue item {queue_id} not found"
244
+ }
245
+
246
+ # If completed, return with ticket ID
247
+ if item.status == QueueStatus.COMPLETED:
248
+ response = {
249
+ "queue_id": queue_id,
250
+ "status": "completed",
251
+ "ticket_id": params["ticket_id"]
252
+ }
253
+
254
+ # Add result data if available
255
+ if item.result:
256
+ if item.result.get("id"):
257
+ response["ticket_id"] = item.result["id"]
258
+ response["success"] = item.result.get("success", True)
259
+
260
+ response["message"] = f"Ticket updated successfully: {response['ticket_id']}"
261
+ return response
262
+
263
+ # If failed, return error
264
+ if item.status == QueueStatus.FAILED:
265
+ return {
266
+ "queue_id": queue_id,
267
+ "status": "failed",
268
+ "error": item.error_message or "Ticket update failed",
269
+ "ticket_id": params["ticket_id"]
270
+ }
271
+
272
+ # Check timeout
273
+ elapsed = asyncio.get_event_loop().time() - start_time
274
+ if elapsed > max_wait_time:
275
+ return {
276
+ "queue_id": queue_id,
277
+ "status": "timeout",
278
+ "message": f"Ticket update timed out after {max_wait_time} seconds. Use ticket_status with queue_id to check status.",
279
+ "ticket_id": params["ticket_id"]
280
+ }
281
+
282
+ # Wait before next poll
283
+ await asyncio.sleep(poll_interval)
170
284
 
171
285
  async def _handle_delete(self, params: Dict[str, Any]) -> Dict[str, Any]:
172
286
  """Handle ticket deletion."""
@@ -220,11 +334,61 @@ class MCPTicketServer:
220
334
  manager = WorkerManager()
221
335
  manager.start_if_needed()
222
336
 
223
- return {
224
- "queue_id": queue_id,
225
- "status": "queued",
226
- "message": f"State transition queued with ID: {queue_id}"
227
- }
337
+ # Poll for completion with timeout
338
+ max_wait_time = 30 # seconds
339
+ poll_interval = 0.5 # seconds
340
+ start_time = asyncio.get_event_loop().time()
341
+
342
+ while True:
343
+ # Check queue status
344
+ item = queue.get_item(queue_id)
345
+
346
+ if not item:
347
+ return {
348
+ "queue_id": queue_id,
349
+ "status": "error",
350
+ "error": f"Queue item {queue_id} not found"
351
+ }
352
+
353
+ # If completed, return with ticket ID
354
+ if item.status == QueueStatus.COMPLETED:
355
+ response = {
356
+ "queue_id": queue_id,
357
+ "status": "completed",
358
+ "ticket_id": params["ticket_id"],
359
+ "state": params["target_state"]
360
+ }
361
+
362
+ # Add result data if available
363
+ if item.result:
364
+ if item.result.get("id"):
365
+ response["ticket_id"] = item.result["id"]
366
+ response["success"] = item.result.get("success", True)
367
+
368
+ response["message"] = f"State transition completed successfully: {response['ticket_id']} → {params['target_state']}"
369
+ return response
370
+
371
+ # If failed, return error
372
+ if item.status == QueueStatus.FAILED:
373
+ return {
374
+ "queue_id": queue_id,
375
+ "status": "failed",
376
+ "error": item.error_message or "State transition failed",
377
+ "ticket_id": params["ticket_id"]
378
+ }
379
+
380
+ # Check timeout
381
+ elapsed = asyncio.get_event_loop().time() - start_time
382
+ if elapsed > max_wait_time:
383
+ return {
384
+ "queue_id": queue_id,
385
+ "status": "timeout",
386
+ "message": f"State transition timed out after {max_wait_time} seconds. Use ticket_status with queue_id to check status.",
387
+ "ticket_id": params["ticket_id"]
388
+ }
389
+
390
+ # Wait before next poll
391
+ await asyncio.sleep(poll_interval)
228
392
 
229
393
  async def _handle_comment(self, params: Dict[str, Any]) -> Dict[str, Any]:
230
394
  """Handle comment operations."""
@@ -298,6 +462,144 @@ class MCPTicketServer:
298
462
 
299
463
  return response
300
464
 
465
+ async def _handle_create_pr(self, params: Dict[str, Any]) -> Dict[str, Any]:
466
+ """Handle PR creation for a ticket."""
467
+ ticket_id = params.get("ticket_id")
468
+ if not ticket_id:
469
+ raise ValueError("ticket_id is required")
470
+
471
+ # Check if adapter supports PR creation
472
+ adapter_name = self.adapter.__class__.__name__.lower()
473
+
474
+ if "github" in adapter_name:
475
+ # GitHub adapter supports direct PR creation
476
+ from ..adapters.github import GitHubAdapter
477
+ if isinstance(self.adapter, GitHubAdapter):
478
+ try:
479
+ result = await self.adapter.create_pull_request(
480
+ ticket_id=ticket_id,
481
+ base_branch=params.get("base_branch", "main"),
482
+ head_branch=params.get("head_branch"),
483
+ title=params.get("title"),
484
+ body=params.get("body"),
485
+ draft=params.get("draft", False),
486
+ )
487
+ return {
488
+ "success": True,
489
+ "pr_number": result.get("number"),
490
+ "pr_url": result.get("url"),
491
+ "branch": result.get("branch"),
492
+ "linked_issue": result.get("linked_issue"),
493
+ "message": f"Pull request created successfully: {result.get('url')}",
494
+ }
495
+ except Exception as e:
496
+ return {
497
+ "success": False,
498
+ "error": str(e),
499
+ "ticket_id": ticket_id,
500
+ }
501
+ elif "linear" in adapter_name:
502
+ # Linear adapter needs GitHub config for PR creation
503
+ from ..adapters.linear import LinearAdapter
504
+ if isinstance(self.adapter, LinearAdapter):
505
+ # For Linear, we prepare the branch and metadata but can't create the actual PR
506
+ # without GitHub integration configured
507
+ try:
508
+ github_config = {
509
+ "owner": params.get("github_owner"),
510
+ "repo": params.get("github_repo"),
511
+ "base_branch": params.get("base_branch", "main"),
512
+ "head_branch": params.get("head_branch"),
513
+ }
514
+
515
+ # Validate GitHub config for Linear
516
+ if not github_config.get("owner") or not github_config.get("repo"):
517
+ return {
518
+ "success": False,
519
+ "error": "GitHub owner and repo are required for Linear PR creation",
520
+ "ticket_id": ticket_id,
521
+ }
522
+
523
+ result = await self.adapter.create_pull_request_for_issue(
524
+ ticket_id=ticket_id,
525
+ github_config=github_config,
526
+ )
527
+ return {
528
+ "success": True,
529
+ "branch_name": result.get("branch_name"),
530
+ "ticket_id": ticket_id,
531
+ "message": result.get("message"),
532
+ "github_config": {
533
+ "owner": result.get("github_owner"),
534
+ "repo": result.get("github_repo"),
535
+ "base_branch": result.get("base_branch"),
536
+ },
537
+ }
538
+ except Exception as e:
539
+ return {
540
+ "success": False,
541
+ "error": str(e),
542
+ "ticket_id": ticket_id,
543
+ }
544
+ else:
545
+ return {
546
+ "success": False,
547
+ "error": f"PR creation not supported for adapter: {adapter_name}",
548
+ "ticket_id": ticket_id,
549
+ }
550
+
551
+ async def _handle_link_pr(self, params: Dict[str, Any]) -> Dict[str, Any]:
552
+ """Handle linking an existing PR to a ticket."""
553
+ ticket_id = params.get("ticket_id")
554
+ pr_url = params.get("pr_url")
555
+
556
+ if not ticket_id:
557
+ raise ValueError("ticket_id is required")
558
+ if not pr_url:
559
+ raise ValueError("pr_url is required")
560
+
561
+ adapter_name = self.adapter.__class__.__name__.lower()
562
+
563
+ if "github" in adapter_name:
564
+ from ..adapters.github import GitHubAdapter
565
+ if isinstance(self.adapter, GitHubAdapter):
566
+ try:
567
+ result = await self.adapter.link_existing_pull_request(
568
+ ticket_id=ticket_id,
569
+ pr_url=pr_url,
570
+ )
571
+ return result
572
+ except Exception as e:
573
+ return {
574
+ "success": False,
575
+ "error": str(e),
576
+ "ticket_id": ticket_id,
577
+ "pr_url": pr_url,
578
+ }
579
+ elif "linear" in adapter_name:
580
+ from ..adapters.linear import LinearAdapter
581
+ if isinstance(self.adapter, LinearAdapter):
582
+ try:
583
+ result = await self.adapter.link_to_pull_request(
584
+ ticket_id=ticket_id,
585
+ pr_url=pr_url,
586
+ )
587
+ return result
588
+ except Exception as e:
589
+ return {
590
+ "success": False,
591
+ "error": str(e),
592
+ "ticket_id": ticket_id,
593
+ "pr_url": pr_url,
594
+ }
595
+ else:
596
+ return {
597
+ "success": False,
598
+ "error": f"PR linking not supported for adapter: {adapter_name}",
599
+ "ticket_id": ticket_id,
600
+ "pr_url": pr_url,
601
+ }
602
+
301
603
  async def _handle_initialize(self, params: Dict[str, Any]) -> Dict[str, Any]:
302
604
  """Handle initialize request from MCP client.
303
605
 
@@ -324,6 +626,34 @@ class MCPTicketServer:
324
626
  """List available MCP tools."""
325
627
  return {
326
628
  "tools": [
629
+ {
630
+ "name": "ticket_create_pr",
631
+ "description": "Create a GitHub PR linked to a ticket",
632
+ "inputSchema": {
633
+ "type": "object",
634
+ "properties": {
635
+ "ticket_id": {"type": "string", "description": "Ticket ID to link the PR to"},
636
+ "base_branch": {"type": "string", "description": "Target branch for the PR", "default": "main"},
637
+ "head_branch": {"type": "string", "description": "Source branch name (auto-generated if not provided)"},
638
+ "title": {"type": "string", "description": "PR title (uses ticket title if not provided)"},
639
+ "body": {"type": "string", "description": "PR description (auto-generated with issue link if not provided)"},
640
+ "draft": {"type": "boolean", "description": "Create as draft PR", "default": False},
641
+ },
642
+ "required": ["ticket_id"]
643
+ }
644
+ },
645
+ {
646
+ "name": "ticket_link_pr",
647
+ "description": "Link an existing PR to a ticket",
648
+ "inputSchema": {
649
+ "type": "object",
650
+ "properties": {
651
+ "ticket_id": {"type": "string", "description": "Ticket ID to link the PR to"},
652
+ "pr_url": {"type": "string", "description": "GitHub PR URL to link"},
653
+ },
654
+ "required": ["ticket_id", "pr_url"]
655
+ }
656
+ },
327
657
  {
328
658
  "name": "ticket_create",
329
659
  "description": "Create a new ticket",
@@ -428,6 +758,10 @@ class MCPTicketServer:
428
758
  result = await self._handle_search(arguments)
429
759
  elif tool_name == "ticket_status":
430
760
  result = await self._handle_queue_status(arguments)
761
+ elif tool_name == "ticket_create_pr":
762
+ result = await self._handle_create_pr(arguments)
763
+ elif tool_name == "ticket_link_pr":
764
+ result = await self._handle_link_pr(arguments)
431
765
  else:
432
766
  return {
433
767
  "content": [
@@ -173,7 +173,10 @@ class Queue:
173
173
  ''', (QueueStatus.PROCESSING.value, row[0]))
174
174
  conn.commit()
175
175
 
176
- return QueueItem.from_row(row)
176
+ # Create QueueItem from row and update status
177
+ item = QueueItem.from_row(row)
178
+ item.status = QueueStatus.PROCESSING
179
+ return item
177
180
 
178
181
  return None
179
182
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-ticketer
3
- Version: 0.1.8
3
+ Version: 0.1.12
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>
@@ -33,13 +33,14 @@ Classifier: Typing :: Typed
33
33
  Requires-Python: >=3.9
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
+ Requires-Dist: gql[httpx]>=3.0.0
37
+ Requires-Dist: httpx>=0.25.0
38
+ Requires-Dist: psutil>=5.9.0
36
39
  Requires-Dist: pydantic>=2.0
37
- Requires-Dist: typer>=0.9.0
40
+ Requires-Dist: python-dotenv>=1.0.0
38
41
  Requires-Dist: rich>=13.0.0
39
- Requires-Dist: httpx>=0.25.0
42
+ Requires-Dist: typer>=0.9.0
40
43
  Requires-Dist: typing-extensions>=4.8.0
41
- Requires-Dist: python-dotenv>=1.0.0
42
- Requires-Dist: psutil>=5.9.0
43
44
  Provides-Extra: all
44
45
  Requires-Dist: mcp-ticketer[github,jira,linear,mcp]; extra == "all"
45
46
  Provides-Extra: dev
@@ -1,15 +1,18 @@
1
1
  mcp_ticketer/__init__.py,sha256=ayPQdFr6msypD06_G96a1H0bdFCT1m1wDtv8MZBpY4I,496
2
- mcp_ticketer/__version__.py,sha256=xaUaMuuCEFDRyWYQ--OHg6JhbB17oO3kulskm7AkcVA,1114
2
+ mcp_ticketer/__version__.py,sha256=2z2sS0X87sc9LRMGkMvT42tCltfdduz3SdYRWzVz6sg,1115
3
3
  mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- mcp_ticketer/adapters/__init__.py,sha256=_QRLaX38EUsL-kMvJITY0lYHvrq_ip9Qw4Q1YLavJSo,283
5
- mcp_ticketer/adapters/aitrackdown.py,sha256=ICNimTtF6rPajuVoVEpmdw2TfjYjnWvao8prUwukNn0,15210
6
- mcp_ticketer/adapters/github.py,sha256=5vv_BwjPTJOY0sLFQv342Cz2u8PtS51RV7AK0-NEsLo,35357
4
+ mcp_ticketer/adapters/__init__.py,sha256=K_1egvhHb5F_7yFceUx2YzPGEoc7vX-q8dMVaS4K6gw,356
5
+ mcp_ticketer/adapters/aitrackdown.py,sha256=gqS_N6VGLoG5itUu17ANG5SefaAITYoW-t2xL9SrY-Y,15372
6
+ mcp_ticketer/adapters/github.py,sha256=onT8NhYaf9fIw2eCOTbZSkk7q4IoM7ZADRvRl9qrUz8,43850
7
+ mcp_ticketer/adapters/hybrid.py,sha256=H9B-pfWmDKXO3GgzxB8undEcZTMzLz_1a6zWhj7xfR0,18556
7
8
  mcp_ticketer/adapters/jira.py,sha256=rd-8PseTsRyQNPjsrUJ8vJ8vfBpa6HWFBieOUyvw0Tg,28954
8
- mcp_ticketer/adapters/linear.py,sha256=PYqR30h223un50_Z-0lepPyIasK2uVHyL11mfPqtWV0,44119
9
+ mcp_ticketer/adapters/linear.py,sha256=neTxVy-QD23tTI7XKtnc5CBCpm3yVCULlgxG5oFSQI4,51752
9
10
  mcp_ticketer/cache/__init__.py,sha256=MSi3GLXancfP2-edPC9TFAJk7r0j6H5-XmpMHnkGPbI,137
10
11
  mcp_ticketer/cache/memory.py,sha256=gTzv-xF7qGfiYVUjG7lnzo0ZcqgXQajMl4NAYUcaytg,5133
11
12
  mcp_ticketer/cli/__init__.py,sha256=YeljyLtv906TqkvRuEPhmKO-Uk0CberQ9I6kx1tx2UA,88
12
- mcp_ticketer/cli/main.py,sha256=sGQhyaPZhCZpHM5-1aqaW3KJTfkSv2LteIKlXdavkSQ,27774
13
+ mcp_ticketer/cli/configure.py,sha256=etFutvc0QpaVDMOsZiiN7wKuaT98Od1Tj9W6lsEWw5A,16351
14
+ mcp_ticketer/cli/main.py,sha256=K-Onbn5xla4SGpB1SD1tlby7cdEH44w4le-oKeDt6uI,30338
15
+ mcp_ticketer/cli/migrate_config.py,sha256=iZIstnlr9vkhiW_MlnSyJOkMi4KHQqrZ6Hz1ECD_VUk,6045
13
16
  mcp_ticketer/cli/queue_commands.py,sha256=f3pEHKZ43dBHEIoCBvdfvjfMB9_WJltps9ATwTzorY0,8160
14
17
  mcp_ticketer/cli/utils.py,sha256=NxsS91vKA8xZnDXKU2y0Gcyc4I_ctRyJj-wT7Xd1Q_Q,18589
15
18
  mcp_ticketer/core/__init__.py,sha256=NA-rDvwuAOZ9sUZVYJOWp8bR6mOBG8w_5lpWTT75JNI,318
@@ -18,18 +21,19 @@ mcp_ticketer/core/config.py,sha256=9a2bksbcFr7KXeHSPY6KoSP5Pzt54utYPCmbM-1QKmk,1
18
21
  mcp_ticketer/core/http_client.py,sha256=RM9CEMNcuRb-FxhAijmM_FeBMgxgh1OII9HIPBdJue0,13855
19
22
  mcp_ticketer/core/mappers.py,sha256=8I4jcqDqoQEdWlteDMpVeVF3Wo0fDCkmFPRr8oNv8gA,16933
20
23
  mcp_ticketer/core/models.py,sha256=K-bLuU_DNNVgjHnVFzAIbSa0kJwT2I3Hj24sCklwIYo,4374
24
+ mcp_ticketer/core/project_config.py,sha256=uVhlA9r6GI7h-fWCJeM_s4VMbbj8E7t4QGGOIoC3jd0,19913
21
25
  mcp_ticketer/core/registry.py,sha256=fwje0fnjp0YKPZ0SrVWk82SMNLs7CD0JlHQmx7SigNo,3537
22
26
  mcp_ticketer/mcp/__init__.py,sha256=Bvzof9vBu6VwcXcIZK8RgKv6ycRV9tDlO-9TUmd8zqQ,122
23
- mcp_ticketer/mcp/server.py,sha256=1sl_JZCwqlgOS53cisVNGIg6a2p7H2geC4c6h7g-UvA,19574
27
+ mcp_ticketer/mcp/server.py,sha256=TDuU8ChZC2QYSRo0uGHkVReblTf--hriOjxo-pSAF_Y,34068
24
28
  mcp_ticketer/queue/__init__.py,sha256=xHBoUwor8ZdO8bIHc7nP25EsAp5Si5Co4g_8ybb7fes,230
25
29
  mcp_ticketer/queue/__main__.py,sha256=kQd6iOCKbbFqpRdbIRavuI4_G7-oE898JE4a0yLEYPE,108
26
30
  mcp_ticketer/queue/manager.py,sha256=79AH9oUxdBXH3lmJ3kIlFf2GQkWHL6XB6u5JqVWPq60,7571
27
- mcp_ticketer/queue/queue.py,sha256=UgbIChWPiyI7BJNQ9DYA92D2jVMMtmVWBzotI5ML51A,11394
31
+ mcp_ticketer/queue/queue.py,sha256=z4aivQCtsH5_OUr2OfXSfnFKzugTahNnwHw0LS3ZhZc,11549
28
32
  mcp_ticketer/queue/run_worker.py,sha256=HFoykfDpOoz8OUxWbQ2Fka_UlGrYwjPVZ-DEimGFH9o,802
29
33
  mcp_ticketer/queue/worker.py,sha256=cVjHR_kfnGKAkiUg0HuXCnbKeKNBBEuj0XZHgIuIn4k,14017
30
- mcp_ticketer-0.1.8.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
31
- mcp_ticketer-0.1.8.dist-info/METADATA,sha256=cD0ozxekpO4uT0ychGnrtCNJ7Tig8NwrotX-T2Ri_RA,11177
32
- mcp_ticketer-0.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
- mcp_ticketer-0.1.8.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
34
- mcp_ticketer-0.1.8.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
35
- mcp_ticketer-0.1.8.dist-info/RECORD,,
34
+ mcp_ticketer-0.1.12.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
35
+ mcp_ticketer-0.1.12.dist-info/METADATA,sha256=7acr6QDWin0CGPNxlHTjzcCgVQ12fERtS68xhFQW-No,11211
36
+ mcp_ticketer-0.1.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ mcp_ticketer-0.1.12.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
38
+ mcp_ticketer-0.1.12.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
39
+ mcp_ticketer-0.1.12.dist-info/RECORD,,