mcp-ticketer 0.4.0__py3-none-any.whl → 0.4.2__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/__version__.py +1 -1
- mcp_ticketer/cli/auggie_configure.py +66 -0
- mcp_ticketer/cli/codex_configure.py +68 -0
- mcp_ticketer/cli/gemini_configure.py +66 -0
- mcp_ticketer/cli/main.py +276 -39
- mcp_ticketer/cli/mcp_configure.py +71 -8
- mcp_ticketer/cli/platform_commands.py +5 -15
- mcp_ticketer/cli/ticket_commands.py +15 -5
- mcp_ticketer/mcp/server_sdk.py +93 -0
- mcp_ticketer/mcp/tools/__init__.py +38 -0
- mcp_ticketer/mcp/tools/attachment_tools.py +180 -0
- mcp_ticketer/mcp/tools/bulk_tools.py +273 -0
- mcp_ticketer/mcp/tools/comment_tools.py +90 -0
- mcp_ticketer/mcp/tools/hierarchy_tools.py +383 -0
- mcp_ticketer/mcp/tools/pr_tools.py +154 -0
- mcp_ticketer/mcp/tools/search_tools.py +206 -0
- mcp_ticketer/mcp/tools/ticket_tools.py +277 -0
- {mcp_ticketer-0.4.0.dist-info → mcp_ticketer-0.4.2.dist-info}/METADATA +30 -16
- {mcp_ticketer-0.4.0.dist-info → mcp_ticketer-0.4.2.dist-info}/RECORD +23 -14
- {mcp_ticketer-0.4.0.dist-info → mcp_ticketer-0.4.2.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.4.0.dist-info → mcp_ticketer-0.4.2.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.4.0.dist-info → mcp_ticketer-0.4.2.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.4.0.dist-info → mcp_ticketer-0.4.2.dist-info}/top_level.txt +0 -0
mcp_ticketer/__version__.py
CHANGED
|
@@ -138,6 +138,72 @@ def create_auggie_server_config(
|
|
|
138
138
|
return config
|
|
139
139
|
|
|
140
140
|
|
|
141
|
+
def remove_auggie_mcp(dry_run: bool = False) -> None:
|
|
142
|
+
"""Remove mcp-ticketer from Auggie CLI configuration.
|
|
143
|
+
|
|
144
|
+
IMPORTANT: Auggie CLI ONLY supports global configuration.
|
|
145
|
+
This will remove mcp-ticketer from ~/.augment/settings.json.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
dry_run: Show what would be removed without making changes
|
|
149
|
+
|
|
150
|
+
"""
|
|
151
|
+
# Step 1: Find Auggie config location
|
|
152
|
+
console.print("[cyan]🔍 Removing Auggie CLI global configuration...[/cyan]")
|
|
153
|
+
console.print(
|
|
154
|
+
"[yellow]⚠ NOTE: Auggie only supports global configuration (affects all projects)[/yellow]"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
auggie_config_path = find_auggie_config()
|
|
158
|
+
console.print(f"[dim]Config location: {auggie_config_path}[/dim]")
|
|
159
|
+
|
|
160
|
+
# Step 2: Check if config file exists
|
|
161
|
+
if not auggie_config_path.exists():
|
|
162
|
+
console.print(
|
|
163
|
+
f"[yellow]⚠ No configuration found at {auggie_config_path}[/yellow]"
|
|
164
|
+
)
|
|
165
|
+
console.print("[dim]mcp-ticketer is not configured for Auggie[/dim]")
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
# Step 3: Load existing Auggie configuration
|
|
169
|
+
auggie_config = load_auggie_config(auggie_config_path)
|
|
170
|
+
|
|
171
|
+
# Step 4: Check if mcp-ticketer is configured
|
|
172
|
+
if "mcp-ticketer" not in auggie_config.get("mcpServers", {}):
|
|
173
|
+
console.print("[yellow]⚠ mcp-ticketer is not configured[/yellow]")
|
|
174
|
+
console.print(f"[dim]No mcp-ticketer entry found in {auggie_config_path}[/dim]")
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
# Step 5: Show what would be removed (dry run or actual removal)
|
|
178
|
+
if dry_run:
|
|
179
|
+
console.print("\n[cyan]DRY RUN - Would remove:[/cyan]")
|
|
180
|
+
console.print(" Server name: mcp-ticketer")
|
|
181
|
+
console.print(f" From: {auggie_config_path}")
|
|
182
|
+
console.print(" Scope: Global (all projects)")
|
|
183
|
+
return
|
|
184
|
+
|
|
185
|
+
# Step 6: Remove mcp-ticketer from configuration
|
|
186
|
+
del auggie_config["mcpServers"]["mcp-ticketer"]
|
|
187
|
+
|
|
188
|
+
# Step 7: Save updated configuration
|
|
189
|
+
try:
|
|
190
|
+
save_auggie_config(auggie_config_path, auggie_config)
|
|
191
|
+
console.print("\n[green]✓ Successfully removed mcp-ticketer[/green]")
|
|
192
|
+
console.print(f"[dim]Configuration updated: {auggie_config_path}[/dim]")
|
|
193
|
+
|
|
194
|
+
# Next steps
|
|
195
|
+
console.print("\n[bold cyan]Next Steps:[/bold cyan]")
|
|
196
|
+
console.print("1. Restart Auggie CLI for changes to take effect")
|
|
197
|
+
console.print("2. mcp-ticketer will no longer be available via MCP")
|
|
198
|
+
console.print(
|
|
199
|
+
"\n[yellow]⚠ Note: This removes global configuration affecting all projects[/yellow]"
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
except Exception as e:
|
|
203
|
+
console.print(f"\n[red]✗ Failed to update configuration:[/red] {e}")
|
|
204
|
+
raise
|
|
205
|
+
|
|
206
|
+
|
|
141
207
|
def configure_auggie_mcp(force: bool = False) -> None:
|
|
142
208
|
"""Configure Auggie CLI to use mcp-ticketer.
|
|
143
209
|
|
|
@@ -151,6 +151,74 @@ def create_codex_server_config(
|
|
|
151
151
|
return config
|
|
152
152
|
|
|
153
153
|
|
|
154
|
+
def remove_codex_mcp(dry_run: bool = False) -> None:
|
|
155
|
+
"""Remove mcp-ticketer from Codex CLI configuration.
|
|
156
|
+
|
|
157
|
+
IMPORTANT: Codex CLI ONLY supports global configuration at ~/.codex/config.toml.
|
|
158
|
+
This will remove mcp-ticketer from the global configuration.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
dry_run: Show what would be removed without making changes
|
|
162
|
+
|
|
163
|
+
"""
|
|
164
|
+
# Step 1: Find Codex config location (always global)
|
|
165
|
+
console.print("[cyan]🔍 Removing Codex CLI global configuration...[/cyan]")
|
|
166
|
+
console.print(
|
|
167
|
+
"[yellow]⚠ Note: Codex CLI only supports global configuration[/yellow]"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
codex_config_path = find_codex_config()
|
|
171
|
+
console.print(f"[dim]Config location: {codex_config_path}[/dim]")
|
|
172
|
+
|
|
173
|
+
# Step 2: Check if config file exists
|
|
174
|
+
if not codex_config_path.exists():
|
|
175
|
+
console.print(
|
|
176
|
+
f"[yellow]⚠ No configuration found at {codex_config_path}[/yellow]"
|
|
177
|
+
)
|
|
178
|
+
console.print("[dim]mcp-ticketer is not configured for Codex CLI[/dim]")
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
# Step 3: Load existing Codex configuration
|
|
182
|
+
codex_config = load_codex_config(codex_config_path)
|
|
183
|
+
|
|
184
|
+
# Step 4: Check if mcp-ticketer is configured
|
|
185
|
+
# NOTE: Use underscore mcp_servers, not camelCase
|
|
186
|
+
mcp_servers = codex_config.get("mcp_servers", {})
|
|
187
|
+
if "mcp-ticketer" not in mcp_servers:
|
|
188
|
+
console.print("[yellow]⚠ mcp-ticketer is not configured[/yellow]")
|
|
189
|
+
console.print(f"[dim]No mcp-ticketer entry found in {codex_config_path}[/dim]")
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
# Step 5: Show what would be removed (dry run or actual removal)
|
|
193
|
+
if dry_run:
|
|
194
|
+
console.print("\n[cyan]DRY RUN - Would remove:[/cyan]")
|
|
195
|
+
console.print(" Server name: mcp-ticketer")
|
|
196
|
+
console.print(f" From: {codex_config_path}")
|
|
197
|
+
console.print(" Scope: Global (all sessions)")
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
# Step 6: Remove mcp-ticketer from configuration
|
|
201
|
+
del codex_config["mcp_servers"]["mcp-ticketer"]
|
|
202
|
+
|
|
203
|
+
# Step 7: Save updated configuration
|
|
204
|
+
try:
|
|
205
|
+
save_codex_config(codex_config_path, codex_config)
|
|
206
|
+
console.print("\n[green]✓ Successfully removed mcp-ticketer[/green]")
|
|
207
|
+
console.print(f"[dim]Configuration updated: {codex_config_path}[/dim]")
|
|
208
|
+
|
|
209
|
+
# Next steps
|
|
210
|
+
console.print("\n[bold cyan]Next Steps:[/bold cyan]")
|
|
211
|
+
console.print("1. [bold]Restart Codex CLI[/bold] (required for changes)")
|
|
212
|
+
console.print("2. mcp-ticketer will no longer be available via MCP")
|
|
213
|
+
console.print(
|
|
214
|
+
"\n[yellow]⚠ Note: This removes global configuration affecting all Codex sessions[/yellow]"
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
except Exception as e:
|
|
218
|
+
console.print(f"\n[red]✗ Failed to update configuration:[/red] {e}")
|
|
219
|
+
raise
|
|
220
|
+
|
|
221
|
+
|
|
154
222
|
def configure_codex_mcp(force: bool = False) -> None:
|
|
155
223
|
"""Configure Codex CLI to use mcp-ticketer.
|
|
156
224
|
|
|
@@ -147,6 +147,72 @@ def create_gemini_server_config(
|
|
|
147
147
|
return config
|
|
148
148
|
|
|
149
149
|
|
|
150
|
+
def remove_gemini_mcp(
|
|
151
|
+
scope: Literal["project", "user"] = "project", dry_run: bool = False
|
|
152
|
+
) -> None:
|
|
153
|
+
"""Remove mcp-ticketer from Gemini CLI configuration.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
scope: Configuration scope - "project" or "user"
|
|
157
|
+
dry_run: Show what would be removed without making changes
|
|
158
|
+
|
|
159
|
+
"""
|
|
160
|
+
# Step 1: Find Gemini config location
|
|
161
|
+
config_type = "user-level" if scope == "user" else "project-level"
|
|
162
|
+
console.print(f"[cyan]🔍 Removing {config_type} Gemini CLI configuration...[/cyan]")
|
|
163
|
+
|
|
164
|
+
gemini_config_path = find_gemini_config(scope)
|
|
165
|
+
console.print(f"[dim]Config location: {gemini_config_path}[/dim]")
|
|
166
|
+
|
|
167
|
+
# Step 2: Check if config file exists
|
|
168
|
+
if not gemini_config_path.exists():
|
|
169
|
+
console.print(
|
|
170
|
+
f"[yellow]⚠ No configuration found at {gemini_config_path}[/yellow]"
|
|
171
|
+
)
|
|
172
|
+
console.print("[dim]mcp-ticketer is not configured for Gemini CLI[/dim]")
|
|
173
|
+
return
|
|
174
|
+
|
|
175
|
+
# Step 3: Load existing Gemini configuration
|
|
176
|
+
gemini_config = load_gemini_config(gemini_config_path)
|
|
177
|
+
|
|
178
|
+
# Step 4: Check if mcp-ticketer is configured
|
|
179
|
+
if "mcp-ticketer" not in gemini_config.get("mcpServers", {}):
|
|
180
|
+
console.print("[yellow]⚠ mcp-ticketer is not configured[/yellow]")
|
|
181
|
+
console.print(f"[dim]No mcp-ticketer entry found in {gemini_config_path}[/dim]")
|
|
182
|
+
return
|
|
183
|
+
|
|
184
|
+
# Step 5: Show what would be removed (dry run or actual removal)
|
|
185
|
+
if dry_run:
|
|
186
|
+
console.print("\n[cyan]DRY RUN - Would remove:[/cyan]")
|
|
187
|
+
console.print(" Server name: mcp-ticketer")
|
|
188
|
+
console.print(f" From: {gemini_config_path}")
|
|
189
|
+
console.print(f" Scope: {config_type}")
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
# Step 6: Remove mcp-ticketer from configuration
|
|
193
|
+
del gemini_config["mcpServers"]["mcp-ticketer"]
|
|
194
|
+
|
|
195
|
+
# Step 7: Save updated configuration
|
|
196
|
+
try:
|
|
197
|
+
save_gemini_config(gemini_config_path, gemini_config)
|
|
198
|
+
console.print("\n[green]✓ Successfully removed mcp-ticketer[/green]")
|
|
199
|
+
console.print(f"[dim]Configuration updated: {gemini_config_path}[/dim]")
|
|
200
|
+
|
|
201
|
+
# Next steps
|
|
202
|
+
console.print("\n[bold cyan]Next Steps:[/bold cyan]")
|
|
203
|
+
if scope == "user":
|
|
204
|
+
console.print("1. Gemini CLI global configuration updated")
|
|
205
|
+
console.print("2. mcp-ticketer will no longer be available in any project")
|
|
206
|
+
else:
|
|
207
|
+
console.print("1. Gemini CLI project configuration updated")
|
|
208
|
+
console.print("2. mcp-ticketer will no longer be available in this project")
|
|
209
|
+
console.print("3. Restart Gemini CLI if currently running")
|
|
210
|
+
|
|
211
|
+
except Exception as e:
|
|
212
|
+
console.print(f"\n[red]✗ Failed to update configuration:[/red] {e}")
|
|
213
|
+
raise
|
|
214
|
+
|
|
215
|
+
|
|
150
216
|
def configure_gemini_mcp(
|
|
151
217
|
scope: Literal["project", "user"] = "project", force: bool = False
|
|
152
218
|
) -> None:
|
mcp_ticketer/cli/main.py
CHANGED
|
@@ -891,7 +891,8 @@ def _show_next_steps(
|
|
|
891
891
|
console.print("[dim]Run 'mcp-ticketer --help' for more commands[/dim]")
|
|
892
892
|
|
|
893
893
|
|
|
894
|
-
|
|
894
|
+
# Keep the old install command as deprecated alias to init
|
|
895
|
+
@app.command(deprecated=True, hidden=True)
|
|
895
896
|
def install(
|
|
896
897
|
adapter: Optional[str] = typer.Option(
|
|
897
898
|
None,
|
|
@@ -941,26 +942,14 @@ def install(
|
|
|
941
942
|
None, "--github-token", help="GitHub Personal Access Token"
|
|
942
943
|
),
|
|
943
944
|
) -> None:
|
|
944
|
-
"""
|
|
945
|
-
|
|
946
|
-
This command is synonymous with 'init' and 'setup' - all three provide
|
|
947
|
-
identical functionality with interactive prompts to guide you through
|
|
948
|
-
configuring MCP Ticketer for your preferred ticket management system.
|
|
949
|
-
|
|
950
|
-
Examples:
|
|
951
|
-
# Interactive setup (same as 'init' and 'setup')
|
|
952
|
-
mcp-ticketer install
|
|
945
|
+
"""DEPRECATED: Use 'mcp-ticketer init' instead.
|
|
953
946
|
|
|
954
|
-
|
|
955
|
-
mcp-ticketer install --adapter linear
|
|
956
|
-
|
|
957
|
-
# Initialize for different project
|
|
958
|
-
mcp-ticketer install --path /path/to/project
|
|
959
|
-
|
|
960
|
-
# Save globally (not recommended)
|
|
961
|
-
mcp-ticketer install --global
|
|
947
|
+
This command is deprecated. Use 'mcp-ticketer init' for project initialization.
|
|
962
948
|
|
|
963
949
|
"""
|
|
950
|
+
console.print(
|
|
951
|
+
"[yellow]⚠️ 'install' is deprecated. Use 'mcp-ticketer init' instead.[/yellow]\n"
|
|
952
|
+
)
|
|
964
953
|
# Call init with all parameters
|
|
965
954
|
init(
|
|
966
955
|
adapter=adapter,
|
|
@@ -1149,7 +1138,9 @@ def old_queue_status_command():
|
|
|
1149
1138
|
|
|
1150
1139
|
DEPRECATED: Use 'mcp-ticketer queue status' instead.
|
|
1151
1140
|
"""
|
|
1152
|
-
console.print(
|
|
1141
|
+
console.print(
|
|
1142
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer queue status' instead.[/yellow]\n"
|
|
1143
|
+
)
|
|
1153
1144
|
|
|
1154
1145
|
queue = Queue()
|
|
1155
1146
|
manager = WorkerManager()
|
|
@@ -1192,7 +1183,9 @@ def old_queue_health_command(
|
|
|
1192
1183
|
|
|
1193
1184
|
DEPRECATED: Use 'mcp-ticketer queue health' instead.
|
|
1194
1185
|
"""
|
|
1195
|
-
console.print(
|
|
1186
|
+
console.print(
|
|
1187
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer queue health' instead.[/yellow]\n"
|
|
1188
|
+
)
|
|
1196
1189
|
health_monitor = QueueHealthMonitor()
|
|
1197
1190
|
health = health_monitor.check_health()
|
|
1198
1191
|
|
|
@@ -1294,7 +1287,9 @@ def create(
|
|
|
1294
1287
|
|
|
1295
1288
|
DEPRECATED: Use 'mcp-ticketer ticket create' instead.
|
|
1296
1289
|
"""
|
|
1297
|
-
console.print(
|
|
1290
|
+
console.print(
|
|
1291
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket create' instead.[/yellow]\n"
|
|
1292
|
+
)
|
|
1298
1293
|
|
|
1299
1294
|
# IMMEDIATE HEALTH CHECK - Critical for reliability
|
|
1300
1295
|
health_monitor = QueueHealthMonitor()
|
|
@@ -1508,7 +1503,9 @@ def list_tickets(
|
|
|
1508
1503
|
|
|
1509
1504
|
DEPRECATED: Use 'mcp-ticketer ticket list' instead.
|
|
1510
1505
|
"""
|
|
1511
|
-
console.print(
|
|
1506
|
+
console.print(
|
|
1507
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket list' instead.[/yellow]\n"
|
|
1508
|
+
)
|
|
1512
1509
|
|
|
1513
1510
|
async def _list():
|
|
1514
1511
|
adapter_instance = get_adapter(
|
|
@@ -1562,7 +1559,9 @@ def show(
|
|
|
1562
1559
|
|
|
1563
1560
|
DEPRECATED: Use 'mcp-ticketer ticket show' instead.
|
|
1564
1561
|
"""
|
|
1565
|
-
console.print(
|
|
1562
|
+
console.print(
|
|
1563
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket show' instead.[/yellow]\n"
|
|
1564
|
+
)
|
|
1566
1565
|
|
|
1567
1566
|
async def _show():
|
|
1568
1567
|
adapter_instance = get_adapter(
|
|
@@ -1616,7 +1615,9 @@ def comment(
|
|
|
1616
1615
|
|
|
1617
1616
|
DEPRECATED: Use 'mcp-ticketer ticket comment' instead.
|
|
1618
1617
|
"""
|
|
1619
|
-
console.print(
|
|
1618
|
+
console.print(
|
|
1619
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket comment' instead.[/yellow]\n"
|
|
1620
|
+
)
|
|
1620
1621
|
|
|
1621
1622
|
async def _comment():
|
|
1622
1623
|
adapter_instance = get_adapter(
|
|
@@ -1665,7 +1666,9 @@ def update(
|
|
|
1665
1666
|
|
|
1666
1667
|
DEPRECATED: Use 'mcp-ticketer ticket update' instead.
|
|
1667
1668
|
"""
|
|
1668
|
-
console.print(
|
|
1669
|
+
console.print(
|
|
1670
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket update' instead.[/yellow]\n"
|
|
1671
|
+
)
|
|
1669
1672
|
updates = {}
|
|
1670
1673
|
if title:
|
|
1671
1674
|
updates["title"] = title
|
|
@@ -1738,7 +1741,9 @@ def transition(
|
|
|
1738
1741
|
mcp-ticketer ticket transition BTA-215 done
|
|
1739
1742
|
|
|
1740
1743
|
"""
|
|
1741
|
-
console.print(
|
|
1744
|
+
console.print(
|
|
1745
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket transition' instead.[/yellow]\n"
|
|
1746
|
+
)
|
|
1742
1747
|
|
|
1743
1748
|
# Determine which state to use (prefer flag over positional)
|
|
1744
1749
|
target_state = state if state is not None else state_positional
|
|
@@ -1797,7 +1802,9 @@ def search(
|
|
|
1797
1802
|
|
|
1798
1803
|
DEPRECATED: Use 'mcp-ticketer ticket search' instead.
|
|
1799
1804
|
"""
|
|
1800
|
-
console.print(
|
|
1805
|
+
console.print(
|
|
1806
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket search' instead.[/yellow]\n"
|
|
1807
|
+
)
|
|
1801
1808
|
|
|
1802
1809
|
async def _search():
|
|
1803
1810
|
adapter_instance = get_adapter(
|
|
@@ -1935,13 +1942,241 @@ mcp_app = typer.Typer(
|
|
|
1935
1942
|
)
|
|
1936
1943
|
|
|
1937
1944
|
|
|
1945
|
+
@app.command()
|
|
1946
|
+
def install(
|
|
1947
|
+
platform: Optional[str] = typer.Argument(
|
|
1948
|
+
None,
|
|
1949
|
+
help="Platform to install (claude-code, claude-desktop, auggie, gemini, codex)",
|
|
1950
|
+
),
|
|
1951
|
+
dry_run: bool = typer.Option(
|
|
1952
|
+
False, "--dry-run", help="Show what would be done without making changes"
|
|
1953
|
+
),
|
|
1954
|
+
) -> None:
|
|
1955
|
+
"""Install mcp-ticketer for AI platforms.
|
|
1956
|
+
|
|
1957
|
+
Without arguments, shows installation status and available platforms.
|
|
1958
|
+
With a platform argument, installs MCP configuration for that platform.
|
|
1959
|
+
|
|
1960
|
+
Each platform gets the right configuration automatically:
|
|
1961
|
+
- claude-code: Project-level MCP server
|
|
1962
|
+
- claude-desktop: Global MCP server
|
|
1963
|
+
- auggie: Project-level MCP server
|
|
1964
|
+
- gemini: Project-level MCP server
|
|
1965
|
+
- codex: Project-level MCP server
|
|
1966
|
+
|
|
1967
|
+
Examples:
|
|
1968
|
+
# Show status and available platforms
|
|
1969
|
+
mcp-ticketer install
|
|
1970
|
+
|
|
1971
|
+
# Install for Claude Code (project-level)
|
|
1972
|
+
mcp-ticketer install claude-code
|
|
1973
|
+
|
|
1974
|
+
# Install for Claude Desktop (global)
|
|
1975
|
+
mcp-ticketer install claude-desktop
|
|
1976
|
+
|
|
1977
|
+
# Install for Auggie
|
|
1978
|
+
mcp-ticketer install auggie
|
|
1979
|
+
|
|
1980
|
+
# Dry run to preview changes
|
|
1981
|
+
mcp-ticketer install claude-code --dry-run
|
|
1982
|
+
|
|
1983
|
+
"""
|
|
1984
|
+
# If no platform specified, show help message
|
|
1985
|
+
if platform is None:
|
|
1986
|
+
console.print("[green]✓[/green] mcp-ticketer CLI is already installed.\n")
|
|
1987
|
+
console.print(
|
|
1988
|
+
"[bold]To configure MCP for a specific platform, use:[/bold]\n"
|
|
1989
|
+
" mcp-ticketer install <platform>\n"
|
|
1990
|
+
)
|
|
1991
|
+
console.print("[bold]Available platforms:[/bold]")
|
|
1992
|
+
console.print(" • claude-code - Claude Code (project-level)")
|
|
1993
|
+
console.print(" • claude-desktop - Claude Desktop (global)")
|
|
1994
|
+
console.print(" • auggie - Auggie (project-level)")
|
|
1995
|
+
console.print(" • gemini - Gemini CLI (project-level)")
|
|
1996
|
+
console.print(" • codex - Codex (project-level)")
|
|
1997
|
+
return
|
|
1998
|
+
|
|
1999
|
+
# Import configuration functions
|
|
2000
|
+
from .auggie_configure import configure_auggie_mcp
|
|
2001
|
+
from .codex_configure import configure_codex_mcp
|
|
2002
|
+
from .gemini_configure import configure_gemini_mcp
|
|
2003
|
+
from .mcp_configure import configure_claude_mcp
|
|
2004
|
+
|
|
2005
|
+
# Map platform names to configuration functions
|
|
2006
|
+
platform_mapping = {
|
|
2007
|
+
"claude-code": {
|
|
2008
|
+
"func": lambda: configure_claude_mcp(global_config=False, force=True),
|
|
2009
|
+
"name": "Claude Code",
|
|
2010
|
+
},
|
|
2011
|
+
"claude-desktop": {
|
|
2012
|
+
"func": lambda: configure_claude_mcp(global_config=True, force=True),
|
|
2013
|
+
"name": "Claude Desktop",
|
|
2014
|
+
},
|
|
2015
|
+
"auggie": {
|
|
2016
|
+
"func": lambda: configure_auggie_mcp(force=True),
|
|
2017
|
+
"name": "Auggie",
|
|
2018
|
+
},
|
|
2019
|
+
"gemini": {
|
|
2020
|
+
"func": lambda: configure_gemini_mcp(scope="project", force=True),
|
|
2021
|
+
"name": "Gemini CLI",
|
|
2022
|
+
},
|
|
2023
|
+
"codex": {
|
|
2024
|
+
"func": lambda: configure_codex_mcp(force=True),
|
|
2025
|
+
"name": "Codex",
|
|
2026
|
+
},
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
if platform not in platform_mapping:
|
|
2030
|
+
console.print(f"[red]Unknown platform: {platform}[/red]")
|
|
2031
|
+
console.print("\n[bold]Available platforms:[/bold]")
|
|
2032
|
+
for p in platform_mapping.keys():
|
|
2033
|
+
console.print(f" • {p}")
|
|
2034
|
+
raise typer.Exit(1)
|
|
2035
|
+
|
|
2036
|
+
config = platform_mapping[platform]
|
|
2037
|
+
|
|
2038
|
+
if dry_run:
|
|
2039
|
+
console.print(f"[cyan]DRY RUN - Would install for {config['name']}[/cyan]")
|
|
2040
|
+
return
|
|
2041
|
+
|
|
2042
|
+
try:
|
|
2043
|
+
config["func"]()
|
|
2044
|
+
except Exception as e:
|
|
2045
|
+
console.print(f"[red]Installation failed: {e}[/red]")
|
|
2046
|
+
raise typer.Exit(1)
|
|
2047
|
+
|
|
2048
|
+
|
|
2049
|
+
@app.command()
|
|
2050
|
+
def remove(
|
|
2051
|
+
platform: Optional[str] = typer.Argument(
|
|
2052
|
+
None,
|
|
2053
|
+
help="Platform to remove (claude-code, claude-desktop, auggie, gemini, codex)",
|
|
2054
|
+
),
|
|
2055
|
+
dry_run: bool = typer.Option(
|
|
2056
|
+
False, "--dry-run", help="Show what would be done without making changes"
|
|
2057
|
+
),
|
|
2058
|
+
) -> None:
|
|
2059
|
+
"""Remove mcp-ticketer from AI platforms.
|
|
2060
|
+
|
|
2061
|
+
Without arguments, shows help and available platforms.
|
|
2062
|
+
With a platform argument, removes MCP configuration for that platform.
|
|
2063
|
+
|
|
2064
|
+
Examples:
|
|
2065
|
+
# Remove from Claude Code (project-level)
|
|
2066
|
+
mcp-ticketer remove claude-code
|
|
2067
|
+
|
|
2068
|
+
# Remove from Claude Desktop (global)
|
|
2069
|
+
mcp-ticketer remove claude-desktop
|
|
2070
|
+
|
|
2071
|
+
# Remove from Auggie
|
|
2072
|
+
mcp-ticketer remove auggie
|
|
2073
|
+
|
|
2074
|
+
# Dry run to preview changes
|
|
2075
|
+
mcp-ticketer remove claude-code --dry-run
|
|
2076
|
+
|
|
2077
|
+
"""
|
|
2078
|
+
# If no platform specified, show help message
|
|
2079
|
+
if platform is None:
|
|
2080
|
+
console.print("[bold]Remove mcp-ticketer from AI platforms[/bold]\n")
|
|
2081
|
+
console.print("Usage: mcp-ticketer remove <platform>\n")
|
|
2082
|
+
console.print("[bold]Available platforms:[/bold]")
|
|
2083
|
+
console.print(" • claude-code - Claude Code (project-level)")
|
|
2084
|
+
console.print(" • claude-desktop - Claude Desktop (global)")
|
|
2085
|
+
console.print(" • auggie - Auggie (global)")
|
|
2086
|
+
console.print(" • gemini - Gemini CLI (project-level by default)")
|
|
2087
|
+
console.print(" • codex - Codex (global)")
|
|
2088
|
+
return
|
|
2089
|
+
|
|
2090
|
+
# Import removal functions
|
|
2091
|
+
from .auggie_configure import remove_auggie_mcp
|
|
2092
|
+
from .codex_configure import remove_codex_mcp
|
|
2093
|
+
from .gemini_configure import remove_gemini_mcp
|
|
2094
|
+
from .mcp_configure import remove_claude_mcp
|
|
2095
|
+
|
|
2096
|
+
# Map platform names to removal functions
|
|
2097
|
+
platform_mapping = {
|
|
2098
|
+
"claude-code": {
|
|
2099
|
+
"func": lambda: remove_claude_mcp(global_config=False, dry_run=dry_run),
|
|
2100
|
+
"name": "Claude Code",
|
|
2101
|
+
},
|
|
2102
|
+
"claude-desktop": {
|
|
2103
|
+
"func": lambda: remove_claude_mcp(global_config=True, dry_run=dry_run),
|
|
2104
|
+
"name": "Claude Desktop",
|
|
2105
|
+
},
|
|
2106
|
+
"auggie": {
|
|
2107
|
+
"func": lambda: remove_auggie_mcp(dry_run=dry_run),
|
|
2108
|
+
"name": "Auggie",
|
|
2109
|
+
},
|
|
2110
|
+
"gemini": {
|
|
2111
|
+
"func": lambda: remove_gemini_mcp(scope="project", dry_run=dry_run),
|
|
2112
|
+
"name": "Gemini CLI",
|
|
2113
|
+
},
|
|
2114
|
+
"codex": {
|
|
2115
|
+
"func": lambda: remove_codex_mcp(dry_run=dry_run),
|
|
2116
|
+
"name": "Codex",
|
|
2117
|
+
},
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
if platform not in platform_mapping:
|
|
2121
|
+
console.print(f"[red]Unknown platform: {platform}[/red]")
|
|
2122
|
+
console.print("\n[bold]Available platforms:[/bold]")
|
|
2123
|
+
for p in platform_mapping.keys():
|
|
2124
|
+
console.print(f" • {p}")
|
|
2125
|
+
raise typer.Exit(1)
|
|
2126
|
+
|
|
2127
|
+
config = platform_mapping[platform]
|
|
2128
|
+
|
|
2129
|
+
try:
|
|
2130
|
+
config["func"]()
|
|
2131
|
+
except Exception as e:
|
|
2132
|
+
console.print(f"[red]Removal failed: {e}[/red]")
|
|
2133
|
+
raise typer.Exit(1)
|
|
2134
|
+
|
|
2135
|
+
|
|
2136
|
+
@app.command()
|
|
2137
|
+
def uninstall(
|
|
2138
|
+
platform: Optional[str] = typer.Argument(
|
|
2139
|
+
None,
|
|
2140
|
+
help="Platform to uninstall (claude-code, claude-desktop, auggie, gemini, codex)",
|
|
2141
|
+
),
|
|
2142
|
+
dry_run: bool = typer.Option(
|
|
2143
|
+
False, "--dry-run", help="Show what would be done without making changes"
|
|
2144
|
+
),
|
|
2145
|
+
) -> None:
|
|
2146
|
+
"""Uninstall mcp-ticketer from AI platforms (alias for remove).
|
|
2147
|
+
|
|
2148
|
+
This is an alias for the 'remove' command.
|
|
2149
|
+
|
|
2150
|
+
Without arguments, shows help and available platforms.
|
|
2151
|
+
With a platform argument, removes MCP configuration for that platform.
|
|
2152
|
+
|
|
2153
|
+
Examples:
|
|
2154
|
+
# Uninstall from Claude Code (project-level)
|
|
2155
|
+
mcp-ticketer uninstall claude-code
|
|
2156
|
+
|
|
2157
|
+
# Uninstall from Claude Desktop (global)
|
|
2158
|
+
mcp-ticketer uninstall claude-desktop
|
|
2159
|
+
|
|
2160
|
+
# Uninstall from Auggie
|
|
2161
|
+
mcp-ticketer uninstall auggie
|
|
2162
|
+
|
|
2163
|
+
# Dry run to preview changes
|
|
2164
|
+
mcp-ticketer uninstall claude-code --dry-run
|
|
2165
|
+
|
|
2166
|
+
"""
|
|
2167
|
+
# Call the remove command with the same parameters
|
|
2168
|
+
remove(platform=platform, dry_run=dry_run)
|
|
2169
|
+
|
|
2170
|
+
|
|
1938
2171
|
@app.command(deprecated=True, hidden=True)
|
|
1939
2172
|
def check(queue_id: str = typer.Argument(..., help="Queue ID to check")):
|
|
1940
2173
|
"""Check status of a queued operation.
|
|
1941
2174
|
|
|
1942
2175
|
DEPRECATED: Use 'mcp-ticketer ticket check' instead.
|
|
1943
2176
|
"""
|
|
1944
|
-
console.print(
|
|
2177
|
+
console.print(
|
|
2178
|
+
"[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket check' instead.[/yellow]\n"
|
|
2179
|
+
)
|
|
1945
2180
|
queue = Queue()
|
|
1946
2181
|
item = queue.get_item(queue_id)
|
|
1947
2182
|
|
|
@@ -1981,8 +2216,8 @@ def check(queue_id: str = typer.Argument(..., help="Queue ID to check")):
|
|
|
1981
2216
|
console.print(f"\nRetry Count: {item.retry_count}")
|
|
1982
2217
|
|
|
1983
2218
|
|
|
1984
|
-
@
|
|
1985
|
-
def
|
|
2219
|
+
@mcp_app.command(name="serve")
|
|
2220
|
+
def mcp_serve(
|
|
1986
2221
|
adapter: Optional[AdapterType] = typer.Option(
|
|
1987
2222
|
None, "--adapter", "-a", help="Override default adapter type"
|
|
1988
2223
|
),
|
|
@@ -1993,7 +2228,7 @@ def serve(
|
|
|
1993
2228
|
"""Start MCP server for JSON-RPC communication over stdio.
|
|
1994
2229
|
|
|
1995
2230
|
This command is used by Claude Code/Desktop when connecting to the MCP server.
|
|
1996
|
-
You typically don't need to run this manually - use 'mcp-ticketer
|
|
2231
|
+
You typically don't need to run this manually - use 'mcp-ticketer install add' to configure.
|
|
1997
2232
|
|
|
1998
2233
|
Configuration Resolution:
|
|
1999
2234
|
- When MCP server starts, it uses the current working directory (cwd)
|
|
@@ -2003,7 +2238,8 @@ def serve(
|
|
|
2003
2238
|
2. Global: ~/.mcp-ticketer/config.json
|
|
2004
2239
|
3. Default: aitrackdown adapter with .aitrackdown base path
|
|
2005
2240
|
"""
|
|
2006
|
-
from ..mcp.
|
|
2241
|
+
from ..mcp.server_sdk import configure_adapter
|
|
2242
|
+
from ..mcp.server_sdk import main as sdk_main
|
|
2007
2243
|
|
|
2008
2244
|
# Load configuration (respects project-specific config in cwd)
|
|
2009
2245
|
config = load_config()
|
|
@@ -2044,21 +2280,22 @@ def serve(
|
|
|
2044
2280
|
if sys.stderr.isatty():
|
|
2045
2281
|
# Only print if stderr is a terminal (not redirected)
|
|
2046
2282
|
console.file = sys.stderr
|
|
2047
|
-
console.print(
|
|
2283
|
+
console.print(
|
|
2284
|
+
f"[green]Starting MCP SDK server[/green] with {adapter_type} adapter"
|
|
2285
|
+
)
|
|
2048
2286
|
console.print(
|
|
2049
2287
|
"[dim]Server running on stdio. Send JSON-RPC requests via stdin.[/dim]"
|
|
2050
2288
|
)
|
|
2051
2289
|
|
|
2052
|
-
#
|
|
2290
|
+
# Configure adapter and run SDK server
|
|
2053
2291
|
try:
|
|
2054
|
-
|
|
2055
|
-
|
|
2292
|
+
configure_adapter(adapter_type, adapter_config)
|
|
2293
|
+
sdk_main()
|
|
2056
2294
|
except KeyboardInterrupt:
|
|
2057
|
-
#
|
|
2295
|
+
# Send this to stderr
|
|
2058
2296
|
if sys.stderr.isatty():
|
|
2059
2297
|
console.print("\n[yellow]Server stopped by user[/yellow]")
|
|
2060
|
-
|
|
2061
|
-
asyncio.run(server.stop())
|
|
2298
|
+
sys.exit(0)
|
|
2062
2299
|
except Exception as e:
|
|
2063
2300
|
# Log error to stderr
|
|
2064
2301
|
sys.stderr.write(f"MCP server error: {e}\n")
|