@zhangzhao1102/yapi-mcp-server
Version:
YApi MCP Server - 用于与YApi接口管理平台交互的MCP服务器
387 lines • 17.4 kB
JavaScript
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
import { YApiClient } from './services/yapi-client.js';
import { configManager } from './utils/config.js';
class YApiMCPServer {
constructor() {
this.server = new Server({
name: 'yapi-mcp-server',
version: '1.0.0',
});
this.setupTools();
}
async setupTools() {
// 项目相关工具
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'login',
description: '登录YApi',
inputSchema: {
type: 'object',
properties: {
username: {
type: 'string',
description: '用户名',
},
password: {
type: 'string',
description: '密码',
},
},
},
},
{
name: 'get_project_list',
description: '获取YApi项目列表',
inputSchema: {
type: 'object',
properties: {
group_id: {
type: 'number',
description: '项目分组ID',
},
page: {
type: 'number',
description: '页码,默认为1',
default: 1,
},
limit: {
type: 'number',
description: '每页数量,默认为10',
default: 10,
},
},
},
},
{
name: 'get_project_info',
description: '获取指定项目详细信息',
inputSchema: {
type: 'object',
properties: {
project_id: {
type: 'number',
description: '项目ID',
},
},
required: ['project_id'],
},
},
{
name: 'get_interface_list',
description: '获取项目接口列表',
inputSchema: {
type: 'object',
properties: {
project_id: {
type: 'number',
description: '项目ID',
},
catid: {
type: 'number',
description: '接口分类ID',
},
page: {
type: 'number',
description: '页码,默认为1',
default: 1,
},
limit: {
type: 'number',
description: '每页数量,默认为20',
default: 20,
},
},
required: ['project_id'],
},
},
{
name: 'get_interface_detail',
description: '获取接口详细信息',
inputSchema: {
type: 'object',
properties: {
interface_id: {
type: 'number',
description: '接口ID',
},
},
required: ['interface_id'],
},
},
{
name: 'create_interface',
description: '创建新的接口',
inputSchema: {
type: 'object',
properties: {
project_id: {
type: 'number',
description: '项目ID',
},
catid: {
type: 'number',
description: '接口分类ID',
},
title: {
type: 'string',
description: '接口标题',
},
path: {
type: 'string',
description: '接口路径',
},
method: {
type: 'string',
enum: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
description: '请求方法',
},
desc: {
type: 'string',
description: '接口描述',
},
req_body_type: {
type: 'string',
enum: ['form', 'json', 'file', 'raw'],
description: '请求体类型',
},
status: {
type: 'string',
enum: ['undone', 'done'],
description: '接口状态',
},
},
required: ['project_id', 'catid', 'title', 'path', 'method'],
},
},
{
name: 'update_interface',
description: '更新接口信息',
inputSchema: {
type: 'object',
properties: {
interface_id: {
type: 'number',
description: '接口ID',
},
title: {
type: 'string',
description: '接口标题',
},
path: {
type: 'string',
description: '接口路径',
},
method: {
type: 'string',
description: '请求方法',
},
desc: {
type: 'string',
description: '接口描述',
},
status: {
type: 'string',
enum: ['undone', 'done'],
description: '接口状态',
},
},
required: ['interface_id'],
},
},
{
name: 'delete_interface',
description: '删除接口',
inputSchema: {
type: 'object',
properties: {
interface_id: {
type: 'number',
description: '接口ID',
},
},
required: ['interface_id'],
},
},
{
name: 'run_interface_test',
description: '运行接口测试',
inputSchema: {
type: 'object',
properties: {
interface_id: {
type: 'number',
description: '接口ID',
},
env: {
type: 'string',
description: '测试环境',
},
params: {
type: 'object',
description: '测试参数',
},
},
required: ['interface_id'],
},
},
{
name: 'get_interface_categories',
description: '获取项目接口分类',
inputSchema: {
type: 'object',
properties: {
project_id: {
type: 'number',
description: '项目ID',
},
},
required: ['project_id'],
},
},
{
name: 'create_interface_category',
description: '创建接口分类',
inputSchema: {
type: 'object',
properties: {
project_id: {
type: 'number',
description: '项目ID',
},
name: {
type: 'string',
description: '分类名称',
},
desc: {
type: 'string',
description: '分类描述',
},
},
required: ['project_id', 'name'],
},
},
],
};
});
// 初始化YApi客户端
const config = configManager.getConfig();
this.yapiClient = new YApiClient(config);
await this.yapiClient.login(config.username || '', config.password || '');
// 工具调用处理器
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
// 初始化YApi客户端
const config = configManager.getConfig();
// 验证配置
const validation = configManager.validateConfig();
if (!validation.isValid) {
throw new Error(`配置错误: ${validation.errors.join(', ')}`);
}
console.log('config', config);
this.yapiClient = new YApiClient(config);
let result;
switch (name) {
case 'login':
result = await this.yapiClient.login(config.username || '', config.password || '');
break;
case 'get_project_list':
result = await this.yapiClient.getProjectList(args);
break;
case 'get_project_info':
if (!args || typeof args.project_id !== 'number') {
throw new Error('project_id 参数是必需的且必须是数字');
}
result = await this.yapiClient.getProjectInfo(args.project_id);
break;
case 'get_interface_list':
if (!args || typeof args.project_id !== 'number') {
throw new Error('project_id 参数是必需的且必须是数字');
}
result = await this.yapiClient.getInterfaceList(args);
break;
case 'get_interface_detail':
if (!args || typeof args.interface_id !== 'number') {
throw new Error('interface_id 参数是必需的且必须是数字');
}
result = await this.yapiClient.getInterfaceDetail(args.interface_id);
break;
case 'create_interface':
if (!args) {
throw new Error('参数不能为空');
}
result = await this.yapiClient.createInterface(args);
break;
case 'update_interface':
if (!args) {
throw new Error('参数不能为空');
}
result = await this.yapiClient.updateInterface(args);
break;
case 'delete_interface':
if (!args || typeof args.interface_id !== 'number') {
throw new Error('interface_id 参数是必需的且必须是数字');
}
await this.yapiClient.deleteInterface(args.interface_id);
result = { message: '接口删除成功' };
break;
case 'run_interface_test':
if (!args) {
throw new Error('参数不能为空');
}
result = await this.yapiClient.runInterfaceTest(args);
break;
case 'get_interface_categories':
if (!args || typeof args.project_id !== 'number') {
throw new Error('project_id 参数是必需的且必须是数字');
}
result = await this.yapiClient.getInterfaceCategories(args.project_id);
break;
case 'create_interface_category':
if (!args) {
throw new Error('参数不能为空');
}
result = await this.yapiClient.createInterfaceCategory(args);
break;
default:
throw new Error(`未知的工具: ${name}`);
}
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
}
catch (error) {
return {
content: [
{
type: 'text',
text: `错误: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
});
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
}
}
// 启动服务器
const server = new YApiMCPServer();
server.run().catch((error) => {
console.error('服务器启动失败:', error);
process.exit(1);
});
//# sourceMappingURL=index.js.map