Skip to content

Claude provider: empty tool_filter silently excludes all MCP tools #37

@franklixuefei

Description

@franklixuefei

Bug Description

When using the Claude provider with MCP servers configured, all MCP tools are silently excluded from the API request. Agents only receive the emit_output tool, making them unable to use any MCP server capabilities (filesystem, web search, etc.).

Root Cause

In src/conductor/providers/claude.py, the _convert_mcp_tools_to_claude() method (line ~363):

if tool_filter is not None and tool["name"] not in tool_filter:
    continue

The tool_filter parameter receives [] (empty list) from the call chain:

  1. AgentExecutor.__init__ sets self.workflow_tools = workflow_tools or [] (agent.py line 108)
  2. resolve_agent_tools(agent.tools=None, workflow_tools=[]) returns [] (agent.py line 61)
  3. _execute_with_retry passes tools=[] to _convert_mcp_tools_to_claude

Since [] is not None evaluates to True, and every tool name not in [] is also True, the loop skips every MCP tool.

Expected Behavior

Per the docstring: "If None, all tools are included." An empty list [] should also mean "no filter / all tools", since it represents "no specific tools requested" rather than "explicitly zero tools".

Actual Behavior

  • MCP servers connect successfully and report tools (e.g., 14 filesystem tools, 6 web-search tools)
  • _convert_mcp_tools_to_claude returns [] — all tools filtered out
  • Claude API receives only emit_output — no MCP tools
  • Agent cannot read files, search, or use any MCP capability
  • No error or warning is logged

Reproduction

workflow:
  name: test
  entry_point: reader
  runtime:
    provider: claude
    mcp_servers:
      filesystem:
        command: npx
        args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
        tools: ["*"]
  input:
    path: { type: string, required: true }

agents:
  - name: reader
    model: claude-sonnet-4.6
    prompt: "Use read_file to read {{ workflow.input.path }}"
    output:
      content: { type: string }
    routes:
      - to: $end
ANTHROPIC_API_KEY=sk-ant-... conductor run test.yaml --input path="/tmp/test.txt"

The agent will report it has no tools available — only emit_output.

Suggested Fix

One-line change — replace the is not None check with a truthiness check:

# Before (bug):
if tool_filter is not None and tool["name"] not in tool_filter:
    continue

# After (fix):
if tool_filter and tool["name"] not in tool_filter:
    continue

This makes tool_filter=[] equivalent to tool_filter=None (no filter, include all tools). Only a non-empty list selects specific tools.

Environment

  • Conductor v0.1.0 (commit 391ddaf)
  • Python 3.12.13
  • mcp SDK 1.26.0
  • anthropic SDK 0.84.0
  • MCP server: @modelcontextprotocol/server-filesystem (confirmed 14 tools returned via list_tools)

Impact

High — This bug makes the Claude provider effectively unable to use MCP tools at all, despite MCP servers being properly configured and connected. The Copilot provider is not affected (it has built-in tools and doesn't use this code path).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions