Skip to main content
Glama

get_discussion_entry_details

Retrieve comprehensive details for a individual discussion entry within a Canvas course, including its content and all associated replies when specified.

Instructions

Get detailed information about a specific discussion entry including all its replies.

Args: course_identifier: The Canvas course code (e.g., badm_554_120251_246794) or ID topic_id: The Canvas discussion topic ID entry_id: The Canvas discussion entry ID include_replies: Whether to fetch and include replies (default: True)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
course_identifierYes
entry_idYes
include_repliesNo
topic_idYes

Implementation Reference

  • The primary handler function implementing the 'get_discussion_entry_details' MCP tool. Fetches detailed entry information including content, metadata, and optional replies via Canvas API endpoints like /view, /entry_list, /entries, and /replies.
    @validate_params async def get_discussion_entry_details(course_identifier: str | int, topic_id: str | int, entry_id: str | int, include_replies: bool = True) -> str: """Get detailed information about a specific discussion entry including all its replies. Args: course_identifier: The Canvas course code (e.g., badm_554_120251_246794) or ID topic_id: The Canvas discussion topic ID entry_id: The Canvas discussion entry ID include_replies: Whether to fetch and include replies (default: True) """ course_id = await get_course_id(course_identifier) # Method 1: Try to get entry details from the discussion view endpoint entry_response = None replies = [] try: # First try the discussion view endpoint which includes all entries view_response = await make_canvas_request( "get", f"/courses/{course_id}/discussion_topics/{topic_id}/view" ) if "error" not in view_response and "view" in view_response: # Find our specific entry in the view for entry in view_response.get("view", []): if str(entry.get("id")) == str(entry_id): entry_response = entry if include_replies: replies = entry.get("replies", []) break except Exception as e: log_warning( "Failed to fetch discussion view for entry details", exc=e, course_id=course_id, topic_id=topic_id, entry_id=entry_id ) # Method 2: If view method failed, try the entry_list endpoint if not entry_response: try: entry_list_response = await make_canvas_request( "get", f"/courses/{course_id}/discussion_topics/{topic_id}/entry_list", params={"ids[]": entry_id} ) if "error" not in entry_list_response and isinstance(entry_list_response, list): if entry_list_response: entry_response = entry_list_response[0] except Exception as e: log_warning( "Failed to fetch entry from entry_list", exc=e, course_id=course_id, topic_id=topic_id, entry_id=entry_id ) # Method 3: Fallback to getting all entries and finding our target if not entry_response: try: all_entries = await fetch_all_paginated_results( f"/courses/{course_id}/discussion_topics/{topic_id}/entries", {"per_page": 100} ) if not isinstance(all_entries, dict) or "error" not in all_entries: for entry in all_entries: if str(entry.get("id")) == str(entry_id): entry_response = entry # Get recent_replies from this method if include_replies: replies = entry.get("recent_replies", []) break except Exception as e: log_warning( "Failed to fetch all entries as fallback", exc=e, course_id=course_id, topic_id=topic_id, entry_id=entry_id ) # If we still don't have the entry, return error if not entry_response: return f"Error: Could not find discussion entry {entry_id} in topic {topic_id}. The entry may not exist or you may not have permission to view it." # Method 4: If we have the entry but no replies yet, try the replies endpoint if include_replies and not replies: try: replies_response = await fetch_all_paginated_results( f"/courses/{course_id}/discussion_topics/{topic_id}/entries/{entry_id}/replies", {"per_page": 100} ) if not isinstance(replies_response, dict) or "error" not in replies_response: replies = replies_response except Exception as e: log_warning( "Failed to fetch entry replies from replies endpoint", exc=e, course_id=course_id, topic_id=topic_id, entry_id=entry_id ) # Get topic details for context topic_response = await make_canvas_request( "get", f"/courses/{course_id}/discussion_topics/{topic_id}" ) topic_title = "Unknown Topic" if "error" not in topic_response: topic_title = topic_response.get("title", "Unknown Topic") # Format the entry details course_display = await get_course_code(course_id) or course_identifier user_id = entry_response.get("user_id") user_name = entry_response.get("user_name", "Unknown user") message = entry_response.get("message", "") created_at = format_date(entry_response.get("created_at")) updated_at = format_date(entry_response.get("updated_at")) read_state = entry_response.get("read_state", "unknown") result = f"Discussion Entry Details for '{topic_title}' in Course {course_display}:\n\n" result += f"Topic ID: {topic_id}\n" result += f"Entry ID: {entry_id}\n" result += f"Author: {user_name} (ID: {user_id})\n" result += f"Posted: {created_at}\n" if updated_at != "N/A" and updated_at != created_at: result += f"Updated: {updated_at}\n" result += f"Read State: {read_state.title()}\n" result += f"\nContent:\n{message}\n" # Format replies if include_replies: if replies: result += f"\nReplies ({len(replies)}):\n" result += "=" * 50 + "\n" for i, reply in enumerate(replies, 1): reply_id = reply.get("id") reply_user_name = reply.get("user_name", "Unknown user") reply_message = reply.get("message", "") reply_created_at = format_date(reply.get("created_at")) result += f"\nReply #{i}:\n" result += f"Reply ID: {reply_id}\n" result += f"Author: {reply_user_name}\n" result += f"Posted: {reply_created_at}\n" result += f"Content:\n{reply_message}\n" else: result += "\nNo replies found for this entry." else: result += "\n(Replies not included - set include_replies=True to fetch them)" return result
  • Function that defines and registers all discussion tools, including get_discussion_entry_details, using @mcp.tool() decorators.
    def register_discussion_tools(mcp: FastMCP): """Register all discussion and announcement MCP tools.""" # ===== DISCUSSION TOOLS =====
  • Registration of discussion tools (including get_discussion_entry_details) by calling register_discussion_tools(mcp) in the main server setup.
    def register_all_tools(mcp: FastMCP) -> None: """Register all MCP tools, resources, and prompts.""" log_info("Registering Canvas MCP tools...") # Register tools by category register_course_tools(mcp) register_assignment_tools(mcp) register_discussion_tools(mcp)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vishalsachdev/canvas-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server