{"slug": "day-2-30-llm-tool-calls", "title": "Day 2/30: LLM Tool Calls", "summary": "A developer integrated the Model Context Protocol (MCP) and LangGraph to enable a large language model (LLM) to make tool calls from scratch, giving it the ability to interact with external services without relying on pre-existing frameworks. The approach uses a state graph to model workflows and conditional edges to determine when to execute tool calls. A key lesson learned is the need to carefully design the graph to avoid infinite loops.", "body_md": "I still remember the frustration of trying to integrate a large language model (LLM) into our support bot. The model could understand natural language, generate human-like responses, and even learn from feedback. However, it lacked the ability to interact with external tools and services, making it feel like a disembodied brain - incredibly smart, but unable to act on its knowledge. Our bot would often respond with phrases like \"I can help you with that,\" but then fail to actually perform the task. It was as if the LLM had no \"hands\" to manipulate the world.\n\nThe problem was that our LLM was not designed to make tool calls from scratch. It relied on pre-existing frameworks and libraries to interact with external services, which limited its flexibility and autonomy. We needed a way to give our LLM the ability to call tools and services without relying on these frameworks, essentially giving it \"hands\" to manipulate the world.\n\nTo solve this problem, we turned to the Model Context Protocol (MCP) and LangGraph. MCP provides a standardized way to represent and interact with external tools and services, while LangGraph allows us to model complex workflows and decision-making processes. By combining these two technologies, we could create a system that enables our LLM to make tool calls from scratch, without relying on pre-existing frameworks.\n\nHere's an example of how we used LangGraph and MCP to give our LLM \"hands\":\n\n``` python\nimport langgraph\nfrom langgraph import StateGraph, add_node, add_conditional_edges\nfrom mcp import Tool, ToolCall\n\n# Define a tool that our LLM can call\nclass SendMessageTool(Tool):\n    def __init__(self, message):\n        self.message = message\n\n    def execute(self):\n        # Simulate sending a message\n        print(f\"Sending message: {self.message}\")\n\n# Create a LangGraph state graph\ngraph = StateGraph()\n\n# Add nodes to the graph\nstart_node = add_node(graph, \"start\")\nmessage_node = add_node(graph, \"send_message\")\nend_node = add_node(graph, \"end\")\n\n# Add conditional edges to the graph\nadd_conditional_edges(graph, start_node, message_node, lambda x: x[\"action\"] == \"send_message\")\nadd_conditional_edges(graph, message_node, end_node, lambda x: x[\"message\"] is not None)\n\n# Define a tool call\ntool_call = ToolCall(SendMessageTool, \"Hello, world!\")\n\n# Create an LLM that can make tool calls\nclass LLM:\n    def __init__(self, graph):\n        self.graph = graph\n\n    def make_tool_call(self, tool_call):\n        # Use the graph to determine the next action\n        current_node = self.graph.get_node(\"start\")\n        while current_node != self.graph.get_node(\"end\"):\n            # Get the next node based on the current state\n            next_node = self.graph.get_next_node(current_node, {\"action\": \"send_message\", \"message\": tool_call.tool.message})\n            # Execute the tool call\n            if next_node == self.graph.get_node(\"send_message\"):\n                tool_call.tool.execute()\n            current_node = next_node\n\n# Create an instance of the LLM and make a tool call\nllm = LLM(graph)\nllm.make_tool_call(tool_call)\n```\n\nThis code defines a simple tool that sends a message, and an LLM that uses a LangGraph state graph to determine when to make a tool call. The LLM can make tool calls from scratch, without relying on pre-existing frameworks.\n\nOne practical gotcha we learned from this experience is that it's essential to carefully design the state graph and tool calls to avoid infinite loops. If the graph is not properly structured, the LLM may get stuck in an infinite loop, making repeated tool calls without achieving any meaningful outcome.\n\nAs we continue to develop our agentic AI system, we'll explore more advanced topics, such as integrating multiple tools and services, and using MCP to handle errors and exceptions. Tomorrow, we'll dive deeper into the world of agentic AI and explore new ways to give our LLM \"hands\" to manipulate the world.", "url": "https://wpnews.pro/news/day-2-30-llm-tool-calls", "canonical_source": "https://dev.to/yashwanth_kasi/day-230-llm-tool-calls-1gnk", "published_at": "2026-07-12 08:54:43+00:00", "updated_at": "2026-07-12 09:14:37.615834+00:00", "lang": "en", "topics": ["large-language-models", "ai-agents", "developer-tools"], "entities": ["Model Context Protocol", "LangGraph"], "alternates": {"html": "https://wpnews.pro/news/day-2-30-llm-tool-calls", "markdown": "https://wpnews.pro/news/day-2-30-llm-tool-calls.md", "text": "https://wpnews.pro/news/day-2-30-llm-tool-calls.txt", "jsonld": "https://wpnews.pro/news/day-2-30-llm-tool-calls.jsonld"}}