@youdie006/prodex 0.39.3 → 0.39.4
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/dist/mcp-tools.js +24 -0
- package/dist/mcp.js +27 -3
- package/package.json +1 -1
package/dist/mcp-tools.js
CHANGED
|
@@ -199,3 +199,27 @@ function assertMcpFiles(files) {
|
|
|
199
199
|
assertMcpTextField(file.path, `files[${index}].path`, MAX_MCP_SHORT_TEXT_BYTES);
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* A running MCP server keeps the code it loaded at startup: Node reads a module
|
|
204
|
+
* once. So installing a newer prodex changes nothing for a server that is
|
|
205
|
+
* already up, and the fixes in it look like they did not work. Measured on one
|
|
206
|
+
* machine, three servers serving consults had been running since the middle of
|
|
207
|
+
* the previous month, two releases behind, with nothing saying so.
|
|
208
|
+
*/
|
|
209
|
+
export function staleServerWarning(input) {
|
|
210
|
+
const running = input.running?.trim();
|
|
211
|
+
const installed = input.installed?.trim();
|
|
212
|
+
if (!running || !installed || running === installed)
|
|
213
|
+
return undefined;
|
|
214
|
+
return (`server_outdated: this prodex MCP server is running ${running}, but ${installed} is installed on this machine. ` +
|
|
215
|
+
`A server keeps the code it loaded when it started, so anything fixed since ${running} is not in this one. ` +
|
|
216
|
+
`Restart it - restart the agent session that launched it - to pick up ${installed}.`);
|
|
217
|
+
}
|
|
218
|
+
/** Carries a server-version notice back on a tool result that has room for it. */
|
|
219
|
+
export function withServerVersionNotice(result, warning) {
|
|
220
|
+
if (!warning || typeof result !== "object" || result === null)
|
|
221
|
+
return result;
|
|
222
|
+
const existing = result.warnings;
|
|
223
|
+
const warnings = Array.isArray(existing) ? existing : [];
|
|
224
|
+
return { ...result, warnings: [warning, ...warnings] };
|
|
225
|
+
}
|
package/dist/mcp.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
2
3
|
import { createRequire } from "node:module";
|
|
3
4
|
import process from "node:process";
|
|
4
5
|
import { serializeMessage } from "@modelcontextprotocol/sdk/shared/stdio.js";
|
|
5
6
|
import { JSONRPCMessageSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
6
7
|
import { z } from "zod";
|
|
7
|
-
import { createMcpToolHandlers, MAX_MCP_BRIDGE_TEXT_BYTES, MAX_MCP_SHORT_TEXT_BYTES } from "./mcp-tools.js";
|
|
8
|
+
import { createMcpToolHandlers, MAX_MCP_BRIDGE_TEXT_BYTES, MAX_MCP_SHORT_TEXT_BYTES, staleServerWarning, withServerVersionNotice } from "./mcp-tools.js";
|
|
8
9
|
import { ReceiptKindSchema } from "./schema.js";
|
|
9
10
|
const McpBridgeTextSchema = z.string().max(MAX_MCP_BRIDGE_TEXT_BYTES);
|
|
10
11
|
const McpShortTextSchema = z.string().max(MAX_MCP_SHORT_TEXT_BYTES);
|
|
@@ -25,6 +26,29 @@ function asText(value) {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
const mcpPackageJson = createRequire(import.meta.url)("../package.json");
|
|
29
|
+
/**
|
|
30
|
+
* The version on disk right now, which is NOT what this process is running:
|
|
31
|
+
* `mcpPackageJson` was read once, when the server started. Comparing the two is
|
|
32
|
+
* how a server that has been up for weeks can say so. Read per browser call
|
|
33
|
+
* (those take seconds at least, so one small file read is nothing) and never
|
|
34
|
+
* allowed to break the call it decorates.
|
|
35
|
+
*/
|
|
36
|
+
function installedVersionOnDisk() {
|
|
37
|
+
try {
|
|
38
|
+
const path = createRequire(import.meta.url).resolve("../package.json");
|
|
39
|
+
return JSON.parse(readFileSync(path, "utf8")).version;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function serverVersionNotice() {
|
|
46
|
+
const installed = installedVersionOnDisk();
|
|
47
|
+
return staleServerWarning({
|
|
48
|
+
...(mcpPackageJson.version !== undefined ? { running: mcpPackageJson.version } : {}),
|
|
49
|
+
...(installed !== undefined ? { installed } : {})
|
|
50
|
+
});
|
|
51
|
+
}
|
|
28
52
|
export function createServer(cwd = process.cwd(), options = {}) {
|
|
29
53
|
const server = new McpServer({ name: "prodex", version: mcpPackageJson.version ?? "0.0.0" });
|
|
30
54
|
const handlers = createMcpToolHandlers({ cwd, source: options.source, claimedBy: options.claimedBy });
|
|
@@ -184,7 +208,7 @@ export function createServer(cwd = process.cwd(), options = {}) {
|
|
|
184
208
|
// Progress delivery must never break the consult.
|
|
185
209
|
});
|
|
186
210
|
};
|
|
187
|
-
return asText(await browserConsult(input, onProgress));
|
|
211
|
+
return asText(withServerVersionNotice(await browserConsult(input, onProgress), serverVersionNotice()));
|
|
188
212
|
});
|
|
189
213
|
}
|
|
190
214
|
const browserRecover = options.browserRecover;
|
|
@@ -195,7 +219,7 @@ export function createServer(cwd = process.cwd(), options = {}) {
|
|
|
195
219
|
thread: McpShortTextSchema.min(1).describe("The ChatGPT conversation URL from the blocker (its `thread` field)."),
|
|
196
220
|
timeout_ms: z.number().int().positive().max(600_000).optional()
|
|
197
221
|
}
|
|
198
|
-
}, async (input) => asText(await browserRecover(input)));
|
|
222
|
+
}, async (input) => asText(withServerVersionNotice(await browserRecover(input), serverVersionNotice())));
|
|
199
223
|
}
|
|
200
224
|
return server;
|
|
201
225
|
}
|