@mcpcn/mcp-computer-env 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # 电脑环境信息MCP服务器
2
+
3
+ 跨平台MCP服务器,获取用户电脑的操作系统、架构、常用目录等环境信息,便于大模型理解用户当前运行环境。
4
+
5
+ ## 功能特性
6
+ - 获取操作系统类型、版本、架构(如macOS、Windows、Linux发行版,x86/arm,32/64位等)
7
+ - 获取常用目录路径(桌面、文稿、下载、音乐、图片、视频等)
8
+ - 可扩展更多环境相关信息
9
+
10
+ ## 安装和使用
11
+
12
+ ```bash
13
+ pnpm install
14
+ pnpm build
15
+ pnpm start
16
+ ```
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,238 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
5
+ import os from 'os';
6
+ import path from 'path';
7
+ import process from 'process';
8
+ import * as fs from 'fs';
9
+ import { exec } from 'child_process';
10
+ import { promisify } from 'util';
11
+ const execAsync = promisify(exec);
12
+ // 获取操作系统和架构信息
13
+ function getSystemInfo() {
14
+ const platform = os.platform();
15
+ const arch = os.arch();
16
+ const release = os.release();
17
+ const type = os.type();
18
+ const cpus = os.cpus();
19
+ const cpuModel = cpus && cpus.length > 0 ? cpus[0].model : '';
20
+ const cpuCount = cpus.length;
21
+ const is64bit = arch === 'x64' || arch === 'arm64';
22
+ const isArm = arch.startsWith('arm');
23
+ let distro = '';
24
+ if (platform === 'linux') {
25
+ try {
26
+ // 读取 /etc/os-release 获取发行版
27
+ const content = fs.readFileSync('/etc/os-release', 'utf-8');
28
+ const match = content.match(/^PRETTY_NAME="([^"]+)"/m);
29
+ if (match)
30
+ distro = match[1];
31
+ }
32
+ catch { }
33
+ }
34
+ return {
35
+ platform,
36
+ type,
37
+ release,
38
+ arch,
39
+ is64bit,
40
+ isArm,
41
+ cpuModel,
42
+ cpuCount,
43
+ distro,
44
+ homedir: os.homedir(),
45
+ hostname: os.hostname(),
46
+ user: os.userInfo().username,
47
+ uptime: os.uptime(),
48
+ nodeVersion: process.version,
49
+ };
50
+ }
51
+ // 获取常用目录
52
+ function getCommonDirs() {
53
+ const home = os.homedir();
54
+ const dirs = {
55
+ home,
56
+ desktop: '',
57
+ documents: '',
58
+ downloads: '',
59
+ music: '',
60
+ pictures: '',
61
+ videos: '',
62
+ appData: '',
63
+ temp: os.tmpdir(),
64
+ };
65
+ const platform = os.platform();
66
+ if (platform === 'win32') {
67
+ dirs.desktop = path.join(home, 'Desktop');
68
+ dirs.documents = path.join(home, 'Documents');
69
+ dirs.downloads = path.join(home, 'Downloads');
70
+ dirs.music = path.join(home, 'Music');
71
+ dirs.pictures = path.join(home, 'Pictures');
72
+ dirs.videos = path.join(home, 'Videos');
73
+ dirs.appData = process.env.APPDATA || '';
74
+ }
75
+ else if (platform === 'darwin') {
76
+ dirs.desktop = path.join(home, 'Desktop');
77
+ dirs.documents = path.join(home, 'Documents');
78
+ dirs.downloads = path.join(home, 'Downloads');
79
+ dirs.music = path.join(home, 'Music');
80
+ dirs.pictures = path.join(home, 'Pictures');
81
+ dirs.videos = path.join(home, 'Movies');
82
+ dirs.appData = path.join(home, 'Library', 'Application Support');
83
+ }
84
+ else if (platform === 'linux') {
85
+ dirs.desktop = path.join(home, '桌面');
86
+ dirs.documents = path.join(home, '文档');
87
+ dirs.downloads = path.join(home, '下载');
88
+ dirs.music = path.join(home, '音乐');
89
+ dirs.pictures = path.join(home, '图片');
90
+ dirs.videos = path.join(home, '视频');
91
+ // 兼容英文目录
92
+ if (!fs.existsSync(dirs.desktop))
93
+ dirs.desktop = path.join(home, 'Desktop');
94
+ if (!fs.existsSync(dirs.documents))
95
+ dirs.documents = path.join(home, 'Documents');
96
+ if (!fs.existsSync(dirs.downloads))
97
+ dirs.downloads = path.join(home, 'Downloads');
98
+ if (!fs.existsSync(dirs.music))
99
+ dirs.music = path.join(home, 'Music');
100
+ if (!fs.existsSync(dirs.pictures))
101
+ dirs.pictures = path.join(home, 'Pictures');
102
+ if (!fs.existsSync(dirs.videos))
103
+ dirs.videos = path.join(home, 'Videos');
104
+ dirs.appData = process.env.XDG_CONFIG_HOME || path.join(home, '.config');
105
+ }
106
+ return dirs;
107
+ }
108
+ // 其他可选环境信息工具:内存、磁盘、网络等
109
+ function getMemoryInfo() {
110
+ return {
111
+ total: os.totalmem(),
112
+ free: os.freemem(),
113
+ };
114
+ }
115
+ function getNetworkInfo() {
116
+ return os.networkInterfaces();
117
+ }
118
+ // 获取磁盘分区信息(跨平台)
119
+ async function getDiskInfo() {
120
+ const platform = os.platform();
121
+ if (platform === 'win32') {
122
+ // Windows: 使用wmic
123
+ const { stdout } = await execAsync('wmic logicaldisk get Caption,FileSystem,Size,FreeSpace');
124
+ const lines = stdout.trim().split(/\r?\n/).filter(Boolean);
125
+ const header = lines.shift();
126
+ return lines.map(line => {
127
+ const parts = line.trim().split(/\s+/);
128
+ const [Caption, FileSystem, Size, FreeSpace] = parts;
129
+ const total = parseInt(Size, 10) || 0;
130
+ const free = parseInt(FreeSpace, 10) || 0;
131
+ return {
132
+ filesystem: Caption,
133
+ mount: Caption + '\\',
134
+ type: FileSystem,
135
+ total,
136
+ used: total - free,
137
+ available: free
138
+ };
139
+ });
140
+ }
141
+ else {
142
+ // macOS/Linux: 使用df -kP
143
+ const { stdout } = await execAsync('df -kP');
144
+ const lines = stdout.trim().split(/\n/).filter(Boolean);
145
+ lines.shift(); // 去掉表头
146
+ return lines.map(line => {
147
+ const parts = line.replace(/\s+/g, ' ').split(' ');
148
+ // Filesystem 1024-blocks Used Available Capacity Mounted on
149
+ const [filesystem, blocks, used, available, capacity, ...mountArr] = parts;
150
+ const mount = mountArr.join(' ');
151
+ return {
152
+ filesystem,
153
+ mount,
154
+ type: '', // 跨平台简化,详细类型可用mount命令补充
155
+ total: parseInt(blocks, 10) * 1024,
156
+ used: parseInt(used, 10) * 1024,
157
+ available: parseInt(available, 10) * 1024
158
+ };
159
+ });
160
+ }
161
+ }
162
+ class ComputerEnvServer {
163
+ constructor() {
164
+ this.server = new Server({
165
+ name: 'computer-env-mcp',
166
+ version: '1.0.0',
167
+ }, {
168
+ capabilities: {
169
+ tools: {},
170
+ },
171
+ });
172
+ this.setupToolHandlers();
173
+ this.server.onerror = (error) => console.error('[MCP Error]', error);
174
+ process.on('SIGINT', async () => {
175
+ await this.server.close();
176
+ process.exit(0);
177
+ });
178
+ }
179
+ setupToolHandlers() {
180
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
181
+ tools: [
182
+ {
183
+ name: 'get_system_info',
184
+ description: '获取操作系统类型、版本、架构、CPU等信息,帮助大模型了解当前电脑环境',
185
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
186
+ },
187
+ {
188
+ name: 'get_common_dirs',
189
+ description: '获取常用目录路径,如桌面、文稿、下载、音乐、图片、视频等,自动适配不同操作系统',
190
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
191
+ },
192
+ {
193
+ name: 'get_memory_info',
194
+ description: '获取内存信息,包括总内存和可用内存(单位:字节)',
195
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
196
+ },
197
+ {
198
+ name: 'get_network_info',
199
+ description: '获取网络接口信息,包括本机所有网卡的IP、MAC等',
200
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
201
+ },
202
+ {
203
+ name: 'get_disk_info',
204
+ description: '获取所有磁盘分区的总容量、已用空间、可用空间、文件系统类型、挂载点等信息,自动适配不同操作系统',
205
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
206
+ },
207
+ ],
208
+ }));
209
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
210
+ try {
211
+ switch (request.params.name) {
212
+ case 'get_system_info':
213
+ return { content: [{ type: 'text', text: JSON.stringify(getSystemInfo()) }] };
214
+ case 'get_common_dirs':
215
+ return { content: [{ type: 'text', text: JSON.stringify(getCommonDirs()) }] };
216
+ case 'get_memory_info':
217
+ return { content: [{ type: 'text', text: JSON.stringify(getMemoryInfo()) }] };
218
+ case 'get_network_info':
219
+ return { content: [{ type: 'text', text: JSON.stringify(getNetworkInfo()) }] };
220
+ case 'get_disk_info':
221
+ return { content: [{ type: 'text', text: JSON.stringify(await getDiskInfo()) }] };
222
+ default:
223
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
224
+ }
225
+ }
226
+ catch (error) {
227
+ throw error;
228
+ }
229
+ });
230
+ }
231
+ async run() {
232
+ const transport = new StdioServerTransport();
233
+ await this.server.connect(transport);
234
+ console.error('Computer Env MCP server running on stdio');
235
+ }
236
+ }
237
+ const server = new ComputerEnvServer();
238
+ server.run().catch(console.error);
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@mcpcn/mcp-computer-env",
3
+ "version": "1.0.1",
4
+ "description": "获取用户电脑环境信息的MCP服务器",
5
+ "packageManager": "pnpm@8.12.1",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "computer-env-mcp": "./dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist/**/*"
13
+ ],
14
+ "engines": {
15
+ "node": ">=18"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "computer-env",
20
+ "system-info",
21
+ "环境信息",
22
+ "跨平台"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc && chmod +x dist/index.js",
26
+ "start": "node dist/index.js",
27
+ "dev": "tsc -w",
28
+ "clean": "rm -rf build",
29
+ "prepare": "pnpm clean && pnpm build"
30
+ },
31
+ "type": "module",
32
+ "license": "MIT",
33
+ "devDependencies": {
34
+ "@types/node": "^22.10.2",
35
+ "typescript": "^5.7.2"
36
+ },
37
+ "dependencies": {
38
+ "@modelcontextprotocol/sdk": "^1.0.4"
39
+ }
40
+ }