如何设计一个既提供绘图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. 完成整个工作流程
相关推荐
刘发财3 小时前
弃用html2pdf.js,这个html转pdf方案能力是它的几十倍
前端·javascript·github
ssshooter10 小时前
看完就懂 useSyncExternalStore
前端·javascript·react.js
Live0000011 小时前
在鸿蒙中使用 Repeat 渲染嵌套列表,修改内层列表的一个元素,页面不会更新
前端·javascript·react native
柳杉11 小时前
使用Ai从零开发智慧水利态势感知大屏(开源)
前端·javascript·数据可视化
球球pick小樱花12 小时前
游戏官网前端工具库:海内外案例解析
前端·javascript·css
喝水的长颈鹿12 小时前
【大白话前端 02】网页从解析到绘制的全流程
前端·javascript
用户145369814587812 小时前
VersionCheck.js - 让前端版本更新变得简单优雅
前端·javascript
codingWhat12 小时前
整理「祖传」代码,就是在开发脚手架?
前端·javascript·node.js
码路飞12 小时前
写了个 AI 聊天页面,被 5 种流式格式折腾了一整天 😭
javascript·python
Lee川12 小时前
优雅进化的JavaScript:从ES6+新特性看现代前端开发范式
javascript·面试