Skip to main content
Glama
manimohans

Farcaster MCP Server

by manimohans

get-channel-casts

Retrieve posts from a Farcaster channel to monitor discussions or analyze content. Specify the channel name and optionally limit results.

Instructions

Get casts from a specific Farcaster channel

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
channelYesChannel name (e.g., 'aichannel') or URL
limitNoMaximum number of casts to return (default: 10)

Implementation Reference

  • Full inline handler and registration for the get-channel-casts tool. Fetches casts from Farcaster channel using Hubble API, formats with helpers, returns formatted text.
    server.tool("get-channel-casts", "Get casts from a specific Farcaster channel", {
        channel: zod_1.z.string().describe("Channel name or parent URL"),
        limit: zod_1.z.number().optional().describe("Maximum number of casts to return (default: 10)")
    }, function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
        var channelHash, response, castsText, error_8;
        var channel = _b.channel, _c = _b.limit, limit = _c === void 0 ? 10 : _c;
        return __generator(this, function (_d) {
            switch (_d.label) {
                case 0:
                    _d.trys.push([0, 3, , 4]);
                    channelHash = channel.startsWith("0x") ? channel : "0x".concat(buffer_1.Buffer.from(channel).toString("hex"));
                    return [4 /*yield*/, fetchFromHubble("/castsByParent", {
                            parent_url: channelHash,
                            pageSize: limit,
                            reverse: 1 // Get newest first
                        })];
                case 1:
                    response = _d.sent();
                    if (!response.messages || response.messages.length === 0) {
                        return [2 /*return*/, {
                                content: [
                                    {
                                        type: "text",
                                        text: "No casts found for channel \"".concat(channel, "\"")
                                    }
                                ]
                            }];
                    }
                    return [4 /*yield*/, formatCasts(response.messages, limit)];
                case 2:
                    castsText = _d.sent();
                    return [2 /*return*/, {
                            content: [
                                {
                                    type: "text",
                                    text: "# Recent Casts in Channel \"".concat(channel, "\"\n\n").concat(castsText)
                                }
                            ]
                        }];
                case 3:
                    error_8 = _d.sent();
                    console.error("Error in get-channel-casts:", error_8);
                    return [2 /*return*/, {
                            content: [
                                {
                                    type: "text",
                                    text: "Error fetching channel casts: ".concat(error_8 instanceof Error ? error_8.message : String(error_8))
                                }
                            ],
                            isError: true
                        }];
                case 4: return [2 /*return*/];
            }
        });
    }); });
  • Zod input schema defining parameters for the get-channel-casts tool.
    channel: zod_1.z.string().describe("Channel name or parent URL"),
    limit: zod_1.z.number().optional().describe("Maximum number of casts to return (default: 10)")
  • Key helper function used by the handler to format cast data including fetching user info, reactions, timestamps, and structuring output.
    function formatCasts(casts_1) {
        return __awaiter(this, arguments, void 0, function (casts, limit) {
            var castAdds, limitedCasts, formattedCastsPromises, formattedCasts;
            var _this = this;
            if (limit === void 0) { limit = 10; }
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!casts || casts.length === 0) {
                            return [2 /*return*/, "No casts found."];
                        }
                        console.error("Formatting ".concat(casts.length, " casts"));
                        castAdds = casts.filter(function (cast) {
                            return cast.data && cast.data.type === "MESSAGE_TYPE_CAST_ADD" && cast.data.castAddBody;
                        });
                        if (castAdds.length === 0) {
                            return [2 /*return*/, "No cast additions found."];
                        }
                        limitedCasts = castAdds.slice(0, limit);
                        formattedCastsPromises = limitedCasts.map(function (cast, index) { return __awaiter(_this, void 0, void 0, function () {
                            var fid, userData, reactions, farcasterEpoch, date, username, displayName, replyInfo, embedsInfo, error_4;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        _a.trys.push([0, 3, , 4]);
                                        // Check if cast and cast.data exist
                                        if (!cast || !cast.data || !cast.data.castAddBody) {
                                            console.error("Invalid cast at index ".concat(index, ":"), cast);
                                            return [2 /*return*/, "".concat(index + 1, ". [Invalid cast format]")];
                                        }
                                        fid = cast.data.fid;
                                        return [4 /*yield*/, getUserData(fid)];
                                    case 1:
                                        userData = _a.sent();
                                        return [4 /*yield*/, getReactionsForCast(cast.hash)];
                                    case 2:
                                        reactions = _a.sent();
                                        farcasterEpoch = new Date('2021-01-01T00:00:00Z').getTime() / 1000;
                                        date = new Date((cast.data.timestamp + farcasterEpoch) * 1000).toLocaleString();
                                        username = userData.username || 'unknown';
                                        displayName = userData.displayName || username;
                                        replyInfo = "";
                                        if (cast.data.castAddBody.parentCastId) {
                                            replyInfo = "   Reply to: ".concat(cast.data.castAddBody.parentCastId.fid, "/").concat(cast.data.castAddBody.parentCastId.hash, "\n");
                                        }
                                        embedsInfo = "";
                                        if (cast.data.castAddBody.embeds && cast.data.castAddBody.embeds.length > 0) {
                                            embedsInfo = "   Embeds: " + cast.data.castAddBody.embeds.map(function (embed) {
                                                if (embed.url)
                                                    return embed.url;
                                                return "embedded content";
                                            }).join(", ") + "\n";
                                        }
                                        return [2 /*return*/, "\n".concat(index + 1, ". @").concat(username, " (").concat(displayName, ")\n   FID: ").concat(fid, "\n   Time: ").concat(date, "\n   Text: ").concat(cast.data.castAddBody.text, "\n").concat(replyInfo).concat(embedsInfo, "   Likes: ").concat(reactions.likes, " | Recasts: ").concat(reactions.recasts, "\n   Cast ID: ").concat(cast.hash, "\n   ")];
                                    case 3:
                                        error_4 = _a.sent();
                                        console.error("Error formatting cast at index ".concat(index, ":"), error_4);
                                        return [2 /*return*/, "".concat(index + 1, ". [Error formatting cast]")];
                                    case 4: return [2 /*return*/];
                                }
                            });
                        }); });
                        return [4 /*yield*/, Promise.all(formattedCastsPromises)];
                    case 1:
                        formattedCasts = _a.sent();
                        return [2 /*return*/, formattedCasts.join("\n---\n")];
                }
            });
        });
    }
  • Helper to retrieve user profile data (username, display name, etc.) for a given FID, used in formatting.
    function getUserData(fid) {
        return __awaiter(this, void 0, void 0, function () {
            var usernameResponse, displayNameResponse, pfpResponse, bioResponse, userData, error_2;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        _a.trys.push([0, 5, , 6]);
                        return [4 /*yield*/, fetchFromHubble("/userDataByFid", {
                                fid: fid,
                                user_data_type: 1 // USERNAME
                            })];
                    case 1:
                        usernameResponse = _a.sent();
                        return [4 /*yield*/, fetchFromHubble("/userDataByFid", {
                                fid: fid,
                                user_data_type: 2 // DISPLAY_NAME
                            })];
                    case 2:
                        displayNameResponse = _a.sent();
                        return [4 /*yield*/, fetchFromHubble("/userDataByFid", {
                                fid: fid,
                                user_data_type: 3 // PFP
                            })];
                    case 3:
                        pfpResponse = _a.sent();
                        return [4 /*yield*/, fetchFromHubble("/userDataByFid", {
                                fid: fid,
                                user_data_type: 4 // BIO
                            })];
                    case 4:
                        bioResponse = _a.sent();
                        userData = { fid: fid, type: 0 };
                        if (usernameResponse.messages && usernameResponse.messages.length > 0) {
                            userData.username = usernameResponse.messages[0].data.userDataBody.value;
                        }
                        if (displayNameResponse.messages && displayNameResponse.messages.length > 0) {
                            userData.displayName = displayNameResponse.messages[0].data.userDataBody.value;
                        }
                        if (pfpResponse.messages && pfpResponse.messages.length > 0) {
                            userData.pfpUrl = pfpResponse.messages[0].data.userDataBody.value;
                        }
                        if (bioResponse.messages && bioResponse.messages.length > 0) {
                            userData.bio = bioResponse.messages[0].data.userDataBody.value;
                        }
                        return [2 /*return*/, userData];
                    case 5:
                        error_2 = _a.sent();
                        console.error("Error fetching user data:", error_2);
                        return [2 /*return*/, { fid: fid, type: 0 }];
                    case 6: return [2 /*return*/];
                }
            });
        });
  • Core helper for all API calls to Farcaster Hubble endpoints.
    function fetchFromHubble(endpoint_1) {
        return __awaiter(this, arguments, void 0, function (endpoint, params) {
            var response, error_1;
            var _a;
            if (params === void 0) { params = {}; }
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _b.trys.push([0, 2, , 3]);
                        console.error("Fetching from ".concat(HUBBLE_API_BASE).concat(endpoint, " with params:"), params);
                        return [4 /*yield*/, axios_1.default.get("".concat(HUBBLE_API_BASE).concat(endpoint), {
                                params: params
                            })];
                    case 1:
                        response = _b.sent();
                        console.error("Response status: ".concat(response.status));
                        return [2 /*return*/, response.data];
                    case 2:
                        error_1 = _b.sent();
                        console.error("Error fetching from Hubble API:", error_1);
                        if (axios_1.default.isAxiosError(error_1) && error_1.response) {
                            throw new Error("Hubble API error: ".concat(error_1.response.status, " - ").concat(((_a = error_1.response.data) === null || _a === void 0 ? void 0 : _a.details) || error_1.message));
                        }
                        throw new Error("Failed to fetch from Hubble: ".concat(error_1 instanceof Error ? error_1.message : String(error_1)));
                    case 3: return [2 /*return*/];
                }
            });
        });

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/manimohans/farcaster-mcp'

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