如何设计一个既提供绘图Tools又提供example_data的MCP服务器:

架构设计建议

方案1:全部使用Tools(推荐)

javascript 复制代码
const server = new Server({
  name: "chart-generator",
  version: "1.0.0"
}, {
  capabilities: {
    tools: {}
  }
});

// Tool 1: 获取示例数据
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "get_example_data") {
    const dataType = request.params.arguments?.type || "sales";
    
    const exampleData = {
      sales: [
        {month: "Jan", value: 100},
        {month: "Feb", value: 150},
        {month: "Mar", value: 120}
      ],
      temperature: [
        {date: "2024-01-01", temp: 20},
        {date: "2024-01-02", temp: 22},
        {date: "2024-01-03", temp: 18}
      ]
    };
    
    return {
      content: [{
        type: "text",
        text: JSON.stringify(exampleData[dataType])
      }]
    };
  }
  
  // Tool 2: 绘图工具
  if (request.params.name === "create_chart") {
    const { data, chartType, title } = request.params.arguments;
    
    // 处理数据并生成图表
    const chartResult = await generateChart(data, chartType, title);
    
    return {
      content: [{
        type: "text", 
        text: `Chart created successfully: ${chartResult.url}`
      }]
    };
  }
});

// 注册工具
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "get_example_data",
        description: "获取绘图示例数据",
        inputSchema: {
          type: "object",
          properties: {
            type: {
              type: "string",
              enum: ["sales", "temperature", "population"],
              description: "示例数据类型"
            }
          }
        }
      },
      {
        name: "create_chart",
        description: "根据数据创建图表",
        inputSchema: {
          type: "object",
          properties: {
            data: {
              type: "array",
              description: "图表数据"
            },
            chartType: {
              type: "string",
              enum: ["line", "bar", "pie"],
              description: "图表类型"
            },
            title: {
              type: "string",
              description: "图表标题"
            }
          },
          required: ["data", "chartType"]
        }
      }
    ]
  };
});

方案2:混合模式(Resources + Tools)

javascript 复制代码
const server = new Server({
  name: "chart-generator",
  version: "1.0.0"
}, {
  capabilities: {
    resources: {},
    tools: {}
  }
});

// Resources: 提供示例数据
server.setRequestHandler(ListResourcesRequestSchema, async () => {
  return {
    resources: [
      {
        uri: "data://examples/sales",
        name: "销售数据示例",
        description: "用于演示图表绘制的销售数据",
        mimeType: "application/json"
      },
      {
        uri: "data://examples/temperature", 
        name: "温度数据示例",
        description: "用于演示折线图的温度数据",
        mimeType: "application/json"
      }
    ]
  };
});

server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const uri = request.params.uri;
  
  const exampleData = {
    "data://examples/sales": [
      {month: "Jan", value: 100},
      {month: "Feb", value: 150},
      {month: "Mar", value: 120}
    ],
    "data://examples/temperature": [
      {date: "2024-01-01", temp: 20},
      {date: "2024-01-02", temp: 22}, 
      {date: "2024-01-03", temp: 18}
    ]
  };
  
  if (exampleData[uri]) {
    return {
      contents: [{
        uri,
        mimeType: "application/json",
        text: JSON.stringify(exampleData[uri], null, 2)
      }]
    };
  }
  
  throw new Error("Resource not found");
});

// Tools: 绘图功能
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "create_chart") {
    const { data, chartType, title } = request.params.arguments;
    const chartResult = await generateChart(data, chartType, title);
    
    return {
      content: [{
        type: "text",
        text: `Chart created: ${chartResult.url}`
      }]
    };
  }
});

大模型的使用流程

方案1流程(推荐)

  1. 大模型可以主动调用 get_example_data 获取示例数据
  2. 大模型拿到数据后,主动调用 create_chart 进行绘图
  3. 整个过程无需人工干预

方案2流程

  1. 用户或客户端需要先选择要使用的Resource(example_data)
  2. 大模型获得数据后,可以主动调用 create_chart Tool

Python实现示例

python 复制代码
from mcp.server import Server
from mcp.types import Tool, Resource
import json

app = Server("chart-generator")

# 示例数据
EXAMPLE_DATA = {
    "sales": [
        {"month": "Jan", "value": 100},
        {"month": "Feb", "value": 150},
        {"month": "Mar", "value": 120}
    ],
    "temperature": [
        {"date": "2024-01-01", "temp": 20},
        {"date": "2024-01-02", "temp": 22},
        {"date": "2024-01-03", "temp": 18}
    ]
}

@app.list_tools()
async def list_tools():
    return [
        Tool(
            name="get_example_data",
            description="获取绘图示例数据",
            inputSchema={
                "type": "object",
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": ["sales", "temperature"],
                        "description": "数据类型"
                    }
                }
            }
        ),
        Tool(
            name="create_chart", 
            description="创建图表",
            inputSchema={
                "type": "object",
                "properties": {
                    "data": {"type": "array"},
                    "chart_type": {"type": "string"},
                    "title": {"type": "string"}
                },
                "required": ["data", "chart_type"]
            }
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "get_example_data":
        data_type = arguments.get("type", "sales")
        return json.dumps(EXAMPLE_DATA.get(data_type, []))
    
    elif name == "create_chart":
        # 实现图表生成逻辑
        data = arguments["data"]
        chart_type = arguments["chart_type"] 
        title = arguments.get("title", "Chart")
        
        chart_url = await generate_chart(data, chart_type, title)
        return f"Chart created: {chart_url}"

建议

推荐使用方案1(全Tools),因为:

  1. 大模型可以完全自主工作
  2. 无需人工选择数据
  3. 工作流程更流畅
  4. 更符合"让大模型自己调用"的需求

这样大模型就可以:

  1. 自动获取示例数据
  2. 自动进行绘图
  3. 完成整个工作流程
相关推荐
灵感__idea1 小时前
Hello 算法:贪心的世界
前端·javascript·算法
mounter6251 小时前
【硬核前沿】CXL 深度解析:重塑数据中心架构的“高速公路”,Linux 内核如何应对挑战?-- CXL 协议详解与 LSF/MM 最新动态
linux·服务器·网络·架构·kernel
薿夜2 小时前
SpringSecurity(三)
android
zzzyyy5382 小时前
Linux环境变量
linux·运维·服务器
kebeiovo3 小时前
atomic原子操作实现无锁队列
服务器·c++
CHHC18803 小时前
NetCore树莓派桌面应用程序
linux·运维·服务器
killerbasd4 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
帮我吧智能服务平台4 小时前
装备制造智能制造升级:远程运维与智能服务如何保障产线OEE
运维·服务器·制造
橘子编程5 小时前
JavaScript与TypeScript终极指南
javascript·ubuntu·typescript
叫我一声阿雷吧5 小时前
JS 入门通关手册(45):浏览器渲染原理与重绘重排(性能优化核心,面试必考
javascript·前端面试·前端性能优化·浏览器渲染·浏览器渲染原理,重排重绘·reflow·repaint