Skip to content

Small models via ANTHROPIC_BASE_URL fail to make tool calls due to excessive tool definitions (259 tools sent) #25857

Description

@yj07538Johnny

Description

When using Claude Code with a local model via ANTHROPIC_BASE_URL (e.g., Ollama), the model receives ALL configured tool definitions (built-in + all MCP server tools) in every API request. For projects with multiple MCP servers, this can mean 200+ tool definitions, which overwhelms small models and prevents them from generating tool_use responses.

Environment

  • Claude Code: 2.1.42
  • Ollama: 0.15.6
  • Model: qwen3:8b (8B parameter)
  • Node.js: v20.19.6
  • OS: Ubuntu 22.04 (Linux 6.8.0-90-generic)
  • MCP servers configured: 13

The Problem

The model CAN use tools — proven via direct API call:

# Direct Ollama API call with 1 tool = PERFECT tool_use response
curl -s http://localhost:11434/v1/messages \
  -H "Content-Type: application/json" \
  -H "x-api-key: ollama" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "qwen3:8b",
    "max_tokens": 256,
    "tools": [{
      "name": "bash",
      "description": "Run a bash command",
      "input_schema": {
        "type": "object",
        "properties": {"command": {"type": "string"}},
        "required": ["command"]
      }
    }],
    "messages": [{"role": "user", "content": "Use the bash tool to run: echo hello_world"}]
  }'

Response (correct tool_use):

{
  "content": [
    {"type": "thinking", "thinking": "The user wants me to use the bash tool..."},
    {"type": "tool_use", "id": "call_esd2pde4", "name": "bash", "input": {"command": "echo hello_world"}}
  ],
  "stop_reason": "tool_use"
}

But through Claude Code, the same model outputs plain text instead of tool_use blocks, because it receives 259 tool definitions:

17 built-in tools (Task, TaskOutput, Bash, Glob, Grep, Read, Edit, Write, etc.)
+ 242 MCP server tools (from 13 configured MCP servers in .mcp.json)
= 259 total tools

How I Diagnosed This

  1. HTTP Proxy interception: Created a transparent proxy between Claude Code and Ollama to capture the actual API requests.

  2. Proxy log showed: {"num_tools": 259, "model": "qwen3:8b"}

  3. Debug log analysis (--debug "api"): No tool_use events in the response. The model generated text instead of structured tool calls.

Secondary Issues Found

1. Token counting uses hardcoded haiku model (404 errors)

Claude Code uses claude-haiku-4-5-20251001 for countTokensWithFallback. When ANTHROPIC_BASE_URL points to Ollama, this model doesn't exist, causing hundreds of 404 errors:

countTokensWithFallback: haiku fallback failed: 404
{"error":{"type":"not_found_error","message":"model 'claude-haiku-4-5-20251001' not found"}}

Each tool definition triggers a separate token counting attempt, leading to ~9+ errors per MCP server.

2. --strict-mcp-config partially helps but isn't sufficient

Using --strict-mcp-config with a minimal MCP config successfully reduces MCP tools, but:

  • The 17 built-in tools are always included (no way to filter them)
  • The large CLAUDE.md system prompt is still loaded
  • Combined, this still overwhelms 7-8B parameter models

3. MCP config loading performance

With --strict-mcp-config, MCP config loading took 943 seconds (15+ minutes):

[STARTUP] Loading MCP configs...
[STARTUP] MCP configs loaded in 943498ms

Reproduction Steps

  1. Install Ollama, pull qwen3:8b
  2. Create a project with multiple MCP servers in .mcp.json
  3. Run:
    ANTHROPIC_BASE_URL="http://localhost:11434" \
    ANTHROPIC_API_KEY="ollama" \
    claude --model "qwen3:8b" --print \
      "Use the Bash tool to run: echo hello_world"
  4. Observe: model outputs text instead of making tool calls
  5. Compare: direct curl to localhost:11434/v1/messages with 1 tool definition produces correct tool_use response

Expected Behavior

When using ANTHROPIC_BASE_URL with a non-Anthropic model:

  1. There should be a way to limit which tools are sent (e.g., --include-tools "Bash,Read,Write" or --max-tools N)
  2. Token counting should gracefully skip when haiku isn't available (not error per-tool)
  3. MCP config loading should not take 15+ minutes

Suggested Fix

A --small-model mode or --include-tools flag:

claude --model "qwen3:8b" \
  --print \
  --include-tools "Bash,Read,Write" \
  --strict-mcp-config \
  --mcp-config minimal.json \
  "Use Bash to run: echo hello"

Impact

This effectively prevents using Claude Code with small local models for any agentic task. The tool flooding makes --model with Ollama models decorative-only (text generation, no tool use). Users who want to leverage Claude Code's infrastructure (MCP servers, hooks, permissions) with local models cannot do so.

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions