-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Issue
When using registerTool() with type: "resource" in tool response content, passing a Resource object (which includes metadata like name, description, title, etc.) requires an as any cast to satisfy TypeScript's type checker.
Example
const resource = ALL_RESOURCES[resourceIndex]; // Type: Resource (includes name, description, etc.)
return {
content: [
{
type: "resource" as const,
resource: resource as any, // ← 'as any' required
},
],
};Root Cause
The registerTool() type signature expects resource content in tool responses to be resource content (only uri, text/blob, and mimeType), not resource metadata (which includes additional fields like name, description, title, icons).
However, the type: "resource" content type in prompts (via GetPromptRequestSchema) accepts full Resource metadata objects without casting.
TypeScript Error Without Cast
Type '{ [x: string]: unknown; uri: string; name: string; _meta?: { [x: string]: unknown; } | undefined; title?: string | undefined; icons?: { ...; }[] | undefined; mimeType?: string | undefined; description?: string | undefined; }' is not assignable to type '{ [x: string]: unknown; uri: string; text: string; _meta?: { [x: string]: unknown; } | undefined; mimeType?: string | undefined; } | { [x: string]: unknown; uri: string; blob: string; _meta?: { ...; } | undefined; mimeType?: string | undefined; }'.
Property 'blob' is missing in type '{ [x: string]: unknown; uri: string; name: string; ... }' but required in type '{ [x: string]: unknown; uri: string; blob: string; ... }'.
Workaround
Extract only content fields:
const resourceContent: { uri: string; text: string; mimeType?: string } | { uri: string; blob: string; mimeType?: string } =
'text' in resource && resource.text
? { uri: resource.uri, text: resource.text as string, mimeType: resource.mimeType }
: { uri: resource.uri, blob: resource.blob as string, mimeType: resource.mimeType };
return {
content: [{
type: "resource" as const,
resource: resourceContent,
}],
};However, this is verbose and loses the metadata that might be useful to include in tool responses.
Questions
- Should tool response resource content accept full
Resourcemetadata objects? This would match prompt behavior. - Or should there be a clearer separation? Perhaps different types like
ResourceContentvsResourceMetadata. - Is the
as anycast acceptable for now? It works at runtime but hides potential type issues.
Context
Found while migrating the "everything" example server to use modern registerTool() APIs. See: modelcontextprotocol/servers#3017
Reproduction
See src/everything/everything.ts in the servers repo, specifically the GET_RESOURCE_REFERENCE tool around line 714.