Skip to main content
Glama
freestylefly

WeRead MCP Server

by freestylefly

get_book_best_reviews

Retrieve top-rated reviews for any book by specifying its ID and the desired number of reviews. Supports pagination for accessing additional results.

Instructions

Get popular reviews for a specific book

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
book_idYesBook ID
countNoNumber of reviews to return
max_idxNoPagination index
synckeyNoSync key for pagination

Implementation Reference

  • Main handler for get_book_best_reviews tool: validates input, fetches book info and best reviews, processes review data (ratings, filtering), formats and returns JSON response.
    case "get_book_best_reviews": {
      const bookId = String(request.params.arguments?.book_id || "");
      const count = Number(request.params.arguments?.count || 10);
      const maxIdx = Number(request.params.arguments?.max_idx || 0);
      const synckey = Number(request.params.arguments?.synckey || 0);
      
      if (!bookId) {
        throw new Error("书籍ID不能为空");
      }
      
      // 1. 获取书籍信息
      const bookInfo = await wereadApi.getBookinfo(bookId);
      
      // 2. 获取热门书评
      const bestReviewsData = await wereadApi.getBestReviews(bookId, count, maxIdx, synckey);
      
      // 控制台打印原始返回数据,方便调试
      // console.error("热门书评原始数据:", JSON.stringify(bestReviewsData, null, 2));
      
      // 3. 提取基础数据
      const hasMore = bestReviewsData.reviewsHasMore || false;
      const syncKey = bestReviewsData.synckey || 0;
      const totalCount = bestReviewsData.reviewsCnt || 0;
      
      // 4. 处理每条书评 - 根据接口确切的数据结构
      let processedReviews: any[] = [];
      
      if (bestReviewsData.reviews && Array.isArray(bestReviewsData.reviews)) {
        processedReviews = bestReviewsData.reviews
          .filter((item: any) => {
            return item && item.review && item.review.review;
          })
          .map((item: any) => {
            const reviewContainer = item.review; // {reviewId, review}
            const review = reviewContainer.review; // 实际评论内容
            const author = review.author || {};
            
            // 仅处理有内容的评论
            if (!review.content && !review.htmlContent) {
              return null;
            }
            
            // 处理评分 - 实际返回示例中用star表示评分(0-100)
            let rating = 0;
            if (review.star) {
              rating = review.star / 20; // 转换为5分制
            } else if (review.newRatingLevel) {
              // 有些评论用newRatingLevel表示评分级别
              switch(review.newRatingLevel) {
                case 1: rating = 5; break; // "好看"
                case 2: rating = 3; break; // "一般"
                case 3: rating = 1; break; // "不行"
                default: rating = 0;
              }
            }
            
            // 构建评论对象
            return {
              review_id: reviewContainer.reviewId || "",
              content: review.content || review.htmlContent || "",
              rating: rating,
              likes: review.liked || reviewContainer.likesCount || 0,
              comments: review.comments || 0,
              created_time: review.createTime ? new Date(review.createTime * 1000).toISOString() : "",
              //user_id: author.userVid || "",
              author_nickname: author.name || "",
              //avatar_url: author.avatar || ""
              is_spoiler: !!review.notVisibleToFriends,
              is_top: item.idx === 1 || !!item.isTop // 置顶评论判断
            };
          })
          .filter(Boolean); // 过滤掉null值
      }
      
      // 5. 返回结果
      return {
        content: [{
          type: "text",
          text: JSON.stringify({
            book_id: bookId,
            book_title: bookInfo.title || "",
            book_author: bookInfo.author || "",
            total_reviews: totalCount,
            has_more: hasMore,
            sync_key: syncKey,
            reviews: processedReviews
          }, null, 2)
        }]
      };
    }
  • Tool schema definition including input parameters for book_id (required), count, max_idx, synckey with descriptions and defaults.
    {
      name: "get_book_best_reviews",
      description: "Get popular reviews for a specific book",
      inputSchema: {
        type: "object",
        properties: {
          book_id: {
            type: "string",
            description: "Book ID"
          },
          count: {
            type: "integer",
            description: "Number of reviews to return",
            default: 10
          },
          max_idx: {
            type: "integer",
            description: "Pagination index",
            default: 0
          },
          synckey: {
            type: "integer",
            description: "Sync key for pagination",
            default: 0
          }
        },
        required: ["book_id"]
      }
    },
  • src/index.ts:52-153 (registration)
    Registration of all tools including get_book_best_reviews in the ListToolsRequestHandler response.
    server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: "get_bookshelf",
            description: "Get all books in the user's bookshelf with comprehensive statistics and categorization information",
            inputSchema: {
              type: "object",
              properties: {},
              required: []
            }
          },
          {
            name: "search_books",
            description: "Search for books in the user's bookshelf by keywords and return matching books with details and reading progress",
            inputSchema: {
              type: "object",
              properties: {
                keyword: {
                  type: "string",
                  description: "Search keyword to match book title, author, translator or category"
                },
                exact_match: {
                  type: "boolean",
                  description: "Whether to use exact matching, default is fuzzy matching",
                  default: false
                },
                include_details: {
                  type: "boolean",
                  description: "Whether to include detailed information",
                  default: true
                },
                max_results: {
                  type: "integer",
                  description: "Maximum number of results to return",
                  default: 5
                }
              },
              required: ["keyword"]
            }
          },
          {
            name: "get_book_notes_and_highlights",
            description: "Get all highlights and notes for a specific book, organized by chapter",
            inputSchema: {
              type: "object",
              properties: {
                book_id: {
                  type: "string",
                  description: "Book ID"
                },
                include_chapters: {
                  type: "boolean",
                  description: "Whether to include chapter information",
                  default: true
                },
                organize_by_chapter: {
                  type: "boolean",
                  description: "Whether to organize by chapter",
                  default: true
                },
                highlight_style: {
                  type: ["integer", "null"],
                  description: "Highlight style filter, null means all",
                  default: null
                }
              },
              required: ["book_id"]
            }
          },
          {
            name: "get_book_best_reviews",
            description: "Get popular reviews for a specific book",
            inputSchema: {
              type: "object",
              properties: {
                book_id: {
                  type: "string",
                  description: "Book ID"
                },
                count: {
                  type: "integer",
                  description: "Number of reviews to return",
                  default: 10
                },
                max_idx: {
                  type: "integer",
                  description: "Pagination index",
                  default: 0
                },
                synckey: {
                  type: "integer",
                  description: "Sync key for pagination",
                  default: 0
                }
              },
              required: ["book_id"]
            }
          },
        ]
      };
    });
  • Core API method that fetches best reviews from WeRead API endpoint using retry logic and standard request handling.
    public async getBestReviews(bookId: string, count: number = 10, maxIdx: number = 0, synckey: number = 0): Promise<any> {
      await this.ensureInitialized();
      return this.retry(async () => {
        const data = await this.makeApiRequest<any>(WEREAD_BEST_REVIEW_URL, "get", {
          bookId,
          synckey,
          maxIdx,
          count
        });
        
        return data;
      });
    }
  • API endpoint URL constant for fetching best reviews.
    const WEREAD_BEST_REVIEW_URL = "https://weread.qq.com/web/review/list/best";
Install Server

Other Tools

Related 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/freestylefly/mcp-server-weread'

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