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