Skip to main content
Glama

discourse_read_post

Retrieve content from a specific post in Discourse forums by providing its post ID for reading and analysis.

Instructions

Read a specific post.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
post_idYes

Implementation Reference

  • The asynchronous handler function that executes the tool logic: fetches the post data from Discourse API using the selected site's client, extracts relevant information like username, content, and URL, truncates if necessary, formats into a text response, and handles errors.
    async ({ post_id }, _extra: any) => {
      try {
        const { base, client } = ctx.siteState.ensureSelectedSite();
        // Prefer raw by asking API for include_raw
        const data = (await client.getCached(`/posts/${post_id}.json?include_raw=true`, 10000)) as any;
        const username = data?.username || data?.user_id || "user";
        const created = data?.created_at || "";
        const raw: string = data?.raw || data?.cooked || "";
        const limit = Number.isFinite(ctx.maxReadLength) ? ctx.maxReadLength : 50000;
        const content = raw.slice(0, limit);
        const url = data?.topic_slug && data?.topic_id
          ? `${base}/t/${data.topic_slug}/${data.topic_id}/${data.post_number}`
          : `${base}/posts/${post_id}`;
        const text = `Post by @${username} (${created})\n\n${content}${raw.length > content.length ? `\n… (+${raw.length - content.length} more)` : ""}\n\nLink: ${url}`;
        return { content: [{ type: "text", text }] };
      } catch (e: any) {
        return { content: [{ type: "text", text: `Failed to read post ${post_id}: ${e?.message || String(e)}` }], isError: true };
      }
    }
  • Zod schema defining the input parameters for the tool: a positive integer post_id.
    const schema = z.object({
      post_id: z.number().int().positive(),
    });
  • The server.registerTool call that registers the 'discourse_read_post' tool, specifying its name, metadata (title, description), input schema, and handler function.
    server.registerTool(
      "discourse_read_post",
      {
        title: "Read Post",
        description: "Read a specific post.",
        inputSchema: schema.shape,
      },
      async ({ post_id }, _extra: any) => {
        try {
          const { base, client } = ctx.siteState.ensureSelectedSite();
          // Prefer raw by asking API for include_raw
          const data = (await client.getCached(`/posts/${post_id}.json?include_raw=true`, 10000)) as any;
          const username = data?.username || data?.user_id || "user";
          const created = data?.created_at || "";
          const raw: string = data?.raw || data?.cooked || "";
          const limit = Number.isFinite(ctx.maxReadLength) ? ctx.maxReadLength : 50000;
          const content = raw.slice(0, limit);
          const url = data?.topic_slug && data?.topic_id
            ? `${base}/t/${data.topic_slug}/${data.topic_id}/${data.post_number}`
            : `${base}/posts/${post_id}`;
          const text = `Post by @${username} (${created})\n\n${content}${raw.length > content.length ? `\n… (+${raw.length - content.length} more)` : ""}\n\nLink: ${url}`;
          return { content: [{ type: "text", text }] };
        } catch (e: any) {
          return { content: [{ type: "text", text: `Failed to read post ${post_id}: ${e?.message || String(e)}` }], isError: true };
        }
      }
    );
  • The call to registerReadPost during the initialization of all tools in the registry, passing server, context, and options.
    registerReadPost(server, ctx, { allowWrites: false });

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/SamSaffron/discourse-mcp'

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