Skip to main content
Glama
lookup-item.ts•4.85 kB
import { z } from "zod" import { ErrorLogger, ItemNotFoundError, isCrateNotFoundError, isJSONParseError, isMCPDocsRsError } from "../errors.js" import { findItem } from "../rustdoc-parser.js" import type { DocsFetcher, DocsResponse, LookupItemArgs } from "../types.js" // Input schema for lookup_item_docs tool export const lookupItemInputSchema = { crateName: z.string().describe("Name of the Rust crate"), itemPath: z .string() .describe('Path to specific item (e.g., "struct.MyStruct" or "fn.my_function")'), version: z.string().optional().describe("Specific version or semver range"), target: z.string().optional().describe("Target platform") } // Tool metadata export const lookupItemTool = { name: "lookup_item_docs", description: "Lookup documentation for a specific item (struct, function, etc.) in a Rust crate", annotations: { title: "Lookup Rust Item Documentation", readOnlyHint: true, destructiveHint: true, idempotentHint: true, openWorldHint: true } } // Handler for lookup_item_docs export const createLookupItemHandler = (fetcher: DocsFetcher) => { return async (args: LookupItemArgs): Promise<DocsResponse> => { try { const { data: json, fromCache } = await fetcher.fetchCrateJson( args.crateName, args.version, args.target ) // Log cache status internally for debugging ErrorLogger.logInfo("Item documentation retrieved", { crateName: args.crateName, itemPath: args.itemPath, fromCache }) const itemContent = findItem(json, args.itemPath) if (!itemContent) { throw new ItemNotFoundError(args.crateName, args.itemPath) } return { content: [ { type: "text", text: itemContent } ] } } catch (error) { // Log the error with full context if (error instanceof Error) { ErrorLogger.log(error) } // Provide user-friendly error messages based on error type let errorMessage: string if (isJSONParseError(error)) { errorMessage = "Failed to parse JSON from docs.rs. The response may not be valid rustdoc JSON." } else if (isCrateNotFoundError(error)) { errorMessage = error.message } else if (isMCPDocsRsError(error)) { errorMessage = error.message } else if (error instanceof Error) { errorMessage = error.message } else { errorMessage = "Unknown error occurred" } return { content: [ { type: "text", text: `Error: ${errorMessage}` } ], isError: true } } } } // Prompt arguments schema for lookup_item_docs export const lookupItemPromptSchema = { crateName: z.string().optional().describe("Name of the Rust crate"), itemPath: z .string() .optional() .describe('Path to specific item (e.g., "struct.MyStruct" or "fn.my_function")'), version: z.string().optional().describe("Specific version or semver range"), target: z.string().optional().describe("Target platform") } // Prompt for lookup_item_docs with dynamic argument handling export const lookupItemPrompt = { name: "lookup_item_docs", description: "Provide detailed information about a specific item from a Rust crate", argsSchema: lookupItemPromptSchema, handler: (args: any) => { // Check if required arguments are missing if (!args?.crateName && !args?.itemPath) { return { messages: [ { role: "user" as const, content: { type: "text" as const, text: "I need to know which Rust crate and item you'd like documentation for. Please provide:\n1. The crate name (e.g., 'tokio', 'serde')\n2. The item path (e.g., 'struct.Runtime', 'fn.spawn')" } } ] } } if (!args?.crateName) { return { messages: [ { role: "user" as const, content: { type: "text" as const, text: `Which Rust crate contains the item "${args.itemPath}"? Please provide the crate name.` } } ] } } if (!args?.itemPath) { return { messages: [ { role: "user" as const, content: { type: "text" as const, text: `What specific item from the "${args.crateName}" crate would you like documentation for? Please provide the item path (e.g., 'struct.MyStruct', 'fn.my_function', 'trait.MyTrait').` } } ] } } // Build the prompt text with the provided arguments let promptText = `Please provide detailed information about the "${args.itemPath}" from the Rust crate "${args.crateName}"` if (args.version) { promptText += ` version ${args.version}` } promptText += `. Include: 1. Purpose and functionality 2. Parameters/fields and their types 3. Usage examples if available 4. Related items I'll fetch the documentation for you.` return { messages: [ { role: "user" as const, content: { type: "text" as const, text: promptText } } ] } } }

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/vexxvakan/mcp-docsrs'

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