Skip to content

fix: use provider-agnostic schema for non-OpenAI tool conversion (#4472)#4473

Open
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1770967305-fix-mcp-tool-schema-gemini-bedrock
Open

fix: use provider-agnostic schema for non-OpenAI tool conversion (#4472)#4473
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1770967305-fix-mcp-tool-schema-gemini-bedrock

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Feb 13, 2026

fix: use provider-agnostic schema for non-OpenAI tool conversion (#4472)

Summary

extract_tool_info() in common.py called generate_model_description() when converting a tool's args_schema to parameters. That function applies OpenAI strict-mode transformations (additionalProperties: false, forcing all properties required, title on every object) that Gemini and Bedrock reject.

This PR adds generate_tool_parameters_schema() — a new provider-agnostic path that:

  • Resolves $ref / $defs
  • Strips anyOf null unions (for Optional fields)
  • Recursively removes title, default, and additionalProperties
  • Preserves the original required array (does not force every property required)

extract_tool_info() now calls this new function instead of generate_model_description() for the args_schema fallback path.

Files changed:

  • lib/crewai/src/crewai/utilities/pydantic_schema_utils.py — added _strip_schema_metadata() and generate_tool_parameters_schema()
  • lib/crewai/src/crewai/llms/providers/utils/common.py — switched extract_tool_info to use new function
  • lib/crewai/tests/utilities/test_tool_schema_compatibility.py — 24 new tests

Review & Testing Checklist for Human

  • Verify this is the correct code path for MCP tools: The fix targets the args_schema fallback in extract_tool_info() (line ~82 of common.py). This path is only hit when the tool dict is in "direct format" (no "function" key), has no inline "parameters", and does have an "args_schema". Confirm MCP tools actually flow through this branch and not the "function" or "parameters" branches above it.
  • Stripping default values: The helper removes default from all properties recursively. Verify this doesn't cause issues for providers that can usefully consume defaults (e.g., OpenAI or Anthropic direct format). Note: this code path is only reached for the args_schema fallback, not for tools that already supply inline parameters.
  • _strip_schema_metadata mutates in-place: The helper does schema.pop(key) on the passed dict. It's safe in generate_tool_parameters_schema (fresh dict from model_json_schema), but since it's a module-level function that tests import directly, consider whether it should defensively copy.
  • End-to-end manual test: Set up an MCP tool (e.g., the firewall tool from the issue) and verify it works with gemini-2.5-flash and Bedrock Claude — this is the scenario from the bug report and cannot be fully validated by unit tests alone.

Notes

Fixes #4472 — MCP tools (and any tool with args_schema) produced JSON
schemas incompatible with Gemini and Bedrock/Anthropic because
extract_tool_info() called generate_model_description() which applies
OpenAI-specific transformations (additionalProperties: false, forcing
all properties required, title fields).

Added generate_tool_parameters_schema() that produces clean schemas
without those provider-specific metadata fields. Updated
extract_tool_info() to use it for the args_schema path.

Co-Authored-By: João <joao@crewai.com>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring


from typing import Any, Optional

import pytest
from pydantic import BaseModel, Field

from crewai.llms.providers.utils.common import extract_tool_info, safe_tool_conversion
from crewai.tools.base_tool import BaseTool
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants