This commit is contained in:
2025-10-25 16:26:14 +08:00
parent 4d74088cf1
commit b7e1af9b10
3 changed files with 136 additions and 12 deletions

View File

@@ -4,7 +4,8 @@
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"mcp": "node src/mcp.ts"
},
"keywords": [],
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
@@ -15,6 +16,7 @@
"@types/node": "^24.9.1"
},
"dependencies": {
"dotenv": "^17.2.3"
"dotenv": "^17.2.3",
"@modelcontextprotocol/sdk": "^1.0.0"
}
}

View File

@@ -1,5 +1,4 @@
import dotenv from 'dotenv';
import path from 'path';
dotenv.config();
const token = process.env.BAILIAN_API_KEY || '';
@@ -26,26 +25,26 @@ const chat = async (message: { role: string, content: string }[]) => {
const fn1 = {
id: 'get_weather',
description: '获取天气',
description: '获取天气,参数是 location 地址,返回该城市的当前天气',
fn: async (params: { location: string }) => {
return `当前${params.location}的天气是25度湿度60%。`;
}
}
const fn2 = {
id: 'get_time',
description: '获取时间',
fn: async (params: { timezone: string }) => {
return `当前${params.timezone}的时间是:2024-06-01 10:00 AM`;
description: `获取时间, 参数是 city 地址,返回该城市的当前时间`,
fn: async (params: { city: string }) => {
return `当前${params.city}的时间是:${new Date().toLocaleTimeString()}`;
}
}
const fns = [fn1, fn2];
const callPrompst = `你是一个函数调用助手,可以根据用户的需求选择合适的函数进行调用,并返回 JSON 数据, 格式为 { id: string, payload: {} } ,函数列表如下:
const callPrompts = `你是一个函数调用助手,可以根据用户的需求选择合适的函数进行调用,
并返回 JSON 数据, 格式为 { id: string, payload: {} } ,函数列表如下:
${fns.map(fn => `id: ${fn.id}
description: ${fn.description}`).join('\n\n')}
`;
const pickJson = (text: string) => {
const jsonStart = text.indexOf('{');
const jsonEnd = text.lastIndexOf('}');
@@ -61,10 +60,11 @@ const pickJson = (text: string) => {
return null;
}
const main = async () => {
const userMessage = '请告诉我北京的天气。';
// const userMessage = '请告诉我上海的天气。';
const userMessage = '请告诉我杭州的时间。';
const messages = [
{ role: 'system', content: callPrompst },
{ role: 'system', content: callPrompts },
{ role: 'user', content: userMessage }
];
// 获取函数调用建议
@@ -76,7 +76,7 @@ const main = async () => {
const fn = fns.find(f => f.id === json?.id);
if (fn) {
const fnResult = await fn.fn({ location: '北京', timezone: '纽约' });
const fnResult = await fn.fn({ ...json.payload });
console.log(`Function ${fn.id} result:`, fnResult);
} else {
console.log('No matching function found.');

122
src/mcp.ts Normal file
View File

@@ -0,0 +1,122 @@
import { Server } from '@modelcontextprotocol/sdk/server';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types';
import type { CallToolRequest } from '@modelcontextprotocol/sdk/types';
// 创建MCP服务器实例
const server = new Server(
{
name: 'weather-time-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// 获取天气工具
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'get_weather',
description: '获取天气,参数是 location 地址,返回该城市的当前天气',
inputSchema: {
type: 'object',
properties: {
location: {
type: 'string',
description: '要查询天气的城市地址'
}
},
required: ['location']
}
},
{
name: 'get_time',
description: '获取时间, 参数是 city 地址,返回该城市的当前时间',
inputSchema: {
type: 'object',
properties: {
city: {
type: 'string',
description: '要查询时间的城市地址'
}
},
required: ['city']
}
}
]
};
});
// 处理工具调用
server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'get_weather': {
const location = args?.location as string;
if (!location) {
throw new Error('缺少必需的参数: location');
}
const weather = `当前${location}的天气是25度湿度60%。`;
return {
content: [
{
type: 'text',
text: weather
}
]
};
}
case 'get_time': {
const city = args?.city as string;
if (!city) {
throw new Error('缺少必需的参数: city');
}
const time = `当前${city}的时间是2024-06-01 10:00 AM。`;
return {
content: [
{
type: 'text',
text: time
}
]
};
}
default:
throw new Error(`未知工具: ${name}`);
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `错误: ${error instanceof Error ? error.message : String(error)}`
}
],
isError: true
};
}
});
// 启动服务器
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Weather & Time MCP Server running on stdio');
}
main().catch((error) => {
console.error('服务器启动失败:', error);
process.exit(1);
});