-
Notifications
You must be signed in to change notification settings - Fork 338
Description
Problem
I'm trying to integrate mcp-server-kubernetes into my agent. Such MCP server provides a set of kubectl-related tools, whose arguments are specified using camelCase in their respective schemas (e.g., see kubectl_get definition).
What I'm observing is that my agent MCP client is actually issuing tools/call requests containing arguments specified using snake_case instead. E.g., this is what I gathered by recording the incoming traffic to the MCP server:
{
"method": "tools/call",
"params": {
"name": "kubectl_get",
"arguments": {
"resource_type": "pods",
"namespace": "<REDACTED>",
"output": "wide"
}
},
"jsonrpc": "2.0",
"id": 1
}You can see that the request contains resource_type instead of resourceType, causing the server to fail at handling it.
Expected behavior
I'd expect tools/call requests arguments to be passed in the same way they are advertised in the provided tool schema.
Code example
Here is a simplified version of the code that is triggering the issue:
from __future__ import annotations
from typing import Annotated
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.graph import START, StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
from typing_extensions import TypedDict
DEFAULT_SYSTEM_PROMPT = "..."
class State(TypedDict):
messages: Annotated[list, add_messages]
class AgentGraph:
def __init__(self) -> None:
# ...
self.graph_builder = StateGraph(State)
self.graph = None
# ...
async def initialize(self) -> None:
llm = # ...
mcp_client = MultiServerMCPClient(
{
"k8s": {
"url": "http://localhost:4001/sse",
"transport": "sse",
},
}
)
tools = (
[
# list of non-MCP tools available to the agent
]
+ await mcp_client.get_tools()
)
llm_with_tools = llm.bind_tools(tools)
def chatbot(state: State):
messages = [{"role": "system", "content": DEFAULT_SYSTEM_PROMPT}] + state["messages"]
return {"messages": [llm_with_tools.invoke(messages)]}
self.graph_builder.add_node("chatbot", chatbot)
tool_node = ToolNode(tools=tools)
self.graph_builder.add_node("tools", tool_node)
self.graph_builder.add_edge(START, "chatbot")
self.graph_builder.add_conditional_edges(
"chatbot",
tools_condition,
)
self.graph_builder.add_edge("tools", "chatbot")
self.graph = self.graph_builder.compile(debug=True)
# ...