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

Files changed (87) hide show
  1. mcp_ticketer/__init__.py +10 -10
  2. mcp_ticketer/__version__.py +1 -1
  3. mcp_ticketer/adapters/aitrackdown.py +385 -6
  4. mcp_ticketer/adapters/asana/adapter.py +108 -0
  5. mcp_ticketer/adapters/asana/mappers.py +14 -0
  6. mcp_ticketer/adapters/github.py +525 -11
  7. mcp_ticketer/adapters/hybrid.py +47 -5
  8. mcp_ticketer/adapters/jira.py +521 -0
  9. mcp_ticketer/adapters/linear/adapter.py +1784 -101
  10. mcp_ticketer/adapters/linear/client.py +85 -3
  11. mcp_ticketer/adapters/linear/mappers.py +96 -8
  12. mcp_ticketer/adapters/linear/queries.py +168 -1
  13. mcp_ticketer/adapters/linear/types.py +80 -4
  14. mcp_ticketer/analysis/__init__.py +56 -0
  15. mcp_ticketer/analysis/dependency_graph.py +255 -0
  16. mcp_ticketer/analysis/health_assessment.py +304 -0
  17. mcp_ticketer/analysis/orphaned.py +218 -0
  18. mcp_ticketer/analysis/project_status.py +594 -0
  19. mcp_ticketer/analysis/similarity.py +224 -0
  20. mcp_ticketer/analysis/staleness.py +266 -0
  21. mcp_ticketer/automation/__init__.py +11 -0
  22. mcp_ticketer/automation/project_updates.py +378 -0
  23. mcp_ticketer/cli/adapter_diagnostics.py +3 -1
  24. mcp_ticketer/cli/auggie_configure.py +17 -5
  25. mcp_ticketer/cli/codex_configure.py +97 -61
  26. mcp_ticketer/cli/configure.py +851 -103
  27. mcp_ticketer/cli/cursor_configure.py +314 -0
  28. mcp_ticketer/cli/diagnostics.py +13 -12
  29. mcp_ticketer/cli/discover.py +5 -0
  30. mcp_ticketer/cli/gemini_configure.py +17 -5
  31. mcp_ticketer/cli/init_command.py +880 -0
  32. mcp_ticketer/cli/instruction_commands.py +6 -0
  33. mcp_ticketer/cli/main.py +233 -3151
  34. mcp_ticketer/cli/mcp_configure.py +672 -98
  35. mcp_ticketer/cli/mcp_server_commands.py +415 -0
  36. mcp_ticketer/cli/platform_detection.py +77 -12
  37. mcp_ticketer/cli/platform_installer.py +536 -0
  38. mcp_ticketer/cli/project_update_commands.py +350 -0
  39. mcp_ticketer/cli/setup_command.py +639 -0
  40. mcp_ticketer/cli/simple_health.py +12 -10
  41. mcp_ticketer/cli/ticket_commands.py +264 -24
  42. mcp_ticketer/core/__init__.py +28 -6
  43. mcp_ticketer/core/adapter.py +166 -1
  44. mcp_ticketer/core/config.py +21 -21
  45. mcp_ticketer/core/exceptions.py +7 -1
  46. mcp_ticketer/core/label_manager.py +732 -0
  47. mcp_ticketer/core/mappers.py +31 -19
  48. mcp_ticketer/core/models.py +135 -0
  49. mcp_ticketer/core/onepassword_secrets.py +1 -1
  50. mcp_ticketer/core/priority_matcher.py +463 -0
  51. mcp_ticketer/core/project_config.py +132 -14
  52. mcp_ticketer/core/session_state.py +171 -0
  53. mcp_ticketer/core/state_matcher.py +592 -0
  54. mcp_ticketer/core/url_parser.py +425 -0
  55. mcp_ticketer/core/validators.py +69 -0
  56. mcp_ticketer/mcp/server/diagnostic_helper.py +175 -0
  57. mcp_ticketer/mcp/server/main.py +106 -25
  58. mcp_ticketer/mcp/server/routing.py +655 -0
  59. mcp_ticketer/mcp/server/server_sdk.py +58 -0
  60. mcp_ticketer/mcp/server/tools/__init__.py +31 -12
  61. mcp_ticketer/mcp/server/tools/analysis_tools.py +854 -0
  62. mcp_ticketer/mcp/server/tools/attachment_tools.py +6 -8
  63. mcp_ticketer/mcp/server/tools/bulk_tools.py +259 -202
  64. mcp_ticketer/mcp/server/tools/comment_tools.py +74 -12
  65. mcp_ticketer/mcp/server/tools/config_tools.py +1184 -136
  66. mcp_ticketer/mcp/server/tools/diagnostic_tools.py +211 -0
  67. mcp_ticketer/mcp/server/tools/hierarchy_tools.py +870 -460
  68. mcp_ticketer/mcp/server/tools/instruction_tools.py +7 -5
  69. mcp_ticketer/mcp/server/tools/label_tools.py +942 -0
  70. mcp_ticketer/mcp/server/tools/pr_tools.py +3 -7
  71. mcp_ticketer/mcp/server/tools/project_status_tools.py +158 -0
  72. mcp_ticketer/mcp/server/tools/project_update_tools.py +473 -0
  73. mcp_ticketer/mcp/server/tools/search_tools.py +180 -97
  74. mcp_ticketer/mcp/server/tools/session_tools.py +308 -0
  75. mcp_ticketer/mcp/server/tools/ticket_tools.py +1070 -123
  76. mcp_ticketer/mcp/server/tools/user_ticket_tools.py +218 -236
  77. mcp_ticketer/queue/worker.py +1 -1
  78. mcp_ticketer/utils/__init__.py +5 -0
  79. mcp_ticketer/utils/token_utils.py +246 -0
  80. mcp_ticketer-2.0.1.dist-info/METADATA +1366 -0
  81. mcp_ticketer-2.0.1.dist-info/RECORD +122 -0
  82. mcp_ticketer-0.12.0.dist-info/METADATA +0 -550
  83. mcp_ticketer-0.12.0.dist-info/RECORD +0 -91
  84. {mcp_ticketer-0.12.0.dist-info → mcp_ticketer-2.0.1.dist-info}/WHEEL +0 -0
  85. {mcp_ticketer-0.12.0.dist-info → mcp_ticketer-2.0.1.dist-info}/entry_points.txt +0 -0
  86. {mcp_ticketer-0.12.0.dist-info → mcp_ticketer-2.0.1.dist-info}/licenses/LICENSE +0 -0
  87. {mcp_ticketer-0.12.0.dist-info → mcp_ticketer-2.0.1.dist-info}/top_level.txt +0 -0
