Skip to content

McpServer.registerTool() does not support icons field from ToolScheme #1864

@sainathreddyb

Description

@sainathreddyb

Describe the bug

The MCP spec's ToolSchema includes IconsSchema.shape, making icons a valid top-level property on tool definitions. However, the high-level McpServer.registerTool() API has two gaps:

  1. The config parameter type only accepts title, description, inputSchema, outputSchema, annotations, and _metaicons is not included.
  2. The setToolRequestHandlers listing handler in mcp.js does not include icons when building the toolDefinition object for tools/list responses.

To Reproduce

  1. Create an MCP server using @modelcontextprotocol/sdk@1.29.0
  2. Attempt to pass icons in the registerTool config:
server.registerTool(
  "my-tool",
  {
    title: "My Tool",
    description: "A tool with an icon",
    icons: [
      {
        src: "https://example.com/icon.png",
        mimeType: "image/png",
      },
    ],
  },
  async () => {
    return { content: [{ type: "text", text: "hello" }] };
  }
);
  1. TypeScript reports a type error — icons is not a valid property on the config object.
  2. Even if icons is forced onto the registered tool object, the tools/list response handler does not serialize it:
// In setToolRequestHandlers (mcp.js)
const toolDefinition = {
    name,
    title: tool.title,
    description: tool.description,
    inputSchema: /* ... */,
    annotations: tool.annotations,
    execution: tool.execution,
    _meta: tool._meta
    // icons is missing here
};

Expected behavior

registerTool should accept an optional icons array in its config, and the tool listing handler should include icons in the tools/list response — matching the spec's ToolSchema:

export const ToolSchema = z.object({
  ...BaseMetadataSchema.shape,
  ...IconsSchema.shape,  // <-- icons is part of the spec
  description: z.string().optional(),
  // ...
});

Logs

N/A — this is a type-level and serialization gap, not a runtime error.

Additional context

  • SDK version: @modelcontextprotocol/sdk@1.29.0
  • The server-level Implementation object correctly supports icons, websiteUrl, and description. The gap is only in the tool-level registerTool API and its listing handler.
  • Current workaround: passing icons via _meta gets them into the response, but not at the spec-expected top-level location in the tool definition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions