@dahawa/hawa-cli-analysis 1.0.7 → 1.0.8
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/.tools.json +6 -6
- package/.vscode/launch.json +26 -26
- package/_uclaude.js +0 -0
- package/anthropic-transformer.js +986 -986
- package/api-anthropic.js +279 -279
- package/api-openai.js +538 -538
- package/clogger-openai.js +190 -190
- package/clogger.js +318 -318
- package/codex/mcp-client.js +556 -556
- package/codex/mcpclient.js +117 -117
- package/codex/mcpserver.js +374 -374
- package/codex/mcpserverproxy.js +143 -143
- package/codex/test.js +30 -30
- package/mcp/claude-mcpproxy-launcher.js +4 -4
- package/package.json +2 -1
- package/simple-transform-example.js +212 -212
- package/tests/test-lazy-load.js +35 -35
- package/tests/test_mcp_proxy.js +50 -50
- package/tests/test_supabase_mcp.js +41 -41
- package/uclaude.js +3 -3
- package/ucodex-proxy.js +172 -172
- package/ucodex.js +127 -127
package/codex/mcpserverproxy.js
CHANGED
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
import JsonRpcClient from "./mcpclient.js"
|
|
2
|
-
import { pathToFileURL } from "url";
|
|
3
|
-
import readline from 'node:readline';
|
|
4
|
-
import {getOptions} from "../untils.js"
|
|
5
|
-
import LogManager from "../logger-manager.js";
|
|
6
|
-
const logger = LogManager.getSystemLogger();
|
|
7
|
-
|
|
8
|
-
// ---- 2) JSON-RPC 帮助函数 ----
|
|
9
|
-
function send(resultOrError, id) {
|
|
10
|
-
const msg = { jsonrpc: '2.0', ...(resultOrError.error ? { error: resultOrError.error } : { result: resultOrError.result }), id };
|
|
11
|
-
process.stdout.write(JSON.stringify(msg) + '\n');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function error(code, message, data) {
|
|
15
|
-
return { error: { code, message, ...(data !== undefined ? { data } : {}) } };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function ok(result) {
|
|
19
|
-
return { result };
|
|
20
|
-
}
|
|
21
|
-
let mcpServerName = getOptions().mcpServerName;
|
|
22
|
-
if(!mcpServerName){
|
|
23
|
-
logger.error("MCP server name is required --mcpServerName=supabase");
|
|
24
|
-
process.exit(1);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
logger.debug("执行代理 MCPServer " + mcpServerName);
|
|
28
|
-
|
|
29
|
-
// 这里执行异步连接 mcpServer,不需要启动的时候全部连接
|
|
30
|
-
let mcpclient = new JsonRpcClient();
|
|
31
|
-
|
|
32
|
-
logger.debug("执行代理 MCPServer , 创建客户端成功 " );
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// ---- 3) 处理 JSON-RPC 请求 ----
|
|
36
|
-
async function handleRequest({ id, method, params }) {
|
|
37
|
-
logger.debug(` handleRequest ${mcpServerName} ` + JSON.stringify({id,method,params}));
|
|
38
|
-
try {
|
|
39
|
-
// a) 初始化握手(极简实现)
|
|
40
|
-
if (method === 'initialize') {
|
|
41
|
-
/**
|
|
42
|
-
return send(
|
|
43
|
-
ok({
|
|
44
|
-
protocolVersion: '2025-03-26', // 示例:协议版本字符串
|
|
45
|
-
capabilities: { tools: {} }, // 表示支持工具子协议
|
|
46
|
-
serverInfo: { name: 'Supabase', version: '0.0.1' },
|
|
47
|
-
}),
|
|
48
|
-
id,
|
|
49
|
-
);
|
|
50
|
-
*/
|
|
51
|
-
let res = await mcpclient.call(`${mcpServerName}_initialize`);
|
|
52
|
-
logger.debug(" mcpclient result: " + JSON.stringify(res));
|
|
53
|
-
return send(ok(res), id);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// b) 列出工具
|
|
57
|
-
if (method === 'tools/list') {
|
|
58
|
-
let tools = await mcpclient.call(`${mcpServerName}_list`);
|
|
59
|
-
return send(ok(tools), id);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// c) 调用工具
|
|
63
|
-
if (method === 'tools/call') {
|
|
64
|
-
let result = await mcpclient.call(`${mcpServerName}_call`, params);
|
|
65
|
-
return send(ok(result ?? { content: [] }), id);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// d) 可选心跳
|
|
69
|
-
if (method === 'ping') return send(ok({}), id);
|
|
70
|
-
|
|
71
|
-
// e) 未实现的方法
|
|
72
|
-
return send(error(-32601, `Method not found: ${method}`), id);
|
|
73
|
-
} catch (e) {
|
|
74
|
-
logger.error(` handleRequest ${mcpServerName} error ` + e?.message + " " + e + "\nStack trace: " + e.stack);
|
|
75
|
-
return send(error(-32603, 'Internal error ' + e?.message , { message: String(e?.message || e) }), id);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// ---- 4) 读 STDIN(每行一个 JSON-RPC 消息) ----
|
|
80
|
-
const rl = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
81
|
-
|
|
82
|
-
rl.on('line', async (line) => {
|
|
83
|
-
if (!line.trim()) return;
|
|
84
|
-
let msg;
|
|
85
|
-
try {
|
|
86
|
-
msg = JSON.parse(line);
|
|
87
|
-
} catch {
|
|
88
|
-
// 非法 JSON:按 JSON-RPC 返回解析错误
|
|
89
|
-
return send(error(-32700, 'Parse error'), null);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// 只处理 Request;Notification 没有 id
|
|
93
|
-
if (msg?.jsonrpc !== '2.0' || typeof msg?.method !== 'string') {
|
|
94
|
-
return send(error(-32600, 'Invalid Request'), msg?.id ?? null);
|
|
95
|
-
}
|
|
96
|
-
// 异步处理
|
|
97
|
-
handleRequest(msg);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// 可选:把错误打印到 stderr(不影响 JSON-RPC 数据流)
|
|
101
|
-
process.on('uncaughtException', (e) => console.error('uncaught:', e));
|
|
102
|
-
process.on('unhandledRejection', (e) => console.error('unhandled:', e));
|
|
103
|
-
|
|
104
|
-
//console.log(`mcpclient.call('${mcpServerName}_list')`);
|
|
105
|
-
//let tools = await mcpclient.call(`${mcpServerName}_list`);
|
|
106
|
-
//console.log(JSON.stringify(tools, null, 2));
|
|
107
|
-
async function main(){
|
|
108
|
-
logger.debug(`mcpclient.call('${mcpServerName}_initialize')`);
|
|
109
|
-
try {
|
|
110
|
-
let initialize = await mcpclient.call(`${mcpServerName}_initialize`);
|
|
111
|
-
logger.debug(JSON.stringify(initialize, null, 2));
|
|
112
|
-
} catch (error) {
|
|
113
|
-
logger.error("Error initializing MCP client:", error);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* 判断当前模块是否是主运行模块:
|
|
119
|
-
* ✅ node xxx.js 直接执行 → true
|
|
120
|
-
* 🚫 import 时 → false
|
|
121
|
-
* 🚫 子进程 (spawn/fork) 启动时 → false
|
|
122
|
-
*/
|
|
123
|
-
export function isMainModule() {
|
|
124
|
-
// 当前模块文件 URL
|
|
125
|
-
const currentFile = pathToFileURL(process.argv[1]).href;
|
|
126
|
-
|
|
127
|
-
// 是否为直接运行
|
|
128
|
-
const isDirectRun = import.meta.url === currentFile;
|
|
129
|
-
|
|
130
|
-
// 是否为子进程
|
|
131
|
-
const isChildProcess =
|
|
132
|
-
process.send !== undefined ||
|
|
133
|
-
process.env.__IS_SUBPROCESS__ === "1" ||
|
|
134
|
-
(process.ppid !== 1 && process.ppid !== process.pid);
|
|
135
|
-
logger.debug("isChildProcess:", isDirectRun && !isChildProcess);
|
|
136
|
-
return isDirectRun && !isChildProcess;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
//if(isMainModule()){
|
|
140
|
-
// main();
|
|
141
|
-
//}
|
|
142
|
-
|
|
143
|
-
logger.debug("Environment Variables: " + JSON.stringify(process.env, null, 2));
|
|
1
|
+
import JsonRpcClient from "./mcpclient.js"
|
|
2
|
+
import { pathToFileURL } from "url";
|
|
3
|
+
import readline from 'node:readline';
|
|
4
|
+
import {getOptions} from "../untils.js"
|
|
5
|
+
import LogManager from "../logger-manager.js";
|
|
6
|
+
const logger = LogManager.getSystemLogger();
|
|
7
|
+
|
|
8
|
+
// ---- 2) JSON-RPC 帮助函数 ----
|
|
9
|
+
function send(resultOrError, id) {
|
|
10
|
+
const msg = { jsonrpc: '2.0', ...(resultOrError.error ? { error: resultOrError.error } : { result: resultOrError.result }), id };
|
|
11
|
+
process.stdout.write(JSON.stringify(msg) + '\n');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function error(code, message, data) {
|
|
15
|
+
return { error: { code, message, ...(data !== undefined ? { data } : {}) } };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function ok(result) {
|
|
19
|
+
return { result };
|
|
20
|
+
}
|
|
21
|
+
let mcpServerName = getOptions().mcpServerName;
|
|
22
|
+
if(!mcpServerName){
|
|
23
|
+
logger.error("MCP server name is required --mcpServerName=supabase");
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
logger.debug("执行代理 MCPServer " + mcpServerName);
|
|
28
|
+
|
|
29
|
+
// 这里执行异步连接 mcpServer,不需要启动的时候全部连接
|
|
30
|
+
let mcpclient = new JsonRpcClient();
|
|
31
|
+
|
|
32
|
+
logger.debug("执行代理 MCPServer , 创建客户端成功 " );
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// ---- 3) 处理 JSON-RPC 请求 ----
|
|
36
|
+
async function handleRequest({ id, method, params }) {
|
|
37
|
+
logger.debug(` handleRequest ${mcpServerName} ` + JSON.stringify({id,method,params}));
|
|
38
|
+
try {
|
|
39
|
+
// a) 初始化握手(极简实现)
|
|
40
|
+
if (method === 'initialize') {
|
|
41
|
+
/**
|
|
42
|
+
return send(
|
|
43
|
+
ok({
|
|
44
|
+
protocolVersion: '2025-03-26', // 示例:协议版本字符串
|
|
45
|
+
capabilities: { tools: {} }, // 表示支持工具子协议
|
|
46
|
+
serverInfo: { name: 'Supabase', version: '0.0.1' },
|
|
47
|
+
}),
|
|
48
|
+
id,
|
|
49
|
+
);
|
|
50
|
+
*/
|
|
51
|
+
let res = await mcpclient.call(`${mcpServerName}_initialize`);
|
|
52
|
+
logger.debug(" mcpclient result: " + JSON.stringify(res));
|
|
53
|
+
return send(ok(res), id);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// b) 列出工具
|
|
57
|
+
if (method === 'tools/list') {
|
|
58
|
+
let tools = await mcpclient.call(`${mcpServerName}_list`);
|
|
59
|
+
return send(ok(tools), id);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// c) 调用工具
|
|
63
|
+
if (method === 'tools/call') {
|
|
64
|
+
let result = await mcpclient.call(`${mcpServerName}_call`, params);
|
|
65
|
+
return send(ok(result ?? { content: [] }), id);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// d) 可选心跳
|
|
69
|
+
if (method === 'ping') return send(ok({}), id);
|
|
70
|
+
|
|
71
|
+
// e) 未实现的方法
|
|
72
|
+
return send(error(-32601, `Method not found: ${method}`), id);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
logger.error(` handleRequest ${mcpServerName} error ` + e?.message + " " + e + "\nStack trace: " + e.stack);
|
|
75
|
+
return send(error(-32603, 'Internal error ' + e?.message , { message: String(e?.message || e) }), id);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ---- 4) 读 STDIN(每行一个 JSON-RPC 消息) ----
|
|
80
|
+
const rl = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
81
|
+
|
|
82
|
+
rl.on('line', async (line) => {
|
|
83
|
+
if (!line.trim()) return;
|
|
84
|
+
let msg;
|
|
85
|
+
try {
|
|
86
|
+
msg = JSON.parse(line);
|
|
87
|
+
} catch {
|
|
88
|
+
// 非法 JSON:按 JSON-RPC 返回解析错误
|
|
89
|
+
return send(error(-32700, 'Parse error'), null);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 只处理 Request;Notification 没有 id
|
|
93
|
+
if (msg?.jsonrpc !== '2.0' || typeof msg?.method !== 'string') {
|
|
94
|
+
return send(error(-32600, 'Invalid Request'), msg?.id ?? null);
|
|
95
|
+
}
|
|
96
|
+
// 异步处理
|
|
97
|
+
handleRequest(msg);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// 可选:把错误打印到 stderr(不影响 JSON-RPC 数据流)
|
|
101
|
+
process.on('uncaughtException', (e) => console.error('uncaught:', e));
|
|
102
|
+
process.on('unhandledRejection', (e) => console.error('unhandled:', e));
|
|
103
|
+
|
|
104
|
+
//console.log(`mcpclient.call('${mcpServerName}_list')`);
|
|
105
|
+
//let tools = await mcpclient.call(`${mcpServerName}_list`);
|
|
106
|
+
//console.log(JSON.stringify(tools, null, 2));
|
|
107
|
+
async function main(){
|
|
108
|
+
logger.debug(`mcpclient.call('${mcpServerName}_initialize')`);
|
|
109
|
+
try {
|
|
110
|
+
let initialize = await mcpclient.call(`${mcpServerName}_initialize`);
|
|
111
|
+
logger.debug(JSON.stringify(initialize, null, 2));
|
|
112
|
+
} catch (error) {
|
|
113
|
+
logger.error("Error initializing MCP client:", error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 判断当前模块是否是主运行模块:
|
|
119
|
+
* ✅ node xxx.js 直接执行 → true
|
|
120
|
+
* 🚫 import 时 → false
|
|
121
|
+
* 🚫 子进程 (spawn/fork) 启动时 → false
|
|
122
|
+
*/
|
|
123
|
+
export function isMainModule() {
|
|
124
|
+
// 当前模块文件 URL
|
|
125
|
+
const currentFile = pathToFileURL(process.argv[1]).href;
|
|
126
|
+
|
|
127
|
+
// 是否为直接运行
|
|
128
|
+
const isDirectRun = import.meta.url === currentFile;
|
|
129
|
+
|
|
130
|
+
// 是否为子进程
|
|
131
|
+
const isChildProcess =
|
|
132
|
+
process.send !== undefined ||
|
|
133
|
+
process.env.__IS_SUBPROCESS__ === "1" ||
|
|
134
|
+
(process.ppid !== 1 && process.ppid !== process.pid);
|
|
135
|
+
logger.debug("isChildProcess:", isDirectRun && !isChildProcess);
|
|
136
|
+
return isDirectRun && !isChildProcess;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//if(isMainModule()){
|
|
140
|
+
// main();
|
|
141
|
+
//}
|
|
142
|
+
|
|
143
|
+
logger.debug("Environment Variables: " + JSON.stringify(process.env, null, 2));
|
|
144
144
|
logger.debug("Process Arguments: " + JSON.stringify(process.argv, null, 2));
|
package/codex/test.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { Client, StreamableHTTPClientTransport } from './mcp-client.js';
|
|
2
|
-
import LogManager from '../logger-manager.js';
|
|
3
|
-
|
|
4
|
-
const logger = LogManager.getSystemLogger();
|
|
5
|
-
|
|
6
|
-
const issuer = 'https://radar.mcp.cloudflare.com';
|
|
7
|
-
const client = new Client({ name: 'radar-demo', version: '1.0.0' });
|
|
8
|
-
const transport = new StreamableHTTPClientTransport(`${issuer}/mcp`, {
|
|
9
|
-
|
|
10
|
-
oauth: {
|
|
11
|
-
issuer,
|
|
12
|
-
// 显式覆盖端点(根据你调试日志里看到的为准)
|
|
13
|
-
//authorizationUrl: `${issuer}/oauth/authorize`,
|
|
14
|
-
//tokenUrl: `${issuer}/oauth/token`,
|
|
15
|
-
//registrationUrl: `${issuer}/oauth/register`,
|
|
16
|
-
|
|
17
|
-
// 先尝试动态注册;如报“no registration_endpoint”,请改为手动 clientId
|
|
18
|
-
// clientId: '从门户或运维处获得',
|
|
19
|
-
scopes: ['openid','profile','email','offline_access'],
|
|
20
|
-
redirectUri: 'http://127.0.0.1:53175/callback',
|
|
21
|
-
tokenStorePath: '.mcp_oauth_tokens.json',
|
|
22
|
-
clientName: 'demo-radar-auto-reg',
|
|
23
|
-
debug: true
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
await client.connect(transport); // 需要登录时会自动拉起浏览器
|
|
30
|
-
logger.debug('Radar tools:', await client.listTools());
|
|
1
|
+
import { Client, StreamableHTTPClientTransport } from './mcp-client.js';
|
|
2
|
+
import LogManager from '../logger-manager.js';
|
|
3
|
+
|
|
4
|
+
const logger = LogManager.getSystemLogger();
|
|
5
|
+
|
|
6
|
+
const issuer = 'https://radar.mcp.cloudflare.com';
|
|
7
|
+
const client = new Client({ name: 'radar-demo', version: '1.0.0' });
|
|
8
|
+
const transport = new StreamableHTTPClientTransport(`${issuer}/mcp`, {
|
|
9
|
+
|
|
10
|
+
oauth: {
|
|
11
|
+
issuer,
|
|
12
|
+
// 显式覆盖端点(根据你调试日志里看到的为准)
|
|
13
|
+
//authorizationUrl: `${issuer}/oauth/authorize`,
|
|
14
|
+
//tokenUrl: `${issuer}/oauth/token`,
|
|
15
|
+
//registrationUrl: `${issuer}/oauth/register`,
|
|
16
|
+
|
|
17
|
+
// 先尝试动态注册;如报“no registration_endpoint”,请改为手动 clientId
|
|
18
|
+
// clientId: '从门户或运维处获得',
|
|
19
|
+
scopes: ['openid','profile','email','offline_access'],
|
|
20
|
+
redirectUri: 'http://127.0.0.1:53175/callback',
|
|
21
|
+
tokenStorePath: '.mcp_oauth_tokens.json',
|
|
22
|
+
clientName: 'demo-radar-auto-reg',
|
|
23
|
+
debug: true
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
await client.connect(transport); // 需要登录时会自动拉起浏览器
|
|
30
|
+
logger.debug('Radar tools:', await client.listTools());
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {startMCPServerProxy} from "../codex/mcpserver.js"
|
|
2
|
-
|
|
3
|
-
startMCPServerProxy();
|
|
4
|
-
|
|
1
|
+
import {startMCPServerProxy} from "../codex/mcpserver.js"
|
|
2
|
+
|
|
3
|
+
startMCPServerProxy();
|
|
4
|
+
|
|
5
5
|
process.stdout.write("ok_ok\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dahawa/hawa-cli-analysis",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"main": "index",
|
|
5
5
|
"bin": {
|
|
6
6
|
"uclaude": "uclaude.js",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
11
|
+
"start": "node uclaude.js",
|
|
11
12
|
"publish": "npm publish --access public"
|
|
12
13
|
},
|
|
13
14
|
"type": "module",
|