Skip to main content
Glama
moria97
by moria97

search-book

Search for books on Douban using ISBN numbers or keyword queries to find titles, authors, and publication details.

Instructions

search books from douban, either by ISBN or by query

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qNoquery string, e.g. "python"
isbnNoISBN number, e.g. "9787501524044"

Implementation Reference

  • src/index.ts:25-55 (registration)
    Registration of the 'search-book' tool with MCP server, including description, input schema, and inline handler function.
    server.tool(
      TOOL.SEARCH_BOOK,
      'search books from douban, either by ISBN or by query',
      {
        q: z.string().optional().describe('query string, e.g. "python"'),
        isbn: z.string().optional().describe('ISBN number, e.g. "9787501524044"')
      },
      async (args) => {
        if (!args.isbn && !args.q) {
          throw new McpError(ErrorCode.InvalidParams, "Either q or isbn must be provided")
        }
        const books = await searchBooks(args)
        const text = json2md({
          table: {
            headers: ['publish_date', 'title', 'author', 'rating' ,'id', 'isbn'],
            rows: books.map(_ => ({
              id: _.id || '',
              title: _.title || '',
              author: (_.author || []).join('、'),
              publish_date: _.pubdate,
              isbn: _.isbn13 || '',
              rating: `${_.rating?.average || 0} (${_.rating?.numRaters || 0}人)`
            }))
          }
        })
    
        return {
          content: [{ type: 'text', text }]
        }
      }
    );
  • Helper function searchBooks that dispatches to keyword or ISBN search on Douban API.
    export async function searchBooks(params: {
      q?: string
      isbn?: string
    }) {
      if (params.q) {
        return searchByKeyword(params.q)
      }
      if (params.isbn) {
        return searchByISBN(params.isbn)
      }
      return []
    }
  • Implementation of keyword-based book search using Douban v2 API.
    async function searchByKeyword (q: string) {
      const url = new URL('https://api.douban.com/v2/book/search')
      url.searchParams.set('q', q)
      url.searchParams.set('apikey', apiKey)
      const res: {
        count: number
        start: number
        total: number
        books: Douban.Book[]
      } = await (await fetch(url.toString(), {
        headers: FAKE_HEADERS
      })).json()
    
      return res?.books ? res.books.map(parseDoubanBook) : []
    }
  • TOOL enum defining the 'search-book' name as SEARCH_BOOK constant, used for registration.
    export enum TOOL {
      SEARCH_BOOK = 'search-book',
      LIST_BOOK_REVIEWS = 'list-book-reviews',
      SEARCH_MOVIE = 'search-movie',
      LIST_MOVIE_REVIEWS = 'list-movie-reviews',
      BROWSE = 'browse',
      LIST_GROUP_TOPICS = 'list-group-topics',
      GET_GROUP_TOPIC_DETAIL = 'get-group-topic-detail'
    }
  • TypeScript interface for Douban Book, used in search results.
    interface Book {
      rating: {
        max: number
        numRaters: number
        average: string
        min: number
      }
      subtitle: string
      author: string[]
      pubdate: string
      tags: {
        count: number
        name: string
        title: string
      }[]
      origin_title: string
      image: string
      binding: string
      translator: any[]
      catalog: string
      pages: string
      images: {
        small: string
        large: string
        medium: string
      }
      alt: string
      id: string
      publisher: string
      isbn10: string
      isbn13: string
      title: string
      url: string
      alt_title: string
      author_intro: string
      summary: string
      series: {
        id: string
        title: string
      }
      price: string
      ebook_url: string
    }

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/moria97/douban-mcp'

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