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
Resource metadata objects? This would match prompt behavior.
- Or should there be a clearer separation? Perhaps different types like
ResourceContent vs ResourceMetadata.
- Is the
as any cast 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.
Issue
When using
registerTool()withtype: "resource"in tool response content, passing aResourceobject (which includes metadata likename,description,title, etc.) requires anas anycast to satisfy TypeScript's type checker.Example
Root Cause
The
registerTool()type signature expects resource content in tool responses to be resource content (onlyuri,text/blob, andmimeType), not resource metadata (which includes additional fields likename,description,title,icons).However, the
type: "resource"content type in prompts (viaGetPromptRequestSchema) accepts fullResourcemetadata objects without casting.TypeScript Error Without Cast
Workaround
Extract only content fields:
However, this is verbose and loses the metadata that might be useful to include in tool responses.
Questions
Resourcemetadata objects? This would match prompt behavior.ResourceContentvsResourceMetadata.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#3017Reproduction
See
src/everything/everything.tsin the servers repo, specifically theGET_RESOURCE_REFERENCEtool around line 714.