UNPKG

@mcpcn/mcp-computer-env

Version:

获取用户电脑环境信息的MCP服务器

239 lines (238 loc) 9.45 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js'; import os from 'os'; import path from 'path'; import process from 'process'; import * as fs from 'fs'; import { exec } from 'child_process'; import { promisify } from 'util'; const execAsync = promisify(exec); // 获取操作系统和架构信息 function getSystemInfo() { const platform = os.platform(); const arch = os.arch(); const release = os.release(); const type = os.type(); const cpus = os.cpus(); const cpuModel = cpus && cpus.length > 0 ? cpus[0].model : ''; const cpuCount = cpus.length; const is64bit = arch === 'x64' || arch === 'arm64'; const isArm = arch.startsWith('arm'); let distro = ''; if (platform === 'linux') { try { // 读取 /etc/os-release 获取发行版 const content = fs.readFileSync('/etc/os-release', 'utf-8'); const match = content.match(/^PRETTY_NAME="([^"]+)"/m); if (match) distro = match[1]; } catch { } } return { platform, type, release, arch, is64bit, isArm, cpuModel, cpuCount, distro, homedir: os.homedir(), hostname: os.hostname(), user: os.userInfo().username, uptime: os.uptime(), nodeVersion: process.version, }; } // 获取常用目录 function getCommonDirs() { const home = os.homedir(); const dirs = { home, desktop: '', documents: '', downloads: '', music: '', pictures: '', videos: '', appData: '', temp: os.tmpdir(), }; const platform = os.platform(); if (platform === 'win32') { dirs.desktop = path.join(home, 'Desktop'); dirs.documents = path.join(home, 'Documents'); dirs.downloads = path.join(home, 'Downloads'); dirs.music = path.join(home, 'Music'); dirs.pictures = path.join(home, 'Pictures'); dirs.videos = path.join(home, 'Videos'); dirs.appData = process.env.APPDATA || ''; } else if (platform === 'darwin') { dirs.desktop = path.join(home, 'Desktop'); dirs.documents = path.join(home, 'Documents'); dirs.downloads = path.join(home, 'Downloads'); dirs.music = path.join(home, 'Music'); dirs.pictures = path.join(home, 'Pictures'); dirs.videos = path.join(home, 'Movies'); dirs.appData = path.join(home, 'Library', 'Application Support'); } else if (platform === 'linux') { dirs.desktop = path.join(home, '桌面'); dirs.documents = path.join(home, '文档'); dirs.downloads = path.join(home, '下载'); dirs.music = path.join(home, '音乐'); dirs.pictures = path.join(home, '图片'); dirs.videos = path.join(home, '视频'); // 兼容英文目录 if (!fs.existsSync(dirs.desktop)) dirs.desktop = path.join(home, 'Desktop'); if (!fs.existsSync(dirs.documents)) dirs.documents = path.join(home, 'Documents'); if (!fs.existsSync(dirs.downloads)) dirs.downloads = path.join(home, 'Downloads'); if (!fs.existsSync(dirs.music)) dirs.music = path.join(home, 'Music'); if (!fs.existsSync(dirs.pictures)) dirs.pictures = path.join(home, 'Pictures'); if (!fs.existsSync(dirs.videos)) dirs.videos = path.join(home, 'Videos'); dirs.appData = process.env.XDG_CONFIG_HOME || path.join(home, '.config'); } return dirs; } // 其他可选环境信息工具:内存、磁盘、网络等 function getMemoryInfo() { return { total: os.totalmem(), free: os.freemem(), }; } function getNetworkInfo() { return os.networkInterfaces(); } // 获取磁盘分区信息(跨平台) async function getDiskInfo() { const platform = os.platform(); if (platform === 'win32') { // Windows: 使用wmic const { stdout } = await execAsync('wmic logicaldisk get Caption,FileSystem,Size,FreeSpace'); const lines = stdout.trim().split(/\r?\n/).filter(Boolean); const header = lines.shift(); return lines.map(line => { const parts = line.trim().split(/\s+/); const [Caption, FileSystem, Size, FreeSpace] = parts; const total = parseInt(Size, 10) || 0; const free = parseInt(FreeSpace, 10) || 0; return { filesystem: Caption, mount: Caption + '\\', type: FileSystem, total, used: total - free, available: free }; }); } else { // macOS/Linux: 使用df -kP const { stdout } = await execAsync('df -kP'); const lines = stdout.trim().split(/\n/).filter(Boolean); lines.shift(); // 去掉表头 return lines.map(line => { const parts = line.replace(/\s+/g, ' ').split(' '); // Filesystem 1024-blocks Used Available Capacity Mounted on const [filesystem, blocks, used, available, capacity, ...mountArr] = parts; const mount = mountArr.join(' '); return { filesystem, mount, type: '', // 跨平台简化,详细类型可用mount命令补充 total: parseInt(blocks, 10) * 1024, used: parseInt(used, 10) * 1024, available: parseInt(available, 10) * 1024 }; }); } } class ComputerEnvServer { constructor() { this.server = new Server({ name: 'computer-env-mcp', version: '1.0.0', }, { capabilities: { tools: {}, }, }); this.setupToolHandlers(); this.server.onerror = (error) => console.error('[MCP Error]', error); process.on('SIGINT', async () => { await this.server.close(); process.exit(0); }); } setupToolHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'get_system_info', description: '获取操作系统类型、版本、架构、CPU等信息,帮助大模型了解当前电脑环境', inputSchema: { type: 'object', properties: {}, additionalProperties: false }, }, { name: 'get_common_dirs', description: '获取常用目录路径,如桌面、文稿、下载、音乐、图片、视频等,自动适配不同操作系统', inputSchema: { type: 'object', properties: {}, additionalProperties: false }, }, { name: 'get_memory_info', description: '获取内存信息,包括总内存和可用内存(单位:字节)', inputSchema: { type: 'object', properties: {}, additionalProperties: false }, }, { name: 'get_network_info', description: '获取网络接口信息,包括本机所有网卡的IP、MAC等', inputSchema: { type: 'object', properties: {}, additionalProperties: false }, }, { name: 'get_disk_info', description: '获取所有磁盘分区的总容量、已用空间、可用空间、文件系统类型、挂载点等信息,自动适配不同操作系统', inputSchema: { type: 'object', properties: {}, additionalProperties: false }, }, ], })); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { switch (request.params.name) { case 'get_system_info': return { content: [{ type: 'text', text: JSON.stringify(getSystemInfo()) }] }; case 'get_common_dirs': return { content: [{ type: 'text', text: JSON.stringify(getCommonDirs()) }] }; case 'get_memory_info': return { content: [{ type: 'text', text: JSON.stringify(getMemoryInfo()) }] }; case 'get_network_info': return { content: [{ type: 'text', text: JSON.stringify(getNetworkInfo()) }] }; case 'get_disk_info': return { content: [{ type: 'text', text: JSON.stringify(await getDiskInfo()) }] }; default: throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`); } } catch (error) { throw error; } }); } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('Computer Env MCP server running on stdio'); } } const server = new ComputerEnvServer(); server.run().catch(console.error);