Skip to content

Commit 929d1f5

Browse files
authored
Merge pull request #344 from vuepress-reco/feature/ai-component
feat: init reco mcp
2 parents f840f51 + ed3f803 commit 929d1f5

File tree

16 files changed

+1944
-31
lines changed

16 files changed

+1944
-31
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* 探索 @modelcontextprotocol/sdk 的 API 结构
5+
*/
6+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8+
9+
// 创建 MCP 服务器实例
10+
try {
11+
console.log('正在创建 McpServer 实例...');
12+
const server = new McpServer({
13+
name: "api-explorer",
14+
version: "1.0.0"
15+
});
16+
17+
console.log('\n== 实例创建成功 ==');
18+
19+
// 查看实例属性
20+
console.log('\n== McpServer 实例的属性 ==');
21+
console.log(Object.keys(server));
22+
23+
// 查看实例方法
24+
console.log('\n== McpServer 实例的方法 ==');
25+
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(server))
26+
.filter(name => name !== 'constructor');
27+
console.log(methods);
28+
29+
// 探索 server.server 属性
30+
if (server.server) {
31+
console.log("\n== server.server 的属性 ==");
32+
console.log(Object.keys(server.server));
33+
34+
console.log("\n== server.server 的方法 ==");
35+
const serverMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(server.server))
36+
.filter(name => name !== 'constructor');
37+
console.log(serverMethods);
38+
39+
// 查看 setRequestHandler 的签名
40+
if (typeof server.server.setRequestHandler === 'function') {
41+
console.log("\n== setRequestHandler 函数存在 ==");
42+
console.log("函数签名:", server.server.setRequestHandler.toString().split('\n')[0]);
43+
}
44+
}
45+
46+
// 检查工具相关方法
47+
console.log("\n== 检查工具相关 API ==");
48+
const toolMethods = [
49+
'registerTool', 'defineBasicTool', 'addTool', 'defineTool', 'addToolHandler'
50+
];
51+
52+
for (const method of toolMethods) {
53+
if (typeof server[method] === 'function') {
54+
console.log(`找到方法: server.${method}`);
55+
} else {
56+
console.log(`未找到方法: server.${method}`);
57+
}
58+
}
59+
60+
// 检查连接相关方法
61+
console.log("\n== 检查连接相关方法 ==");
62+
const connectionMethods = ['connect', 'listen'];
63+
64+
for (const method of connectionMethods) {
65+
if (typeof server[method] === 'function') {
66+
console.log(`找到方法: server.${method}`);
67+
} else {
68+
console.log(`未找到方法: server.${method}`);
69+
}
70+
}
71+
72+
// 搜索所有可用方法
73+
console.log("\n== 搜索所有 server 实例方法 ==");
74+
console.log(methods);
75+
76+
} catch (error) {
77+
console.error("\n探索 SDK API 时出错:", error);
78+
}
79+
80+
console.log("\n探索完成!");
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"name": "@vuepress-reco/mcp",
3+
"version": "2.0.0",
4+
"description": "MCP server for vuepress-theme-reco",
5+
"keywords": [
6+
"vuepress",
7+
"vuepress-theme-reco",
8+
"mcp"
9+
],
10+
"homepage": "https://github.com/vuepress-reco/vuepress-theme-reco#readme",
11+
"bugs": {
12+
"url": "https://github.com/vuepress-reco/vuepress-theme-reco/issues"
13+
},
14+
"repository": {
15+
"type": "git",
16+
"url": "git+https://github.com/vuepress-reco/vuepress-theme-reco.git"
17+
},
18+
"license": "MIT",
19+
"author": "reco_luan",
20+
"type": "module",
21+
"exports": {
22+
".": "./lib/node/index.js",
23+
"./package.json": "./package.json"
24+
},
25+
"main": "lib/node/index.js",
26+
"types": "lib/node/index.d.ts",
27+
"files": [
28+
"lib",
29+
"templates"
30+
],
31+
"bin": {
32+
"vuepress-reco-mcp": "./lib/node/cli.js"
33+
},
34+
"scripts": {
35+
"build": "tsc --build tsconfig.build.json",
36+
"clean": "rimraf lib *.tsbuildinfo",
37+
"start": "node lib/node/cli.js"
38+
},
39+
"dependencies": {
40+
"@modelcontextprotocol/sdk": "^1.10.1",
41+
"@vuepress/core": "2.0.0-beta.67",
42+
"@vuepress/utils": "2.0.0-beta.67",
43+
"chalk": "^5.3.0",
44+
"commander": "^11.1.0",
45+
"fs-extra": "^11.2.0",
46+
"inquirer": "^9.2.12",
47+
"ora": "^7.0.1",
48+
"zod": "^3.22.4"
49+
},
50+
"devDependencies": {
51+
"@types/fs-extra": "^11.0.4",
52+
"@types/inquirer": "^9.0.7"
53+
},
54+
"publishConfig": {
55+
"access": "public"
56+
}
57+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env node
2+
3+
import { startServer } from './index.js';
4+
5+
// 启动 MCP 服务器
6+
async function main() {
7+
try {
8+
await startServer();
9+
} catch (error) {
10+
console.error('启动 MCP 服务器失败:', error);
11+
process.exit(1);
12+
}
13+
}
14+
15+
main();
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3+
import { logger } from './utils.js';
4+
import { FeatureConfigOptions, ProjectInitOptions } from '../types/index.js';
5+
6+
/**
7+
* vuepress-reco MCP 服务器入口
8+
* 提供项目初始化和功能配置工具
9+
*/
10+
11+
// 创建 MCP 服务器实例
12+
const server = new McpServer({
13+
name: "vuepress-reco",
14+
version: "2.0.0"
15+
});
16+
17+
// 注册工具
18+
// 初始化项目工具
19+
server.tool("init-project", async (args: any) => {
20+
try {
21+
// 动态导入处理函数
22+
const { initProjectHandler } = await import('./tools/initProject.js');
23+
const result = await initProjectHandler(args as ProjectInitOptions);
24+
25+
return {
26+
content: [{
27+
type: "text",
28+
text: result.success
29+
? `项目 ${args?.name || '新'} 创建成功!\n\n${result.message}`
30+
: `项目创建失败:${result.message}`
31+
}]
32+
};
33+
} catch (error) {
34+
const errorMessage = error instanceof Error ? error.message : String(error);
35+
logger.error(`初始化项目时发生错误: ${errorMessage}`);
36+
return {
37+
content: [
38+
{
39+
type: "text",
40+
text: `初始化项目时发生错误: ${errorMessage}`
41+
}
42+
]
43+
};
44+
}
45+
});
46+
47+
// 定义初始化项目工具的参数
48+
// 注意:这里只是定义参数,但实际上 MCP SDK 可能不支持这种方式
49+
// 直接在代码中保留参数定义,作为文档目的
50+
type InitProjectParams = {
51+
name: string;
52+
description: string;
53+
type: "blog" | "docs" | "custom";
54+
i18n: boolean;
55+
typescript: boolean;
56+
plugins: string[];
57+
};
58+
59+
// 功能配置工具
60+
server.tool("config-features", async (args: any) => {
61+
try {
62+
// 动态导入处理函数
63+
const { configFeaturesHandler } = await import('./tools/configFeatures.js');
64+
const result = await configFeaturesHandler(args as FeatureConfigOptions);
65+
66+
return {
67+
content: [
68+
{
69+
type: "text",
70+
text: result.success
71+
? `功能配置成功!\n\n${result.message}\n\n已配置的功能:\n${result.configuredFeatures?.map((feature: string) => `- ${feature}`).join('\n') || '无'}`
72+
: `功能配置失败:${result.message}`
73+
}
74+
]
75+
};
76+
} catch (error) {
77+
const errorMessage = error instanceof Error ? error.message : String(error);
78+
logger.error(`配置功能时发生错误: ${errorMessage}`);
79+
return {
80+
content: [
81+
{
82+
type: "text",
83+
text: `配置功能时发生错误: ${errorMessage}`
84+
}
85+
]
86+
};
87+
}
88+
});
89+
90+
// 定义功能配置工具的参数
91+
// 注意:这里只是定义参数,但实际上 MCP SDK 可能不支持这种方式
92+
// 直接在代码中保留参数定义,作为文档目的
93+
type ConfigFeaturesParams = {
94+
enableAIChat?: boolean;
95+
aiChatConfig?: {
96+
apiKey?: string;
97+
model?: string;
98+
temperature?: number;
99+
maxTokens?: number;
100+
};
101+
enableComments?: boolean;
102+
commentsConfig?: {
103+
provider?: "giscus" | "waline" | "twikoo";
104+
options?: Record<string, any>;
105+
};
106+
enableCodeCopy?: boolean;
107+
enableBulletinPopover?: boolean;
108+
bulletinPopoverConfig?: {
109+
title?: string;
110+
body?: string;
111+
footer?: string;
112+
};
113+
enableVuePreview?: boolean;
114+
enableMarkdownTask?: boolean;
115+
};
116+
117+
/**
118+
* 启动 MCP 服务器
119+
*/
120+
export async function startServer() {
121+
const transport = new StdioServerTransport();
122+
await server.connect(transport);
123+
console.error("vuepress-theme-reco MCP 服务器已启动,运行在 stdio 上");
124+
}

0 commit comments

Comments
 (0)