Skip to main content
Glama
GetArtworkByIdTool.ts4.4 kB
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import imageToBase64 from 'image-to-base64'; import z from 'zod'; import { artworkResponseSchema, artworkSchema } from '../schemas/schemas'; import { BaseTool } from './BaseTool'; const artworkByIdSchema = z.object({ id: z.number().describe('The ID of the artwork to retrieve.'), includeImage: z.boolean().optional().default(true).describe('Whether to include the artwork image in the response.'), }); export class GetArtworkByIdTool extends BaseTool<typeof artworkByIdSchema, any> { public readonly name: string = 'get-artwork-by-id'; public readonly description: string = `Get additional information, including an image if available, about a specific artwork by its ID` + ` from the Art Institute of Chicago. ` + `Using the value of Artwork ID from the 'search-by-title' tool.`; public readonly inputSchema = artworkByIdSchema; public readonly imageByTitle = new Map<string, string>(); private readonly fields: string[] = Object.keys(artworkSchema._def.shape()); constructor(private server: McpServer) { super(); } public async executeCore(input: z.infer<typeof this.inputSchema>) { const { id, includeImage } = input; const url = new URL(`${this.apiBaseUrl}/artworks/${id}`); url.searchParams.set('fields', this.fields.join(',')); const parsedResponse = await this.safeApiRequest( url, { method: 'GET' }, artworkResponseSchema, ); const artwork = parsedResponse.data; const text = this.formatArtworkDetails(artwork, `${parsedResponse.config.iiif_url}`); const content = []; content.push({ type: 'text' as const, text }); if (includeImage) { const image = await this.getArtworkImage(artwork, `${parsedResponse.config.iiif_url}`); if (image) { content.push(image); } } return { content }; } private formatArtworkDetails(artwork: z.infer<typeof artworkSchema>, iiif_url: string) { return `Title: ${artwork.title}\n` + `${artwork.alt_titles ? `Alt Titles: ${artwork.alt_titles.join(', ')}\n` : ''}` + `Artist: ${artwork.artist_display}\n` + `Artist ID: ${artwork.artist_id}\n` + `Description: ${artwork.description ?? 'No description available'}\n` + `Image ID: ${artwork.image_id}\n` + `Place of Origin: ${artwork.place_of_origin}\n` + `Dimensions: ${artwork.dimensions}\n` + `Medium: ${artwork.medium_display}\n` + `Credit Line: ${artwork.credit_line}\n` + `Department: ${artwork.department_title}\n` + `Is On View: ${artwork.is_on_view ? 'Yes' : 'No'}\n` + `Main Reference Number: ${artwork.main_reference_number}\n` + `Has not been viewed much: ${artwork.has_not_been_viewed_much ? 'Yes' : 'No'}\n` + `Date Start: ${artwork.date_start ?? 'N/A'}\n` + `Date End: ${artwork.date_end ?? 'N/A'}\n` + `Date: ${artwork.date_display ?? 'N/A'}\n` + `Fiscal Year: ${artwork.fiscal_year ?? 'N/A'}\n` + `Is Public Domain: ${artwork.is_public_domain ? 'Yes' : 'No'}\n` + `Gallery: ${artwork.gallery_title ?? 'N/A'}\n` + `Artwork Type: ${artwork.artwork_type_title}\n` + `Artist Title: ${artwork.artist_title}\n` + `Artist Titles: ${artwork.artist_titles.join(', ')}\n` + `Style Title: ${artwork.style_title ?? 'N/A'}\n` + `Image URL: ${artwork.image_id ? `${iiif_url}/${artwork.image_id}/full/843,/0/default.jpg` : 'N/A'}\n`; } private async getArtworkImage(artwork: z.infer<typeof artworkSchema>, iiif_url: string) { if (artwork.image_id) { try { const imageURL = `${iiif_url}/${artwork.image_id}/full/843,/0/default.jpg`; const imageBase64 = await imageToBase64(imageURL); const title = `${artwork.title} (${artwork.artist_title})`; this.imageByTitle.set(title, imageBase64); this.server.server.notification({ method: 'notifications/resources/list_changed', }); return { type: 'image' as const, data: imageBase64, mimeType: 'image/jpeg', }; } catch (error) { console.error(`Error fetching image for artwork ${artwork.id}:`, error); return { type: 'text' as const, text: `Error fetching image for artwork ${artwork.id}: ${error}`, }; } } return null; } }

Implementation Reference

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