Skip to main content
Glama
rhettlong

USCardForum MCP Server

by rhettlong

get_all_topic_posts

Fetch all posts from a USCardForum topic with automatic pagination, allowing control over post ranges and limits for efficient data retrieval.

Instructions

Fetch all posts from a topic with automatic pagination.

Args:
    topic_id: The numeric topic ID
    include_raw: Include markdown source (default: False)
    start_post_number: First post to fetch (default: 1)
    end_post_number: Last post to fetch (optional, fetches to end if not set)
    max_posts: Maximum number of posts to return (optional safety limit)

This automatically handles pagination to fetch multiple batches.

IMPORTANT: For topics with many posts (>100), use max_posts to limit
the response size. You can always fetch more with start_post_number.

Use cases:
- Fetch entire small topic: get_all_topic_posts(topic_id=123)
- Fetch first 50 posts: get_all_topic_posts(topic_id=123, max_posts=50)
- Fetch posts 51-100: get_all_topic_posts(topic_id=123, start_post_number=51, max_posts=50)
- Fetch specific range: get_all_topic_posts(topic_id=123, start=10, end=30)

Returns the same Post structure as get_topic_posts but for all matching posts.

Pro tip: Use get_topic_info first to check post_count before deciding
whether to fetch all or paginate manually.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
topic_idYesThe numeric topic ID
include_rawNoInclude markdown source (default: False)
start_post_numberNoFirst post to fetch (default: 1)
end_post_numberNoLast post to fetch (optional, fetches to end if not set)
max_postsNoMaximum number of posts to return (optional safety limit)

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Primary MCP tool handler for get_all_topic_posts. Decorated with @mcp.tool(), defines input/output schema using Annotated and Field, implements logic by delegating to DiscourseClient.get_all_topic_posts().
    @mcp.tool()
    def get_all_topic_posts(
        topic_id: Annotated[
            int,
            Field(description="The numeric topic ID"),
        ],
        include_raw: Annotated[
            bool,
            Field(default=False, description="Include markdown source (default: False)"),
        ] = False,
        start_post_number: Annotated[
            int,
            Field(default=1, description="First post to fetch (default: 1)"),
        ] = 1,
        end_post_number: Annotated[
            int | None,
            Field(default=None, description="Last post to fetch (optional, fetches to end if not set)"),
        ] = None,
        max_posts: Annotated[
            int | None,
            Field(default=None, description="Maximum number of posts to return (optional safety limit)"),
        ] = None,
    ) -> list[Post]:
        """
        Fetch all posts from a topic with automatic pagination.
    
        Args:
            topic_id: The numeric topic ID
            include_raw: Include markdown source (default: False)
            start_post_number: First post to fetch (default: 1)
            end_post_number: Last post to fetch (optional, fetches to end if not set)
            max_posts: Maximum number of posts to return (optional safety limit)
    
        This automatically handles pagination to fetch multiple batches.
    
        IMPORTANT: For topics with many posts (>100), use max_posts to limit
        the response size. You can always fetch more with start_post_number.
    
        Use cases:
        - Fetch entire small topic: get_all_topic_posts(topic_id=123)
        - Fetch first 50 posts: get_all_topic_posts(topic_id=123, max_posts=50)
        - Fetch posts 51-100: get_all_topic_posts(topic_id=123, start_post_number=51, max_posts=50)
        - Fetch specific range: get_all_topic_posts(topic_id=123, start=10, end=30)
    
        Returns the same Post structure as get_topic_posts but for all matching posts.
    
        Pro tip: Use get_topic_info first to check post_count before deciding
        whether to fetch all or paginate manually.
        """
        return get_client().get_all_topic_posts(
            topic_id,
            include_raw=include_raw,
            start_post_number=start_post_number,
            end_post_number=end_post_number,
            max_posts=max_posts,
        )
  • Top-level import of all tools including get_all_topic_posts (line 20) in the main server entrypoint, which triggers auto-registration via FastMCP decorators.
    from uscardforum.server_tools import (
        analyze_user,
        bookmark_post,
        compare_cards,
        find_data_points,
        get_all_topic_posts,
        get_categories,
        get_current_session,
        get_hot_topics,
        get_new_topics,
        get_notifications,
        get_top_topics,
        get_topic_info,
        get_topic_posts,
        get_user_actions,
        get_user_badges,
        get_user_followers,
        get_user_following,
        get_user_reactions,
        get_user_replies,
        get_user_summary,
        get_user_topics,
        list_users_with_badge,
        login,
        research_topic,
        resource_categories,
        resource_hot_topics,
        resource_new_topics,
        search_forum,
        subscribe_topic,
    )
  • DiscourseClient wrapper method get_all_topic_posts that delegates to internal _topics API, called by the MCP tool handler.
    def get_all_topic_posts(
        self,
        topic_id: int,
        *,
        include_raw: bool = False,
        start_post_number: int = 1,
        end_post_number: int | None = None,
        max_posts: int | None = None,
    ) -> list[Post]:
        """Fetch all posts in a topic with automatic pagination.
    
        Args:
            topic_id: Topic ID
            include_raw: Include raw markdown (default: False)
            start_post_number: Starting post number (default: 1)
            end_post_number: Optional ending post number
            max_posts: Optional maximum posts to fetch
    
        Returns:
            List of all matching posts
        """
        return self._topics.get_all_topic_posts(
            topic_id,
            include_raw=include_raw,
            start_post_number=start_post_number,
            end_post_number=end_post_number,
            max_posts=max_posts,
        )
  • Core implementation of get_all_topic_posts in TopicsAPI class, performing automatic pagination by repeatedly calling get_topic_posts until conditions met.
    def get_all_topic_posts(
        self,
        topic_id: int,
        *,
        include_raw: bool = False,
        start_post_number: int = 1,
        end_post_number: int | None = None,
        max_posts: int | None = None,
    ) -> list[Post]:
        """Fetch all posts in a topic with automatic pagination.
    
        Args:
            topic_id: Topic ID
            include_raw: Include raw markdown (default: False)
            start_post_number: Starting post number (default: 1)
            end_post_number: Optional ending post number
            max_posts: Optional maximum posts to fetch
    
        Returns:
            List of all matching posts
        """
        current = max(1, int(start_post_number))
        collected: list[Post] = []
        seen_numbers: set[int] = set()
    
        while True:
            if max_posts is not None and len(collected) >= int(max_posts):
                break
    
            batch = self.get_topic_posts(
                topic_id, post_number=current, include_raw=include_raw
            )
            if not batch:
                break
    
            last_in_batch: int | None = None
            for post in batch:
                pn = post.post_number
                if pn not in seen_numbers:
                    if end_post_number is not None and pn > int(end_post_number):
                        last_in_batch = last_in_batch or pn
                        continue
                    seen_numbers.add(pn)
                    collected.append(post)
                    last_in_batch = pn
                    if max_posts is not None and len(collected) >= int(max_posts):
                        break
    
            if last_in_batch is None:
                break
            current = last_in_batch + 1
            if end_post_number is not None and current > int(end_post_number):
                break
    
        collected.sort(key=lambda p: p.post_number)
        return collected
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and does an excellent job disclosing behavioral traits. It explains automatic pagination handling, safety considerations for large topics, and the relationship between parameters like start_post_number and max_posts. It also clarifies the return structure matches 'get_topic_posts' but for all matching posts.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly structured and front-loaded with the core purpose, followed by organized sections for arguments, important notes, use cases, returns, and pro tips. Every sentence earns its place by providing essential information without redundancy, making it both comprehensive and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (5 parameters, automatic pagination) and the presence of an output schema (which handles return values), the description is complete. It covers purpose, usage guidelines, parameter interactions, behavioral traits, and relationships with sibling tools, leaving no significant gaps for agent understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the baseline is 3, but the description adds significant value beyond the schema. It explains how parameters interact (e.g., 'end_post_number fetches to end if not set'), provides practical examples of parameter combinations, and clarifies the safety purpose of max_posts. The 'Pro tip' section adds contextual guidance about parameter usage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('fetch all posts from a topic') and distinguishes it from sibling tools like 'get_topic_posts' by emphasizing automatic pagination. It explicitly mentions fetching entire topics versus manual pagination alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool versus alternatives, including specific use cases with parameter examples. It advises using 'get_topic_info first to check post_count before deciding whether to fetch all or paginate manually,' and includes an 'IMPORTANT' note about limiting response size for large topics.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/rhettlong/uscardforum-mcp'

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