Skip to main content
Glama

get_message

Retrieve a Basecamp project message by ID and render its content in markdown, HTML, text, or raw JSON format for viewing or processing.

Instructions

Fetch a single message by ID; render body as markdown/html/text, or return raw JSON.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYes
message_idYes
renderNo

Implementation Reference

  • The handler fetches the message content from Basecamp API using project_id and message_id, renders the HTML body to the specified format (markdown, html, text, or json), and returns the formatted output.
    async ({ project_id, message_id, render }) => {
      const msg = await bcRequest<any>(
        "GET",
        `/buckets/${project_id}/messages/${message_id}.json`
      );
      const subject = msg.subject ?? msg.title ?? "(no subject)";
      const html = msg.content || msg.body || "";
    
      const mode = render ?? "markdown";
      if (mode === "json") {
        return {
          content: [{ type: "text", text: JSON.stringify(msg, null, 2) }],
        };
      }
    
      const body = renderBody(html, mode as "markdown" | "html" | "text");
      const output =
        mode === "markdown"
          ? `# ${subject}\n\n${body}`
          : `${subject}\n\n${body}`;
    
      return { content: [{ type: "text", text: output }] };
    }
  • Input schema definition using Zod, including required project_id and message_id (numbers), and optional render format.
    {
      title: "Get a message",
      description:
        "Fetch a single message by ID; render body as markdown/html/text, or return raw JSON.",
      inputSchema: {
        project_id: z.number().int(),
        message_id: z.number().int(),
        render: z.enum(["markdown", "html", "text", "json"]).optional(), // default markdown
      },
    },
  • Direct registration of the 'get_message' tool on the MCP server, including name, schema, and handler.
    server.registerTool(
      "get_message",
      {
        title: "Get a message",
        description:
          "Fetch a single message by ID; render body as markdown/html/text, or return raw JSON.",
        inputSchema: {
          project_id: z.number().int(),
          message_id: z.number().int(),
          render: z.enum(["markdown", "html", "text", "json"]).optional(), // default markdown
        },
      },
      async ({ project_id, message_id, render }) => {
        const msg = await bcRequest<any>(
          "GET",
          `/buckets/${project_id}/messages/${message_id}.json`
        );
        const subject = msg.subject ?? msg.title ?? "(no subject)";
        const html = msg.content || msg.body || "";
    
        const mode = render ?? "markdown";
        if (mode === "json") {
          return {
            content: [{ type: "text", text: JSON.stringify(msg, null, 2) }],
          };
        }
    
        const body = renderBody(html, mode as "markdown" | "html" | "text");
        const output =
          mode === "markdown"
            ? `# ${subject}\n\n${body}`
            : `${subject}\n\n${body}`;
    
        return { content: [{ type: "text", text: output }] };
      }
    );
  • Helper function to render message HTML body into markdown (default), HTML, or plain text. Used by the get_message handler.
    function renderBody(
      html: string,
      render: "markdown" | "html" | "text" = "markdown"
    ): string {
      const markdown = td.turndown(html || "");
      if (render === "markdown") return markdown;
      if (render === "html") return html || "";
      // crude Markdown → plain-text
      return markdown
        .replace(/```[\s\S]*?```/g, "") // drop code blocks
        .replace(/`([^`]+)`/g, "$1") // inline code
        .replace(/!\[([^\]]*)]\([^)]*\)/g, "$1") // images
        .replace(/\[([^\]]+)]\([^)]*\)/g, "$1") // links
        .replace(/^[#>\-\*\d\.\s]+/gm, "") // headings/quotes/lists
        .replace(/[*_~`]/g, "") // emphasis
        .trim();
    }
  • Top-level call to registerMessageTools, which includes registration of the 'get_message' tool.
    registerMessageTools(server);

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/craigashields/basecamp-mcp'

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