ChatCompletionsRequest drops MCP tool parameter schemas from parametersJsonSchema
- Dominant language
- Java
- Stars
- 1.7k
- Forks
- 420
- Avg merge
- 4d 12h
- Merged PRs (30d)
- 31
Description
## 🔴 Required Information
**Describe the Bug:**
ADK's native `McpToolset` is unusable with the native chat-completions connector for MCP tools that take parameters.
`AbstractMcpTool` declares MCP tool input schemas through `FunctionDeclaration.parametersJsonSchema(...)`, but `com.google.adk.models.chat.ChatCompletionsRequest` reads only `FunctionDeclaration.parameters()`.
When only the raw JSON schema is populated, the chat-completions path falls back to an empty parameter schema:
```json
{
"type": "object",
"properties": {}
}
```
As a result, the model receives a parameterless tool declaration for an MCP tool that actually requires arguments and commonly calls the tool with `{}`.
This appears to be an incompatibility between two first-party `core/` ADK components rather than a consumer configuration issue.
**Steps to Reproduce:**
1. Create an MCP tool with a required parameter, for example:
```json
{
"type": "object",
"properties": {
"jobId": {
"type": "string"
}
},
"required": ["jobId"]
}
```
2. Expose the MCP tool through ADK's native `McpToolset` / `AbstractMcpTool`.
3. Use the tool with a model backed by `ChatCompletionsHttpClient`.
4. Inspect the outbound `/chat/completions` request.
5. Observe that the generated tool declaration contains an empty parameter schema instead of the MCP tool's JSON schema.
**Expected Behavior:**
The outbound OpenAI-compatible tool declaration should preserve the MCP tool's parameter schema, including its properties and required fields:
```json
{
"type": "function",
"function": {
"name": "analyze_premerge_failures_by_job",
"parameters": {
"type": "object",
"properties": {
"jobId": {
"type": "string"
}
},
"required": ["jobId"]
}
}
}
```
The model should therefore be able to identify `jobId` as a required argument and provide it when calling the tool.
**Observed Behavior:**
The outbound declaration contains an empty schema:
```json
{
"type": "function",
"function": {
"name": "analyze_premerge_failures_by_job",
"parameters": {
"type": "object",
"properties": {}
}
}
}
```
The model cannot see that `jobId` exists and commonly emits an empty argument object:
```json
{}
```
This prevents parameterized MCP tools from being used correctly through the chat-completions connector.
---
## 🟡 Optional Information
**Regression:**
No known regression has been established. The issue is observed with ADK `1.7.1`.
**Logs:**
The relevant evidence is the outbound `/chat/completions` request. The tool declaration contains the following schema instead of the MCP-provided schema:
```json
{
"type": "object",
"properties": {}
}
```
**Screenshots / Video:**
N/A.
**Additional Context:**
`FunctionDeclaration` supports two representations for function parameters:
* typed `parameters(Schema)`
* raw `parametersJsonSchema(...)`
`AbstractMcpTool` populates the raw `parametersJsonSchema` form for MCP tool input schemas. `ChatCompletionsRequest` currently consumes only the typed `parameters(Schema)` form.
We also observed the same raw-only declaration shape through an application-side MCP adapter, but the native `McpToolset` reproduction demonstrates that the issue does not depend on that adapter.
A closely related fix already exists for the Claude connector in PR #1342 / commit `760c8da`. That fix forwards the raw schema directly, preserving JSON Schema constructs such as `$ref` and `$defs`.
OpenAI-compatible chat-completions APIs also accept raw JSON Schema, so forwarding `parametersJsonSchema` directly appears preferable to converting it into the narrower typed `Schema` representation.
**Impact:**
Any parameterized MCP tool is affected when used through the chat-completions connector. In our case, this blocks:
* a tool accepting `jobId`
* parameterized architecture-analysis MCP tools
Zero-argument tools continue to work because their empty schema is valid.
**Temporary Workaround:**
Until ADK is fixed, we materialize the raw schemas into typed `parameters(Schema)` in our `BaseLlm` implementation before delegating to `ChatCompletionsHttpClient`.
This workaround is connector-local and is covered by a wire-level regression test.
**Minimal Reproduction Code:**
A minimal reproduction should consist of:
```java
// Create an MCP tool whose input schema contains a required parameter,
// expose it through the native McpToolset, and invoke it through
// ChatCompletionsHttpClient.
//
// The outbound /chat/completions request contains:
// {
// "type": "object",
// "properties": {}
// }
// instead of the MCP tool's declared schema.
```
The important distinction is that the MCP tool declaration populates `parametersJsonSchema(...)`, while `ChatCompletionsRequest` currently reads `parameters()`.
**How often has this issue occurred?:**
* Always (100%)
Contributor guide
Assessment
This issue has not been assessed yet.