Skip to content

MCP ToolsΒΆ

Model Context Protocol (MCP) tool registration, execution, and lifecycle management.

Define tools with MCPTool, manage them with MCPToolManager, and execute them by name or ID β€” all thread-safe.

v2.0 Improvements

MCPTool uses __slots__ for memory efficiency. MCPToolManager uses threading.Lock for thread safety and provides remove_tool() cleanup.


OverviewΒΆ

Class Purpose
MCPTool Data class representing a single tool (id, name, capability, execute function)
MCPToolManager Registry that stores, lists, and executes tools

Quick StartΒΆ

Python
from agenticaiframework.mcp_tools import MCPTool, MCPToolManager

# Define a tool
def calculate_sum(a: int, b: int) -> int:
    return a + b

tool = MCPTool(
    id="sum_tool",
    name="Calculator Sum",
    capability="Adds two numbers together",
    execute_fn=calculate_sum,
)

# Register and execute
manager = MCPToolManager()
manager.register_tool(tool)

result = manager.execute_tool("sum_tool", a=5, b=3) # 8
result = manager.execute_tool_by_name("Calculator Sum", a=10, b=20) # 30

Defining ToolsΒΆ

Each MCPTool has four attributes (stored via __slots__):

Attribute Type Description
id str Unique identifier
name str Human-readable name
capability str Description of what the tool does
execute_fn Callable The function to invoke
Python
import httpx
from agenticaiframework.mcp_tools import MCPTool

def web_search(query: str) -> list[dict]:
    resp = httpx.get("https://api.search.example/v1", params={"q": query})
    return resp.json()["results"]

search_tool = MCPTool(
    id="web_search",
    name="Web Search",
    capability="Search the web for information",
    execute_fn=web_search,
)

Managing ToolsΒΆ

RegisterΒΆ

Python
manager = MCPToolManager()
manager.register_tool(tool)

ListΒΆ

Python
1
2
3
tools = manager.list_tools() # list of MCPTool objects
for t in tools:
    logger.info(f"{t.id}: {t.name} - {t.capability}")

Execute by IDΒΆ

Python
result = manager.execute_tool("web_search", query="Python async patterns")

Execute by NameΒΆ

Python
result = manager.execute_tool_by_name("Web Search", query="Python async patterns")

RemoveΒΆ

Python
manager.remove_tool("web_search")

Thread SafetyΒΆ

All MCPToolManager operations are protected by threading.Lock:

Python
import threading
from agenticaiframework.mcp_tools import MCPTool, MCPToolManager

manager = MCPToolManager()

def register_in_thread(tool):
    manager.register_tool(tool)

tools = [MCPTool(id=f"t{i}", name=f"Tool {i}", capability="...", execute_fn=lambda: i) for i in range(10)]
threads = [threading.Thread(target=register_in_thread, args=(t,)) for t in tools]
for t in threads:
    t.start()
for t in threads:
    t.join()

assert len(manager.list_tools()) == 10

API ReferenceΒΆ

MCPToolΒΆ

Attribute Type Description
id str Unique tool identifier
name str Human-readable name
capability str Tool description
execute_fn Callable Function to invoke

Uses __slots__ β€” no __dict__ overhead.

MCPToolManagerΒΆ

Method Returns Description
register_tool(tool) None Register an MCPTool instance
execute_tool(tool_id, **kwargs) Any Execute a tool by its ID
execute_tool_by_name(name, **kwargs) Any Execute a tool by its name
list_tools() list[MCPTool] List all registered tools
remove_tool(tool_id) None Remove a tool by ID

Best PracticesΒΆ

Do

  • Use descriptive capability strings β€” LLMs use them for tool selection.
  • Use unique, stable id values (e.g. snake_case identifiers).
  • Handle exceptions inside execute_fn or wrap calls in try/except.
  • Clean up with remove_tool() when tools are no longer needed.

Don't

  • Register multiple tools with the same id (last one wins).
  • Use long-blocking operations in execute_fn without timeouts.
  • Forget that execute_fn runs synchronously on the calling thread.

  • Tools β€” general tool framework
  • Hub β€” component registry
  • Agents β€” agent lifecycle
  • Integration β€” third-party integrations