Azure / Azure/azure-sdk-for-python

Foundry Toolbox MCP proxy rejects MCPStreamableHTTPTool.call_tool() from custom tool code — "No tool config matches tool name"

Aperta
#46,864 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub
bug customer-reported Foundry Machine Learning needs-team-attention Service Attention
Lingua principale
Python
Stelle
5.6k
Fork
3.4k
Merge medio
2g 2h
PR unite (30g)
213

Descrizione

## Python Version and Packages

- `agent-framework-core`: 1.2.2
- `agent-framework-foundry`: 1.2.2
- `agent-framework-devui`: 1.0.0b260304
- Python: 3.12.10
- OS: Windows 11
- MCP protocol version: 2025-11-25
- Foundry Toolbox endpoint: `{project_endpoint}/toolboxes/{name}/versions/{version}/mcp?api-version=v1`

## Description

Calling `MCPStreamableHTTPTool.call_tool()` directly from Python code inside a custom `@tool` function fails with:

```
McpError: No tool config matches tool name 'WorkIQSharePoint.readSmallBinaryFile'. Provide matching _meta.tools entries.
```

The **exact same tool** succeeds when the framework's executor pipeline invokes it (i.e., when the LLM decides to call it as a tool). This means:
- ✅ LLM → framework executor → `call_tool()` → **works**
- ❌ Custom `@tool` Python code → `toolbox_ref.call_tool()` → **fails**

This is a **regression** — the same code was working in production until recently (around May 10-12, 2026). No SDK or agent code was changed — the Foundry Toolbox MCP server-side appears to have started enforcing `_meta.tool_configuration` validation on `tools/call` requests.

## Steps to Reproduce

1. Create a Foundry Toolbox with MCP tools (e.g., WorkIQ SharePoint connector)
2. Connect via `MCPStreamableHTTPTool` with proper auth headers and `Foundry-Features: Toolboxes=V1Preview`
3. Register the toolbox as a tool on an `Agent`
4. Inside a custom `@tool` function, call `toolbox_ref.call_tool("ServerLabel.ToolName", arg=value)`

```python
from agent_framework import Agent, MCPStreamableHTTPTool, tool
import httpx

# Setup toolbox connection
toolbox = MCPStreamableHTTPTool(
name="my-toolbox",
url=f"{project_endpoint}/toolboxes/my-toolbox/versions/1/mcp?api-version=v1",
http_client=httpx.AsyncClient(
auth=MyAuth(token_provider),
headers={"Foundry-Features": "Toolboxes=V1Preview"},
),
load_prompts=False,
)

# Custom tool that calls MCP toolbox directly
@tool(approval_mode="never_require")
async def save_file_to_storage(document_library_id: str, file_id: str) -> dict:
# This FAILS:
result = await toolbox.call_tool(
"WorkIQSharePoint.readSmallBinaryFile",
documentLibraryId=document_library_id,
fileId=file_id,
)
# ... process result and save to storage ...

agent = Agent(client=client, tools=[toolbox, save_file_to_storage])
```

## Error

```
mcp.shared.exceptions.McpError: No tool config matches tool name 'WorkIQSharePoint.readSmallBinaryFile'. Provide matching _meta.tools entries.
```

The error originates from the Foundry Toolbox MCP server (`POST .../toolboxes/.../mcp`), not from the SDK.

## Root Cause Analysis

Looking at `MCPTool.call_tool()` in `_mcp.py`:

```python
otel_meta = _inject_otel_into_mcp_meta()
result = await self.session.call_tool(tool_name, arguments=filtered_kwargs, meta=otel_meta)
```

The `meta` parameter only contains OpenTelemetry trace context. It does **not** include the `_meta.tool_configuration` block that the Foundry Toolbox MCP proxy now requires.

When the framework's executor pipeline calls a tool (LLM → executor → `call_tool`), the `_meta.tool_configuration` is somehow injected (likely by the responses API or the executor's function invocation pipeline). But direct `call_tool()` from code bypasses this.

## Expected Behavior

`MCPStreamableHTTPTool.call_tool()` should work from custom tool code. The `_meta.tool_configuration` entries (available from `tools/list` response at connect time) should be automatically injected into the `meta` parameter of `session.call_tool()`.

## Actual Behavior

The Foundry Toolbox MCP proxy rejects the call because `_meta.tool_configuration` is missing from the request.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia in _mcp.py, da MCPTool.call_tool(), quindi segui come vengono conservati la risposta tools/list e i valori _meta prima dell’esecuzione di session.call_tool(). Riproduci il percorso diretto del custom-tool e confronta i metadati della richiesta con la pipeline dell’executor; il lavoro è completo quando Foundry Toolbox accetta la chiamata diretta con la configurazione dello strumento richiesta.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
api, backend
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
58/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.