From 6262b5e8e56c94df1784d7549ee0f14eb85ac204 Mon Sep 17 00:00:00 2001 From: a-akimov Date: Sat, 16 May 2026 17:17:48 +0200 Subject: [PATCH 1/2] Fix issue #28 regarding the tool use --- mcp-client-python/client.py | 64 +++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/mcp-client-python/client.py b/mcp-client-python/client.py index 697bad89..81ed1d2b 100644 --- a/mcp-client-python/client.py +++ b/mcp-client-python/client.py @@ -12,6 +12,7 @@ # Claude model constant ANTHROPIC_MODEL = "claude-sonnet-4-5" +MAX_TOOL_TURNS = 10 class MCPClient: @@ -64,45 +65,52 @@ async def process_query(self, query: str) -> str: """Process a query using Claude and available tools""" messages = [{"role": "user", "content": query}] - response = await self.session.list_tools() + tools_response = await self.session.list_tools() available_tools = [ {"name": tool.name, "description": tool.description, "input_schema": tool.inputSchema} - for tool in response.tools + for tool in tools_response.tools ] - # Initial Claude API call + final_text = [] + response = self.anthropic.messages.create( model=ANTHROPIC_MODEL, max_tokens=1000, messages=messages, tools=available_tools ) - # Process response and handle tool calls - final_text = [] - - for content in response.content: - if content.type == "text": - final_text.append(content.text) - elif content.type == "tool_use": - tool_name = content.name - tool_args = content.input - - # Execute tool call - result = await self.session.call_tool(tool_name, tool_args) - final_text.append(f"[Calling tool {tool_name} with args {tool_args}]") - - # Continue conversation with tool results - if hasattr(content, "text") and content.text: - messages.append({"role": "assistant", "content": content.text}) - messages.append({"role": "user", "content": result.content}) - - # Get next response from Claude - response = self.anthropic.messages.create( - model=ANTHROPIC_MODEL, - max_tokens=1000, - messages=messages, + for _ in range(MAX_TOOL_TURNS): + tool_uses = [] + for content in response.content: + if content.type == "text": + final_text.append(content.text) + elif content.type == "tool_use": + tool_uses.append(content) + + if not tool_uses: + return "\n".join(final_text) + + tool_results = [] + for tool_use in tool_uses: + result = await self.session.call_tool(tool_use.name, tool_use.input) + final_text.append(f"[Calling tool {tool_use.name} with args {tool_use.input}]") + tool_results.append( + { + "type": "tool_result", + "tool_use_id": tool_use.id, + "content": result.content, + } ) - final_text.append(response.content[0].text) + messages.append({"role": "assistant", "content": response.content}) + messages.append({"role": "user", "content": tool_results}) + + response = self.anthropic.messages.create( + model=ANTHROPIC_MODEL, + max_tokens=1000, + messages=messages, + tools=available_tools, + ) + final_text.append(f"[Stopped after {MAX_TOOL_TURNS} tool-use turns]") return "\n".join(final_text) async def chat_loop(self): From 2c55ad9ac9ed0eff1f5687c4f43d97d4f13a351c Mon Sep 17 00:00:00 2001 From: a-akimov Date: Sat, 16 May 2026 17:41:47 +0200 Subject: [PATCH 2/2] Fix `chat_loop` to exit cleanly --- mcp-client-python/client.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mcp-client-python/client.py b/mcp-client-python/client.py index 81ed1d2b..44d5d5da 100644 --- a/mcp-client-python/client.py +++ b/mcp-client-python/client.py @@ -121,13 +121,15 @@ async def chat_loop(self): while True: try: query = input("\nQuery: ").strip() + except (EOFError, KeyboardInterrupt): + break - if query.lower() == "quit": - break + if query.lower() == "quit": + break + try: response = await self.process_query(query) print("\n" + response) - except Exception as e: print(f"\nError: {str(e)}")