@@ -3,10 +3,43 @@
3
3
  This module implements tools for adding and retrieving comments on tickets.
4
4
  """
5
5
 
6
+ import logging
6
7
  from typing import Any
7
8
 
9
+ from ....core.adapter import BaseAdapter
8
10
  from ....core.models import Comment
9
- from ..server_sdk import get_adapter, mcp
11
+ from ....core.url_parser import is_url
12
+ from ..server_sdk import get_adapter, get_router, has_router, mcp
13
+
14
+
15
+ def _build_adapter_metadata(
16
+ adapter: BaseAdapter,
17
+ ticket_id: str | None = None,
18
+ is_routed: bool = False,
19
+ ) -> dict[str, Any]:
20
+ """Build adapter metadata for MCP responses.
21
+
22
+ Args:
23
+ adapter: The adapter that handled the operation
24
+ ticket_id: Optional ticket ID to include in metadata
25
+ is_routed: Whether this was routed via URL detection
26
+
27
+ Returns:
28
+ Dictionary with adapter metadata fields
29
+
30
+ """
31
+ metadata = {
32
+ "adapter": adapter.adapter_type,
33
+ "adapter_name": adapter.adapter_display_name,
34
+ }
35
+
36
+ if ticket_id:
37
+ metadata["ticket_id"] = ticket_id
38
+
39
+ if is_routed:
40
+ metadata["routed_from_url"] = True
41
+
42
+ return metadata
10
43
 
11
44
 
12
45
  @mcp.tool()
@@ -17,14 +50,17 @@ async def ticket_comment(
17
50
  limit: int = 10,
18
51
  offset: int = 0,
19
52
  ) -> dict[str, Any]:
20
- """Add or list comments on a ticket.
53
+ """Add or list comments on a ticket using ID or URL.
21
54
 
22
55
  This tool supports two operations:
23
56
  - 'add': Add a new comment to a ticket (requires 'text' parameter)
24
57
  - 'list': Retrieve comments from a ticket (supports pagination)
25
58
 
59
+ Supports both plain ticket IDs and full URLs from multiple platforms.
60
+ See ticket_read for supported URL formats.
61
+
26
62
  Args:
27
- ticket_id: Unique identifier of the ticket
63
+ ticket_id: Ticket ID or URL
28
64
  operation: Operation to perform - must be 'add' or 'list'
29
65
  text: Comment text (required when operation='add')
30
66
  limit: Maximum number of comments to return (used when operation='list', default: 10)
@@ -35,8 +71,6 @@ async def ticket_comment(
35
71
 
36
72
  """
