set_model_response is missing from the MCP _RESERVED_TOOL_NAMES guard
@sanketpatil06 đang làm issue này rồi.
Từ ngày 17/9/2026.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 88/100
Hướng nghiên cứu
Bắt đầu tại src/google/adk/tools/mcp_tool/mcp_tool.py và kiểm tra guard _RESERVED_TOOL_NAMES, sau đó đọc các test liên quan trong test_mcp_tool.py. Thêm set_model_response vào các tên được dành riêng và bổ sung trường hợp một máy chủ MCP quảng bá tên đó. Hoàn tất khi việc đăng ký nhất quán raise ValueError như với các tên tool được dành riêng khác.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
_RESERVED_TOOL_NAMES in src/google/adk/tools/mcp_tool/mcp_tool.py omits set_model_response, even though it is a tool name the framework itself puts on the wire. The guard added in #6796 states its own invariant in the comment above the set:
# Tool names the framework itself puts on the wire. A server advertising one of
# these would have its tool dispatched in place of the framework's own, so the
# name is refused at registration.
_RESERVED_TOOL_NAMES = frozenset({
REQUEST_EUC_FUNCTION_CALL_NAME, # adk_request_credential
REQUEST_CONFIRMATION_FUNCTION_CALL_NAME, # adk_request_confirmation
REQUEST_INPUT_FUNCTION_CALL_NAME, # adk_request_input
transfer_to_agent.__name__, # transfer_to_agent
})
set_model_response satisfies that description but is not in the set, so an MCP server advertising it is accepted where the other four are refused.
set_model_response is a framework-owned tool name
- Defined as
def set_model_response() -> str:insrc/google/adk/tools/set_model_response_tool.py(self.func = set_model_response), so that is its declaration name. - Injected into the request whenever
output_schemais set alongside other tools:
src/google/adk/flows/llm_flows/prompt/_schema.py:54set_response_tool = SetModelResponseTool(agent.output_schema) llm_request.append_tools([set_response_tool]) - The framework then instructs the model to use it by name: "you must provide your final response using the set_model_response tool" (
_schema.py:57-64). - And it reads the answer back by that name —
get_structured_model_response()(_schema.py:97) is reached frombase_llm_flow.py:710with the comment "Check if this is a set_model_response function response".
Why that matters at an MCP boundary
LlmRequest.append_tools resolves a duplicate name by last-wins with only a warning (src/google/adk/models/llm_request.py):
if tool.name in self.tools_dict:
# Both declarations are still advertised to the model, but only one
# tool can hold the name, so calls land on the survivor.
logging.warning(
"Duplicate tool name %r: the previously registered tool is shadowed ...",
tool.name,
)
self.tools_dict[tool.name] = tool
So if an MCP server advertises set_model_response, one of the two tools holds the name and the model's set_model_response call is dispatched there. If the server's tool is the survivor, the agent's structured final answer is delivered to the third-party MCP server and the framework never sees it — which is the outcome the reserved-name check exists to prevent. If the framework's tool is the survivor, the duplicate is still advertised and callable by name, so calls can land on the wrong one.
Either way the invariant stated in the #6796 comment is violated: the name is never refused at registration.
Reproduction sketch
agent = LlmAgent(
model=..., tools=[McpToolset(connection_params=<server that advertises
a tool named "set_model_response">)],
output_schema=MySchema,
)
# Expected: ValueError, as for transfer_to_agent / adk_request_confirmation
# Actual: accepted; a warning is logged at request build time
Suggested fix
Add the name to the set:
_RESERVED_TOOL_NAMES = frozenset({
REQUEST_EUC_FUNCTION_CALL_NAME,
REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,
REQUEST_INPUT_FUNCTION_CALL_NAME,
transfer_to_agent.__name__,
'set_model_response',
})
If it is useful, the same reasoning may apply to other in-model names the framework injects (google_search, google_maps, url_context, vertex_ai_search, code_execution, load_artifacts, load_memory) — I have not verified each of those reaches tools_dict, so I have deliberately kept this report to the one name I traced end to end.
Happy to send the set change plus a unit test alongside test_mcp_tool.py if that is the preferred route.
- Ngôn ngữ chính
- Python
- Star
- 21.6k
- Fork
- 4k
- Merge trung bình
- 13 giờ 49 phút
- Pull request đã merge (30 ngày)
- 10
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của google/adk-python
-
mcp
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
google/adk-python#7217 · 2 bình luận · 1 người được giao ·
-
tools
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
google/adk-python#7206 · 1 bình luận · 1 người được giao ·
-
tools
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
google/adk-python#7205 · 1 bình luận · 1 người được giao ·
-
mcp
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
google/adk-python#7196 · 1 bình luận · 1 người được giao ·
-
eval request clarification
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 86/100
google/adk-python#7146 · 2 bình luận · 1 người được giao ·
Tất cả issue của google/adk-python
Issue tương tự
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
use-agent-os/agent-os#3314 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
BasedHardware/omi#15662 · 1 bình luận ·
-
documentation help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 90/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
AiursoftWeb/AnduinOS-2#19 ·