Custom Tools not working in the SDK

Resolved 💬 7 comments Opened Sep 14, 2025 by ajasingh Closed Sep 24, 2025

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Im an trying the new Custom tool feaure in the SDK but im not getting any response from the query object neither im getting any exception so Not really sure what is wrong in the code

import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-code";

import { z } from "zod";

const customServer = createSdkMcpServer({
  name: "my-custom-tools",
  version: "1.0.0",
  tools: [
    tool(
      "get_weather",
      "Get current weather for a location",
      {
        location: z.string().describe("City name or coordinates"),
        units: z
          .enum(["celsius", "fahrenheit"])
          .default("celsius")
          .describe("Temperature units"),
      },
      async (args) => {
        // Call weather API
        const response = await fetch(
          `https://api.weather.com/v1/current?q=${args.location}&units=${args.units}`
        );
        const data = await response.json();

        return {
          content: [
            {
              type: "text",
              text: `Temperature: ${data.temp}°\nConditions: ${data.conditions}\nHumidity: ${data.humidity}%`,
            },
          ],
        };
      }
    ),
  ],
});

async function* generateMessages() {
  yield {
    type: "user",
    message: {
      role: "user",
      content: "What's the weather in San Francisco?",
    },
  };
}

const messages = [];
try {
  console.log("starting query ...");
  for await (const message of query({
    prompt: generateMessages(), // Use async generator for streaming input
    options: {
      permissionMode: 'bypassPermissions',  
      mcpServers: {
        "my-custom-tools": customServer, // Pass as object/dictionary, not array
      },
      // Optionally specify which tools Claude can use
      allowedTools: [
        "mcp__my-custom-tools__get_weather", // Allow the weather tool
        // Add other tools as needed
      ],
      maxTurns: 10,
    },
  })) {
    console.log("✅ Success:", message);
  }
} catch (error) {
  console.error("❌ Error:", error.message);
}

What Should Happen?

Console.log should print something

Error Messages/Logs

Steps to Reproduce

import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-code";

import { z } from "zod";

const customServer = createSdkMcpServer({
  name: "my-custom-tools",
  version: "1.0.0",
  tools: [
    tool(
      "get_weather",
      "Get current weather for a location",
      {
        location: z.string().describe("City name or coordinates"),
        units: z
          .enum(["celsius", "fahrenheit"])
          .default("celsius")
          .describe("Temperature units"),
      },
      async (args) => {
        // Call weather API
        const response = await fetch(
          `https://api.weather.com/v1/current?q=${args.location}&units=${args.units}`
        );
        const data = await response.json();

        return {
          content: [
            {
              type: "text",
              text: `Temperature: ${data.temp}°\nConditions: ${data.conditions}\nHumidity: ${data.humidity}%`,
            },
          ],
        };
      }
    ),
  ],
});

async function* generateMessages() {
  yield {
    type: "user",
    message: {
      role: "user",
      content: "What's the weather in San Francisco?",
    },
  };
}

const messages = [];
try {
  console.log("starting query ...");
  for await (const message of query({
    prompt: generateMessages(), // Use async generator for streaming input
    options: {
      permissionMode: 'bypassPermissions',  
      mcpServers: {
        "my-custom-tools": customServer, // Pass as object/dictionary, not array
      },
      // Optionally specify which tools Claude can use
      allowedTools: [
        "mcp__my-custom-tools__get_weather", // Allow the weather tool
        // Add other tools as needed
      ],
      maxTurns: 10,
    },
  })) {
    console.log("✅ Success:", message);
  }
} catch (error) {
  console.error("❌ Error:", error.message);
}

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

1.0.113

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