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
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states what the tool does but doesn't describe important behavioral aspects like whether this is a read-only operation, potential rate limits, authentication requirements, response format, or error handling. The description is functional but lacks transparency about how the tool behaves beyond its basic function.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise - a single sentence that efficiently communicates the essential information. Every word earns its place, with no redundant or unnecessary information. The structure is straightforward and front-loaded with the core functionality.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with 2 parameters and no output schema, the description is insufficiently complete. It doesn't explain what the search returns (book metadata, results format), how results are structured, whether there's pagination, or what happens when both parameters are provided. Without annotations and with no output schema, the description should provide more context about the tool's behavior and results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, with both parameters ('q' and 'isbn') having clear descriptions in the schema. The description adds minimal value beyond the schema by mentioning the two search methods ('by ISBN or by query'), but doesn't provide additional semantic context about parameter usage, constraints, or interactions between parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('search books from douban') and the resource ('books'), making the purpose understandable. However, it doesn't differentiate this tool from its sibling 'search-movie' beyond mentioning 'books' vs 'movie' - a human can infer the difference, but the description doesn't explicitly contrast them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool by stating 'either by ISBN or by query,' suggesting it's for book searches. However, it doesn't provide explicit guidance on when to choose this over alternatives like 'browse' or 'list-book-reviews,' nor does it mention any prerequisites or exclusions for usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

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

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