vector-task-mcp 1.0.0__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.
src/__init__.py ADDED
@@ -0,0 +1,44 @@
1
+ """
2
+ Vector Task MCP Server - Core Package
3
+ ======================================
4
+
5
+ This package provides vector-based task management capabilities for Claude Desktop
6
+ using sqlite-vec and sentence-transformers.
7
+
8
+ Modules:
9
+ models: Data models and type definitions
10
+ security: Security utilities and validation
11
+ embeddings: Sentence transformer wrapper (requires sentence-transformers)
12
+ task_store: SQLite-vec operations and task storage (requires sqlite-vec)
13
+ """
14
+
15
+ __version__ = "1.0.0"
16
+ __author__ = "Vector Task MCP Server"
17
+
18
+ # Core modules that don't require external dependencies
19
+ from .models import Task, TaskStatus, Priority, TaskStats, Config
20
+ from .security import SecurityError, validate_working_dir, sanitize_input
21
+
22
+ # Optional imports that require external dependencies
23
+ def get_embedding_model(model_name: str):
24
+ """Get embedding model (requires sentence-transformers)"""
25
+ from .embeddings import get_embedding_model as _get_model
26
+ return _get_model(model_name)
27
+
28
+ def get_task_store(db_path, embedding_model_name=None):
29
+ """Get task store (requires sqlite-vec)"""
30
+ from .task_store import TaskStore
31
+ return TaskStore(db_path, embedding_model_name)
32
+
33
+ __all__ = [
34
+ "Task",
35
+ "TaskStatus",
36
+ "Priority",
37
+ "TaskStats",
38
+ "Config",
39
+ "SecurityError",
40
+ "validate_working_dir",
41
+ "sanitize_input",
42
+ "get_embedding_model",
43
+ "get_task_store"
44
+ ]
src/embeddings.py ADDED
@@ -0,0 +1,68 @@
1
+ """
2
+ Embedding Model Module
3
+ ======================
4
+
5
+ Provides sentence transformer embedding functionality for semantic task search.
6
+ """
7
+
8
+ from typing import List, Union
9
+ import numpy as np
10
+ from sentence_transformers import SentenceTransformer
11
+
12
+
13
+ class EmbeddingModel:
14
+ """Wrapper for sentence transformer embedding model."""
15
+
16
+ def __init__(self, model_name: str):
17
+ """
18
+ Initialize embedding model.
19
+
20
+ Args:
21
+ model_name: HuggingFace model name (e.g., 'sentence-transformers/all-MiniLM-L6-v2')
22
+ """
23
+ self.model_name = model_name
24
+ self.model = SentenceTransformer(model_name)
25
+
26
+ def encode(self, text: Union[str, List[str]]) -> np.ndarray:
27
+ """
28
+ Encode text to embedding vector(s).
29
+
30
+ Args:
31
+ text: Single text string or list of texts
32
+
33
+ Returns:
34
+ Numpy array of embeddings (1D for single text, 2D for list)
35
+ """
36
+ embeddings = self.model.encode(text, convert_to_numpy=True)
37
+
38
+ # Ensure float32 for sqlite-vec compatibility
39
+ return embeddings.astype(np.float32)
40
+
41
+ def encode_single(self, text: str) -> np.ndarray:
42
+ """
43
+ Encode single text to embedding vector.
44
+
45
+ Args:
46
+ text: Single text string
47
+
48
+ Returns:
49
+ Numpy array of embedding (1D float32)
50
+ """
51
+ return self.encode(text)
52
+
53
+ def get_embedding_dim(self) -> int:
54
+ """Get embedding dimension."""
55
+ return self.model.get_sentence_embedding_dimension()
56
+
57
+
58
+ def get_embedding_model(model_name: str) -> EmbeddingModel:
59
+ """
60
+ Factory function to get embedding model instance.
61
+
62
+ Args:
63
+ model_name: HuggingFace model name
64
+
65
+ Returns:
66
+ Initialized EmbeddingModel instance
67
+ """
68
+ return EmbeddingModel(model_name)
src/models.py ADDED
@@ -0,0 +1,162 @@
1
+ """
2
+ Data Models and Type Definitions
3
+ ================================
4
+
5
+ Defines the core data structures used throughout the vector task system.
6
+ """
7
+
8
+ from dataclasses import dataclass
9
+ from datetime import datetime
10
+ from enum import Enum
11
+ from typing import List, Optional, Dict, Any
12
+ import json
13
+
14
+
15
+ class TaskStatus(Enum):
16
+ """Task status values for task management"""
17
+ PENDING = "pending"
18
+ IN_PROGRESS = "in_progress"
19
+ COMPLETED = "completed"
20
+ STOPPED = "stopped"
21
+
22
+ @classmethod
23
+ def list_values(cls) -> List[str]:
24
+ """Get list of all status values"""
25
+ return [status.value for status in cls]
26
+
27
+ @classmethod
28
+ def is_valid(cls, value: str) -> bool:
29
+ """Check if a value is a valid status"""
30
+ return value in cls.list_values()
31
+
32
+
33
+ class Priority(Enum):
34
+ """Task priority levels for task management"""
35
+ LOW = "low"
36
+ MEDIUM = "medium"
37
+ HIGH = "high"
38
+ CRITICAL = "critical"
39
+
40
+ @classmethod
41
+ def list_values(cls) -> List[str]:
42
+ """Get list of all priority values"""
43
+ return [priority.value for priority in cls]
44
+
45
+ @classmethod
46
+ def is_valid(cls, value: str) -> bool:
47
+ """Check if a value is a valid priority"""
48
+ return value in cls.list_values()
49
+
50
+
51
+ @dataclass
52
+ class Task:
53
+ """Represents a task entry"""
54
+ id: Optional[int] = None
55
+ parent_id: Optional[int] = None
56
+ status: str = TaskStatus.PENDING.value
57
+ priority: str = Priority.MEDIUM.value
58
+ title: str = ""
59
+ content: str = ""
60
+ comment: Optional[str] = None
61
+ created_at: Optional[datetime] = None
62
+ start_at: Optional[datetime] = None
63
+ finish_at: Optional[datetime] = None
64
+ content_hash: Optional[str] = None
65
+ tags: List[str] = None
66
+
67
+ def __post_init__(self):
68
+ """Initialize default values"""
69
+ if self.tags is None:
70
+ self.tags = []
71
+ if self.created_at is None:
72
+ self.created_at = datetime.utcnow()
73
+
74
+ def to_dict(self) -> Dict[str, Any]:
75
+ """Convert to dictionary for JSON serialization"""
76
+ return {
77
+ "id": self.id,
78
+ "parent_id": self.parent_id,
79
+ "status": self.status,
80
+ "priority": self.priority,
81
+ "title": self.title,
82
+ "content": self.content,
83
+ "comment": self.comment,
84
+ "created_at": self.created_at.isoformat() if self.created_at else None,
85
+ "start_at": self.start_at.isoformat() if self.start_at else None,
86
+ "finish_at": self.finish_at.isoformat() if self.finish_at else None,
87
+ "content_hash": self.content_hash,
88
+ "tags": self.tags
89
+ }
90
+
91
+ @classmethod
92
+ def from_db_row(cls, row: tuple) -> 'Task':
93
+ """Create Task from database row"""
94
+ return cls(
95
+ id=row[0],
96
+ parent_id=row[1] if len(row) > 1 else None,
97
+ status=row[2] if len(row) > 2 else TaskStatus.PENDING.value,
98
+ priority=row[3] if len(row) > 3 else Priority.MEDIUM.value,
99
+ title=row[4] if len(row) > 4 else "",
100
+ content=row[5] if len(row) > 5 else "",
101
+ comment=row[6] if len(row) > 6 else None,
102
+ tags=json.loads(row[7]) if len(row) > 7 and row[7] else [],
103
+ created_at=datetime.fromisoformat(row[8]) if len(row) > 8 and row[8] else None,
104
+ start_at=datetime.fromisoformat(row[9]) if len(row) > 9 and row[9] else None,
105
+ finish_at=datetime.fromisoformat(row[10]) if len(row) > 10 and row[10] else None,
106
+ content_hash=row[11] if len(row) > 11 else None
107
+ )
108
+
109
+
110
+ @dataclass
111
+ class TaskStats:
112
+ """Task statistics and breakdown by status"""
113
+ total_tasks: int = 0
114
+ by_status: Dict[str, int] = None
115
+ pending_count: int = 0
116
+ in_progress_count: int = 0
117
+ completed_count: int = 0
118
+ stopped_count: int = 0
119
+ with_subtasks: int = 0
120
+
121
+ def __post_init__(self):
122
+ """Initialize default values"""
123
+ if self.by_status is None:
124
+ self.by_status = {}
125
+
126
+ def to_dict(self) -> Dict[str, Any]:
127
+ """Convert to dictionary for JSON serialization"""
128
+ return {
129
+ "total_tasks": self.total_tasks,
130
+ "by_status": self.by_status,
131
+ "pending_count": self.pending_count,
132
+ "in_progress_count": self.in_progress_count,
133
+ "completed_count": self.completed_count,
134
+ "stopped_count": self.stopped_count,
135
+ "with_subtasks": self.with_subtasks
136
+ }
137
+
138
+
139
+ # Configuration constants
140
+ class Config:
141
+ """Configuration constants"""
142
+
143
+ # Server configuration
144
+ SERVER_NAME = "Vector Task MCP Server"
145
+ SERVER_VERSION = "1.0.0"
146
+
147
+ # Content limits
148
+ MAX_MEMORY_LENGTH = 10000 # Maximum length for content and comments (10K chars)
149
+ MAX_TAG_LENGTH = 50 # Maximum length for single tag
150
+ MAX_TAGS_PER_MEMORY = 10 # Maximum number of tags per task
151
+
152
+ # Search limits
153
+ MAX_MEMORIES_PER_SEARCH = 50 # Maximum results per search/list operation
154
+
155
+ # Bulk operation limits
156
+ MAX_BULK_CREATE = 50 # Maximum tasks per bulk create operation
157
+ MAX_BULK_DELETE = 100 # Maximum task IDs per bulk delete operation
158
+
159
+ # Database configuration
160
+ DB_NAME = "vector_tasks.db"
161
+ EMBEDDING_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
162
+ EMBEDDING_DIM = 384