第一篇的服务端什么都干不了。给它接一个工具。
四个部件
server.addTool(
name: 'desk.count',
description: 'How many people are waiting at the desk right now',
inputSchema: const {'type': 'object', 'properties': {}},
handler: (args) async =>
CallToolResult(content: [TextContent(text: '{"waiting":3}')]),
);
再声明把这项能力打开。
capabilities: ServerCapabilities(tools: ToolsCapability(listChanged: true))
有三块不是我们读的
四块里只有 handler 是我们的代码在读。其余三块全都由调用方来读。
问一句 tools/list,出去的是这个。
{
"tools": [
{
"name": "desk.count",
"description": "How many people are waiting at the desk right now",
"inputSchema": {
"type": "object",
"properties": {}
}
}
]
}
人写的客户端会照这份清单画按钮。模型则会读这份清单,决定该调哪个工具。 而这个判断的依据,就是 description 那一行。
所以那一行不是注释。它是会跑的代码。
命名
用 desk.count 这样带点的名字。前面是关于什么,后面是做什么。
desk.count 数有多少人在等
desk.admit 从队列里放人进来
camera.settings 读摄像头的设置
工具只有三个时看着无所谓。到二十个,没规矩这件事就露出来了。 而且名字一旦发出去就改不了——它已经嵌在调用方的代码里。