188 lines
3.5 KiB
JavaScript
188 lines
3.5 KiB
JavaScript
// 引入必要的模块
|
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
import { z } from "zod";
|
|
import open, { openApp, apps } from "open";
|
|
|
|
// 创建 MCP 服务器实例
|
|
// 为其设置一个名字和版本
|
|
const server = new McpServer(
|
|
{
|
|
name: "local-open-mcp",
|
|
version: "1.0.0",
|
|
},
|
|
{
|
|
capabilities: {
|
|
prompts: {},
|
|
tools: {},
|
|
},
|
|
}
|
|
);
|
|
|
|
server.registerTool(
|
|
'open_url',
|
|
{
|
|
description: "打开指定的URL链接",
|
|
inputSchema: z.object({
|
|
url: z.string().describe("URL链接"),
|
|
}),
|
|
},
|
|
|
|
async ({ url }) => {
|
|
try {
|
|
|
|
await open(url);
|
|
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `已打开URL: ${url}`,
|
|
},
|
|
],
|
|
};
|
|
|
|
} catch (error) {
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `打开URL失败: ${error.message}`,
|
|
},
|
|
],
|
|
isError: true,
|
|
};
|
|
}
|
|
}
|
|
)
|
|
server.registerTool(
|
|
'open_file',
|
|
{
|
|
description: "打开指定的本地文件",
|
|
inputSchema: z.object({
|
|
filePath: z.string().describe("文件路径"),
|
|
}),
|
|
},
|
|
|
|
async ({ filePath }) => {
|
|
try {
|
|
|
|
await open(filePath);
|
|
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `已打开文件: ${filePath}`,
|
|
},
|
|
],
|
|
};
|
|
|
|
} catch (error) {
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `打开文件失败: ${error.message}`,
|
|
},
|
|
],
|
|
isError: true,
|
|
};
|
|
}
|
|
}
|
|
)
|
|
|
|
server.registerTool(
|
|
'open_directory',
|
|
{
|
|
description: "打开指定的本地文件夹",
|
|
inputSchema: z.object({
|
|
directoryPath: z.string().describe("文件夹路径"),
|
|
}),
|
|
},
|
|
|
|
async ({ directoryPath }) => {
|
|
try {
|
|
|
|
await open(directoryPath);
|
|
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `已打开文件夹: ${directoryPath}`,
|
|
},
|
|
],
|
|
};
|
|
|
|
} catch (error) {
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `打开文件夹失败: ${error.message}`,
|
|
},
|
|
],
|
|
isError: true,
|
|
};
|
|
}
|
|
}
|
|
)
|
|
|
|
|
|
server.registerTool(
|
|
'open_app',
|
|
{
|
|
description: "打开指定的本地应用程序",
|
|
inputSchema: z.object({
|
|
appName: z.string().describe("应用程序名称"),
|
|
args: z.array(z.string()).optional().describe("传递给应用程序的可选参数"),
|
|
}),
|
|
},
|
|
|
|
async ({ appName, args }) => {
|
|
try {
|
|
|
|
await openApp(appName, {arguments: args});
|
|
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `已打开应用程序: ${appName}`,
|
|
},
|
|
],
|
|
};
|
|
|
|
} catch (error) {
|
|
return {
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `打开应用程序失败: ${error.message}`,
|
|
},
|
|
],
|
|
isError: true,
|
|
};
|
|
}
|
|
}
|
|
)
|
|
|
|
|
|
|
|
|
|
// 启动服务器,使用标准输入/输出(stdio)与客户端通信
|
|
async function main() {
|
|
const transport = new StdioServerTransport();
|
|
await server.connect(transport);
|
|
console.error("Open Local MCP 服务器已通过 stdio 启动"); // 日志输出到 stderr
|
|
|
|
}
|
|
|
|
// 运行主函数,并捕获可能的错误
|
|
main().catch((error) => {
|
|
console.error("服务器运行出现致命错误:", error);
|
|
process.exit(1);
|
|
});
|
|
|
|
export { server }; |