@holin-work/holin-cli 1.3.8 → 1.3.9
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/bin/holin-cli.js +32 -13
- package/package.json +1 -1
package/bin/holin-cli.js
CHANGED
|
@@ -268,10 +268,26 @@ function createProxyServer() {
|
|
|
268
268
|
return;
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
-
// Build upstream request
|
|
272
|
-
//
|
|
273
|
-
//
|
|
274
|
-
const
|
|
271
|
+
// Build upstream request based on path
|
|
272
|
+
// /mcp → https://api.holin.work/icbu/mcp (MCP protocol)
|
|
273
|
+
// /api/* → https://api.holin.work/api/* (platform API, e.g. file upload)
|
|
274
|
+
const upstreamBase = "https://api.holin.work";
|
|
275
|
+
let upstreamPath;
|
|
276
|
+
let isMcpRequest = false;
|
|
277
|
+
if (req.url.startsWith("/mcp")) {
|
|
278
|
+
upstreamPath = "/icbu/mcp";
|
|
279
|
+
isMcpRequest = true;
|
|
280
|
+
} else if (req.url.startsWith("/api/")) {
|
|
281
|
+
upstreamPath = req.url;
|
|
282
|
+
} else {
|
|
283
|
+
// Unknown path
|
|
284
|
+
const body = JSON.stringify({ error: "not_found", message: `Unknown path: ${req.url}` });
|
|
285
|
+
res.writeHead(404, { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) });
|
|
286
|
+
res.end(body);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const upstreamUrl = new URL(upstreamBase);
|
|
275
291
|
const bodyBuffer = Buffer.concat(chunks);
|
|
276
292
|
const forwardHeaders = { ...req.headers };
|
|
277
293
|
delete forwardHeaders["transfer-encoding"];
|
|
@@ -282,25 +298,28 @@ function createProxyServer() {
|
|
|
282
298
|
const options = {
|
|
283
299
|
hostname: upstreamUrl.hostname,
|
|
284
300
|
port: upstreamUrl.port || 443,
|
|
285
|
-
path:
|
|
301
|
+
path: upstreamPath,
|
|
286
302
|
method: req.method,
|
|
287
303
|
headers: forwardHeaders,
|
|
288
304
|
};
|
|
289
305
|
|
|
290
|
-
// Parse request body to determine MCP method
|
|
306
|
+
// Parse request body to determine MCP method (only for MCP requests)
|
|
291
307
|
let mcpMethod = "";
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
308
|
+
if (isMcpRequest) {
|
|
309
|
+
try {
|
|
310
|
+
const parsed = JSON.parse(rawBody);
|
|
311
|
+
mcpMethod = parsed.method || "";
|
|
312
|
+
} catch { /* not JSON */ }
|
|
313
|
+
}
|
|
296
314
|
|
|
297
|
-
// Non-streaming methods should return JSON, not SSE
|
|
315
|
+
// Non-streaming methods should return JSON, not SSE (only for MCP requests)
|
|
298
316
|
// Accio expects JSON for initialize and tools/list
|
|
299
|
-
const shouldConvertToJson = mcpMethod === "initialize" || mcpMethod === "tools/list";
|
|
317
|
+
const shouldConvertToJson = isMcpRequest && (mcpMethod === "initialize" || mcpMethod === "tools/list");
|
|
300
318
|
|
|
301
319
|
const proxyReq = https.request(options, (proxyRes) => {
|
|
302
320
|
const elapsed = Date.now() - requestStart;
|
|
303
|
-
|
|
321
|
+
const routeLabel = isMcpRequest ? `mcp/${mcpMethod || "unknown"}` : req.url;
|
|
322
|
+
log(`[proxy] ← ${proxyRes.statusCode} ${elapsed}ms content-type=${proxyRes.headers["content-type"]} route=${routeLabel}`);
|
|
304
323
|
|
|
305
324
|
if (shouldConvertToJson && proxyRes.headers["content-type"]?.includes("text/event-stream")) {
|
|
306
325
|
// Collect SSE response and convert to JSON
|