UNPKG

@modelcontextprotocol/server-everything

Version:

MCP server that exercises all the features of the MCP protocol

85 lines (84 loc) • 3.55 kB
import { z } from "zod"; import { textResource, textResourceUri, blobResourceUri, blobResource, RESOURCE_TYPE_BLOB, RESOURCE_TYPE_TEXT, RESOURCE_TYPES, } from "../resources/templates.js"; import { TOOL_ICONS } from "../server/icons.js"; // Tool input schema const GetResourceReferenceSchema = z.object({ resourceType: z .enum([RESOURCE_TYPE_TEXT, RESOURCE_TYPE_BLOB]) .default(RESOURCE_TYPE_TEXT) .describe("Whether to reference a text resource or a blob resource"), resourceId: z .number() .default(1) .describe("ID of the text or blob resource to fetch, a positive integer"), }); // Tool configuration const name = "get-resource-reference"; const config = { title: "Get Resource Reference Tool", description: "Returns a resource reference that can be used by MCP clients", inputSchema: GetResourceReferenceSchema, icons: TOOL_ICONS, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }; /** * Registers the 'get-resource-reference' tool. * * The registered tool validates and processes arguments for retrieving a resource * reference. Supported resource types include predefined `RESOURCE_TYPE_TEXT` and * `RESOURCE_TYPE_BLOB`. The retrieved resource's reference will include the resource * ID, type, and its associated URI. * * The tool performs the following operations: * 1. Validates the `resourceType` argument to ensure it matches a supported type. * 2. Validates the `resourceId` argument to ensure it is a finite positive integer. * 3. Constructs a URI for the resource based on its type (text or blob). * 4. Retrieves the resource and returns it in a content block. * * @param {McpServer} server - The McpServer instance where the tool will be registered. */ export const registerGetResourceReferenceTool = (server) => { server.registerTool(name, config, async (args) => { // Validate resource type argument const { resourceType } = args; /* v8 ignore next -- unreachable: the input schema's enum rejects any other resourceType before the handler runs */ if (!RESOURCE_TYPES.includes(resourceType)) { throw new Error(`Invalid resourceType: ${args?.resourceType}. Must be ${RESOURCE_TYPE_TEXT} or ${RESOURCE_TYPE_BLOB}.`); } // Validate resourceId argument const resourceId = Number(args?.resourceId); if (!Number.isFinite(resourceId) || !Number.isInteger(resourceId) || resourceId < 1) { throw new Error(`Invalid resourceId: ${args?.resourceId}. Must be a finite positive integer.`); } // Get resource based on the resource type const uri = resourceType === RESOURCE_TYPE_TEXT ? textResourceUri(resourceId) : blobResourceUri(resourceId); const resource = resourceType === RESOURCE_TYPE_TEXT ? textResource(uri, resourceId) : blobResource(uri, resourceId); return { content: [ { type: "text", text: `Returning resource reference for Resource ${resourceId}:`, }, { type: "resource", resource: resource, }, { type: "text", text: `You can access this resource using the URI: ${resource.uri}`, }, ], }; }); };