html2pptx-local-mcp 1.1.26 → 1.1.27
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.
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
2
1
|
export interface EditOptions {
|
|
3
2
|
port?: string;
|
|
4
3
|
baseUrl?: string;
|
|
@@ -18,7 +17,7 @@ declare function normalizeBaseUrl(raw: string): URL;
|
|
|
18
17
|
declare function readRegisteredEditorBaseUrl(root: string): Promise<string | null>;
|
|
19
18
|
declare function resolveEditorBaseUrl(root: string, explicitBaseUrl: string | undefined): Promise<URL>;
|
|
20
19
|
declare function buildEditorUrl(baseUrl: URL, rel: string, bridgeUrl: string, sessionToken: string): URL;
|
|
21
|
-
declare function createBridgeServer(ctx: BridgeContext):
|
|
20
|
+
declare function createBridgeServer(ctx: BridgeContext): any;
|
|
22
21
|
declare function listen(server: ReturnType<typeof createBridgeServer>, requestedPort: number): Promise<number>;
|
|
23
22
|
export declare function editCommand(input: string | undefined, options?: EditOptions): Promise<void>;
|
|
24
23
|
export declare const editCommandInternalsForTest: {
|
|
@@ -734,7 +734,56 @@ function buildServerInstructions(client = {}, { localOnly = false } = {}) {
|
|
|
734
734
|
return lines.join('\n');
|
|
735
735
|
}
|
|
736
736
|
|
|
737
|
-
|
|
737
|
+
/**
|
|
738
|
+
* Pull a sanitized `{ name, version }` snapshot out of the raw
|
|
739
|
+
* `params.clientInfo` that MCP clients send during `initialize`. Returns
|
|
740
|
+
* `null` if the payload is unusable so callers can treat "no info" uniformly.
|
|
741
|
+
*
|
|
742
|
+
* @param {unknown} raw
|
|
743
|
+
* @returns {{ name: string, version?: string } | null}
|
|
744
|
+
*/
|
|
745
|
+
export function extractClientInfo(raw) {
|
|
746
|
+
if (!raw || typeof raw !== 'object') return null;
|
|
747
|
+
const name = typeof raw.name === 'string' ? raw.name.trim() : '';
|
|
748
|
+
if (!name) return null;
|
|
749
|
+
const version = typeof raw.version === 'string' ? raw.version.trim() : '';
|
|
750
|
+
return version ? { name, version } : { name };
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Decide whether html2pptx_open_local_slide_editor should auto-open the OS
|
|
755
|
+
* default browser when the MCP caller did not explicitly set `openBrowser`.
|
|
756
|
+
*
|
|
757
|
+
* Strategy: conservative allowlist. Only known terminal-style CLI clients
|
|
758
|
+
* (Claude Code, Codex CLI, anything whose advertised clientInfo.name ends in
|
|
759
|
+
* `-cli`) get the auto-open default. Desktop/IDE clients (Claude Desktop,
|
|
760
|
+
* Cursor, Cline, unknown) keep the existing "return URL only, let the host
|
|
761
|
+
* render it inline" behavior — that's the right default for future MCP
|
|
762
|
+
* side-pane UI surfaces.
|
|
763
|
+
*
|
|
764
|
+
* @param {{ name?: string } | null | undefined} clientInfo
|
|
765
|
+
* @returns {boolean}
|
|
766
|
+
*/
|
|
767
|
+
export function inferOpenBrowserDefault(clientInfo) {
|
|
768
|
+
const rawName = String(clientInfo?.name ?? '').trim().toLowerCase();
|
|
769
|
+
if (!rawName) return false;
|
|
770
|
+
if (/^claude[\s\-_]?code/.test(rawName)) return true;
|
|
771
|
+
if (/^codex(?:[\s\-_]|$)/.test(rawName)) return true;
|
|
772
|
+
if (/[\-_]cli$/.test(rawName)) return true;
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Resolve the effective `openBrowser` flag for the local slide editor tool.
|
|
778
|
+
* Explicit boolean from args always wins; otherwise fall back to the
|
|
779
|
+
* clientInfo heuristic above.
|
|
780
|
+
*/
|
|
781
|
+
export function resolveOpenBrowserFlag(argsOpenBrowser, clientInfo) {
|
|
782
|
+
if (typeof argsOpenBrowser === 'boolean') return argsOpenBrowser;
|
|
783
|
+
return inferOpenBrowserDefault(clientInfo);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
export async function executeTool(name, args, client, { sendNotification, progressToken, clientInfo } = {}) {
|
|
738
787
|
switch (name) {
|
|
739
788
|
case 'html2pptx_list_export_plans': {
|
|
740
789
|
const data = await client.listExportPlans();
|
|
@@ -918,7 +967,7 @@ export async function executeTool(name, args, client, { sendNotification, progre
|
|
|
918
967
|
baseUrl: typeof args.baseUrl === 'string' ? args.baseUrl : undefined,
|
|
919
968
|
editorPort: Number.isFinite(args.editorPort) ? args.editorPort : undefined,
|
|
920
969
|
port: Number.isFinite(args.port) ? args.port : undefined,
|
|
921
|
-
openBrowser: args.openBrowser
|
|
970
|
+
openBrowser: resolveOpenBrowserFlag(args.openBrowser, clientInfo),
|
|
922
971
|
reuseExisting: args.reuseExisting !== false,
|
|
923
972
|
});
|
|
924
973
|
return buildToolResponse(renderLocalSlideEditorText(data), data);
|
|
@@ -936,7 +985,7 @@ export async function executeTool(name, args, client, { sendNotification, progre
|
|
|
936
985
|
}
|
|
937
986
|
}
|
|
938
987
|
|
|
939
|
-
export async function handleMcpMessage(message, { protocolVersion = DEFAULT_PROTOCOL, client, sendNotification, serverInfo = SERVER_INFO, localOnly = false }) {
|
|
988
|
+
export async function handleMcpMessage(message, { protocolVersion = DEFAULT_PROTOCOL, client, sendNotification, serverInfo = SERVER_INFO, localOnly = false, clientInfo = null }) {
|
|
940
989
|
if (!message || typeof message !== 'object') {
|
|
941
990
|
return { protocolVersion, response: null };
|
|
942
991
|
}
|
|
@@ -955,6 +1004,7 @@ export async function handleMcpMessage(message, { protocolVersion = DEFAULT_PROT
|
|
|
955
1004
|
const negotiatedProtocol = negotiateProtocol(params?.protocolVersion);
|
|
956
1005
|
return {
|
|
957
1006
|
protocolVersion: negotiatedProtocol,
|
|
1007
|
+
clientInfo: extractClientInfo(params?.clientInfo),
|
|
958
1008
|
response: {
|
|
959
1009
|
jsonrpc: '2.0',
|
|
960
1010
|
id,
|
|
@@ -1168,7 +1218,7 @@ export async function handleMcpMessage(message, { protocolVersion = DEFAULT_PROT
|
|
|
1168
1218
|
try {
|
|
1169
1219
|
const toolArgs = params?.arguments ?? {};
|
|
1170
1220
|
const progressToken = toolArgs._meta?.progressToken ?? params?._meta?.progressToken;
|
|
1171
|
-
const payload = await executeTool(params?.name, toolArgs, client, { sendNotification, progressToken });
|
|
1221
|
+
const payload = await executeTool(params?.name, toolArgs, client, { sendNotification, progressToken, clientInfo });
|
|
1172
1222
|
return {
|
|
1173
1223
|
protocolVersion,
|
|
1174
1224
|
response: {
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
let inputBuffer = Buffer.alloc(0);
|
|
15
15
|
let negotiatedProtocol = DEFAULT_PROTOCOL;
|
|
16
16
|
let wireMode = 'content-length';
|
|
17
|
+
let mcpClientInfo = null;
|
|
17
18
|
|
|
18
19
|
process.stdin.on('data', (chunk) => {
|
|
19
20
|
inputBuffer = Buffer.concat([inputBuffer, chunk]);
|
|
@@ -126,6 +127,7 @@ async function handleMessage(message) {
|
|
|
126
127
|
const handled = await handleMcpMessage(message, {
|
|
127
128
|
protocolVersion: negotiatedProtocol,
|
|
128
129
|
client,
|
|
130
|
+
clientInfo: mcpClientInfo,
|
|
129
131
|
serverInfo: {
|
|
130
132
|
...SERVER_INFO,
|
|
131
133
|
name: 'html2pptx-local',
|
|
@@ -136,6 +138,9 @@ async function handleMessage(message) {
|
|
|
136
138
|
},
|
|
137
139
|
});
|
|
138
140
|
negotiatedProtocol = handled.protocolVersion;
|
|
141
|
+
if (handled.clientInfo !== undefined) {
|
|
142
|
+
mcpClientInfo = handled.clientInfo;
|
|
143
|
+
}
|
|
139
144
|
|
|
140
145
|
if (handled.response) {
|
|
141
146
|
sendMessage(handled.response);
|