@mearl/mcp-server 2.0.0
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 +116 -0
- package/dist/configure.d.ts +11 -0
- package/dist/configure.js +289 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +13 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +1837 -0
- package/dist/install-cli.d.ts +9 -0
- package/dist/install-cli.js +17 -0
- package/dist/mcp-clients.d.ts +23 -0
- package/dist/mcp-clients.js +153 -0
- package/dist/types.d.ts +120 -0
- package/dist/types.js +2 -0
- package/dist/uninstall.d.ts +9 -0
- package/dist/uninstall.js +152 -0
- package/package.json +48 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* mearl-mcp-install - 用户友好的安装命令
|
|
4
|
+
*
|
|
5
|
+
* 使用方式:
|
|
6
|
+
* mearl-mcp-install
|
|
7
|
+
* MEARL_EXTENSION_ID=xxx mearl-mcp-install
|
|
8
|
+
*/
|
|
9
|
+
import { installNativeHost } from '@mearl/native-host';
|
|
10
|
+
console.log('🚀 Mearl MCP Installer\n');
|
|
11
|
+
const extensionId = process.env.MEARL_EXTENSION_ID;
|
|
12
|
+
// Install both host manifests so MCP and Skills integrations can coexist.
|
|
13
|
+
const success = await installNativeHost({
|
|
14
|
+
mode: 'both',
|
|
15
|
+
...(extensionId ? { extensionId } : {}),
|
|
16
|
+
});
|
|
17
|
+
process.exit(success ? 0 : 1);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP 客户端配置定义
|
|
3
|
+
*/
|
|
4
|
+
export interface MCPClientConfig {
|
|
5
|
+
name: string;
|
|
6
|
+
configPath: string;
|
|
7
|
+
useServersFormat?: boolean;
|
|
8
|
+
useTomlFormat?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const MCP_CLIENTS: Record<string, MCPClientConfig>;
|
|
11
|
+
export declare function isNpxMode(): boolean;
|
|
12
|
+
export declare function getMCPServerConfig(useServersFormat?: boolean, useNpx?: boolean): any;
|
|
13
|
+
/**
|
|
14
|
+
* 检测已安装的 MCP 客户端
|
|
15
|
+
* @returns 已安装的客户端 ID 列表
|
|
16
|
+
*/
|
|
17
|
+
export declare function detectInstalledClients(): string[];
|
|
18
|
+
/**
|
|
19
|
+
* 检测单个 MCP 客户端是否已安装
|
|
20
|
+
* @param clientId 客户端 ID
|
|
21
|
+
* @returns 是否已安装
|
|
22
|
+
*/
|
|
23
|
+
export declare function isClientInstalled(clientId: string): boolean;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP 客户端配置定义
|
|
3
|
+
*/
|
|
4
|
+
import { join, dirname } from 'path';
|
|
5
|
+
import { homedir, platform } from 'os';
|
|
6
|
+
import { existsSync } from 'fs';
|
|
7
|
+
/**
|
|
8
|
+
* 获取跨平台的配置文件路径
|
|
9
|
+
* @param paths 不同平台的路径配置
|
|
10
|
+
* @returns 当前平台对应的完整路径
|
|
11
|
+
*/
|
|
12
|
+
function getPlatformConfigPath(paths) {
|
|
13
|
+
const os = platform();
|
|
14
|
+
const basePath = homedir();
|
|
15
|
+
if (os === 'win32' && paths.win32) {
|
|
16
|
+
return join(basePath, paths.win32);
|
|
17
|
+
}
|
|
18
|
+
else if (os === 'darwin' && paths.darwin) {
|
|
19
|
+
return join(basePath, paths.darwin);
|
|
20
|
+
}
|
|
21
|
+
else if (paths.linux) {
|
|
22
|
+
return join(basePath, paths.linux);
|
|
23
|
+
}
|
|
24
|
+
// Fallback: 使用 darwin 路径作为默认
|
|
25
|
+
return join(basePath, paths.darwin || paths.linux || paths.win32 || '');
|
|
26
|
+
}
|
|
27
|
+
export const MCP_CLIENTS = {
|
|
28
|
+
'vscode-copilot': {
|
|
29
|
+
name: 'VSCode Copilot',
|
|
30
|
+
configPath: getPlatformConfigPath({
|
|
31
|
+
win32: join(process.env.APPDATA || '', 'Code/User/mcp.json'),
|
|
32
|
+
darwin: 'Library/Application Support/Code/User/mcp.json',
|
|
33
|
+
linux: '.config/Code/User/mcp.json',
|
|
34
|
+
}),
|
|
35
|
+
useServersFormat: true,
|
|
36
|
+
},
|
|
37
|
+
'claude-code': {
|
|
38
|
+
name: 'Claude Code',
|
|
39
|
+
configPath: getPlatformConfigPath({
|
|
40
|
+
win32: join(process.env.APPDATA || '', 'Claude Code/mcp_config.json'),
|
|
41
|
+
darwin: '.config/claude-code/mcp_config.json',
|
|
42
|
+
linux: '.config/claude-code/mcp_config.json',
|
|
43
|
+
}),
|
|
44
|
+
},
|
|
45
|
+
cursor: {
|
|
46
|
+
name: 'Cursor',
|
|
47
|
+
configPath: getPlatformConfigPath({
|
|
48
|
+
win32: join(process.env.APPDATA || '', 'Cursor/mcp_config.json'),
|
|
49
|
+
darwin: '.cursor/mcp_config.json',
|
|
50
|
+
linux: '.cursor/mcp_config.json',
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
qoder: {
|
|
54
|
+
name: 'Qoder',
|
|
55
|
+
configPath: getPlatformConfigPath({
|
|
56
|
+
win32: join(process.env.APPDATA || '', 'Qoder/mcp_config.json'),
|
|
57
|
+
darwin: 'Library/Application Support/Qoder/mcp_config.json',
|
|
58
|
+
linux: '.config/qoder/mcp_config.json',
|
|
59
|
+
}),
|
|
60
|
+
},
|
|
61
|
+
codex: {
|
|
62
|
+
name: 'Codex',
|
|
63
|
+
configPath: getPlatformConfigPath({
|
|
64
|
+
win32: '.codex/config.toml',
|
|
65
|
+
darwin: '.codex/config.toml',
|
|
66
|
+
linux: '.codex/config.toml',
|
|
67
|
+
}),
|
|
68
|
+
useTomlFormat: true,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
// 检测是否通过 npx 运行
|
|
72
|
+
export function isNpxMode() {
|
|
73
|
+
// 检查 npm_execpath 环境变量
|
|
74
|
+
const execPath = process.env.npm_execpath || '';
|
|
75
|
+
if (execPath.includes('npx')) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
// 检查 npm_config_user_agent
|
|
79
|
+
const userAgent = process.env.npm_config_user_agent || '';
|
|
80
|
+
if (userAgent.includes('npx')) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
// 检查 process.argv[1] 是否包含 _npx
|
|
84
|
+
const argv1 = process.argv[1] || '';
|
|
85
|
+
if (argv1.includes('_npx') || argv1.includes('.npm/_npx')) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
// 检查 npm_command 是否为 exec (npx 使用 npm exec)
|
|
89
|
+
const npmCommand = process.env.npm_command || '';
|
|
90
|
+
if (npmCommand === 'exec') {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
// 获取 MCP Server 配置模板
|
|
96
|
+
export function getMCPServerConfig(useServersFormat, useNpx) {
|
|
97
|
+
if (useServersFormat) {
|
|
98
|
+
// VS Code 格式
|
|
99
|
+
if (useNpx) {
|
|
100
|
+
return {
|
|
101
|
+
type: 'stdio',
|
|
102
|
+
command: 'npx',
|
|
103
|
+
args: ['-y', '@mearl/mcp-server'],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
type: 'stdio',
|
|
108
|
+
command: 'mearl-mcp-server',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// Claude Code/Cursor 格式
|
|
112
|
+
if (useNpx) {
|
|
113
|
+
return {
|
|
114
|
+
command: 'npx',
|
|
115
|
+
args: ['-y', '@mearl/mcp-server'],
|
|
116
|
+
env: {},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
command: 'mearl-mcp-server',
|
|
121
|
+
args: [],
|
|
122
|
+
env: {},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 检测已安装的 MCP 客户端
|
|
127
|
+
* @returns 已安装的客户端 ID 列表
|
|
128
|
+
*/
|
|
129
|
+
export function detectInstalledClients() {
|
|
130
|
+
const installed = [];
|
|
131
|
+
for (const [id, config] of Object.entries(MCP_CLIENTS)) {
|
|
132
|
+
// 检查配置文件的父目录是否存在
|
|
133
|
+
// 因为配置文件本身可能不存在,但如果应用已安装,其配置目录应该存在
|
|
134
|
+
const configDir = dirname(config.configPath);
|
|
135
|
+
if (existsSync(configDir)) {
|
|
136
|
+
installed.push(id);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return installed;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 检测单个 MCP 客户端是否已安装
|
|
143
|
+
* @param clientId 客户端 ID
|
|
144
|
+
* @returns 是否已安装
|
|
145
|
+
*/
|
|
146
|
+
export function isClientInstalled(clientId) {
|
|
147
|
+
const config = MCP_CLIENTS[clientId];
|
|
148
|
+
if (!config) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
const configDir = dirname(config.configPath);
|
|
152
|
+
return existsSync(configDir);
|
|
153
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export interface MtopRequest {
|
|
2
|
+
id: number;
|
|
3
|
+
timestamp: string;
|
|
4
|
+
timestampMs: number;
|
|
5
|
+
method: string;
|
|
6
|
+
url: string;
|
|
7
|
+
apiName: string;
|
|
8
|
+
status: number;
|
|
9
|
+
statusText: string;
|
|
10
|
+
headers: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
value: string;
|
|
13
|
+
}>;
|
|
14
|
+
responseHeaders: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
value: string;
|
|
17
|
+
}>;
|
|
18
|
+
queryString: Record<string, string>;
|
|
19
|
+
postData: Record<string, any> | null;
|
|
20
|
+
responseBody: any;
|
|
21
|
+
duration?: number;
|
|
22
|
+
proxyData?: any;
|
|
23
|
+
}
|
|
24
|
+
export interface ConsoleLog {
|
|
25
|
+
level: 'log' | 'warn' | 'error' | 'info';
|
|
26
|
+
message: string;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
/** 来源文件和行号,格式 "filename.js:42",仅在可获取时存在 */
|
|
29
|
+
source?: string;
|
|
30
|
+
args: any[];
|
|
31
|
+
}
|
|
32
|
+
export interface WaitForRequestParams {
|
|
33
|
+
pattern: string;
|
|
34
|
+
timeout?: number;
|
|
35
|
+
includeExisting?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface GetRequestsParams {
|
|
38
|
+
count?: number;
|
|
39
|
+
filter?: string;
|
|
40
|
+
since?: number;
|
|
41
|
+
}
|
|
42
|
+
export interface GetLogsParams {
|
|
43
|
+
level?: 'log' | 'warn' | 'error' | 'info' | 'all';
|
|
44
|
+
since?: number;
|
|
45
|
+
limit?: number;
|
|
46
|
+
filter?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface SetMockParams {
|
|
49
|
+
apiName: string;
|
|
50
|
+
mockData: any;
|
|
51
|
+
enabled?: boolean;
|
|
52
|
+
duration?: number;
|
|
53
|
+
conditions?: Record<string, any>;
|
|
54
|
+
}
|
|
55
|
+
export interface GetApiSchemaParams {
|
|
56
|
+
api: string;
|
|
57
|
+
version?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface GetSelectedElementParams {
|
|
60
|
+
includeOuterHTML?: boolean;
|
|
61
|
+
includeScreenshot?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface RequestsResponse {
|
|
64
|
+
meta: {
|
|
65
|
+
/** 实际返回的请求数量 */
|
|
66
|
+
count: number;
|
|
67
|
+
/** 缓冲区中符合过滤条件的总请求数 */
|
|
68
|
+
totalMatched: number;
|
|
69
|
+
/** 缓冲区中的总请求数(未过滤) */
|
|
70
|
+
totalInBuffer: number;
|
|
71
|
+
/** 应用的过滤器(如果有) */
|
|
72
|
+
filter?: string;
|
|
73
|
+
/** 时间过滤器(秒) */
|
|
74
|
+
since?: number;
|
|
75
|
+
/** 是否包含请求/响应体 */
|
|
76
|
+
includeBody: boolean;
|
|
77
|
+
/** 是否包含请求/响应头 */
|
|
78
|
+
includeHeaders: boolean;
|
|
79
|
+
/** 提取的字段(如果有) */
|
|
80
|
+
fields?: string[];
|
|
81
|
+
/** 是否只返回键结构 */
|
|
82
|
+
keysOnly: boolean;
|
|
83
|
+
};
|
|
84
|
+
/** 请求数据列表 */
|
|
85
|
+
requests: MtopRequest[];
|
|
86
|
+
}
|
|
87
|
+
export interface LogsResponse {
|
|
88
|
+
meta: {
|
|
89
|
+
/** 实际返回的日志数量 */
|
|
90
|
+
count: number;
|
|
91
|
+
/** 符合过滤条件的总日志数 */
|
|
92
|
+
totalMatched: number;
|
|
93
|
+
/** 应用的日志级别过滤 */
|
|
94
|
+
level: string;
|
|
95
|
+
/** 时间过滤器(秒) */
|
|
96
|
+
since?: number;
|
|
97
|
+
/** 应用的过滤模式 */
|
|
98
|
+
filter?: string;
|
|
99
|
+
};
|
|
100
|
+
/** 日志数据列表 */
|
|
101
|
+
logs: ConsoleLog[];
|
|
102
|
+
}
|
|
103
|
+
export interface ScreenshotResponse {
|
|
104
|
+
meta: {
|
|
105
|
+
/** 截图格式 */
|
|
106
|
+
format: 'png' | 'jpeg';
|
|
107
|
+
/** 截图宽度 */
|
|
108
|
+
width: number;
|
|
109
|
+
/** 截图高度 */
|
|
110
|
+
height: number;
|
|
111
|
+
/** 截图数据大小(字节) */
|
|
112
|
+
size: number;
|
|
113
|
+
/** 截图的页面 URL */
|
|
114
|
+
url: string;
|
|
115
|
+
/** 截图的页面标题 */
|
|
116
|
+
title: string;
|
|
117
|
+
};
|
|
118
|
+
/** Base64 编码的截图数据 */
|
|
119
|
+
data: string;
|
|
120
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* mearl-mcp-uninstall - 卸载清理脚本
|
|
4
|
+
*
|
|
5
|
+
* 使用方式:
|
|
6
|
+
* npx @mearl/mcp-server --uninstall
|
|
7
|
+
* 或 mearl-mcp-uninstall (如果全局安装)
|
|
8
|
+
*/
|
|
9
|
+
import { unlinkSync, existsSync, readFileSync, writeFileSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import { homedir, platform } from 'os';
|
|
12
|
+
import { execSync } from 'child_process';
|
|
13
|
+
import prompts from 'prompts';
|
|
14
|
+
import { HOST_NAME } from './constants.js';
|
|
15
|
+
import { MCP_CLIENTS } from './mcp-clients.js';
|
|
16
|
+
// 获取 Native Messaging Host 配置目录
|
|
17
|
+
function getNativeHostDir() {
|
|
18
|
+
const os = platform();
|
|
19
|
+
if (os === 'darwin') {
|
|
20
|
+
return join(homedir(), 'Library/Application Support/Google/Chrome/NativeMessagingHosts');
|
|
21
|
+
}
|
|
22
|
+
else if (os === 'linux') {
|
|
23
|
+
return join(homedir(), '.config/google-chrome/NativeMessagingHosts');
|
|
24
|
+
}
|
|
25
|
+
else if (os === 'win32') {
|
|
26
|
+
throw new Error('Windows 需要手动删除注册表项,请参考 README.md');
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
throw new Error(`不支持的平台: ${os}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// 检查是否全局安装
|
|
33
|
+
function isGloballyInstalled() {
|
|
34
|
+
try {
|
|
35
|
+
const cmd = platform() === 'win32' ? 'where' : 'which';
|
|
36
|
+
execSync(`${cmd} mearl-mcp-server`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// 清理 MCP 配置文件中的 mearl
|
|
44
|
+
function cleanMCPConfig(configPath, clientConfig) {
|
|
45
|
+
try {
|
|
46
|
+
if (!existsSync(configPath)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
50
|
+
const config = JSON.parse(content);
|
|
51
|
+
const useServersFormat = clientConfig.useServersFormat;
|
|
52
|
+
let hasConfig = false;
|
|
53
|
+
if (useServersFormat) {
|
|
54
|
+
// VS Code 格式:检查 servers
|
|
55
|
+
if (config.servers && config.servers['mearl']) {
|
|
56
|
+
delete config.servers['mearl'];
|
|
57
|
+
hasConfig = true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Claude Code/Cursor 格式:检查 mcpServers
|
|
62
|
+
if (config.mcpServers && config.mcpServers['mearl']) {
|
|
63
|
+
delete config.mcpServers['mearl'];
|
|
64
|
+
hasConfig = true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (!hasConfig) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
// 写回文件
|
|
71
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error(` ⚠️ 清理配置失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// 卸载主函数
|
|
80
|
+
async function uninstall() {
|
|
81
|
+
console.log('🗑️ Mearl MCP 卸载\n');
|
|
82
|
+
try {
|
|
83
|
+
// 1. 清理 Native Messaging Host 配置
|
|
84
|
+
console.log('清理 Native Messaging Host...');
|
|
85
|
+
const hostDir = getNativeHostDir();
|
|
86
|
+
const manifestPath = join(hostDir, `${HOST_NAME}.json`);
|
|
87
|
+
const wrapperPath = join(hostDir, `${HOST_NAME}-launcher.sh`);
|
|
88
|
+
let hasDeleted = false;
|
|
89
|
+
if (existsSync(manifestPath)) {
|
|
90
|
+
unlinkSync(manifestPath);
|
|
91
|
+
console.log(`✅ 删除配置文件`);
|
|
92
|
+
hasDeleted = true;
|
|
93
|
+
}
|
|
94
|
+
if (existsSync(wrapperPath)) {
|
|
95
|
+
unlinkSync(wrapperPath);
|
|
96
|
+
hasDeleted = true;
|
|
97
|
+
}
|
|
98
|
+
if (!hasDeleted) {
|
|
99
|
+
console.log('未找到配置文件');
|
|
100
|
+
}
|
|
101
|
+
// 2. 检查全局安装
|
|
102
|
+
console.log('\n检查 npm 全局安装...');
|
|
103
|
+
if (isGloballyInstalled()) {
|
|
104
|
+
console.log('⚠️ 请手动卸载: npm uninstall -g @mearl/mcp-server');
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
console.log('✅ 未检测到全局安装');
|
|
108
|
+
}
|
|
109
|
+
// 3. 清理 MCP 客户端配置
|
|
110
|
+
console.log('\n清理 MCP 客户端配置...');
|
|
111
|
+
// 检测哪些客户端有配置文件
|
|
112
|
+
const availableClients = Object.entries(MCP_CLIENTS)
|
|
113
|
+
.filter(([_, client]) => existsSync(client.configPath))
|
|
114
|
+
.map(([key, client]) => ({
|
|
115
|
+
title: client.name,
|
|
116
|
+
value: key,
|
|
117
|
+
}));
|
|
118
|
+
if (availableClients.length === 0) {
|
|
119
|
+
console.log('未找到 MCP 配置');
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const response = await prompts({
|
|
123
|
+
type: 'multiselect',
|
|
124
|
+
name: 'clients',
|
|
125
|
+
message: '选择要清理的客户端:',
|
|
126
|
+
choices: availableClients,
|
|
127
|
+
instructions: false,
|
|
128
|
+
hint: '空格选择,回车确认',
|
|
129
|
+
});
|
|
130
|
+
if (response.clients && response.clients.length > 0) {
|
|
131
|
+
for (const clientKey of response.clients) {
|
|
132
|
+
const client = MCP_CLIENTS[clientKey];
|
|
133
|
+
if (cleanMCPConfig(client.configPath, client)) {
|
|
134
|
+
console.log(`✅ 已清理 ${client.name}`);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
console.log(`未找到 ${client.name} 配置`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.log('已取消');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
console.log('\n✅ 卸载完成!');
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
console.error('\n❌ 卸载失败:', error instanceof Error ? error.message : String(error));
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
uninstall();
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mearl/mcp-server",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "MCP Server for Mearl - enables AI to interact with Chrome browser requests and logs",
|
|
5
|
+
"mcpName": "io.github.F-loat/mearl",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"@mearl/mcp-server": "./dist/index.js",
|
|
10
|
+
"mearl-mcp-server": "./dist/index.js",
|
|
11
|
+
"mearl-mcp-configure": "./dist/configure.js",
|
|
12
|
+
"mearl-mcp-uninstall": "./dist/uninstall.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mcp",
|
|
20
|
+
"chrome-extension",
|
|
21
|
+
"devtools",
|
|
22
|
+
"mearl",
|
|
23
|
+
"ai"
|
|
24
|
+
],
|
|
25
|
+
"author": "",
|
|
26
|
+
"license": "ISC",
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"registry": "https://registry.npmjs.org"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
32
|
+
"prompts": "^2.4.2",
|
|
33
|
+
"@mearl/client": "2.0.0",
|
|
34
|
+
"@mearl/native-host": "2.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^24.9.1",
|
|
38
|
+
"@types/prompts": "^2.4.9",
|
|
39
|
+
"typescript": "^5.8.3"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "rm -rf dist/ && tsc",
|
|
43
|
+
"dev": "tsc --watch",
|
|
44
|
+
"start": "node dist/index.js",
|
|
45
|
+
"setup": "pnpm build && npm link",
|
|
46
|
+
"typecheck": "tsc --noEmit"
|
|
47
|
+
}
|
|
48
|
+
}
|