crewai - ✅(Solved) Fix [BUG] JSON schema issue between CrewAI MCPServerAdapter and Bedrock LLM Claude / Gemini when using Tool Inputs [3 pull requests, 3 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
crewAIInc/crewAI#4472Fetched 2026-04-08 00:41:53
View on GitHub
Comments
3
Participants
3
Timeline
15
Reactions
1
Timeline (top)
referenced ×5cross-referenced ×4commented ×3labeled ×2

I have a crewai script which uses MCP Tools, when using Bedrock LLM / Gemini, I'm getting issue related to JSON Schema.

Error Message

except Exception as e: print(f"Error during crew kickoff: {e}") Error which I observer, ERROR:root:Google Gemini API error: 400 - value at properties.command must be a list An unknown error occurred. Please check the details below. Error details: 400 INVALID_ARGUMENT. {'error': {'code': 400, 'message': 'value at properties.command must be a list', 'status': 'INVALID_ARGUMENT'}} ERROR:root:AWS Bedrock ClientError (ValidationException): The model returned the following errors: tools.0.input_schema: JSON schema is invalid - please consult https://json-schema.org or our documentation at https://docs.anthropic.com/en/docs/tool-use

Root Cause

I have a crewai script which uses MCP Tools, when using Bedrock LLM / Gemini, I'm getting issue related to JSON Schema.

Fix Action

Fixed

PR fix notes

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

Description (problem / solution / changelog)

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

Changed files

  • lib/crewai/src/crewai/llms/providers/utils/common.py (modified, +2/-3)
  • lib/crewai/src/crewai/utilities/pydantic_schema_utils.py (modified, +56/-0)
  • lib/crewai/tests/utilities/test_tool_schema_compatibility.py (added, +287/-0)

PR #4579: fix: preserve null types in tool parameter schemas for LLM

Description (problem / solution / changelog)

Tool parameter schemas were stripping null from optional fields via generate_model_description, forcing the LLM to provide non-null values for fields. Adds strip_null_types parameter to generate_model_description and passes False when generating tool schemas, so optional fields keep anyOf: [{type: T}, {type: null}]

Changed files

  • lib/crewai/src/crewai/utilities/agent_utils.py (modified, +3/-1)
  • lib/crewai/src/crewai/utilities/pydantic_schema_utils.py (modified, +11/-2)
  • lib/crewai/tests/utilities/test_agent_utils.py (modified, +74/-1)

PR #4601: Lorenze/fix/issue 4472

Description (problem / solution / changelog)

on top of: https://github.com/crewAIInc/crewAI/pull/4579 address: https://github.com/crewAIInc/crewAI/issues/4472

Changed files

  • lib/crewai/src/crewai/llms/providers/bedrock/completion.py (modified, +4/-0)
  • lib/crewai/src/crewai/llms/providers/gemini/completion.py (modified, +6/-0)
  • lib/crewai/src/crewai/utilities/agent_utils.py (modified, +3/-1)
  • lib/crewai/src/crewai/utilities/pydantic_schema_utils.py (modified, +40/-2)
  • lib/crewai/tests/agents/test_native_tool_calling.py (modified, +165/-0)
  • lib/crewai/tests/cassettes/agents/TestNativeToolCallingBehavior.test_bedrock_mcp_tool_with_optional_fields_no_schema_error.yaml (added, +128/-0)
  • lib/crewai/tests/cassettes/agents/TestNativeToolCallingBehavior.test_gemini_mcp_tool_with_optional_fields_no_schema_error.yaml (added, +161/-0)
  • lib/crewai/tests/utilities/test_agent_utils.py (modified, +173/-1)
RAW_BUFFERClick to expand / collapse

Description

I have a crewai script which uses MCP Tools, when using Bedrock LLM / Gemini, I'm getting issue related to JSON Schema.

Steps to Reproduce

Shared the code snippet

Expected behavior

None

Screenshots/Code snippets

from crewai import Agent, Task, Crew, Process, LLM from crewai_tools import MCPServerAdapter from dotenv import load_dotenv import os

load_dotenv()

''' llm = LLM( model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0", temperature=0, ) '''

llm = LLM( model="gemini/gemini-2.5-flash", # or gemini/gemini-2.0-flash api_key=os.getenv("GEMINI_API_KEY"), )

server_params = { "url": "http://10.10.10.10/mcp", "transport": "streamable-http", }

mcp_server_adapter = MCPServerAdapter(server_params) mcp_tools = mcp_server_adapter.tools

my_agent = Agent( role="Firewall Configuration Analyst", goal="Use MCP tools to analyze and optimize firewall configurations.", backstory="An AI agent that specializes in firewall management using MCP tools.", tools=mcp_tools, verbose=True, llm=llm, max_iter=3, # Limit to 3 iterations )

my_task = Task( name="Firewall Analysis Task", description=( "{input} - From the User's input, gather info about the firewall hostname/IP address" "And identify what is required from firewall and get the appropriate Fortigate cli commands." "and execute it using the tool which is more relevant. " "You MUST call use the appropriate MCP Tools with:\n" "- hostname: the firewall IP address\n" "- command: the CLI command string (optional)\n" "Show what is being sent to MCP Tool\n" "Do not respond without calling the tool.\n" ), expected_output="Detailed Analysis of the firewall configuration based on the User's input and the results from the MCP tools.", agent=my_agent, ) crew = Crew( name="Firewall Configuration Crew", agents=[my_agent], tasks=[my_task], verbose=True, process=Process.sequential, )

try: result = crew.kickoff( inputs={ "input": "Firewall IP: 10.10.10.10. I want to check the current firewall status." } ) print(result) except Exception as e: print(f"Error during crew kickoff: {e}")

Operating System

Ubuntu 20.04

Python Version

3.12

crewAI Version

1.9.3

crewAI Tools Version

1.9.3

Virtual Environment

Venv

Evidence

Error which I observer,

When using Gemini LLM

ERROR:root:Google Gemini API error: 400 - value at properties.command must be a list An unknown error occurred. Please check the details below. Error details: 400 INVALID_ARGUMENT. {'error': {'code': 400, 'message': 'value at properties.command must be a list', 'status': 'INVALID_ARGUMENT'}}

When using AWS Bedrock CLaude LLM

ERROR:root:AWS Bedrock ClientError (ValidationException): The model returned the following errors: tools.0.input_schema: JSON schema is invalid - please consult https://json-schema.org or our documentation at https://docs.anthropic.com/en/docs/tool-use

Possible Solution

None

Additional context

None

extent analysis

Fix Plan

To resolve the JSON schema issues with both Gemini and Bedrock LLMs, we need to ensure that the input to the MCP tools adheres to the expected JSON schema.

For Gemini LLM

The error indicates that the command property must be a list. We can modify the code to pass the command as a list:

my_task = Task(
    # ... other properties ...
    description=(
        "{input} - From the User's input, gather info about the firewall hostname/IP address"
        "And identify what is required from firewall and get the appropriate Fortigate cli commands."
        "and execute it using the tool which is more relevant. "
        "You MUST call use the appropriate MCP Tools with:\n"
        "- hostname: the firewall IP address\n"
        "- command: the CLI command string (optional)\n"
        "Show what is being sent to MCP Tool\n"
        "Do not respond without calling the tool.\n"
    ),
    # ... other properties ...
)

# When calling the MCP tool, ensure the command is a list
mcp_tools.execute_tool(hostname="10.10.10.10", command=["cli command string"])

For Bedrock LLM

The error suggests that the JSON schema for the tool's input is invalid. We need to consult the documentation and ensure that our input schema conforms to the expected format.

Assuming the input schema expects a specific structure, we can define it as follows:

input_schema = {
    "type": "object",
    "properties": {
        "hostname": {"type": "string"},
        "command": {"type": "array", "items": {"type": "string"}}
    },
    "required": ["hostname"]
}

# When calling the MCP tool, use the defined input schema
mcp_tools.execute_tool(input_schema, hostname="10.10.10.10", command=["cli command string"])

Verification

To verify that the fix worked, run the crew kickoff with the modified code and check for any errors related to JSON schema validation. If the errors persist, consult the documentation for the specific LLM and MCP tools being used to ensure that the input schema and command format are correct.

Extra Tips

  • Always consult the documentation for the LLM and MCP tools being used to ensure that the input schema and command format are correct.
  • Use tools like jsonschema to validate your input schema before passing it to the MCP tools.
  • Consider adding error handling to catch and handle any validation errors that may occur during execution.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

None

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING