threenative-engine-mcp 0.2.2 → 0.2.3
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 +13 -0
- package/dist/index.js +33 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,3 +30,16 @@ The first that exists wins, so the manifest can never drift from the engine the
|
|
|
30
30
|
|
|
31
31
|
A project copy committed at scaffold time is therefore inert whenever the package is installed:
|
|
32
32
|
the two never need re-syncing by hand.
|
|
33
|
+
|
|
34
|
+
## The call log
|
|
35
|
+
|
|
36
|
+
Every tool call appends one JSON line to `.threenative/engine-mcp.log` in the launch directory, so
|
|
37
|
+
a finished session's searches can be read back:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{"time":"2026-09-14T20:20:00.000Z","results":["MultiMesh3D"],"scope":"mechanic","situation":"spawn many identical props","tool":"engine_search_capabilities","verdict":"matched"}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
A rejected call is logged with its `error`, which is where an agent asked for something the engine
|
|
44
|
+
could not answer. `THREENATIVE_ENGINE_MCP_LOG` names another file, or `off` to disable the log. A
|
|
45
|
+
log that cannot be written reports once on stderr and never fails a tool call.
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { realpathSync, readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { realpathSync, readFileSync, existsSync, mkdirSync, appendFileSync } from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { createInterface } from 'readline';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
@@ -417,6 +417,22 @@ var TOOL_DEFINITIONS = [
|
|
|
417
417
|
function toolDefinitions() {
|
|
418
418
|
return TOOL_DEFINITIONS;
|
|
419
419
|
}
|
|
420
|
+
var DEFAULT_LOG_FILE = path.join(".threenative", "engine-mcp.log");
|
|
421
|
+
var logBroken = false;
|
|
422
|
+
function logToolCall(entry) {
|
|
423
|
+
if (logBroken) return;
|
|
424
|
+
const target = process.env.THREENATIVE_ENGINE_MCP_LOG ?? DEFAULT_LOG_FILE;
|
|
425
|
+
if (target === "off") return;
|
|
426
|
+
try {
|
|
427
|
+
mkdirSync(path.dirname(path.resolve(target)), { recursive: true });
|
|
428
|
+
appendFileSync(target, `${JSON.stringify({ time: (/* @__PURE__ */ new Date()).toISOString(), ...entry })}
|
|
429
|
+
`);
|
|
430
|
+
} catch (error) {
|
|
431
|
+
logBroken = true;
|
|
432
|
+
process.stderr.write(`engine-mcp log disabled (${target}): ${String(error)}
|
|
433
|
+
`);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
420
436
|
function jsonRpcError(id, code, message) {
|
|
421
437
|
return JSON.stringify({ id, jsonrpc: "2.0", error: { code, message } });
|
|
422
438
|
}
|
|
@@ -439,12 +455,22 @@ function handleToolCall(params, manifestFile) {
|
|
|
439
455
|
const scope = argumentsValue.scope ?? "mechanic";
|
|
440
456
|
if (scope !== "request" && scope !== "mechanic")
|
|
441
457
|
throw new Error("engine_search_capabilities scope must be 'request' or 'mechanic'.");
|
|
442
|
-
|
|
458
|
+
const response = searchCapabilities(argumentsValue.situation, manifestFile, scope);
|
|
459
|
+
logToolCall({
|
|
460
|
+
results: response.results.map((result) => result.symbol),
|
|
461
|
+
scope,
|
|
462
|
+
situation: argumentsValue.situation,
|
|
463
|
+
tool: name,
|
|
464
|
+
verdict: response.verdict
|
|
465
|
+
});
|
|
466
|
+
return toolText(response);
|
|
443
467
|
}
|
|
444
468
|
if (name === "engine_capability_detail") {
|
|
445
469
|
if (typeof argumentsValue.symbol !== "string")
|
|
446
470
|
throw new Error("engine_capability_detail requires a string 'symbol' argument.");
|
|
447
|
-
|
|
471
|
+
const detail = capabilityDetail(argumentsValue.symbol, manifestFile);
|
|
472
|
+
logToolCall({ symbol: argumentsValue.symbol, tool: name });
|
|
473
|
+
return toolText(detail);
|
|
448
474
|
}
|
|
449
475
|
throw new Error(`Unknown engine MCP tool '${String(name)}'.`);
|
|
450
476
|
}
|
|
@@ -464,7 +490,7 @@ function handleLine(line, manifestFile) {
|
|
|
464
490
|
capabilities: { tools: { listChanged: false } },
|
|
465
491
|
instructions: AUTHORING_INSTRUCTIONS,
|
|
466
492
|
protocolVersion: "2025-06-18",
|
|
467
|
-
serverInfo: { name: "threenative-engine-mcp", version: "0.2.
|
|
493
|
+
serverInfo: { name: "threenative-engine-mcp", version: "0.2.3" }
|
|
468
494
|
});
|
|
469
495
|
}
|
|
470
496
|
if (request.method === "tools/list") {
|
|
@@ -476,7 +502,9 @@ function handleLine(line, manifestFile) {
|
|
|
476
502
|
}
|
|
477
503
|
return jsonRpcError(request.id, -32601, `Method not found: ${request.method}`);
|
|
478
504
|
} catch (error) {
|
|
479
|
-
|
|
505
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
506
|
+
if (request.method === "tools/call") logToolCall({ error: message, request: request.params });
|
|
507
|
+
return jsonRpcError(request.id, -32e3, message);
|
|
480
508
|
}
|
|
481
509
|
}
|
|
482
510
|
function runServer(manifestFile = defaultManifestPath()) {
|