mcp-ticketer 0.4.1__py3-none-any.whl → 0.4.3__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 +3 -12
- mcp_ticketer/__version__.py +1 -1
- mcp_ticketer/adapters/aitrackdown.py +243 -11
- mcp_ticketer/adapters/github.py +15 -14
- mcp_ticketer/adapters/hybrid.py +11 -11
- mcp_ticketer/adapters/jira.py +22 -25
- mcp_ticketer/adapters/linear/adapter.py +9 -21
- mcp_ticketer/adapters/linear/client.py +2 -1
- mcp_ticketer/adapters/linear/mappers.py +2 -1
- mcp_ticketer/cache/memory.py +6 -5
- mcp_ticketer/cli/adapter_diagnostics.py +4 -2
- mcp_ticketer/cli/auggie_configure.py +66 -0
- mcp_ticketer/cli/codex_configure.py +70 -2
- mcp_ticketer/cli/configure.py +7 -14
- mcp_ticketer/cli/diagnostics.py +2 -2
- mcp_ticketer/cli/discover.py +6 -11
- mcp_ticketer/cli/gemini_configure.py +68 -2
- mcp_ticketer/cli/linear_commands.py +6 -7
- mcp_ticketer/cli/main.py +341 -203
- mcp_ticketer/cli/mcp_configure.py +61 -2
- mcp_ticketer/cli/ticket_commands.py +27 -30
- mcp_ticketer/cli/utils.py +23 -22
- mcp_ticketer/core/__init__.py +3 -1
- mcp_ticketer/core/adapter.py +82 -13
- mcp_ticketer/core/config.py +27 -29
- mcp_ticketer/core/env_discovery.py +10 -10
- mcp_ticketer/core/env_loader.py +8 -8
- mcp_ticketer/core/http_client.py +16 -16
- mcp_ticketer/core/mappers.py +10 -10
- mcp_ticketer/core/models.py +50 -20
- mcp_ticketer/core/project_config.py +40 -34
- mcp_ticketer/core/registry.py +2 -2
- mcp_ticketer/mcp/dto.py +32 -32
- mcp_ticketer/mcp/response_builder.py +2 -2
- mcp_ticketer/mcp/server.py +17 -37
- mcp_ticketer/mcp/server_sdk.py +93 -0
- mcp_ticketer/mcp/tools/__init__.py +36 -0
- mcp_ticketer/mcp/tools/attachment_tools.py +179 -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/queue/health_monitor.py +4 -4
- mcp_ticketer/queue/manager.py +2 -2
- mcp_ticketer/queue/queue.py +16 -16
- mcp_ticketer/queue/ticket_registry.py +7 -7
- mcp_ticketer/queue/worker.py +2 -2
- {mcp_ticketer-0.4.1.dist-info → mcp_ticketer-0.4.3.dist-info}/METADATA +90 -17
- mcp_ticketer-0.4.3.dist-info/RECORD +73 -0
- mcp_ticketer-0.4.1.dist-info/RECORD +0 -64
- {mcp_ticketer-0.4.1.dist-info → mcp_ticketer-0.4.3.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.4.1.dist-info → mcp_ticketer-0.4.3.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.4.1.dist-info → mcp_ticketer-0.4.3.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.4.1.dist-info → mcp_ticketer-0.4.3.dist-info}/top_level.txt +0 -0
mcp_ticketer/cli/main.py
CHANGED
|
@@ -5,7 +5,6 @@ import json
|
|
|
5
5
|
import os
|
|
6
6
|
from enum import Enum
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import Optional
|
|
9
8
|
|
|
10
9
|
import typer
|
|
11
10
|
from dotenv import load_dotenv
|
|
@@ -21,7 +20,8 @@ from ..core.models import Comment, SearchQuery
|
|
|
21
20
|
from ..queue import Queue, QueueStatus, WorkerManager
|
|
22
21
|
from ..queue.health_monitor import HealthStatus, QueueHealthMonitor
|
|
23
22
|
from ..queue.ticket_registry import TicketRegistry
|
|
24
|
-
from .configure import configure_wizard, set_adapter_config,
|
|
23
|
+
from .configure import (configure_wizard, set_adapter_config,
|
|
24
|
+
show_current_config)
|
|
25
25
|
from .diagnostics import run_diagnostics
|
|
26
26
|
from .discover import app as discover_app
|
|
27
27
|
from .migrate_config import migrate_config_command
|
|
@@ -84,7 +84,7 @@ class AdapterType(str, Enum):
|
|
|
84
84
|
GITHUB = "github"
|
|
85
85
|
|
|
86
86
|
|
|
87
|
-
def load_config(project_dir:
|
|
87
|
+
def load_config(project_dir: Path | None = None) -> dict:
|
|
88
88
|
"""Load configuration from project-local config file ONLY.
|
|
89
89
|
|
|
90
90
|
SECURITY: This method ONLY reads from the current project directory
|
|
@@ -146,7 +146,7 @@ def load_config(project_dir: Optional[Path] = None) -> dict:
|
|
|
146
146
|
return {"adapter": "aitrackdown", "config": {"base_path": ".aitrackdown"}}
|
|
147
147
|
|
|
148
148
|
|
|
149
|
-
def _discover_from_env_files() ->
|
|
149
|
+
def _discover_from_env_files() -> str | None:
|
|
150
150
|
"""Discover adapter configuration from .env or .env.local files.
|
|
151
151
|
|
|
152
152
|
Returns:
|
|
@@ -270,7 +270,7 @@ def merge_config(updates: dict) -> dict:
|
|
|
270
270
|
|
|
271
271
|
|
|
272
272
|
def get_adapter(
|
|
273
|
-
override_adapter:
|
|
273
|
+
override_adapter: str | None = None, override_config: dict | None = None
|
|
274
274
|
):
|
|
275
275
|
"""Get configured adapter instance.
|
|
276
276
|
|
|
@@ -387,13 +387,13 @@ def _prompt_for_adapter_selection(console: Console) -> str:
|
|
|
387
387
|
|
|
388
388
|
@app.command()
|
|
389
389
|
def setup(
|
|
390
|
-
adapter:
|
|
390
|
+
adapter: str | None = typer.Option(
|
|
391
391
|
None,
|
|
392
392
|
"--adapter",
|
|
393
393
|
"-a",
|
|
394
394
|
help="Adapter type to use (interactive prompt if not specified)",
|
|
395
395
|
),
|
|
396
|
-
project_path:
|
|
396
|
+
project_path: str | None = typer.Option(
|
|
397
397
|
None, "--path", help="Project path (default: current directory)"
|
|
398
398
|
),
|
|
399
399
|
global_config: bool = typer.Option(
|
|
@@ -402,36 +402,36 @@ def setup(
|
|
|
402
402
|
"-g",
|
|
403
403
|
help="Save to global config instead of project-specific",
|
|
404
404
|
),
|
|
405
|
-
base_path:
|
|
405
|
+
base_path: str | None = typer.Option(
|
|
406
406
|
None,
|
|
407
407
|
"--base-path",
|
|
408
408
|
"-p",
|
|
409
409
|
help="Base path for ticket storage (AITrackdown only)",
|
|
410
410
|
),
|
|
411
|
-
api_key:
|
|
411
|
+
api_key: str | None = typer.Option(
|
|
412
412
|
None, "--api-key", help="API key for Linear or API token for JIRA"
|
|
413
413
|
),
|
|
414
|
-
team_id:
|
|
414
|
+
team_id: str | None = typer.Option(
|
|
415
415
|
None, "--team-id", help="Linear team ID (required for Linear adapter)"
|
|
416
416
|
),
|
|
417
|
-
jira_server:
|
|
417
|
+
jira_server: str | None = typer.Option(
|
|
418
418
|
None,
|
|
419
419
|
"--jira-server",
|
|
420
420
|
help="JIRA server URL (e.g., https://company.atlassian.net)",
|
|
421
421
|
),
|
|
422
|
-
jira_email:
|
|
422
|
+
jira_email: str | None = typer.Option(
|
|
423
423
|
None, "--jira-email", help="JIRA user email for authentication"
|
|
424
424
|
),
|
|
425
|
-
jira_project:
|
|
425
|
+
jira_project: str | None = typer.Option(
|
|
426
426
|
None, "--jira-project", help="Default JIRA project key"
|
|
427
427
|
),
|
|
428
|
-
github_owner:
|
|
428
|
+
github_owner: str | None = typer.Option(
|
|
429
429
|
None, "--github-owner", help="GitHub repository owner"
|
|
430
430
|
),
|
|
431
|
-
github_repo:
|
|
431
|
+
github_repo: str | None = typer.Option(
|
|
432
432
|
None, "--github-repo", help="GitHub repository name"
|
|
433
433
|
),
|
|
434
|
-
github_token:
|
|
434
|
+
github_token: str | None = typer.Option(
|
|
435
435
|
None, "--github-token", help="GitHub Personal Access Token"
|
|
436
436
|
),
|
|
437
437
|
) -> None:
|
|
@@ -471,13 +471,13 @@ def setup(
|
|
|
471
471
|
|
|
472
472
|
@app.command()
|
|
473
473
|
def init(
|
|
474
|
-
adapter:
|
|
474
|
+
adapter: str | None = typer.Option(
|
|
475
475
|
None,
|
|
476
476
|
"--adapter",
|
|
477
477
|
"-a",
|
|
478
478
|
help="Adapter type to use (interactive prompt if not specified)",
|
|
479
479
|
),
|
|
480
|
-
project_path:
|
|
480
|
+
project_path: str | None = typer.Option(
|
|
481
481
|
None, "--path", help="Project path (default: current directory)"
|
|
482
482
|
),
|
|
483
483
|
global_config: bool = typer.Option(
|
|
@@ -486,40 +486,40 @@ def init(
|
|
|
486
486
|
"-g",
|
|
487
487
|
help="Save to global config instead of project-specific",
|
|
488
488
|
),
|
|
489
|
-
base_path:
|
|
489
|
+
base_path: str | None = typer.Option(
|
|
490
490
|
None,
|
|
491
491
|
"--base-path",
|
|
492
492
|
"-p",
|
|
493
493
|
help="Base path for ticket storage (AITrackdown only)",
|
|
494
494
|
),
|
|
495
|
-
api_key:
|
|
495
|
+
api_key: str | None = typer.Option(
|
|
496
496
|
None, "--api-key", help="API key for Linear or API token for JIRA"
|
|
497
497
|
),
|
|
498
|
-
team_id:
|
|
498
|
+
team_id: str | None = typer.Option(
|
|
499
499
|
None, "--team-id", help="Linear team ID (required for Linear adapter)"
|
|
500
500
|
),
|
|
501
|
-
jira_server:
|
|
501
|
+
jira_server: str | None = typer.Option(
|
|
502
502
|
None,
|
|
503
503
|
"--jira-server",
|
|
504
504
|
help="JIRA server URL (e.g., https://company.atlassian.net)",
|
|
505
505
|
),
|
|
506
|
-
jira_email:
|
|
506
|
+
jira_email: str | None = typer.Option(
|
|
507
507
|
None, "--jira-email", help="JIRA user email for authentication"
|
|
508
508
|
),
|
|
509
|
-
jira_project:
|
|
509
|
+
jira_project: str | None = typer.Option(
|
|
510
510
|
None, "--jira-project", help="Default JIRA project key"
|
|
511
511
|
),
|
|
512
|
-
github_owner:
|
|
512
|
+
github_owner: str | None = typer.Option(
|
|
513
513
|
None, "--github-owner", help="GitHub repository owner"
|
|
514
514
|
),
|
|
515
|
-
github_repo:
|
|
515
|
+
github_repo: str | None = typer.Option(
|
|
516
516
|
None, "--github-repo", help="GitHub repository name"
|
|
517
517
|
),
|
|
518
|
-
github_token:
|
|
518
|
+
github_token: str | None = typer.Option(
|
|
519
519
|
None, "--github-token", help="GitHub Personal Access Token"
|
|
520
520
|
),
|
|
521
521
|
) -> None:
|
|
522
|
-
"""Initialize mcp-ticketer for the current project.
|
|
522
|
+
"""Initialize mcp-ticketer for the current project (synonymous with 'install' and 'setup').
|
|
523
523
|
|
|
524
524
|
This command sets up MCP Ticketer configuration with interactive prompts
|
|
525
525
|
to guide you through the process. It auto-detects adapter configuration
|
|
@@ -528,11 +528,13 @@ def init(
|
|
|
528
528
|
Creates .mcp-ticketer/config.json in the current directory with
|
|
529
529
|
auto-detected or specified adapter configuration.
|
|
530
530
|
|
|
531
|
-
Note: '
|
|
531
|
+
Note: 'init', 'install', and 'setup' are all synonyms - use whichever feels natural.
|
|
532
532
|
|
|
533
533
|
Examples:
|
|
534
|
-
# Interactive setup (
|
|
534
|
+
# Interactive setup (all three commands are identical)
|
|
535
535
|
mcp-ticketer init
|
|
536
|
+
mcp-ticketer install
|
|
537
|
+
mcp-ticketer setup
|
|
536
538
|
|
|
537
539
|
# Force specific adapter
|
|
538
540
|
mcp-ticketer init --adapter linear
|
|
@@ -669,20 +671,29 @@ def init(
|
|
|
669
671
|
if linear_api_key:
|
|
670
672
|
linear_config["api_key"] = linear_api_key
|
|
671
673
|
|
|
672
|
-
# Team ID
|
|
674
|
+
# Team ID or Team Key
|
|
675
|
+
# Try environment variables first
|
|
676
|
+
linear_team_key = os.getenv("LINEAR_TEAM_KEY")
|
|
673
677
|
linear_team_id = team_id or os.getenv("LINEAR_TEAM_ID")
|
|
674
|
-
if not linear_team_id and not discovered:
|
|
675
|
-
console.print("\nYou need your Linear team ID.")
|
|
676
|
-
console.print("[dim]Find it in Linear settings or team URL[/dim]\n")
|
|
677
678
|
|
|
678
|
-
|
|
679
|
+
if not linear_team_key and not linear_team_id and not discovered:
|
|
680
|
+
console.print("\n[bold]Linear Team Configuration[/bold]")
|
|
681
|
+
console.print("Enter your team key (e.g., 'ENG', 'DESIGN', 'PRODUCT')")
|
|
682
|
+
console.print("[dim]Find it in: Linear Settings → Teams → Your Team → Key field[/dim]\n")
|
|
683
|
+
|
|
684
|
+
linear_team_key = typer.prompt("Team key")
|
|
679
685
|
|
|
686
|
+
# Save whichever was provided
|
|
687
|
+
if linear_team_key:
|
|
688
|
+
linear_config["team_key"] = linear_team_key
|
|
680
689
|
if linear_team_id:
|
|
681
690
|
linear_config["team_id"] = linear_team_id
|
|
682
691
|
|
|
683
|
-
if not linear_config.get("api_key") or
|
|
692
|
+
if not linear_config.get("api_key") or (
|
|
693
|
+
not linear_config.get("team_id") and not linear_config.get("team_key")
|
|
694
|
+
):
|
|
684
695
|
console.print(
|
|
685
|
-
"[red]Error:[/red] Linear requires both API key and team ID"
|
|
696
|
+
"[red]Error:[/red] Linear requires both API key and team ID/key"
|
|
686
697
|
)
|
|
687
698
|
console.print(
|
|
688
699
|
"Run 'mcp-ticketer init --adapter linear' with proper credentials"
|
|
@@ -891,98 +902,20 @@ def _show_next_steps(
|
|
|
891
902
|
console.print("[dim]Run 'mcp-ticketer --help' for more commands[/dim]")
|
|
892
903
|
|
|
893
904
|
|
|
894
|
-
# Keep the old install command as deprecated alias to init
|
|
895
|
-
@app.command(deprecated=True, hidden=True)
|
|
896
|
-
def install(
|
|
897
|
-
adapter: Optional[str] = typer.Option(
|
|
898
|
-
None,
|
|
899
|
-
"--adapter",
|
|
900
|
-
"-a",
|
|
901
|
-
help="Adapter type to use (auto-detected from .env if not specified)",
|
|
902
|
-
),
|
|
903
|
-
project_path: Optional[str] = typer.Option(
|
|
904
|
-
None, "--path", help="Project path (default: current directory)"
|
|
905
|
-
),
|
|
906
|
-
global_config: bool = typer.Option(
|
|
907
|
-
False,
|
|
908
|
-
"--global",
|
|
909
|
-
"-g",
|
|
910
|
-
help="Save to global config instead of project-specific",
|
|
911
|
-
),
|
|
912
|
-
base_path: Optional[str] = typer.Option(
|
|
913
|
-
None,
|
|
914
|
-
"--base-path",
|
|
915
|
-
"-p",
|
|
916
|
-
help="Base path for ticket storage (AITrackdown only)",
|
|
917
|
-
),
|
|
918
|
-
api_key: Optional[str] = typer.Option(
|
|
919
|
-
None, "--api-key", help="API key for Linear or API token for JIRA"
|
|
920
|
-
),
|
|
921
|
-
team_id: Optional[str] = typer.Option(
|
|
922
|
-
None, "--team-id", help="Linear team ID (required for Linear adapter)"
|
|
923
|
-
),
|
|
924
|
-
jira_server: Optional[str] = typer.Option(
|
|
925
|
-
None,
|
|
926
|
-
"--jira-server",
|
|
927
|
-
help="JIRA server URL (e.g., https://company.atlassian.net)",
|
|
928
|
-
),
|
|
929
|
-
jira_email: Optional[str] = typer.Option(
|
|
930
|
-
None, "--jira-email", help="JIRA user email for authentication"
|
|
931
|
-
),
|
|
932
|
-
jira_project: Optional[str] = typer.Option(
|
|
933
|
-
None, "--jira-project", help="Default JIRA project key"
|
|
934
|
-
),
|
|
935
|
-
github_owner: Optional[str] = typer.Option(
|
|
936
|
-
None, "--github-owner", help="GitHub repository owner"
|
|
937
|
-
),
|
|
938
|
-
github_repo: Optional[str] = typer.Option(
|
|
939
|
-
None, "--github-repo", help="GitHub repository name"
|
|
940
|
-
),
|
|
941
|
-
github_token: Optional[str] = typer.Option(
|
|
942
|
-
None, "--github-token", help="GitHub Personal Access Token"
|
|
943
|
-
),
|
|
944
|
-
) -> None:
|
|
945
|
-
"""DEPRECATED: Use 'mcp-ticketer init' instead.
|
|
946
|
-
|
|
947
|
-
This command is deprecated. Use 'mcp-ticketer init' for project initialization.
|
|
948
|
-
|
|
949
|
-
"""
|
|
950
|
-
console.print(
|
|
951
|
-
"[yellow]⚠️ 'install' is deprecated. Use 'mcp-ticketer init' instead.[/yellow]\n"
|
|
952
|
-
)
|
|
953
|
-
# Call init with all parameters
|
|
954
|
-
init(
|
|
955
|
-
adapter=adapter,
|
|
956
|
-
project_path=project_path,
|
|
957
|
-
global_config=global_config,
|
|
958
|
-
base_path=base_path,
|
|
959
|
-
api_key=api_key,
|
|
960
|
-
team_id=team_id,
|
|
961
|
-
jira_server=jira_server,
|
|
962
|
-
jira_email=jira_email,
|
|
963
|
-
jira_project=jira_project,
|
|
964
|
-
github_owner=github_owner,
|
|
965
|
-
github_repo=github_repo,
|
|
966
|
-
github_token=github_token,
|
|
967
|
-
)
|
|
968
|
-
|
|
969
|
-
|
|
970
905
|
@app.command("set")
|
|
971
906
|
def set_config(
|
|
972
|
-
adapter:
|
|
907
|
+
adapter: AdapterType | None = typer.Option(
|
|
973
908
|
None, "--adapter", "-a", help="Set default adapter"
|
|
974
909
|
),
|
|
975
|
-
team_key:
|
|
910
|
+
team_key: str | None = typer.Option(
|
|
976
911
|
None, "--team-key", help="Linear team key (e.g., BTA)"
|
|
977
912
|
),
|
|
978
|
-
team_id:
|
|
979
|
-
owner:
|
|
980
|
-
|
|
981
|
-
),
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
project: Optional[str] = typer.Option(None, "--project", help="JIRA project key"),
|
|
985
|
-
base_path: Optional[str] = typer.Option(
|
|
913
|
+
team_id: str | None = typer.Option(None, "--team-id", help="Linear team ID"),
|
|
914
|
+
owner: str | None = typer.Option(None, "--owner", help="GitHub repository owner"),
|
|
915
|
+
repo: str | None = typer.Option(None, "--repo", help="GitHub repository name"),
|
|
916
|
+
server: str | None = typer.Option(None, "--server", help="JIRA server URL"),
|
|
917
|
+
project: str | None = typer.Option(None, "--project", help="JIRA project key"),
|
|
918
|
+
base_path: str | None = typer.Option(
|
|
986
919
|
None, "--base-path", help="AITrackdown base path"
|
|
987
920
|
),
|
|
988
921
|
) -> None:
|
|
@@ -1072,16 +1005,12 @@ def set_config(
|
|
|
1072
1005
|
@app.command("configure")
|
|
1073
1006
|
def configure_command(
|
|
1074
1007
|
show: bool = typer.Option(False, "--show", help="Show current configuration"),
|
|
1075
|
-
adapter:
|
|
1008
|
+
adapter: str | None = typer.Option(
|
|
1076
1009
|
None, "--adapter", help="Set default adapter type"
|
|
1077
1010
|
),
|
|
1078
|
-
api_key:
|
|
1079
|
-
project_id:
|
|
1080
|
-
|
|
1081
|
-
),
|
|
1082
|
-
team_id: Optional[str] = typer.Option(
|
|
1083
|
-
None, "--team-id", help="Set team ID (Linear)"
|
|
1084
|
-
),
|
|
1011
|
+
api_key: str | None = typer.Option(None, "--api-key", help="Set API key/token"),
|
|
1012
|
+
project_id: str | None = typer.Option(None, "--project-id", help="Set project ID"),
|
|
1013
|
+
team_id: str | None = typer.Option(None, "--team-id", help="Set team ID (Linear)"),
|
|
1085
1014
|
global_scope: bool = typer.Option(
|
|
1086
1015
|
False,
|
|
1087
1016
|
"--global",
|
|
@@ -1257,29 +1186,29 @@ def old_queue_health_command(
|
|
|
1257
1186
|
@app.command(deprecated=True, hidden=True)
|
|
1258
1187
|
def create(
|
|
1259
1188
|
title: str = typer.Argument(..., help="Ticket title"),
|
|
1260
|
-
description:
|
|
1189
|
+
description: str | None = typer.Option(
|
|
1261
1190
|
None, "--description", "-d", help="Ticket description"
|
|
1262
1191
|
),
|
|
1263
1192
|
priority: Priority = typer.Option(
|
|
1264
1193
|
Priority.MEDIUM, "--priority", "-p", help="Priority level"
|
|
1265
1194
|
),
|
|
1266
|
-
tags:
|
|
1195
|
+
tags: list[str] | None = typer.Option(
|
|
1267
1196
|
None, "--tag", "-t", help="Tags (can be specified multiple times)"
|
|
1268
1197
|
),
|
|
1269
|
-
assignee:
|
|
1198
|
+
assignee: str | None = typer.Option(
|
|
1270
1199
|
None, "--assignee", "-a", help="Assignee username"
|
|
1271
1200
|
),
|
|
1272
|
-
project:
|
|
1201
|
+
project: str | None = typer.Option(
|
|
1273
1202
|
None,
|
|
1274
1203
|
"--project",
|
|
1275
1204
|
help="Parent project/epic ID (synonym for --epic)",
|
|
1276
1205
|
),
|
|
1277
|
-
epic:
|
|
1206
|
+
epic: str | None = typer.Option(
|
|
1278
1207
|
None,
|
|
1279
1208
|
"--epic",
|
|
1280
1209
|
help="Parent epic/project ID (synonym for --project)",
|
|
1281
1210
|
),
|
|
1282
|
-
adapter:
|
|
1211
|
+
adapter: AdapterType | None = typer.Option(
|
|
1283
1212
|
None, "--adapter", help="Override default adapter"
|
|
1284
1213
|
),
|
|
1285
1214
|
) -> None:
|
|
@@ -1488,14 +1417,14 @@ def create(
|
|
|
1488
1417
|
|
|
1489
1418
|
@app.command("list", deprecated=True, hidden=True)
|
|
1490
1419
|
def list_tickets(
|
|
1491
|
-
state:
|
|
1420
|
+
state: TicketState | None = typer.Option(
|
|
1492
1421
|
None, "--state", "-s", help="Filter by state"
|
|
1493
1422
|
),
|
|
1494
|
-
priority:
|
|
1423
|
+
priority: Priority | None = typer.Option(
|
|
1495
1424
|
None, "--priority", "-p", help="Filter by priority"
|
|
1496
1425
|
),
|
|
1497
1426
|
limit: int = typer.Option(10, "--limit", "-l", help="Maximum number of tickets"),
|
|
1498
|
-
adapter:
|
|
1427
|
+
adapter: AdapterType | None = typer.Option(
|
|
1499
1428
|
None, "--adapter", help="Override default adapter"
|
|
1500
1429
|
),
|
|
1501
1430
|
) -> None:
|
|
@@ -1551,7 +1480,7 @@ def list_tickets(
|
|
|
1551
1480
|
def show(
|
|
1552
1481
|
ticket_id: str = typer.Argument(..., help="Ticket ID"),
|
|
1553
1482
|
comments: bool = typer.Option(False, "--comments", "-c", help="Show comments"),
|
|
1554
|
-
adapter:
|
|
1483
|
+
adapter: AdapterType | None = typer.Option(
|
|
1555
1484
|
None, "--adapter", help="Override default adapter"
|
|
1556
1485
|
),
|
|
1557
1486
|
) -> None:
|
|
@@ -1607,7 +1536,7 @@ def show(
|
|
|
1607
1536
|
def comment(
|
|
1608
1537
|
ticket_id: str = typer.Argument(..., help="Ticket ID"),
|
|
1609
1538
|
content: str = typer.Argument(..., help="Comment content"),
|
|
1610
|
-
adapter:
|
|
1539
|
+
adapter: AdapterType | None = typer.Option(
|
|
1611
1540
|
None, "--adapter", help="Override default adapter"
|
|
1612
1541
|
),
|
|
1613
1542
|
) -> None:
|
|
@@ -1648,17 +1577,15 @@ def comment(
|
|
|
1648
1577
|
@app.command(deprecated=True, hidden=True)
|
|
1649
1578
|
def update(
|
|
1650
1579
|
ticket_id: str = typer.Argument(..., help="Ticket ID"),
|
|
1651
|
-
title:
|
|
1652
|
-
description:
|
|
1580
|
+
title: str | None = typer.Option(None, "--title", help="New title"),
|
|
1581
|
+
description: str | None = typer.Option(
|
|
1653
1582
|
None, "--description", "-d", help="New description"
|
|
1654
1583
|
),
|
|
1655
|
-
priority:
|
|
1584
|
+
priority: Priority | None = typer.Option(
|
|
1656
1585
|
None, "--priority", "-p", help="New priority"
|
|
1657
1586
|
),
|
|
1658
|
-
assignee:
|
|
1659
|
-
|
|
1660
|
-
),
|
|
1661
|
-
adapter: Optional[AdapterType] = typer.Option(
|
|
1587
|
+
assignee: str | None = typer.Option(None, "--assignee", "-a", help="New assignee"),
|
|
1588
|
+
adapter: AdapterType | None = typer.Option(
|
|
1662
1589
|
None, "--adapter", help="Override default adapter"
|
|
1663
1590
|
),
|
|
1664
1591
|
) -> None:
|
|
@@ -1718,13 +1645,13 @@ def update(
|
|
|
1718
1645
|
@app.command(deprecated=True, hidden=True)
|
|
1719
1646
|
def transition(
|
|
1720
1647
|
ticket_id: str = typer.Argument(..., help="Ticket ID"),
|
|
1721
|
-
state_positional:
|
|
1648
|
+
state_positional: TicketState | None = typer.Argument(
|
|
1722
1649
|
None, help="Target state (positional - deprecated, use --state instead)"
|
|
1723
1650
|
),
|
|
1724
|
-
state:
|
|
1651
|
+
state: TicketState | None = typer.Option(
|
|
1725
1652
|
None, "--state", "-s", help="Target state (recommended)"
|
|
1726
1653
|
),
|
|
1727
|
-
adapter:
|
|
1654
|
+
adapter: AdapterType | None = typer.Option(
|
|
1728
1655
|
None, "--adapter", help="Override default adapter"
|
|
1729
1656
|
),
|
|
1730
1657
|
) -> None:
|
|
@@ -1789,12 +1716,12 @@ def transition(
|
|
|
1789
1716
|
|
|
1790
1717
|
@app.command(deprecated=True, hidden=True)
|
|
1791
1718
|
def search(
|
|
1792
|
-
query:
|
|
1793
|
-
state:
|
|
1794
|
-
priority:
|
|
1795
|
-
assignee:
|
|
1719
|
+
query: str | None = typer.Argument(None, help="Search query"),
|
|
1720
|
+
state: TicketState | None = typer.Option(None, "--state", "-s"),
|
|
1721
|
+
priority: Priority | None = typer.Option(None, "--priority", "-p"),
|
|
1722
|
+
assignee: str | None = typer.Option(None, "--assignee", "-a"),
|
|
1796
1723
|
limit: int = typer.Option(10, "--limit", "-l"),
|
|
1797
|
-
adapter:
|
|
1724
|
+
adapter: AdapterType | None = typer.Option(
|
|
1798
1725
|
None, "--adapter", help="Override default adapter"
|
|
1799
1726
|
),
|
|
1800
1727
|
) -> None:
|
|
@@ -1852,7 +1779,7 @@ app.add_typer(discover_app, name="discover")
|
|
|
1852
1779
|
# Add diagnostics command
|
|
1853
1780
|
@app.command("diagnose")
|
|
1854
1781
|
def diagnose_command(
|
|
1855
|
-
output_file:
|
|
1782
|
+
output_file: str | None = typer.Option(
|
|
1856
1783
|
None, "--output", "-o", help="Save full report to file"
|
|
1857
1784
|
),
|
|
1858
1785
|
json_output: bool = typer.Option(
|
|
@@ -1899,7 +1826,7 @@ def diagnose_command(
|
|
|
1899
1826
|
|
|
1900
1827
|
@app.command("doctor")
|
|
1901
1828
|
def doctor_alias(
|
|
1902
|
-
output_file:
|
|
1829
|
+
output_file: str | None = typer.Option(
|
|
1903
1830
|
None, "--output", "-o", help="Save full report to file"
|
|
1904
1831
|
),
|
|
1905
1832
|
json_output: bool = typer.Option(
|
|
@@ -1941,50 +1868,229 @@ mcp_app = typer.Typer(
|
|
|
1941
1868
|
add_completion=False,
|
|
1942
1869
|
)
|
|
1943
1870
|
|
|
1944
|
-
# Create install command group (like kuzu-memory)
|
|
1945
|
-
install_app = typer.Typer(
|
|
1946
|
-
name="install",
|
|
1947
|
-
help="Manage AI system integrations",
|
|
1948
|
-
add_completion=False,
|
|
1949
|
-
)
|
|
1950
|
-
|
|
1951
1871
|
|
|
1952
|
-
@
|
|
1953
|
-
def
|
|
1954
|
-
|
|
1955
|
-
|
|
1872
|
+
@app.command()
|
|
1873
|
+
def install(
|
|
1874
|
+
adapter: str | None = typer.Option(
|
|
1875
|
+
None,
|
|
1876
|
+
"--adapter",
|
|
1877
|
+
"-a",
|
|
1878
|
+
help="Adapter type to use (interactive prompt if not specified)",
|
|
1879
|
+
),
|
|
1880
|
+
project_path: str | None = typer.Option(
|
|
1881
|
+
None, "--path", help="Project path (default: current directory)"
|
|
1956
1882
|
),
|
|
1957
|
-
|
|
1958
|
-
|
|
1883
|
+
global_config: bool = typer.Option(
|
|
1884
|
+
False,
|
|
1885
|
+
"--global",
|
|
1886
|
+
"-g",
|
|
1887
|
+
help="Save to global config instead of project-specific",
|
|
1888
|
+
),
|
|
1889
|
+
base_path: str | None = typer.Option(
|
|
1890
|
+
None,
|
|
1891
|
+
"--base-path",
|
|
1892
|
+
"-p",
|
|
1893
|
+
help="Base path for ticket storage (AITrackdown only)",
|
|
1894
|
+
),
|
|
1895
|
+
api_key: str | None = typer.Option(
|
|
1896
|
+
None, "--api-key", help="API key for Linear or API token for JIRA"
|
|
1897
|
+
),
|
|
1898
|
+
team_id: str | None = typer.Option(
|
|
1899
|
+
None, "--team-id", help="Linear team ID (required for Linear adapter)"
|
|
1900
|
+
),
|
|
1901
|
+
jira_server: str | None = typer.Option(
|
|
1902
|
+
None,
|
|
1903
|
+
"--jira-server",
|
|
1904
|
+
help="JIRA server URL (e.g., https://company.atlassian.net)",
|
|
1905
|
+
),
|
|
1906
|
+
jira_email: str | None = typer.Option(
|
|
1907
|
+
None, "--jira-email", help="JIRA user email for authentication"
|
|
1908
|
+
),
|
|
1909
|
+
jira_project: str | None = typer.Option(
|
|
1910
|
+
None, "--jira-project", help="Default JIRA project key"
|
|
1911
|
+
),
|
|
1912
|
+
github_owner: str | None = typer.Option(
|
|
1913
|
+
None, "--github-owner", help="GitHub repository owner"
|
|
1914
|
+
),
|
|
1915
|
+
github_repo: str | None = typer.Option(
|
|
1916
|
+
None, "--github-repo", help="GitHub repository name"
|
|
1917
|
+
),
|
|
1918
|
+
github_token: str | None = typer.Option(
|
|
1919
|
+
None, "--github-token", help="GitHub Personal Access Token"
|
|
1920
|
+
),
|
|
1921
|
+
platform: str | None = typer.Option(
|
|
1922
|
+
None,
|
|
1923
|
+
"--platform",
|
|
1924
|
+
help="Platform to configure MCP for (claude-code, claude-desktop, auggie, gemini, codex)",
|
|
1925
|
+
),
|
|
1926
|
+
dry_run: bool = typer.Option(
|
|
1927
|
+
False,
|
|
1928
|
+
"--dry-run",
|
|
1929
|
+
help="Show what would be done without making changes (for platform installation)",
|
|
1930
|
+
),
|
|
1931
|
+
) -> None:
|
|
1932
|
+
"""Install and initialize mcp-ticketer (synonymous with 'init' and 'setup').
|
|
1933
|
+
|
|
1934
|
+
Without arguments, runs interactive setup wizard to configure your ticket adapter.
|
|
1935
|
+
With --platform, installs MCP configuration for AI platforms.
|
|
1936
|
+
|
|
1937
|
+
This command serves two purposes:
|
|
1938
|
+
1. Adapter initialization (same as 'init' and 'setup')
|
|
1939
|
+
2. Platform MCP configuration (when using --platform flag)
|
|
1940
|
+
|
|
1941
|
+
Examples:
|
|
1942
|
+
# Interactive setup (same as 'init' and 'setup')
|
|
1943
|
+
mcp-ticketer install
|
|
1944
|
+
|
|
1945
|
+
# Setup with specific adapter
|
|
1946
|
+
mcp-ticketer install --adapter linear
|
|
1947
|
+
|
|
1948
|
+
# Install MCP for Claude Code
|
|
1949
|
+
mcp-ticketer install --platform claude-code
|
|
1950
|
+
|
|
1951
|
+
# Install MCP for Claude Desktop
|
|
1952
|
+
mcp-ticketer install --platform claude-desktop
|
|
1953
|
+
|
|
1954
|
+
"""
|
|
1955
|
+
# If platform flag is provided, handle MCP platform installation
|
|
1956
|
+
if platform is not None:
|
|
1957
|
+
# Import configuration functions
|
|
1958
|
+
from .auggie_configure import configure_auggie_mcp
|
|
1959
|
+
from .codex_configure import configure_codex_mcp
|
|
1960
|
+
from .gemini_configure import configure_gemini_mcp
|
|
1961
|
+
from .mcp_configure import configure_claude_mcp
|
|
1962
|
+
|
|
1963
|
+
# Map platform names to configuration functions
|
|
1964
|
+
platform_mapping = {
|
|
1965
|
+
"claude-code": {
|
|
1966
|
+
"func": lambda: configure_claude_mcp(global_config=False, force=True),
|
|
1967
|
+
"name": "Claude Code",
|
|
1968
|
+
},
|
|
1969
|
+
"claude-desktop": {
|
|
1970
|
+
"func": lambda: configure_claude_mcp(global_config=True, force=True),
|
|
1971
|
+
"name": "Claude Desktop",
|
|
1972
|
+
},
|
|
1973
|
+
"auggie": {
|
|
1974
|
+
"func": lambda: configure_auggie_mcp(force=True),
|
|
1975
|
+
"name": "Auggie",
|
|
1976
|
+
},
|
|
1977
|
+
"gemini": {
|
|
1978
|
+
"func": lambda: configure_gemini_mcp(scope="project", force=True),
|
|
1979
|
+
"name": "Gemini CLI",
|
|
1980
|
+
},
|
|
1981
|
+
"codex": {
|
|
1982
|
+
"func": lambda: configure_codex_mcp(force=True),
|
|
1983
|
+
"name": "Codex",
|
|
1984
|
+
},
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
if platform not in platform_mapping:
|
|
1988
|
+
console.print(f"[red]Unknown platform: {platform}[/red]")
|
|
1989
|
+
console.print("\n[bold]Available platforms:[/bold]")
|
|
1990
|
+
for p in platform_mapping.keys():
|
|
1991
|
+
console.print(f" • {p}")
|
|
1992
|
+
raise typer.Exit(1)
|
|
1993
|
+
|
|
1994
|
+
config = platform_mapping[platform]
|
|
1995
|
+
|
|
1996
|
+
if dry_run:
|
|
1997
|
+
console.print(f"[cyan]DRY RUN - Would install for {config['name']}[/cyan]")
|
|
1998
|
+
return
|
|
1999
|
+
|
|
2000
|
+
try:
|
|
2001
|
+
config["func"]()
|
|
2002
|
+
except Exception as e:
|
|
2003
|
+
console.print(f"[red]Installation failed: {e}[/red]")
|
|
2004
|
+
raise typer.Exit(1)
|
|
2005
|
+
return
|
|
2006
|
+
|
|
2007
|
+
# Otherwise, delegate to init for adapter initialization
|
|
2008
|
+
# This makes 'install' and 'init' synonymous when called without --platform
|
|
2009
|
+
init(
|
|
2010
|
+
adapter=adapter,
|
|
2011
|
+
project_path=project_path,
|
|
2012
|
+
global_config=global_config,
|
|
2013
|
+
base_path=base_path,
|
|
2014
|
+
api_key=api_key,
|
|
2015
|
+
team_id=team_id,
|
|
2016
|
+
jira_server=jira_server,
|
|
2017
|
+
jira_email=jira_email,
|
|
2018
|
+
jira_project=jira_project,
|
|
2019
|
+
github_owner=github_owner,
|
|
2020
|
+
github_repo=github_repo,
|
|
2021
|
+
github_token=github_token,
|
|
2022
|
+
)
|
|
2023
|
+
|
|
2024
|
+
|
|
2025
|
+
@app.command()
|
|
2026
|
+
def remove(
|
|
2027
|
+
platform: str | None = typer.Argument(
|
|
2028
|
+
None,
|
|
2029
|
+
help="Platform to remove (claude-code, claude-desktop, auggie, gemini, codex)",
|
|
1959
2030
|
),
|
|
1960
2031
|
dry_run: bool = typer.Option(
|
|
1961
2032
|
False, "--dry-run", help="Show what would be done without making changes"
|
|
1962
2033
|
),
|
|
1963
|
-
verbose: bool = typer.Option(False, "--verbose", help="Enable verbose output"),
|
|
1964
2034
|
) -> None:
|
|
1965
|
-
"""
|
|
2035
|
+
"""Remove mcp-ticketer from AI platforms.
|
|
1966
2036
|
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
- claude-desktop: Global MCP server
|
|
2037
|
+
Without arguments, shows help and available platforms.
|
|
2038
|
+
With a platform argument, removes MCP configuration for that platform.
|
|
1970
2039
|
|
|
1971
2040
|
Examples:
|
|
1972
|
-
#
|
|
1973
|
-
mcp-ticketer
|
|
2041
|
+
# Remove from Claude Code (project-level)
|
|
2042
|
+
mcp-ticketer remove claude-code
|
|
2043
|
+
|
|
2044
|
+
# Remove from Claude Desktop (global)
|
|
2045
|
+
mcp-ticketer remove claude-desktop
|
|
1974
2046
|
|
|
1975
|
-
#
|
|
1976
|
-
mcp-ticketer
|
|
2047
|
+
# Remove from Auggie
|
|
2048
|
+
mcp-ticketer remove auggie
|
|
1977
2049
|
|
|
1978
2050
|
# Dry run to preview changes
|
|
1979
|
-
mcp-ticketer
|
|
2051
|
+
mcp-ticketer remove claude-code --dry-run
|
|
1980
2052
|
|
|
1981
2053
|
"""
|
|
1982
|
-
|
|
2054
|
+
# If no platform specified, show help message
|
|
2055
|
+
if platform is None:
|
|
2056
|
+
console.print("[bold]Remove mcp-ticketer from AI platforms[/bold]\n")
|
|
2057
|
+
console.print("Usage: mcp-ticketer remove <platform>\n")
|
|
2058
|
+
console.print("[bold]Available platforms:[/bold]")
|
|
2059
|
+
console.print(" • claude-code - Claude Code (project-level)")
|
|
2060
|
+
console.print(" • claude-desktop - Claude Desktop (global)")
|
|
2061
|
+
console.print(" • auggie - Auggie (global)")
|
|
2062
|
+
console.print(" • gemini - Gemini CLI (project-level by default)")
|
|
2063
|
+
console.print(" • codex - Codex (global)")
|
|
2064
|
+
return
|
|
2065
|
+
|
|
2066
|
+
# Import removal functions
|
|
2067
|
+
from .auggie_configure import remove_auggie_mcp
|
|
2068
|
+
from .codex_configure import remove_codex_mcp
|
|
2069
|
+
from .gemini_configure import remove_gemini_mcp
|
|
2070
|
+
from .mcp_configure import remove_claude_mcp
|
|
1983
2071
|
|
|
1984
|
-
# Map platform names to
|
|
2072
|
+
# Map platform names to removal functions
|
|
1985
2073
|
platform_mapping = {
|
|
1986
|
-
"claude-code": {
|
|
1987
|
-
|
|
2074
|
+
"claude-code": {
|
|
2075
|
+
"func": lambda: remove_claude_mcp(global_config=False, dry_run=dry_run),
|
|
2076
|
+
"name": "Claude Code",
|
|
2077
|
+
},
|
|
2078
|
+
"claude-desktop": {
|
|
2079
|
+
"func": lambda: remove_claude_mcp(global_config=True, dry_run=dry_run),
|
|
2080
|
+
"name": "Claude Desktop",
|
|
2081
|
+
},
|
|
2082
|
+
"auggie": {
|
|
2083
|
+
"func": lambda: remove_auggie_mcp(dry_run=dry_run),
|
|
2084
|
+
"name": "Auggie",
|
|
2085
|
+
},
|
|
2086
|
+
"gemini": {
|
|
2087
|
+
"func": lambda: remove_gemini_mcp(scope="project", dry_run=dry_run),
|
|
2088
|
+
"name": "Gemini CLI",
|
|
2089
|
+
},
|
|
2090
|
+
"codex": {
|
|
2091
|
+
"func": lambda: remove_codex_mcp(dry_run=dry_run),
|
|
2092
|
+
"name": "Codex",
|
|
2093
|
+
},
|
|
1988
2094
|
}
|
|
1989
2095
|
|
|
1990
2096
|
if platform not in platform_mapping:
|
|
@@ -1996,17 +2102,48 @@ def install_add(
|
|
|
1996
2102
|
|
|
1997
2103
|
config = platform_mapping[platform]
|
|
1998
2104
|
|
|
1999
|
-
if dry_run:
|
|
2000
|
-
console.print(f"[cyan]DRY RUN - Would install for {config['name']}[/cyan]")
|
|
2001
|
-
return
|
|
2002
|
-
|
|
2003
2105
|
try:
|
|
2004
|
-
|
|
2106
|
+
config["func"]()
|
|
2005
2107
|
except Exception as e:
|
|
2006
|
-
console.print(f"[red]
|
|
2108
|
+
console.print(f"[red]Removal failed: {e}[/red]")
|
|
2007
2109
|
raise typer.Exit(1)
|
|
2008
2110
|
|
|
2009
2111
|
|
|
2112
|
+
@app.command()
|
|
2113
|
+
def uninstall(
|
|
2114
|
+
platform: str | None = typer.Argument(
|
|
2115
|
+
None,
|
|
2116
|
+
help="Platform to uninstall (claude-code, claude-desktop, auggie, gemini, codex)",
|
|
2117
|
+
),
|
|
2118
|
+
dry_run: bool = typer.Option(
|
|
2119
|
+
False, "--dry-run", help="Show what would be done without making changes"
|
|
2120
|
+
),
|
|
2121
|
+
) -> None:
|
|
2122
|
+
"""Uninstall mcp-ticketer from AI platforms (alias for remove).
|
|
2123
|
+
|
|
2124
|
+
This is an alias for the 'remove' command.
|
|
2125
|
+
|
|
2126
|
+
Without arguments, shows help and available platforms.
|
|
2127
|
+
With a platform argument, removes MCP configuration for that platform.
|
|
2128
|
+
|
|
2129
|
+
Examples:
|
|
2130
|
+
# Uninstall from Claude Code (project-level)
|
|
2131
|
+
mcp-ticketer uninstall claude-code
|
|
2132
|
+
|
|
2133
|
+
# Uninstall from Claude Desktop (global)
|
|
2134
|
+
mcp-ticketer uninstall claude-desktop
|
|
2135
|
+
|
|
2136
|
+
# Uninstall from Auggie
|
|
2137
|
+
mcp-ticketer uninstall auggie
|
|
2138
|
+
|
|
2139
|
+
# Dry run to preview changes
|
|
2140
|
+
mcp-ticketer uninstall claude-code --dry-run
|
|
2141
|
+
|
|
2142
|
+
"""
|
|
2143
|
+
# Call the remove command with the same parameters
|
|
2144
|
+
remove(platform=platform, dry_run=dry_run)
|
|
2145
|
+
|
|
2146
|
+
|
|
2010
2147
|
@app.command(deprecated=True, hidden=True)
|
|
2011
2148
|
def check(queue_id: str = typer.Argument(..., help="Queue ID to check")):
|
|
2012
2149
|
"""Check status of a queued operation.
|
|
@@ -2057,10 +2194,10 @@ def check(queue_id: str = typer.Argument(..., help="Queue ID to check")):
|
|
|
2057
2194
|
|
|
2058
2195
|
@mcp_app.command(name="serve")
|
|
2059
2196
|
def mcp_serve(
|
|
2060
|
-
adapter:
|
|
2197
|
+
adapter: AdapterType | None = typer.Option(
|
|
2061
2198
|
None, "--adapter", "-a", help="Override default adapter type"
|
|
2062
2199
|
),
|
|
2063
|
-
base_path:
|
|
2200
|
+
base_path: str | None = typer.Option(
|
|
2064
2201
|
None, "--base-path", help="Base path for AITrackdown adapter"
|
|
2065
2202
|
),
|
|
2066
2203
|
):
|
|
@@ -2077,7 +2214,8 @@ def mcp_serve(
|
|
|
2077
2214
|
2. Global: ~/.mcp-ticketer/config.json
|
|
2078
2215
|
3. Default: aitrackdown adapter with .aitrackdown base path
|
|
2079
2216
|
"""
|
|
2080
|
-
from ..mcp.
|
|
2217
|
+
from ..mcp.server_sdk import configure_adapter
|
|
2218
|
+
from ..mcp.server_sdk import main as sdk_main
|
|
2081
2219
|
|
|
2082
2220
|
# Load configuration (respects project-specific config in cwd)
|
|
2083
2221
|
config = load_config()
|
|
@@ -2118,21 +2256,22 @@ def mcp_serve(
|
|
|
2118
2256
|
if sys.stderr.isatty():
|
|
2119
2257
|
# Only print if stderr is a terminal (not redirected)
|
|
2120
2258
|
console.file = sys.stderr
|
|
2121
|
-
console.print(
|
|
2259
|
+
console.print(
|
|
2260
|
+
f"[green]Starting MCP SDK server[/green] with {adapter_type} adapter"
|
|
2261
|
+
)
|
|
2122
2262
|
console.print(
|
|
2123
2263
|
"[dim]Server running on stdio. Send JSON-RPC requests via stdin.[/dim]"
|
|
2124
2264
|
)
|
|
2125
2265
|
|
|
2126
|
-
#
|
|
2266
|
+
# Configure adapter and run SDK server
|
|
2127
2267
|
try:
|
|
2128
|
-
|
|
2129
|
-
|
|
2268
|
+
configure_adapter(adapter_type, adapter_config)
|
|
2269
|
+
sdk_main()
|
|
2130
2270
|
except KeyboardInterrupt:
|
|
2131
|
-
#
|
|
2271
|
+
# Send this to stderr
|
|
2132
2272
|
if sys.stderr.isatty():
|
|
2133
2273
|
console.print("\n[yellow]Server stopped by user[/yellow]")
|
|
2134
|
-
|
|
2135
|
-
asyncio.run(server.stop())
|
|
2274
|
+
sys.exit(0)
|
|
2136
2275
|
except Exception as e:
|
|
2137
2276
|
# Log error to stderr
|
|
2138
2277
|
sys.stderr.write(f"MCP server error: {e}\n")
|
|
@@ -2292,7 +2431,6 @@ def mcp_auggie(
|
|
|
2292
2431
|
|
|
2293
2432
|
# Add command groups to main app (must be after all subcommands are defined)
|
|
2294
2433
|
app.add_typer(mcp_app, name="mcp")
|
|
2295
|
-
app.add_typer(install_app, name="install")
|
|
2296
2434
|
|
|
2297
2435
|
|
|
2298
2436
|
def main():
|