55
66from mcp .server .fastmcp import FastMCP
77
8+ from ..annotations import ADDITIVE , ADDITIVE_IDEMPOTENT , DESTRUCTIVE , READONLY
89from ..permissions import PermissionLevel , require_permission
910from ..state import get_client
1011
@@ -125,7 +126,7 @@ def _format_participant(p: dict[str, Any]) -> dict[str, Any]:
125126def _register_read_tools (mcp : FastMCP ) -> None :
126127 """Register read-only Talk tools."""
127128
128- @mcp .tool ()
129+ @mcp .tool (annotations = READONLY )
129130 @require_permission (PermissionLevel .READ )
130131 async def list_conversations (include_notifications_disabled : bool = False ) -> str :
131132 """List all Talk conversations the current user is part of.
@@ -149,7 +150,7 @@ async def list_conversations(include_notifications_disabled: bool = False) -> st
149150 conversations = [_format_conversation (room ) for room in data ]
150151 return json .dumps (conversations , indent = 2 , default = str )
151152
152- @mcp .tool ()
153+ @mcp .tool (annotations = READONLY )
153154 @require_permission (PermissionLevel .READ )
154155 async def get_conversation (token : str ) -> str :
155156 """Get details about a specific Talk conversation.
@@ -165,7 +166,7 @@ async def get_conversation(token: str) -> str:
165166 data = await client .ocs_get (f"apps/spreed/api/v4/room/{ token } " )
166167 return json .dumps (_format_conversation (data ), indent = 2 , default = str )
167168
168- @mcp .tool ()
169+ @mcp .tool (annotations = READONLY )
169170 @require_permission (PermissionLevel .READ )
170171 async def get_messages (
171172 token : str ,
@@ -218,7 +219,7 @@ async def get_messages(
218219
219220 return "\n " .join (lines )
220221
221- @mcp .tool ()
222+ @mcp .tool (annotations = READONLY )
222223 @require_permission (PermissionLevel .READ )
223224 async def get_participants (token : str ) -> str :
224225 """List participants in a Talk conversation.
@@ -236,7 +237,7 @@ async def get_participants(token: str) -> str:
236237 participants = [_format_participant (p ) for p in data ]
237238 return json .dumps (participants , indent = 2 , default = str )
238239
239- @mcp .tool ()
240+ @mcp .tool (annotations = READONLY )
240241 @require_permission (PermissionLevel .READ )
241242 async def get_poll (token : str , poll_id : int ) -> str :
242243 """Get a poll from a Talk conversation.
@@ -264,7 +265,7 @@ async def get_poll(token: str, poll_id: int) -> str:
264265def _register_poll_tools (mcp : FastMCP ) -> None :
265266 """Register poll-related Talk tools (write + destructive)."""
266267
267- @mcp .tool ()
268+ @mcp .tool (annotations = ADDITIVE )
268269 @require_permission (PermissionLevel .WRITE )
269270 async def create_poll (
270271 token : str ,
@@ -304,7 +305,7 @@ async def create_poll(
304305 data = await client .ocs_post (f"apps/spreed/api/v1/poll/{ token } " , data = post_data )
305306 return json .dumps (_format_poll (data ), indent = 2 , default = str )
306307
307- @mcp .tool ()
308+ @mcp .tool (annotations = ADDITIVE_IDEMPOTENT )
308309 @require_permission (PermissionLevel .WRITE )
309310 async def vote_poll (token : str , poll_id : int , option_ids : list [int ]) -> str :
310311 """Vote on a poll in a Talk conversation.
@@ -332,7 +333,7 @@ async def vote_poll(token: str, poll_id: int, option_ids: list[int]) -> str:
332333 data = await client .ocs_post (f"apps/spreed/api/v1/poll/{ token } /{ poll_id } " , data = post_data )
333334 return json .dumps (_format_poll (data ), indent = 2 , default = str )
334335
335- @mcp .tool ()
336+ @mcp .tool (annotations = DESTRUCTIVE )
336337 @require_permission (PermissionLevel .DESTRUCTIVE )
337338 async def close_poll (token : str , poll_id : int ) -> str :
338339 """Close a poll in a Talk conversation.
@@ -358,7 +359,7 @@ async def close_poll(token: str, poll_id: int) -> str:
358359def _register_write_tools (mcp : FastMCP ) -> None :
359360 """Register write and destructive Talk tools for conversations and messages."""
360361
361- @mcp .tool ()
362+ @mcp .tool (annotations = ADDITIVE )
362363 @require_permission (PermissionLevel .WRITE )
363364 async def send_message (token : str , message : str , reply_to : int = 0 ) -> str :
364365 """Send a chat message to a Talk conversation.
@@ -381,7 +382,7 @@ async def send_message(token: str, message: str, reply_to: int = 0) -> str:
381382 data = await client .ocs_post (f"apps/spreed/api/v1/chat/{ token } " , data = post_data )
382383 return json .dumps (_format_message_full (data ), indent = 2 , default = str )
383384
384- @mcp .tool ()
385+ @mcp .tool (annotations = ADDITIVE )
385386 @require_permission (PermissionLevel .WRITE )
386387 async def create_conversation (
387388 room_type : int ,
@@ -410,7 +411,7 @@ async def create_conversation(
410411 data = await client .ocs_post ("apps/spreed/api/v4/room" , data = post_data )
411412 return json .dumps (_format_conversation (data ), indent = 2 , default = str )
412413
413- @mcp .tool ()
414+ @mcp .tool (annotations = DESTRUCTIVE )
414415 @require_permission (PermissionLevel .DESTRUCTIVE )
415416 async def delete_message (token : str , message_id : int ) -> str :
416417 """Delete a chat message from a Talk conversation.
@@ -429,7 +430,7 @@ async def delete_message(token: str, message_id: int) -> str:
429430 await client .ocs_delete (f"apps/spreed/api/v1/chat/{ token } /{ message_id } " )
430431 return f"Message { message_id } deleted from conversation { token } ."
431432
432- @mcp .tool ()
433+ @mcp .tool (annotations = DESTRUCTIVE )
433434 @require_permission (PermissionLevel .DESTRUCTIVE )
434435 async def leave_conversation (token : str ) -> str :
435436 """Leave a Talk conversation.
0 commit comments