33import logging
44from typing import Any , Dict , List
55
6- from mcp .server .models import InitializationOptions
76from mcp .server import NotificationOptions , Server
7+ from mcp .server .models import InitializationOptions
88from mcp .server .stdio import stdio_server
99import mcp .types as types
1010
1111from task_tracker .api .linear_client import LinearClient
12- from task_tracker .api .timetracking_client import TimeTrackingClient
13-
14- linear_client = asyncio .run (LinearClient .create ())
15- timetracking_client = TimeTrackingClient ()
16- server = Server ("task-tracker" )
12+ from task_tracker .api .trackingtime_client import TrackingTimeClient
1713
1814logging .basicConfig (
1915 level = logging .INFO ,
2016 format = '%(asctime)s - %(levelname)s - %(message)s'
2117)
2218logger = logging .getLogger ("task-tracker" )
23- logger .info ("task-tracker server started" )
19+ logger .info ("starting task-tracker server" )
20+
21+ linear_client = asyncio .run (LinearClient .create ())
22+ trackingtime_client = TrackingTimeClient ()
23+ server = Server ("task-tracker" )
2424
2525
2626@server .list_tools ()
@@ -42,88 +42,91 @@ async def handle_list_tools() -> List[types.Tool]:
4242 }
4343 ),
4444 types .Tool (
45- name = "log_time " ,
46- description = "Log time for a task " ,
45+ name = "set_current_team " ,
46+ description = "Set the current Linear team by name " ,
4747 inputSchema = {
4848 "type" : "object" ,
4949 "properties" : {
50- "task_id" : {"type" : "string" },
51- "duration" : {"type" : "integer" },
52- "description" : {"type" : "string" }
50+ "team_name" : {"type" : "string" }
5351 },
54- "required" : ["task_id" , "duration" , "description " ]
52+ "required" : ["team_name " ]
5553 }
5654 ),
5755 types .Tool (
58- name = "start_tracking" ,
59- description = "Start time tracking for a task" ,
56+ name = "get_my_tasks" ,
57+ description = (
58+ "Get the Linear tasks assigned to me. "
59+ "Support task status: backlog, unstarted, started, completed, canceled, triage. "
60+ "Default is unstarted."
61+ ),
6062 inputSchema = {
6163 "type" : "object" ,
6264 "properties" : {
63- "project" : {
64- "type" : "string" ,
65- "description" : "task project"
66- },
67- "description" : {
68- "type" : "string" ,
69- "description" : "task name"
65+ "status" : {
66+ "type" : "array" ,
67+ "items" : {"type" : "string" },
68+ "optional" : True ,
69+ "description" : "List of task status to filter by"
7070 }
7171 },
72- "required" : ["project" , "description" ]
72+ "required" : []
7373 }
7474 ),
7575 types .Tool (
76- name = "stop_tracking " ,
77- description = "Stop current time tracking " ,
76+ name = "search_tasks " ,
77+ description = "Search Linear tasks by title or identifier " ,
7878 inputSchema = {
7979 "type" : "object" ,
8080 "properties" : {
81- "entry_id" : {"type" : "string" }
81+ "search_term" : {
82+ "type" : "string" ,
83+ "description" : "Text to search for in task titles or identifiers"
84+ }
8285 },
83- "required" : ["entry_id " ]
86+ "required" : ["search_term " ]
8487 }
8588 ),
8689 types .Tool (
87- name = "set_current_team " ,
88- description = "Set the current team by name " ,
90+ name = "start_tracking " ,
91+ description = "Start time tracking for a task " ,
8992 inputSchema = {
9093 "type" : "object" ,
9194 "properties" : {
92- "team_name" : {"type" : "string" }
95+ "project" : {
96+ "type" : "string" ,
97+ "description" : "task project"
98+ },
99+ "description" : {
100+ "type" : "string" ,
101+ "description" : "task name"
102+ }
93103 },
94- "required" : ["team_name " ]
104+ "required" : ["project" , "description " ]
95105 }
96106 ),
97107 types .Tool (
98- name = "get_my_tasks " ,
99- description = "Get tasks assigned to me. Support task status: backlog, unstarted, started, completed, canceled, triage. Default is unstarted. " ,
108+ name = "stop_tracking " ,
109+ description = "Stop current time tracking " ,
100110 inputSchema = {
101111 "type" : "object" ,
102112 "properties" : {
103- "status" : {
104- "type" : "array" ,
105- "items" : {"type" : "string" },
106- "optional" : True ,
107- "description" : "List of task status to filter by"
113+ "task_id" : {
114+ "type" : "string" ,
115+ "description" : "task id"
108116 }
109117 },
110- "required" : []
118+ "required" : ["task_id" ]
111119 }
112120 ),
113121 types .Tool (
114- name = "search_tasks " ,
115- description = "Search for tasks by title or identifier " ,
122+ name = "get_active_tracking " ,
123+ description = "Get the currently active tracking task " ,
116124 inputSchema = {
117125 "type" : "object" ,
118- "properties" : {
119- "search_term" : {
120- "type" : "string" ,
121- "description" : "Text to search for in task titles or identifiers"
122- }
123- },
124- "required" : ["search_term" ]
126+ "properties" : {},
127+ "required" : []
125128 }
126- )
129+ ),
127130 ]
128131
129132
@@ -147,37 +150,6 @@ async def handle_call_tool(name: str, arguments: Dict[str, Any] | None) -> List[
147150 json .dumps (result , indent = 2 )} "
148151 )]
149152
150- elif name == "log_time" :
151- result = await timetracking_client .log_time (
152- task_id = arguments ["task_id" ],
153- duration = arguments ["duration" ],
154- description = arguments ["description" ]
155- )
156- return [types .TextContent (
157- type = "text" ,
158- text = f"Time logged successfully: {
159- json .dumps (result , indent = 2 )} "
160- )]
161-
162- elif name == "start_tracking" :
163- result = await timetracking_client .start_tracking (
164- project = arguments ["project" ],
165- description = arguments ["description" ]
166- )
167- return [types .TextContent (
168- type = "text" ,
169- text = f"Time tracking started: { json .dumps (result , indent = 2 )} "
170- )]
171-
172- elif name == "stop_tracking" :
173- result = await timetracking_client .stop_tracking (
174- entry_id = arguments ["entry_id" ]
175- )
176- return [types .TextContent (
177- type = "text" ,
178- text = f"Time tracking stopped: { json .dumps (result , indent = 2 )} "
179- )]
180-
181153 elif name == "set_current_team" :
182154 team_name = arguments ["team_name" ]
183155 await linear_client .set_current_team (team_name )
@@ -215,6 +187,38 @@ async def handle_call_tool(name: str, arguments: Dict[str, Any] | None) -> List[
215187 json .dumps (tasks , indent = 2 )} "
216188 )]
217189
190+ elif name == "start_tracking" :
191+ result = await trackingtime_client .start_tracking (
192+ project = arguments ["project" ],
193+ description = arguments ["description" ]
194+ )
195+ return [types .TextContent (
196+ type = "text" ,
197+ text = f"Time tracking started: { json .dumps (result , indent = 2 )} "
198+ )]
199+
200+ elif name == "stop_tracking" :
201+ result = await trackingtime_client .stop_tracking (
202+ task_id = arguments ["task_id" ]
203+ )
204+ return [types .TextContent (
205+ type = "text" ,
206+ text = f"Time tracking stopped: { json .dumps (result , indent = 2 )} "
207+ )]
208+
209+ elif name == "get_active_tracking" :
210+ result = await trackingtime_client .get_tracking_task (filter = "TRACKING" )
211+ if not result :
212+ return [types .TextContent (
213+ type = "text" ,
214+ text = "No active time tracking task found"
215+ )]
216+ return [types .TextContent (
217+ type = "text" ,
218+ text = f"Current tracking task:\n {
219+ json .dumps (result , indent = 2 )} "
220+ )]
221+
218222 raise ValueError (f"Unknown tool: { name } " )
219223
220224 except Exception as e :
0 commit comments