37
73
  try:
38
- adapter = get_adapter()
39
-
40
74
  # Validate operation
41
75
  if operation not in ["add", "list"]:
42
76
  return {
@@ -54,29 +88,57 @@ async def ticket_comment(
54
88
 
55
89
  # Create comment object
56
90
  comment = Comment(
57
- ticket_id=ticket_id,
91
+ ticket_id=ticket_id, # Will be normalized by router if URL
58
92
  content=text,
59
93
  )
60
94
 
61
- # Add comment via adapter
62
- created = await adapter.add_comment(comment)
95
+ # Route to appropriate adapter
96
+ is_routed = False
97
+ if is_url(ticket_id) and has_router():
98
+ router = get_router()
99
+ logging.info(f"Routing add_comment for URL: {ticket_id}")
100
+ created = await router.route_add_comment(ticket_id, comment)
101
+ is_routed = True
102
+ normalized_id, _, _ = router._normalize_ticket_id(ticket_id)
103
+ adapter = router._get_adapter(
104
+ router._detect_adapter_from_url(ticket_id)
105
+ )
106
+ else:
107
+ adapter = get_adapter()
108
+ created = await adapter.add_comment(comment)
63
109
 
64
110
  return {
65
111
  "status": "completed",
112
+ **_build_adapter_metadata(adapter, created.ticket_id, is_routed),
66
113
  "operation": "add",
67
114
  "comment": created.model_dump(),
68
115
  }
69
116
 
70
117
  else: # operation == "list"
71
118
  # List comments operation
72
- comments = await adapter.get_comments(
73
- ticket_id=ticket_id, limit=limit, offset=offset
74
- )
119
+ # Route to appropriate adapter
120
+ is_routed = False
121
+ if is_url(ticket_id) and has_router():
122
+ router = get_router()
123
+ logging.info(f"Routing get_comments for URL: {ticket_id}")
124
+ comments = await router.route_get_comments(
125
+ ticket_id, limit=limit, offset=offset
126
+ )
127
+ is_routed = True
128
+ normalized_id, _, _ = router._normalize_ticket_id(ticket_id)
129
+ adapter = router._get_adapter(
130
+ router._detect_adapter_from_url(ticket_id)
131
+ )
132
+ else:
133
+ adapter = get_adapter()
134
+ comments = await adapter.get_comments(
135
+ ticket_id=ticket_id, limit=limit, offset=offset
136
+ )
75
137
 
76
138
  return {
77
139
  "status": "completed",
140
+ **_build_adapter_metadata(adapter, ticket_id, is_routed),
78
141
  "operation": "list",
79
- "ticket_id": ticket_id,
80
142
  "comments": [comment.model_dump() for comment in comments],
81
143
  "count": len(comments),
82
144
  "limit": limit,