refactored all tools to use fastmcp native responses
This commit is contained in:
@@ -91,7 +91,7 @@ def _correct_time_format_for_api(
|
||||
@server.tool()
|
||||
async def list_calendars(
|
||||
user_google_email: str,
|
||||
) -> types.CallToolResult:
|
||||
) -> str:
|
||||
"""
|
||||
Retrieves a list of calendars accessible to the authenticated user.
|
||||
|
||||
@@ -99,9 +99,7 @@ async def list_calendars(
|
||||
user_google_email (str): The user's Google email address. Required.
|
||||
|
||||
Returns:
|
||||
types.CallToolResult: Contains a list of the user's calendars (summary, ID, primary status),
|
||||
an error message if the API call fails,
|
||||
or an authentication guidance message if credentials are required.
|
||||
str: A formatted list of the user's calendars (summary, ID, primary status).
|
||||
"""
|
||||
tool_name = "list_calendars"
|
||||
logger.info(
|
||||
@@ -125,13 +123,7 @@ async def list_calendars(
|
||||
)
|
||||
items = calendar_list_response.get("items", [])
|
||||
if not items:
|
||||
return types.CallToolResult(
|
||||
content=[
|
||||
types.TextContent(
|
||||
type="text", text=f"No calendars found for {user_email}."
|
||||
)
|
||||
]
|
||||
)
|
||||
return f"No calendars found for {user_email}."
|
||||
|
||||
calendars_summary_list = [
|
||||
f"- \"{cal.get('summary', 'No Summary')}\"{' (Primary)' if cal.get('primary') else ''} (ID: {cal['id']})"
|
||||
@@ -142,21 +134,15 @@ async def list_calendars(
|
||||
+ "\n".join(calendars_summary_list)
|
||||
)
|
||||
logger.info(f"Successfully listed {len(items)} calendars for {user_email}.")
|
||||
return types.CallToolResult(
|
||||
content=[types.TextContent(type="text", text=text_output)]
|
||||
)
|
||||
return text_output
|
||||
except HttpError as error:
|
||||
message = f"API error listing calendars: {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with user's email and service_name='Google Calendar'."
|
||||
logger.error(message, exc_info=True)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
except Exception as e:
|
||||
message = f"Unexpected error listing calendars: {e}."
|
||||
logger.exception(message)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
|
||||
|
||||
@server.tool()
|
||||
@@ -166,7 +152,7 @@ async def get_events(
|
||||
time_min: Optional[str] = None,
|
||||
time_max: Optional[str] = None,
|
||||
max_results: int = 25,
|
||||
) -> types.CallToolResult:
|
||||
) -> str:
|
||||
"""
|
||||
Retrieves a list of events from a specified Google Calendar within a given time range.
|
||||
|
||||
@@ -178,9 +164,7 @@ async def get_events(
|
||||
max_results (int): The maximum number of events to return. Defaults to 25.
|
||||
|
||||
Returns:
|
||||
types.CallToolResult: Contains a list of events (summary, start time, link) within the specified range,
|
||||
an error message if the API call fails,
|
||||
or an authentication guidance message if credentials are required.
|
||||
str: A formatted list of events (summary, start time, link) within the specified range.
|
||||
"""
|
||||
tool_name = "get_events"
|
||||
|
||||
@@ -240,14 +224,7 @@ async def get_events(
|
||||
)
|
||||
items = events_result.get("items", [])
|
||||
if not items:
|
||||
return types.CallToolResult(
|
||||
content=[
|
||||
types.TextContent(
|
||||
type="text",
|
||||
text=f"No events found in calendar '{calendar_id}' for {user_email} for the specified time range.",
|
||||
)
|
||||
]
|
||||
)
|
||||
return f"No events found in calendar '{calendar_id}' for {user_email} for the specified time range."
|
||||
|
||||
event_details_list = []
|
||||
for item in items:
|
||||
@@ -265,21 +242,15 @@ async def get_events(
|
||||
+ "\n".join(event_details_list)
|
||||
)
|
||||
logger.info(f"Successfully retrieved {len(items)} events for {user_email}.")
|
||||
return types.CallToolResult(
|
||||
content=[types.TextContent(type="text", text=text_output)]
|
||||
)
|
||||
return text_output
|
||||
except HttpError as error:
|
||||
message = f"API error getting events: {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with user's email and service_name='Google Calendar'."
|
||||
logger.error(message, exc_info=True)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
except Exception as e:
|
||||
message = f"Unexpected error getting events: {e}."
|
||||
logger.exception(message)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
|
||||
|
||||
@server.tool()
|
||||
@@ -293,7 +264,7 @@ async def create_event(
|
||||
location: Optional[str] = None,
|
||||
attendees: Optional[List[str]] = None,
|
||||
timezone: Optional[str] = None,
|
||||
) -> types.CallToolResult:
|
||||
) -> str:
|
||||
"""
|
||||
Creates a new event.
|
||||
|
||||
@@ -309,7 +280,7 @@ async def create_event(
|
||||
timezone (Optional[str]): Timezone (e.g., "America/New_York").
|
||||
|
||||
Returns:
|
||||
A CallToolResult confirming creation or an error/auth guidance message.
|
||||
str: Confirmation message of the successful event creation with event link.
|
||||
"""
|
||||
tool_name = "create_event"
|
||||
logger.info(
|
||||
@@ -363,23 +334,17 @@ async def create_event(
|
||||
logger.info(
|
||||
f"Event created successfully for {user_email}. ID: {created_event.get('id')}, Link: {link}"
|
||||
)
|
||||
return types.CallToolResult(
|
||||
content=[types.TextContent(type="text", text=confirmation_message)]
|
||||
)
|
||||
return confirmation_message
|
||||
except HttpError as error:
|
||||
# Corrected error message to use user_email and provide better guidance
|
||||
# user_email_for_error is now user_email from the helper or the original user_google_email
|
||||
message = f"API error creating event: {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with the user's email ({user_email if user_email != 'Unknown' else 'target Google account'}) and service_name='Google Calendar'."
|
||||
logger.error(message, exc_info=True)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
except Exception as e:
|
||||
message = f"Unexpected error creating event: {e}."
|
||||
logger.exception(message)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
|
||||
|
||||
@server.tool()
|
||||
@@ -394,7 +359,7 @@ async def modify_event(
|
||||
location: Optional[str] = None,
|
||||
attendees: Optional[List[str]] = None,
|
||||
timezone: Optional[str] = None,
|
||||
) -> types.CallToolResult:
|
||||
) -> str:
|
||||
"""
|
||||
Modifies an existing event.
|
||||
|
||||
@@ -411,7 +376,7 @@ async def modify_event(
|
||||
timezone (Optional[str]): New timezone (e.g., "America/New_York").
|
||||
|
||||
Returns:
|
||||
A CallToolResult confirming modification or an error/auth guidance message.
|
||||
str: Confirmation message of the successful event modification with event link.
|
||||
"""
|
||||
tool_name = "modify_event"
|
||||
logger.info(
|
||||
@@ -471,9 +436,7 @@ async def modify_event(
|
||||
if not event_body:
|
||||
message = "No fields provided to modify the event."
|
||||
logger.warning(f"[modify_event] {message}")
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
|
||||
# Log the event ID for debugging
|
||||
logger.info(
|
||||
@@ -494,9 +457,7 @@ async def modify_event(
|
||||
f"[modify_event] Event not found during pre-update verification: {get_error}"
|
||||
)
|
||||
message = f"Event not found during verification. The event with ID '{event_id}' could not be found in calendar '{calendar_id}'. This may be due to incorrect ID format or the event no longer exists."
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
else:
|
||||
logger.warning(
|
||||
f"[modify_event] Error during pre-update verification, but proceeding with update: {get_error}"
|
||||
@@ -514,9 +475,7 @@ async def modify_event(
|
||||
logger.info(
|
||||
f"Event modified successfully for {user_email}. ID: {updated_event.get('id')}, Link: {link}"
|
||||
)
|
||||
return types.CallToolResult(
|
||||
content=[types.TextContent(type="text", text=confirmation_message)]
|
||||
)
|
||||
return confirmation_message
|
||||
except HttpError as error:
|
||||
# Check for 404 Not Found error specifically
|
||||
if error.resp.status == 404:
|
||||
@@ -525,15 +484,11 @@ async def modify_event(
|
||||
else:
|
||||
message = f"API error modifying event (ID: {event_id}): {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with the user's email ({user_email if user_email != 'Unknown' else 'target Google account'}) and service_name='Google Calendar'."
|
||||
logger.error(message, exc_info=True)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
except Exception as e:
|
||||
message = f"Unexpected error modifying event (ID: {event_id}): {e}."
|
||||
logger.exception(message)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
|
||||
|
||||
@server.tool()
|
||||
@@ -541,7 +496,7 @@ async def delete_event(
|
||||
user_google_email: str,
|
||||
event_id: str,
|
||||
calendar_id: str = "primary",
|
||||
) -> types.CallToolResult:
|
||||
) -> str:
|
||||
"""
|
||||
Deletes an existing event.
|
||||
|
||||
@@ -551,7 +506,7 @@ async def delete_event(
|
||||
calendar_id (str): Calendar ID (default: 'primary').
|
||||
|
||||
Returns:
|
||||
A CallToolResult confirming deletion or an error/auth guidance message.
|
||||
str: Confirmation message of the successful event deletion.
|
||||
"""
|
||||
tool_name = "delete_event"
|
||||
logger.info(
|
||||
@@ -590,9 +545,7 @@ async def delete_event(
|
||||
f"[delete_event] Event not found during pre-delete verification: {get_error}"
|
||||
)
|
||||
message = f"Event not found during verification. The event with ID '{event_id}' could not be found in calendar '{calendar_id}'. This may be due to incorrect ID format or the event no longer exists."
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
else:
|
||||
logger.warning(
|
||||
f"[delete_event] Error during pre-delete verification, but proceeding with deletion: {get_error}"
|
||||
@@ -605,9 +558,7 @@ async def delete_event(
|
||||
|
||||
confirmation_message = f"Successfully deleted event (ID: {event_id}) from calendar '{calendar_id}' for {user_email}."
|
||||
logger.info(f"Event deleted successfully for {user_email}. ID: {event_id}")
|
||||
return types.CallToolResult(
|
||||
content=[types.TextContent(type="text", text=confirmation_message)]
|
||||
)
|
||||
return confirmation_message
|
||||
except HttpError as error:
|
||||
# Check for 404 Not Found error specifically
|
||||
if error.resp.status == 404:
|
||||
@@ -616,12 +567,8 @@ async def delete_event(
|
||||
else:
|
||||
message = f"API error deleting event (ID: {event_id}): {error}. You might need to re-authenticate. LLM: Try 'start_google_auth' with the user's email ({user_email if user_email != 'Unknown' else 'target Google account'}) and service_name='Google Calendar'."
|
||||
logger.error(message, exc_info=True)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
except Exception as e:
|
||||
message = f"Unexpected error deleting event (ID: {event_id}): {e}."
|
||||
logger.exception(message)
|
||||
return types.CallToolResult(
|
||||
isError=True, content=[types.TextContent(type="text", text=message)]
|
||||
)
|
||||
raise Exception(message)
|
||||
|
||||
Reference in New Issue
Block a user