get_comments
Retrieve all comments across projects and tasks with full context including text, author details, timestamps, discussion threads, attachments, and mentions to track project communications and feedback.
Instructions
Get all comments across projects and tasks with full context.
Returns comprehensive comment data including:
Comment text, author, and timestamp
Parent entity (project, task, or other) with details
Discussion threads and replies
Attachments and file references
Mentions of team members or clients
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| extra_filters | No | Additional Productive query filters (e.g. {'filter[discussion_id]': '123'}) | |
| page_number | No | Page number for pagination | |
| page_size | No | Number of comments per page (max 200) | |
| project_id | No | Productive project ID to filter comments by | |
| task_id | No | Productive task ID to filter comments by |
Implementation Reference
- tools.py:213-257 (handler)Core handler function implementing the get_comments tool logic: builds Productive API parameters from inputs (project_id, task_id, pagination, filters), calls client.get_comments, filters response, handles errors.async def get_comments( ctx: Context, project_id: int = None, task_id: int = None, page_number: int = None, page_size: int = config.items_per_page, extra_filters: dict = None ) -> ToolResult: """List comments with optional filters and pagination. Developer notes: - Pass-through for extra_filters (e.g., discussion_id, page_id, task_id). - Enforces configurable default page[size] if not provided. - Sort defaults to "-created_at" (most recent first). - Applies utils.filter_response to sanitize. - Uses consistent scalar filters: filter[project_id][eq], filter[task_id][eq] """ try: await ctx.info("Fetching comments") params = {} if page_number is not None: params["page[number]"] = page_number params["page[size]"] = page_size if project_id is not None: params["filter[project_id][eq]"] = project_id if task_id is not None: params["filter[task_id][eq]"] = task_id if extra_filters: params.update(extra_filters) # Add default sorting params["sort"] = "-created_at" result = await client.get_comments(params=params if params else None) await ctx.info("Successfully retrieved comments") filtered = filter_response(result) return filtered except ProductiveAPIError as e: await _handle_productive_api_error(ctx, e, "comments") except Exception as e: await ctx.error(f"Unexpected error fetching comments: {str(e)}") raise e
- server.py:318-353 (registration)MCP registration of the get_comments tool via @mcp.tool decorator, delegates to tools.get_comments handler, includes input schema definitions via Annotated[Field].async def get_comments( ctx: Context, project_id: Annotated[ int, Field(description="Productive project ID to filter comments by") ] = None, task_id: Annotated[ int, Field(description="Productive task ID to filter comments by") ] = None, page_number: Annotated[int, Field(description="Page number for pagination")] = None, page_size: Annotated[ int, Field(description="Optional number of comments per page (max 200)") ] = None, extra_filters: Annotated[ dict, Field( description="Additional Productive query filters using API syntax. Common filters: filter[project_id][eq] (ID), filter[task_id][eq] (ID), filter[discussion_id][eq] (ID)." ), ] = None, ) -> Dict[str, Any]: """Get all comments across projects and tasks with full context. Returns comprehensive comment data including: - Comment text, author, and timestamp - Parent entity (project, task, or other) with details - Discussion threads and replies - Attachments and file references - Mentions of team members or clients """ return await tools.get_comments( ctx, project_id=project_id, task_id=task_id, page_number=page_number, page_size=page_size, extra_filters=extra_filters, )
- server.py:318-353 (schema)Input schema for get_comments tool defined in the function signature using Annotated and Field descriptions for parameters: project_id, task_id, page_number, page_size, extra_filters.async def get_comments( ctx: Context, project_id: Annotated[ int, Field(description="Productive project ID to filter comments by") ] = None, task_id: Annotated[ int, Field(description="Productive task ID to filter comments by") ] = None, page_number: Annotated[int, Field(description="Page number for pagination")] = None, page_size: Annotated[ int, Field(description="Optional number of comments per page (max 200)") ] = None, extra_filters: Annotated[ dict, Field( description="Additional Productive query filters using API syntax. Common filters: filter[project_id][eq] (ID), filter[task_id][eq] (ID), filter[discussion_id][eq] (ID)." ), ] = None, ) -> Dict[str, Any]: """Get all comments across projects and tasks with full context. Returns comprehensive comment data including: - Comment text, author, and timestamp - Parent entity (project, task, or other) with details - Discussion threads and replies - Attachments and file references - Mentions of team members or clients """ return await tools.get_comments( ctx, project_id=project_id, task_id=task_id, page_number=page_number, page_size=page_size, extra_filters=extra_filters, )
- productive_client.py:90-93 (helper)Helper method in ProductiveClient that performs the actual API GET request to /comments endpoint with optional params.async def get_comments(self, params: Optional[dict] = None) -> Dict[str, Any]: """Get all comments """ return await self._request("GET", "/comments", params=params)