mcp-ticketer 0.4.3__py3-none-any.whl → 0.4.4__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 +12 -3
- mcp_ticketer/__version__.py +1 -1
- mcp_ticketer/adapters/aitrackdown.py +16 -5
- mcp_ticketer/adapters/github.py +1 -2
- mcp_ticketer/adapters/jira.py +1 -2
- mcp_ticketer/adapters/linear/adapter.py +21 -9
- mcp_ticketer/adapters/linear/client.py +1 -2
- mcp_ticketer/adapters/linear/mappers.py +1 -2
- mcp_ticketer/cli/adapter_diagnostics.py +2 -4
- mcp_ticketer/cli/configure.py +9 -3
- mcp_ticketer/cli/discover.py +6 -2
- mcp_ticketer/cli/main.py +147 -32
- mcp_ticketer/core/__init__.py +1 -2
- mcp_ticketer/mcp/server.py +34 -14
- mcp_ticketer/mcp/tools/__init__.py +9 -7
- {mcp_ticketer-0.4.3.dist-info → mcp_ticketer-0.4.4.dist-info}/METADATA +1 -1
- {mcp_ticketer-0.4.3.dist-info → mcp_ticketer-0.4.4.dist-info}/RECORD +21 -21
- {mcp_ticketer-0.4.3.dist-info → mcp_ticketer-0.4.4.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.4.3.dist-info → mcp_ticketer-0.4.4.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.4.3.dist-info → mcp_ticketer-0.4.4.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.4.3.dist-info → mcp_ticketer-0.4.4.dist-info}/top_level.txt +0 -0
mcp_ticketer/__init__.py
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
"""MCP Ticketer - Universal ticket management interface."""
|
|
2
2
|
|
|
3
|
-
from .__version__ import (
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
from .__version__ import (
|
|
4
|
+
__author__,
|
|
5
|
+
__author_email__,
|
|
6
|
+
__copyright__,
|
|
7
|
+
__description__,
|
|
8
|
+
__license__,
|
|
9
|
+
__title__,
|
|
10
|
+
__version__,
|
|
11
|
+
__version_info__,
|
|
12
|
+
get_user_agent,
|
|
13
|
+
get_version,
|
|
14
|
+
)
|
|
6
15
|
|
|
7
16
|
__all__ = [
|
|
8
17
|
"__version__",
|
mcp_ticketer/__version__.py
CHANGED
|
@@ -10,8 +10,15 @@ from typing import Any
|
|
|
10
10
|
from ..core.adapter import BaseAdapter
|
|
11
11
|
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
13
|
-
from ..core.models import (
|
|
14
|
-
|
|
13
|
+
from ..core.models import (
|
|
14
|
+
Attachment,
|
|
15
|
+
Comment,
|
|
16
|
+
Epic,
|
|
17
|
+
Priority,
|
|
18
|
+
SearchQuery,
|
|
19
|
+
Task,
|
|
20
|
+
TicketState,
|
|
21
|
+
)
|
|
15
22
|
from ..core.registry import AdapterRegistry
|
|
16
23
|
|
|
17
24
|
# Import ai-trackdown-pytools when available
|
|
@@ -766,7 +773,7 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
766
773
|
# CRITICAL SECURITY CHECK: Ensure ticket directory is within base attachments
|
|
767
774
|
base_attachments = (self.base_path / "attachments").resolve()
|
|
768
775
|
if not str(attachments_dir).startswith(str(base_attachments)):
|
|
769
|
-
raise ValueError(
|
|
776
|
+
raise ValueError("Invalid ticket_id: path traversal detected")
|
|
770
777
|
|
|
771
778
|
if not attachments_dir.exists():
|
|
772
779
|
return []
|
|
@@ -828,9 +835,13 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
828
835
|
# CRITICAL SECURITY CHECK: Ensure paths are within attachments_dir
|
|
829
836
|
base_resolved = attachments_dir.resolve()
|
|
830
837
|
if not str(attachment_file).startswith(str(base_resolved)):
|
|
831
|
-
raise ValueError(
|
|
838
|
+
raise ValueError(
|
|
839
|
+
"Invalid attachment path: path traversal detected in attachment_id"
|
|
840
|
+
)
|
|
832
841
|
if not str(metadata_file).startswith(str(base_resolved)):
|
|
833
|
-
raise ValueError(
|
|
842
|
+
raise ValueError(
|
|
843
|
+
"Invalid attachment path: path traversal detected in attachment_id"
|
|
844
|
+
)
|
|
834
845
|
|
|
835
846
|
# Delete files if they exist
|
|
836
847
|
deleted = False
|
mcp_ticketer/adapters/github.py
CHANGED
|
@@ -9,8 +9,7 @@ import httpx
|
|
|
9
9
|
|
|
10
10
|
from ..core.adapter import BaseAdapter
|
|
11
11
|
from ..core.env_loader import load_adapter_config, validate_adapter_config
|
|
12
|
-
from ..core.models import
|
|
13
|
-
TicketState)
|
|
12
|
+
from ..core.models import Comment, Epic, Priority, SearchQuery, Task, TicketState
|
|
14
13
|
from ..core.registry import AdapterRegistry
|
|
15
14
|
|
|
16
15
|
|
mcp_ticketer/adapters/jira.py
CHANGED
|
@@ -13,8 +13,7 @@ from httpx import AsyncClient, HTTPStatusError, TimeoutException
|
|
|
13
13
|
|
|
14
14
|
from ..core.adapter import BaseAdapter
|
|
15
15
|
from ..core.env_loader import load_adapter_config, validate_adapter_config
|
|
16
|
-
from ..core.models import
|
|
17
|
-
TicketState)
|
|
16
|
+
from ..core.models import Comment, Epic, Priority, SearchQuery, Task, TicketState
|
|
18
17
|
from ..core.registry import AdapterRegistry
|
|
19
18
|
|
|
20
19
|
logger = logging.getLogger(__name__)
|
|
@@ -20,15 +20,27 @@ from ...core.adapter import BaseAdapter
|
|
|
20
20
|
from ...core.models import Comment, Epic, SearchQuery, Task, TicketState
|
|
21
21
|
from ...core.registry import AdapterRegistry
|
|
22
22
|
from .client import LinearGraphQLClient
|
|
23
|
-
from .mappers import (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
from .
|
|
31
|
-
|
|
23
|
+
from .mappers import (
|
|
24
|
+
build_linear_issue_input,
|
|
25
|
+
build_linear_issue_update_input,
|
|
26
|
+
map_linear_comment_to_comment,
|
|
27
|
+
map_linear_issue_to_task,
|
|
28
|
+
map_linear_project_to_epic,
|
|
29
|
+
)
|
|
30
|
+
from .queries import (
|
|
31
|
+
ALL_FRAGMENTS,
|
|
32
|
+
CREATE_ISSUE_MUTATION,
|
|
33
|
+
LIST_ISSUES_QUERY,
|
|
34
|
+
SEARCH_ISSUES_QUERY,
|
|
35
|
+
UPDATE_ISSUE_MUTATION,
|
|
36
|
+
WORKFLOW_STATES_QUERY,
|
|
37
|
+
)
|
|
38
|
+
from .types import (
|
|
39
|
+
LinearStateMapping,
|
|
40
|
+
build_issue_filter,
|
|
41
|
+
get_linear_priority,
|
|
42
|
+
get_linear_state_type,
|
|
43
|
+
)
|
|
32
44
|
|
|
33
45
|
|
|
34
46
|
class LinearAdapter(BaseAdapter[Task]):
|
|
@@ -16,8 +16,7 @@ except ImportError:
|
|
|
16
16
|
HTTPXAsyncTransport = None
|
|
17
17
|
TransportError = Exception
|
|
18
18
|
|
|
19
|
-
from ...core.exceptions import
|
|
20
|
-
RateLimitError)
|
|
19
|
+
from ...core.exceptions import AdapterError, AuthenticationError, RateLimitError
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
class LinearGraphQLClient:
|
|
@@ -6,8 +6,7 @@ from datetime import datetime
|
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
8
|
from ...core.models import Comment, Epic, Priority, Task, TicketState
|
|
9
|
-
from .types import
|
|
10
|
-
get_universal_state)
|
|
9
|
+
from .types import extract_linear_metadata, get_universal_priority, get_universal_state
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
def map_linear_issue_to_task(issue_data: dict[str, Any]) -> Task:
|
|
@@ -197,8 +197,7 @@ def _test_adapter_instantiation(console: Console) -> None:
|
|
|
197
197
|
if primary:
|
|
198
198
|
adapter_type = primary.adapter_type
|
|
199
199
|
# Build config from discovery
|
|
200
|
-
from ..mcp.server import
|
|
201
|
-
_build_adapter_config_from_env_vars
|
|
200
|
+
from ..mcp.server import _build_adapter_config_from_env_vars
|
|
202
201
|
|
|
203
202
|
config = _build_adapter_config_from_env_vars(adapter_type, {})
|
|
204
203
|
else:
|
|
@@ -385,8 +384,7 @@ def get_adapter_status() -> dict[str, Any]:
|
|
|
385
384
|
adapter_type = primary.adapter_type
|
|
386
385
|
status["configuration_source"] = primary.found_in
|
|
387
386
|
# Build basic config
|
|
388
|
-
from ..mcp.server import
|
|
389
|
-
_build_adapter_config_from_env_vars
|
|
387
|
+
from ..mcp.server import _build_adapter_config_from_env_vars
|
|
390
388
|
|
|
391
389
|
config = _build_adapter_config_from_env_vars(adapter_type, {})
|
|
392
390
|
else:
|
mcp_ticketer/cli/configure.py
CHANGED
|
@@ -8,9 +8,15 @@ from rich.panel import Panel
|
|
|
8
8
|
from rich.prompt import Confirm, Prompt
|
|
9
9
|
from rich.table import Table
|
|
10
10
|
|
|
11
|
-
from ..core.project_config import (
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
from ..core.project_config import (
|
|
12
|
+
AdapterConfig,
|
|
13
|
+
AdapterType,
|
|
14
|
+
ConfigResolver,
|
|
15
|
+
ConfigValidator,
|
|
16
|
+
HybridConfig,
|
|
17
|
+
SyncStrategy,
|
|
18
|
+
TicketerConfig,
|
|
19
|
+
)
|
|
14
20
|
|
|
15
21
|
console = Console()
|
|
16
22
|
|
mcp_ticketer/cli/discover.py
CHANGED
|
@@ -6,8 +6,12 @@ import typer
|
|
|
6
6
|
from rich.console import Console
|
|
7
7
|
|
|
8
8
|
from ..core.env_discovery import DiscoveredAdapter, EnvDiscovery
|
|
9
|
-
from ..core.project_config import (
|
|
10
|
-
|
|
9
|
+
from ..core.project_config import (
|
|
10
|
+
AdapterConfig,
|
|
11
|
+
ConfigResolver,
|
|
12
|
+
ConfigValidator,
|
|
13
|
+
TicketerConfig,
|
|
14
|
+
)
|
|
11
15
|
|
|
12
16
|
console = Console()
|
|
13
17
|
app = typer.Typer(help="Auto-discover configuration from .env files")
|
mcp_ticketer/cli/main.py
CHANGED
|
@@ -20,8 +20,7 @@ from ..core.models import Comment, SearchQuery
|
|
|
20
20
|
from ..queue import Queue, QueueStatus, WorkerManager
|
|
21
21
|
from ..queue.health_monitor import HealthStatus, QueueHealthMonitor
|
|
22
22
|
from ..queue.ticket_registry import TicketRegistry
|
|
23
|
-
from .configure import
|
|
24
|
-
show_current_config)
|
|
23
|
+
from .configure import configure_wizard, set_adapter_config, show_current_config
|
|
25
24
|
from .diagnostics import run_diagnostics
|
|
26
25
|
from .discover import app as discover_app
|
|
27
26
|
from .migrate_config import migrate_config_command
|
|
@@ -679,7 +678,9 @@ def init(
|
|
|
679
678
|
if not linear_team_key and not linear_team_id and not discovered:
|
|
680
679
|
console.print("\n[bold]Linear Team Configuration[/bold]")
|
|
681
680
|
console.print("Enter your team key (e.g., 'ENG', 'DESIGN', 'PRODUCT')")
|
|
682
|
-
console.print(
|
|
681
|
+
console.print(
|
|
682
|
+
"[dim]Find it in: Linear Settings → Teams → Your Team → Key field[/dim]\n"
|
|
683
|
+
)
|
|
683
684
|
|
|
684
685
|
linear_team_key = typer.prompt("Team key")
|
|
685
686
|
|
|
@@ -893,10 +894,11 @@ def _show_next_steps(
|
|
|
893
894
|
console.print("\n3. [cyan]Check local ticket storage:[/cyan]")
|
|
894
895
|
console.print(" ls .aitrackdown/")
|
|
895
896
|
|
|
896
|
-
console.print("\n4. [cyan]
|
|
897
|
-
console.print(" mcp-ticketer
|
|
898
|
-
console.print(" mcp-ticketer
|
|
899
|
-
console.print(" mcp-ticketer
|
|
897
|
+
console.print("\n4. [cyan]Install MCP for AI clients (optional):[/cyan]")
|
|
898
|
+
console.print(" mcp-ticketer install claude-code # For Claude Code")
|
|
899
|
+
console.print(" mcp-ticketer install claude-desktop # For Claude Desktop")
|
|
900
|
+
console.print(" mcp-ticketer install auggie # For Auggie")
|
|
901
|
+
console.print(" mcp-ticketer install gemini # For Gemini CLI")
|
|
900
902
|
|
|
901
903
|
console.print(f"\n[dim]Configuration saved to: {config_file_path}[/dim]")
|
|
902
904
|
console.print("[dim]Run 'mcp-ticketer --help' for more commands[/dim]")
|
|
@@ -1871,6 +1873,10 @@ mcp_app = typer.Typer(
|
|
|
1871
1873
|
|
|
1872
1874
|
@app.command()
|
|
1873
1875
|
def install(
|
|
1876
|
+
platform: str | None = typer.Argument(
|
|
1877
|
+
None,
|
|
1878
|
+
help="Platform to install (claude-code, claude-desktop, gemini, codex, auggie)",
|
|
1879
|
+
),
|
|
1874
1880
|
adapter: str | None = typer.Option(
|
|
1875
1881
|
None,
|
|
1876
1882
|
"--adapter",
|
|
@@ -1918,41 +1924,31 @@ def install(
|
|
|
1918
1924
|
github_token: str | None = typer.Option(
|
|
1919
1925
|
None, "--github-token", help="GitHub Personal Access Token"
|
|
1920
1926
|
),
|
|
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
1927
|
dry_run: bool = typer.Option(
|
|
1927
1928
|
False,
|
|
1928
1929
|
"--dry-run",
|
|
1929
1930
|
help="Show what would be done without making changes (for platform installation)",
|
|
1930
1931
|
),
|
|
1931
1932
|
) -> None:
|
|
1932
|
-
"""Install
|
|
1933
|
+
"""Install MCP for AI platforms OR initialize adapter setup.
|
|
1933
1934
|
|
|
1934
|
-
|
|
1935
|
-
|
|
1935
|
+
With platform argument (new syntax): Install MCP configuration for AI platforms
|
|
1936
|
+
Without platform argument (legacy): Run adapter setup wizard (same as 'init' and 'setup')
|
|
1936
1937
|
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
mcp-ticketer install
|
|
1938
|
+
New Command Structure:
|
|
1939
|
+
# Install MCP for AI platforms
|
|
1940
|
+
mcp-ticketer install claude-code # Claude Code (project-level)
|
|
1941
|
+
mcp-ticketer install claude-desktop # Claude Desktop (global)
|
|
1942
|
+
mcp-ticketer install gemini # Gemini CLI
|
|
1943
|
+
mcp-ticketer install codex # Codex
|
|
1944
|
+
mcp-ticketer install auggie # Auggie
|
|
1944
1945
|
|
|
1945
|
-
|
|
1946
|
+
Legacy Adapter Setup (still supported):
|
|
1947
|
+
mcp-ticketer install # Interactive setup wizard
|
|
1946
1948
|
mcp-ticketer install --adapter linear
|
|
1947
1949
|
|
|
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
1950
|
"""
|
|
1955
|
-
# If platform
|
|
1951
|
+
# If platform argument is provided, handle MCP platform installation (NEW SYNTAX)
|
|
1956
1952
|
if platform is not None:
|
|
1957
1953
|
# Import configuration functions
|
|
1958
1954
|
from .auggie_configure import configure_auggie_mcp
|
|
@@ -2004,8 +2000,8 @@ def install(
|
|
|
2004
2000
|
raise typer.Exit(1)
|
|
2005
2001
|
return
|
|
2006
2002
|
|
|
2007
|
-
# Otherwise, delegate to init for adapter initialization
|
|
2008
|
-
# This makes 'install' and 'init' synonymous when called without
|
|
2003
|
+
# Otherwise, delegate to init for adapter initialization (LEGACY BEHAVIOR)
|
|
2004
|
+
# This makes 'install' and 'init' synonymous when called without platform argument
|
|
2009
2005
|
init(
|
|
2010
2006
|
adapter=adapter,
|
|
2011
2007
|
project_path=project_path,
|
|
@@ -2429,6 +2425,125 @@ def mcp_auggie(
|
|
|
2429
2425
|
raise typer.Exit(1)
|
|
2430
2426
|
|
|
2431
2427
|
|
|
2428
|
+
@mcp_app.command(name="status")
|
|
2429
|
+
def mcp_status():
|
|
2430
|
+
"""Check MCP server status.
|
|
2431
|
+
|
|
2432
|
+
Shows whether the MCP server is configured and running for various platforms.
|
|
2433
|
+
|
|
2434
|
+
Examples:
|
|
2435
|
+
mcp-ticketer mcp status
|
|
2436
|
+
|
|
2437
|
+
"""
|
|
2438
|
+
import json
|
|
2439
|
+
from pathlib import Path
|
|
2440
|
+
|
|
2441
|
+
console.print("[bold]MCP Server Status[/bold]\n")
|
|
2442
|
+
|
|
2443
|
+
# Check project-level configuration
|
|
2444
|
+
project_config = Path.cwd() / ".mcp-ticketer" / "config.json"
|
|
2445
|
+
if project_config.exists():
|
|
2446
|
+
console.print(f"[green]✓[/green] Project config found: {project_config}")
|
|
2447
|
+
try:
|
|
2448
|
+
with open(project_config) as f:
|
|
2449
|
+
config = json.load(f)
|
|
2450
|
+
adapter = config.get("default_adapter", "aitrackdown")
|
|
2451
|
+
console.print(f" Default adapter: [cyan]{adapter}[/cyan]")
|
|
2452
|
+
except Exception as e:
|
|
2453
|
+
console.print(f" [yellow]Warning: Could not read config: {e}[/yellow]")
|
|
2454
|
+
else:
|
|
2455
|
+
console.print("[yellow]○[/yellow] No project config found")
|
|
2456
|
+
|
|
2457
|
+
# Check Claude Code configuration
|
|
2458
|
+
claude_code_config = Path.cwd() / ".mcp" / "config.json"
|
|
2459
|
+
if claude_code_config.exists():
|
|
2460
|
+
console.print(
|
|
2461
|
+
f"\n[green]✓[/green] Claude Code configured: {claude_code_config}"
|
|
2462
|
+
)
|
|
2463
|
+
else:
|
|
2464
|
+
console.print("\n[yellow]○[/yellow] Claude Code not configured")
|
|
2465
|
+
|
|
2466
|
+
# Check Claude Desktop configuration
|
|
2467
|
+
claude_desktop_config = (
|
|
2468
|
+
Path.home()
|
|
2469
|
+
/ "Library"
|
|
2470
|
+
/ "Application Support"
|
|
2471
|
+
/ "Claude"
|
|
2472
|
+
/ "claude_desktop_config.json"
|
|
2473
|
+
)
|
|
2474
|
+
if claude_desktop_config.exists():
|
|
2475
|
+
try:
|
|
2476
|
+
with open(claude_desktop_config) as f:
|
|
2477
|
+
config = json.load(f)
|
|
2478
|
+
if "mcpServers" in config and "mcp-ticketer" in config["mcpServers"]:
|
|
2479
|
+
console.print(
|
|
2480
|
+
f"[green]✓[/green] Claude Desktop configured: {claude_desktop_config}"
|
|
2481
|
+
)
|
|
2482
|
+
else:
|
|
2483
|
+
console.print(
|
|
2484
|
+
"[yellow]○[/yellow] Claude Desktop config exists but mcp-ticketer not found"
|
|
2485
|
+
)
|
|
2486
|
+
except Exception:
|
|
2487
|
+
console.print(
|
|
2488
|
+
"[yellow]○[/yellow] Claude Desktop config exists but could not be read"
|
|
2489
|
+
)
|
|
2490
|
+
else:
|
|
2491
|
+
console.print("[yellow]○[/yellow] Claude Desktop not configured")
|
|
2492
|
+
|
|
2493
|
+
# Check Gemini configuration
|
|
2494
|
+
gemini_project_config = Path.cwd() / ".gemini" / "settings.json"
|
|
2495
|
+
gemini_user_config = Path.home() / ".gemini" / "settings.json"
|
|
2496
|
+
if gemini_project_config.exists():
|
|
2497
|
+
console.print(
|
|
2498
|
+
f"\n[green]✓[/green] Gemini (project) configured: {gemini_project_config}"
|
|
2499
|
+
)
|
|
2500
|
+
elif gemini_user_config.exists():
|
|
2501
|
+
console.print(
|
|
2502
|
+
f"\n[green]✓[/green] Gemini (user) configured: {gemini_user_config}"
|
|
2503
|
+
)
|
|
2504
|
+
else:
|
|
2505
|
+
console.print("\n[yellow]○[/yellow] Gemini not configured")
|
|
2506
|
+
|
|
2507
|
+
# Check Codex configuration
|
|
2508
|
+
codex_config = Path.home() / ".codex" / "config.toml"
|
|
2509
|
+
if codex_config.exists():
|
|
2510
|
+
console.print(f"[green]✓[/green] Codex configured: {codex_config}")
|
|
2511
|
+
else:
|
|
2512
|
+
console.print("[yellow]○[/yellow] Codex not configured")
|
|
2513
|
+
|
|
2514
|
+
# Check Auggie configuration
|
|
2515
|
+
auggie_config = Path.home() / ".augment" / "settings.json"
|
|
2516
|
+
if auggie_config.exists():
|
|
2517
|
+
console.print(f"[green]✓[/green] Auggie configured: {auggie_config}")
|
|
2518
|
+
else:
|
|
2519
|
+
console.print("[yellow]○[/yellow] Auggie not configured")
|
|
2520
|
+
|
|
2521
|
+
console.print(
|
|
2522
|
+
"\n[dim]Run 'mcp-ticketer install <platform>' to configure a platform[/dim]"
|
|
2523
|
+
)
|
|
2524
|
+
|
|
2525
|
+
|
|
2526
|
+
@mcp_app.command(name="stop")
|
|
2527
|
+
def mcp_stop():
|
|
2528
|
+
"""Stop MCP server (placeholder - MCP runs on-demand via stdio).
|
|
2529
|
+
|
|
2530
|
+
Note: The MCP server runs on-demand when AI clients connect via stdio.
|
|
2531
|
+
It doesn't run as a persistent background service, so there's nothing to stop.
|
|
2532
|
+
This command is provided for consistency but has no effect.
|
|
2533
|
+
|
|
2534
|
+
Examples:
|
|
2535
|
+
mcp-ticketer mcp stop
|
|
2536
|
+
|
|
2537
|
+
"""
|
|
2538
|
+
console.print(
|
|
2539
|
+
"[yellow]ℹ[/yellow] MCP server runs on-demand via stdio (not as a background service)"
|
|
2540
|
+
)
|
|
2541
|
+
console.print("There is no persistent server process to stop.")
|
|
2542
|
+
console.print(
|
|
2543
|
+
"\n[dim]The server starts automatically when AI clients connect and stops when they disconnect.[/dim]"
|
|
2544
|
+
)
|
|
2545
|
+
|
|
2546
|
+
|
|
2432
2547
|
# Add command groups to main app (must be after all subcommands are defined)
|
|
2433
2548
|
app.add_typer(mcp_app, name="mcp")
|
|
2434
2549
|
|
mcp_ticketer/core/__init__.py
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"""Core models and abstractions for MCP Ticketer."""
|
|
2
2
|
|
|
3
3
|
from .adapter import BaseAdapter
|
|
4
|
-
from .models import
|
|
5
|
-
TicketType)
|
|
4
|
+
from .models import Attachment, Comment, Epic, Priority, Task, TicketState, TicketType
|
|
6
5
|
from .registry import AdapterRegistry
|
|
7
6
|
|
|
8
7
|
__all__ = [
|
mcp_ticketer/mcp/server.py
CHANGED
|
@@ -12,20 +12,40 @@ from dotenv import load_dotenv
|
|
|
12
12
|
import mcp_ticketer.adapters # noqa: F401
|
|
13
13
|
|
|
14
14
|
from ..core import AdapterRegistry
|
|
15
|
-
from ..core.models import
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
from ..core.models import Comment, Epic, Priority, SearchQuery, Task, TicketState
|
|
16
|
+
from .constants import (
|
|
17
|
+
DEFAULT_BASE_PATH,
|
|
18
|
+
DEFAULT_LIMIT,
|
|
19
|
+
DEFAULT_MAX_DEPTH,
|
|
20
|
+
DEFAULT_OFFSET,
|
|
21
|
+
ERROR_INTERNAL,
|
|
22
|
+
ERROR_METHOD_NOT_FOUND,
|
|
23
|
+
ERROR_PARSE,
|
|
24
|
+
JSONRPC_VERSION,
|
|
25
|
+
MCP_PROTOCOL_VERSION,
|
|
26
|
+
MSG_EPIC_NOT_FOUND,
|
|
27
|
+
MSG_INTERNAL_ERROR,
|
|
28
|
+
MSG_MISSING_TICKET_ID,
|
|
29
|
+
MSG_MISSING_TITLE,
|
|
30
|
+
MSG_NO_TICKETS_PROVIDED,
|
|
31
|
+
MSG_NO_UPDATES_PROVIDED,
|
|
32
|
+
MSG_TICKET_NOT_FOUND,
|
|
33
|
+
MSG_TRANSITION_FAILED,
|
|
34
|
+
MSG_UNKNOWN_METHOD,
|
|
35
|
+
MSG_UNKNOWN_OPERATION,
|
|
36
|
+
MSG_UPDATE_FAILED,
|
|
37
|
+
SERVER_NAME,
|
|
38
|
+
SERVER_VERSION,
|
|
39
|
+
STATUS_COMPLETED,
|
|
40
|
+
STATUS_ERROR,
|
|
41
|
+
)
|
|
42
|
+
from .dto import (
|
|
43
|
+
CreateEpicRequest,
|
|
44
|
+
CreateIssueRequest,
|
|
45
|
+
CreateTaskRequest,
|
|
46
|
+
CreateTicketRequest,
|
|
47
|
+
ReadTicketRequest,
|
|
48
|
+
)
|
|
29
49
|
from .response_builder import ResponseBuilder
|
|
30
50
|
|
|
31
51
|
# Load environment variables early (prioritize .env.local)
|
|
@@ -17,13 +17,15 @@ Modules:
|
|
|
17
17
|
|
|
18
18
|
# Import all tool modules to register them with FastMCP
|
|
19
19
|
# Order matters - import core functionality first
|
|
20
|
-
from . import
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
from . import (
|
|
21
|
+
attachment_tools, # noqa: F401
|
|
22
|
+
bulk_tools, # noqa: F401
|
|
23
|
+
comment_tools, # noqa: F401
|
|
24
|
+
hierarchy_tools, # noqa: F401
|
|
25
|
+
pr_tools, # noqa: F401
|
|
26
|
+
search_tools, # noqa: F401
|
|
27
|
+
ticket_tools, # noqa: F401
|
|
28
|
+
)
|
|
27
29
|
|
|
28
30
|
__all__ = [
|
|
29
31
|
"ticket_tools",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-ticketer
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
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>
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
mcp_ticketer/__init__.py,sha256
|
|
2
|
-
mcp_ticketer/__version__.py,sha256=
|
|
1
|
+
mcp_ticketer/__init__.py,sha256=Xx4WaprO5PXhVPbYi1L6tBmwmJMkYS-lMyG4ieN6QP0,717
|
|
2
|
+
mcp_ticketer/__version__.py,sha256=Mb9Xgbq06svVZk98uwuhxlw-J1Tb25SzmoU6bCUjQyU,1117
|
|
3
3
|
mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
mcp_ticketer/adapters/__init__.py,sha256=B5DFllWn23hkhmrLykNO5uMMSdcFuuPHXyLw_jyFzuE,358
|
|
5
|
-
mcp_ticketer/adapters/aitrackdown.py,sha256=
|
|
6
|
-
mcp_ticketer/adapters/github.py,sha256=
|
|
5
|
+
mcp_ticketer/adapters/aitrackdown.py,sha256=qCR53JpOVlOHiR_pdjGF2RYOemgkKxIwDTOlpcYF18E,30320
|
|
6
|
+
mcp_ticketer/adapters/github.py,sha256=QeZefKs204g2nXZ9yDb3j-HwrufbXBPoXB0zLp6bvW0,47338
|
|
7
7
|
mcp_ticketer/adapters/hybrid.py,sha256=7ocRjK7N7FdXSUCeFc23jFevfVwcPvHPIsEPXV_4o1w,18997
|
|
8
|
-
mcp_ticketer/adapters/jira.py,sha256=
|
|
8
|
+
mcp_ticketer/adapters/jira.py,sha256=9OtYAQfUdUQqEYjs61jzYpVrHu23hyP22mm-Bfn5KqA,35204
|
|
9
9
|
mcp_ticketer/adapters/linear.py,sha256=trm6ZhmlUl80sj51WAPAox_R2HQZXZ-h1QXJsrFYDCQ,587
|
|
10
10
|
mcp_ticketer/adapters/linear/__init__.py,sha256=6l0ZoR6ZHSRcytLfps2AZuk5R189Pq1GfR5-YDQt8-Q,731
|
|
11
|
-
mcp_ticketer/adapters/linear/adapter.py,sha256=
|
|
12
|
-
mcp_ticketer/adapters/linear/client.py,sha256=
|
|
13
|
-
mcp_ticketer/adapters/linear/mappers.py,sha256=
|
|
11
|
+
mcp_ticketer/adapters/linear/adapter.py,sha256=ZCj6ZM5RiWbdiGrhA3NsMTgFImvrzaB0jBIr_3ZCcO8,30959
|
|
12
|
+
mcp_ticketer/adapters/linear/client.py,sha256=0UmWlSEcRiwnSMFYKL89KMrPPL8S8uZ5V6rIY_KFOQU,8803
|
|
13
|
+
mcp_ticketer/adapters/linear/mappers.py,sha256=GN1X7bOcU-5dhDW3dAtSEGivinhFBc8hoKYot8c5tCo,9631
|
|
14
14
|
mcp_ticketer/adapters/linear/queries.py,sha256=K8y7xc3iH-q9LEUmg-0YDBhh546LAwLZDvVLkzx3yY4,7223
|
|
15
15
|
mcp_ticketer/adapters/linear/types.py,sha256=ugXtRGLljDw6yoCnEVgdFs0xLR9ErLdnv4ffh9EAUhk,7874
|
|
16
16
|
mcp_ticketer/cache/__init__.py,sha256=Xcd-cKnt-Cx7jBzvfzUUUPaGkmyXFi5XUFWw3Z4b7d4,138
|
|
17
17
|
mcp_ticketer/cache/memory.py,sha256=rWphWZy7XTbHezC7HMRQN9ISUhYo0Pc2OTgLG30vHnI,5047
|
|
18
18
|
mcp_ticketer/cli/__init__.py,sha256=l9Q8iKmfGkTu0cssHBVqNZTsL4eAtFzOB25AED_0G6g,89
|
|
19
|
-
mcp_ticketer/cli/adapter_diagnostics.py,sha256=
|
|
19
|
+
mcp_ticketer/cli/adapter_diagnostics.py,sha256=pQDdtDgBwSW04wdFEPVzwbul3KgfB9g6ZMS85qpYulY,14988
|
|
20
20
|
mcp_ticketer/cli/auggie_configure.py,sha256=Kd28n16s-X3_KtNfi2fXKij6iK-SnZRHrpgDns3Kq7g,10808
|
|
21
21
|
mcp_ticketer/cli/codex_configure.py,sha256=9BoO8E_OypW7fs7UTRu76FMnU68E_HrbbkD696cgH58,11764
|
|
22
|
-
mcp_ticketer/cli/configure.py,sha256=
|
|
22
|
+
mcp_ticketer/cli/configure.py,sha256=T4LczvZIc2FZM-joqICL8NpjCeThAUknEhJkHsmpdc8,16158
|
|
23
23
|
mcp_ticketer/cli/diagnostics.py,sha256=s7P4vDzPpthgiBJfAOXpunlhZ62buHg_BA5W7ghQBqg,29952
|
|
24
|
-
mcp_ticketer/cli/discover.py,sha256=
|
|
24
|
+
mcp_ticketer/cli/discover.py,sha256=paG8zElIFEK6lgVD-tHWoFDTuWQ185LirFp0fVlYgB0,13148
|
|
25
25
|
mcp_ticketer/cli/gemini_configure.py,sha256=72lXywYJKdGqAhtJpC6fPVYY1T_w7_ND07AfmhumGUc,12010
|
|
26
26
|
mcp_ticketer/cli/linear_commands.py,sha256=YnmqRacAfTdF0CLr4BXOxFs3uwm_hVifbGdTe6t2CfA,17273
|
|
27
|
-
mcp_ticketer/cli/main.py,sha256=
|
|
27
|
+
mcp_ticketer/cli/main.py,sha256=DV05n5-JGIjIX1t4-oR7j5tuE4c2Z0of6KVahUzGiJY,89254
|
|
28
28
|
mcp_ticketer/cli/mcp_configure.py,sha256=lozgV_VZmOyZfPesg0oan8p_f93kGWyTDhE1byCbv4k,12324
|
|
29
29
|
mcp_ticketer/cli/migrate_config.py,sha256=MYsr_C5ZxsGg0P13etWTWNrJ_lc6ElRCkzfQADYr3DM,5956
|
|
30
30
|
mcp_ticketer/cli/platform_commands.py,sha256=pTLRT2wot8dAmy1-roJWWOT0Cxu7j-06BlWDnZ9a4jY,3624
|
|
@@ -32,7 +32,7 @@ mcp_ticketer/cli/queue_commands.py,sha256=mm-3H6jmkUGJDyU_E46o9iRpek8tvFCm77F19O
|
|
|
32
32
|
mcp_ticketer/cli/simple_health.py,sha256=GlOLRRFoifCna995NoHuKpb3xmFkLi2b3Ke1hyeDvq4,7950
|
|
33
33
|
mcp_ticketer/cli/ticket_commands.py,sha256=zmtePGhZzhw_r-0xWQMzXSJMo684PlzEN5LYfcR3_dw,26589
|
|
34
34
|
mcp_ticketer/cli/utils.py,sha256=JU2CtdA8pLaH0R5Xpb_Z4-W-PvQfzhbXl9VR04vzMSE,22992
|
|
35
|
-
mcp_ticketer/core/__init__.py,sha256
|
|
35
|
+
mcp_ticketer/core/__init__.py,sha256=aOnzv5YBfxvd6HvZeEnXeajizde53TcFaMWL3PJh5lY,379
|
|
36
36
|
mcp_ticketer/core/adapter.py,sha256=K8bQ9fQRN6Xjaxgl24f6X5u0PVmj9WFof_MOKapDHbU,12136
|
|
37
37
|
mcp_ticketer/core/config.py,sha256=q95coT6zDAVbN6eFFe6HUHXyqBm669z8g8nKWNfL8fs,19251
|
|
38
38
|
mcp_ticketer/core/env_discovery.py,sha256=iZnmtv1RWnmjjih0iFEInOoK9CU9_oNpfNgmiToQ5wk,19934
|
|
@@ -47,9 +47,9 @@ mcp_ticketer/mcp/__init__.py,sha256=Y05eTzsPk0wH8yKNIM-ekpGjgSDO0bQr0EME-vOP4GE,
|
|
|
47
47
|
mcp_ticketer/mcp/constants.py,sha256=EBGsJtBPaTCvAm5rOMknckrXActrNIls7lRklnh1L4s,2072
|
|
48
48
|
mcp_ticketer/mcp/dto.py,sha256=FR_OBtaxrno8AsHynPwUUW715iAoaBkrr7Ud8HZTQW8,7233
|
|
49
49
|
mcp_ticketer/mcp/response_builder.py,sha256=DUfe1e0CcXPlepLq-cGH6b_THqoZEynYfVKkZEeLe0M,4933
|
|
50
|
-
mcp_ticketer/mcp/server.py,sha256=
|
|
50
|
+
mcp_ticketer/mcp/server.py,sha256=XjlajZs4F7g4rXuuDlxvKQ-kml4PqRBAFnpntxgw_Ds,48832
|
|
51
51
|
mcp_ticketer/mcp/server_sdk.py,sha256=orgOTrvrtBn2BeMJt5HWeodvCU9sWH4o5pQIZ_geXao,2552
|
|
52
|
-
mcp_ticketer/mcp/tools/__init__.py,sha256=
|
|
52
|
+
mcp_ticketer/mcp/tools/__init__.py,sha256=6miiC2Cru8u2TCrm9RYF1jxd7vu9SI7BPLUjtzwOxT8,1056
|
|
53
53
|
mcp_ticketer/mcp/tools/attachment_tools.py,sha256=hDeQV1rkSjZwT__FKLkR04FH_AsAF6QysyeP_CKxdiU,5673
|
|
54
54
|
mcp_ticketer/mcp/tools/bulk_tools.py,sha256=UWY1T5DnWhpBJnqMdLMu7Feen515UAlcn_hOjTmDncc,9199
|
|
55
55
|
mcp_ticketer/mcp/tools/comment_tools.py,sha256=fVJZeSg_rr6tVoVAKF8rv5nUooqg5d4S44s1mKFTYM0,2701
|
|
@@ -65,9 +65,9 @@ mcp_ticketer/queue/queue.py,sha256=q9HDXgnlwspamMJIeu9og7qONttXHmFZHPSaMtJDPlw,1
|
|
|
65
65
|
mcp_ticketer/queue/run_worker.py,sha256=WhoeamL8LKZ66TM8W1PkMPwjF2w_EDFMP-mevs6C1TM,1019
|
|
66
66
|
mcp_ticketer/queue/ticket_registry.py,sha256=8pHAx1H83CzjcaIzi_Tq3DtbDBDcDJIPUS9ofusTuWA,15421
|
|
67
67
|
mcp_ticketer/queue/worker.py,sha256=AJHtpJZEhGoPuCDPXSMsn9DeODelo5f__0C__3zoN08,20970
|
|
68
|
-
mcp_ticketer-0.4.
|
|
69
|
-
mcp_ticketer-0.4.
|
|
70
|
-
mcp_ticketer-0.4.
|
|
71
|
-
mcp_ticketer-0.4.
|
|
72
|
-
mcp_ticketer-0.4.
|
|
73
|
-
mcp_ticketer-0.4.
|
|
68
|
+
mcp_ticketer-0.4.4.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
|
|
69
|
+
mcp_ticketer-0.4.4.dist-info/METADATA,sha256=mHtcKrZBEaJaUSJOkfYV34WE2D9y3dVbDDJ1vseNf_4,15478
|
|
70
|
+
mcp_ticketer-0.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
71
|
+
mcp_ticketer-0.4.4.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
|
|
72
|
+
mcp_ticketer-0.4.4.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
|
|
73
|
+
mcp_ticketer-0.4.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|