如何设计一个既提供绘图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. 完成整个工作流程
相关推荐
成都渲染101云渲染66662 小时前
如何在3ds Max中实现更快、更高质量的渲染
前端·javascript·人工智能
不像程序员的程序媛5 小时前
系统cpu内存负载资源分析
运维·服务器·数据库
SRET6 小时前
Mineradio 沙盒隔离安装完全指南 | 一键安全运行 Electron 应用!!!
javascript·经验分享·安全·electron·aigc·音视频·ai编程
全栈前端老曹6 小时前
【MongoDB】安全与权限管理 —— 用户认证、角色权限、SSL 加密
前端·javascript·数据库·安全·mongodb·nosql·ssl
耍酷的魔镜8 小时前
谈谈如何使用Netty开发实现高性能的RPC服务器
服务器·网络协议·rpc
程序员在囧途10 小时前
likeadmin-api API 中转站怎么做统一报价?从 /pricing、/user/balance 到 task_id 回执的落地方法
运维·服务器·数据库·likeadmin-api·api中转站·token计费
free3510 小时前
作用域链与 Environment:变量查找、遮蔽和赋值怎么实现
javascript
cookies_s_s10 小时前
C++ 字符串动态创建对象 -- 工厂模式、自动注册、模板递归动态调用
服务器·开发语言·c++
YHL10 小时前
🤖 Agent 智能体开发实战 · 第一课:Tool Use —— 让大模型自动干活
前端·javascript·人工智能
想你依然心痛11 小时前
Linux用户空间与内核空间通信:netlink、ioctl、mmap 零拷贝与性能对比
linux·运维·服务器