Skip to main content
Glama

full-text-search

Search the Art Institute of Chicago collection metadata for artworks containing specific terms, with pagination support for browsing results.

Instructions

Search for artworks in the Art Institute of Chicago collection whose metadata contains mention of the query term.Pagination is supported with the page parameter

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesThe term to search the metadata for.
limitNoThe number of resources to return per page.
pageNoThe page of results to return. Used for pagination.

Implementation Reference

  • The executeCore method implements the tool logic: constructs the search URL, calls the Art Institute API, parses response, attaches pagination, and formats the artwork list.
      public async executeCore(input: z.infer<typeof this.inputSchema>) {
        const { query, limit, page } = input;
    
        const url = new URL(`${this.apiBaseUrl}/artworks/search`);
        url.searchParams.set('page', `${page}`);
        url.searchParams.set('limit', `${limit}`);
        url.searchParams.set('q', query);
    
        const parsedData = await this.safeApiRequest(
          url,
          { method: 'GET' },
          artworkSearchResponseSchema,
        );
        // Attach pagination info to each artwork for formatting
        parsedData.data.forEach((artwork) => {
          (artwork as any)._pagination = parsedData.pagination;
        });
        return this.formatArtworkList(parsedData.data, query);
      }
    }
  • Input schema defining parameters for the full-text search tool: query (required), limit and page (optional with defaults).
    const fullTextSearchSchema = z.object({
      query: z.string().describe('The term to search the metadata for.'),
      limit: z.number().optional().default(10).describe('The number of resources to return per page.'),
      page: z.number().optional().default(1).describe('The page of results to return. Used for pagination.'),
    });
  • src/index.ts:69-74 (registration)
    Registers the full-text-search tool with the MCP server using its name, description, input schema, and bound execute method.
    this.server.tool(
      this.fullTextSearchTool.name,
      this.fullTextSearchTool.description,
      this.fullTextSearchTool.inputSchema.shape,
      this.fullTextSearchTool.execute.bind(this.fullTextSearchTool),
    );
  • Output schema used to validate the API response from the artworks/search endpoint in the tool handler.
    export const artworkSearchResponseSchema = z.object({
      preference: z.string().nullable(),
      pagination: paginationSchema,
      data: z.array(z.object({
        _score: z.number(),
        id: z.number(),
        api_model: z.string(),
        api_link: z.string(),
        is_boosted: z.boolean(),
        title: z.string(),
        thumbnail: thumbnailSchema.nullable(),
        timestamp: z.string(),
      })),
      info: apiInfoSchema,
      config: apiConfigSchema,
    });
  • Helper method used by the tool to format the list of search results into a readable text response, including pagination info.
    protected formatArtworkList(artworks: any[], query: string) {
      if (artworks.length === 0) {
        return {
          content: [{ type: 'text' as const, text: `No artworks found for "${query}".` }],
          isError: false,
        };
      }
    
      const artText = artworks.map((artwork) => {
        return `Title: ${artwork.title}\n`
          + `Artwork ID: ${artwork.id}\n`
          + `Thumbnail alt text: ${artwork.thumbnail?.alt_text ?? 'No thumbnail available'}\n`
          + `Score: ${artwork._score}\n`;
      }).join('\n-----\n');
    
      const paginationText = artworks.length > 0
        ? `\nPagination Info\n`
        + `Total: ${artworks[0]._pagination?.total || 'Unknown'}\n`
        + `Total Pages: ${artworks[0]._pagination?.total_pages || 'Unknown'}\n`
        + `Current Page: ${artworks[0]._pagination?.current_page || 'Unknown'}`
        : '';
    
      return {
        content: [{ type: 'text' as const, text: artText + paginationText }],
      };
    }
Behavior3/5

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

With no annotations provided, the description carries full burden. It discloses pagination behavior ('Pagination is supported with the page parameter'), which is valuable. However, it doesn't mention rate limits, authentication requirements, error conditions, or what the search results look like (format, fields returned).

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?

Two sentences with zero waste - the first states the core purpose and scope, the second adds crucial behavioral information about pagination. The description is appropriately sized and front-loaded with the essential information.

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

Completeness3/5

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

For a search tool with 3 parameters and no output schema, the description provides adequate basic information about purpose and pagination. However, without annotations or output schema, it should ideally mention more about the search behavior (case sensitivity, partial matching), result format, or limitations. The description is minimally complete but could be more comprehensive.

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?

Schema description coverage is 100%, so the schema already fully documents all three parameters. The description adds minimal value beyond the schema - it mentions the 'page' parameter for pagination but doesn't provide additional context about query syntax, search behavior, or result ordering that isn't already in the parameter descriptions.

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

Purpose5/5

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

The description clearly states the specific action ('Search for artworks') and resource ('Art Institute of Chicago collection'), with precise scope ('metadata contains mention of the query term'). It distinguishes from siblings like 'search-by-title' or 'search-by-medium' by specifying full-text metadata search rather than field-specific searches.

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 usage for searching metadata with query terms, but doesn't explicitly state when to use this tool versus alternatives like 'search-by-title' or 'search-by-medium'. No guidance is provided about when NOT to use this tool or about prerequisites for effective searching.

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/mikechao/artic-mcp'

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