创建和使用 Calculator MCP 工具示例¶
文件 concurrent_raw_results.txt 包含了在开发 toolregistry 不同集成时进行并发工具调用基准测试的原始统计数据。
我们让 LLM 从该文件中计算各指标的平均值并返回结果。
MCP 数学服务器示例¶
首先定义一个简单的 FastMCP 服务器,提供一些基本的数学运算。
"""Math server using the `fastmcp` standalone library directly.
This module implements a math server that directly uses the fastmcp
standalone library without any additional dependencies.
"""
import argparse
from fastmcp import FastMCP
# Common server configuration
server_name = "Math Server"
mcp = FastMCP(server_name)
# Register all math tools
@mcp.tool()
def add(a: float, b: float) -> float:
"""Add two numbers"""
return a + b
@mcp.tool()
def subtract(a: float, b: float) -> float:
"""Subtract two numbers"""
return a - b
@mcp.tool()
def multiply(a: float, b: float) -> float:
"""Multiply two numbers"""
return a * b
@mcp.tool()
def divide(a: float, b: float) -> float:
"""Divide two numbers"""
return a / b
# Register all math resources
@mcp.resource("math://constants/pi")
def get_pi() -> float:
"""Get the value of pi"""
return 3.141592653589793
@mcp.resource("math://constants/e")
def get_e() -> float:
"""Get the value of e"""
return 2.718281828459045
if __name__ == "__main__":
"""Create a unified math server with all tools and resources"""
parser = argparse.ArgumentParser(description="Math Server")
parser.add_argument(
"--mode",
type=str,
default="stdio",
choices=["stdio", "sse"],
help="Server transport mode: stdio, sse, ws or http",
)
parser.add_argument(
"--port", type=int, default=8000, help="Port number for network modes"
)
args = parser.parse_args()
# Create appropriate app based on mode
if args.mode == "stdio":
mcp.run()
elif args.mode == "sse":
mcp.run(
transport="sse",
host="localhost",
port=args.port,
)
可以使用以下命令运行服务器:
注意,当前推荐的网络传输方式是 Streamable HTTP 而非 SSE。
注册和使用方法¶
我们将分别使用 Cicada MultiModalModel 和 OpenAI 客户端来展示与工具注册表集成的不同方式。
Cicada MultiModalModel 示例¶
import json
import os
from cicada.core.model import MultiModalModel
from cicada.core.utils import cprint
from dotenv import load_dotenv
from toolregistry import ToolRegistry
load_dotenv()
PORT = os.getenv("PORT", 8000)
# Initialize LLM model
model_name = os.getenv("MODEL", "deepseek-v3")
API_KEY = os.getenv("API_KEY", "your-api-key")
BASE_URL = os.getenv("BASE_URL", "https://api.deepseek.com/")
stream = os.getenv("STREAM", "True").lower() == "true"
llm = MultiModalModel(
api_key=API_KEY,
api_base_url=BASE_URL,
model_name=model_name,
stream=stream,
)
# Initialize tool registry and register Calculator static methods
tool_registry = ToolRegistry()
input_file = "examples/hub_related/concurrent_raw_results.txt"
with open(input_file) as f:
input_content = f.read()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Process some integers.")
parser.add_argument(
"--mode", default="stdio", choices=["stdio", "sse"], help="Mode of transport"
)
args = parser.parse_args()
if args.mode == "sse":
# SSE
transport = f"http://localhost:{PORT}/sse"
else:
# stdio
transport = "/home/pding/projects/toolregistry/examples/mcp_related/mcp_servers/math_server.py"
tool_registry.register_from_mcp(transport, namespace=True)
print(tool_registry.get_available_tools())
# Example instruction to compute the averages
instruction = f"""
I have a few test results from multiple runs. Please use the available tools to compute the averages of the metrics for each category.
The input is as
{input_content}
"""
# Query LLM to get result
response = llm.query(instruction, tools=tool_registry, stream=stream)
cprint(json.dumps(response, indent=2))
OpenAI 客户端示例¶
import argparse
import os
from dotenv import load_dotenv
from openai import OpenAI
from toolregistry import ToolRegistry
# Load environment variables from .env file
load_dotenv()
PORT = os.getenv("PORT", 8000)
model_name = os.getenv("MODEL", "deepseek-v3")
stream = os.getenv("STREAM", "True").lower() == "true"
API_KEY = os.getenv("API_KEY", "your-api-key")
BASE_URL = os.getenv("BASE_URL", "https://api.deepseek.com/")
# Initialize tool registry and register Calculator static methods
tool_registry = ToolRegistry()
input_file = "examples/hub_related/concurrent_raw_results.txt"
with open(input_file) as f:
input_content = f.read()
# Set up OpenAI client
client = OpenAI(
api_key=os.getenv("API_KEY", "your-api-key"),
base_url=os.getenv("BASE_URL", "https://api.deepseek.com/"),
)
def handle_tool_calls(response, messages):
"""Handle tool calls in a loop until no more tool calls are needed"""
while response.choices[0].message.tool_calls:
tool_calls = response.choices[0].message.tool_calls
print("Tool calls:", tool_calls)
# Execute tool calls
tool_responses = tool_registry.execute_tool_calls(tool_calls)
# Construct assistant messages with results
assistant_tool_messages = tool_registry.build_tool_call_messages(
tool_calls, tool_responses
)
messages.extend(assistant_tool_messages)
# Send the results back to the model
response = client.chat.completions.create(
model=model_name,
messages=messages,
tools=tool_registry.get_schemas(),
tool_choice="auto",
)
return response
messages = [
{
"role": "user",
"content": f"""
I have a few test results from multiple runs. Please use the available tools to compute the averages of the metrics for each category.
The input is as {input_content}""",
}
]
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Process some integers.")
parser.add_argument(
"--mode", default="stdio", choices=["stdio", "sse"], help="Mode of transport"
)
args = parser.parse_args()
if args.mode == "sse":
# SSE
transport = f"http://localhost:{PORT}/sse"
else:
# stdio
transport = "/home/pding/projects/toolregistry/examples/mcp_related/mcp_servers/math_server.py"
tool_registry.register_from_mcp(transport, namespace=True)
print(tool_registry.get_available_tools())
# Make the chat completion request
response = client.chat.completions.create(
model=model_name,
messages=messages,
tools=tool_registry.get_schemas(),
tool_choice="auto",
)
# Handle tool calls using the new function (without iteration limit)
response = handle_tool_calls(response, messages)
# Print final response
if response.choices[0].message.content:
print(response.choices[0].message.content)