Skip to content

Commit 6028cf2

Browse files
authored
Merge pull request modelcontextprotocol#373 from modelcontextprotocol/ochafik/pdf-server-screenshot-context
feat(pdf-server): send screenshot to updateModelContext
2 parents 782756c + d6705d9 commit 6028cf2

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

examples/pdf-server/src/mcp-app.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ import {
1313
applyHostStyleVariables,
1414
} from "@modelcontextprotocol/ext-apps";
1515
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
16+
import type { ContentBlock } from "@modelcontextprotocol/sdk/spec.types.js";
1617
import * as pdfjsLib from "pdfjs-dist";
1718
import { TextLayer } from "pdfjs-dist";
1819
import "./global.css";
1920
import "./mcp-app.css";
2021

2122
const MAX_MODEL_CONTEXT_LENGTH = 15000;
23+
const MAX_MODEL_CONTEXT_UPDATE_IMAGE_DIMENSION = 768; // Max screenshot dimension
2224
const CHUNK_SIZE = 500 * 1024; // 500KB chunks
2325

2426
// Configure PDF.js worker
@@ -298,7 +300,47 @@ async function updatePageContext() {
298300

299301
const contextText = `${header}\n\nPage content:\n${content}`;
300302

301-
app.updateModelContext({ content: [{ type: "text", text: contextText }] });
303+
// Build content array with text and optional screenshot
304+
const contentBlocks: ContentBlock[] = [{ type: "text", text: contextText }];
305+
306+
// Add screenshot if host supports image content
307+
if (app.getHostCapabilities()?.updateModelContext?.image) {
308+
try {
309+
// Scale down to reduce token usage (tokens depend on dimensions)
310+
const sourceCanvas = canvasEl;
311+
const scale = Math.min(
312+
1,
313+
MAX_MODEL_CONTEXT_UPDATE_IMAGE_DIMENSION /
314+
Math.max(sourceCanvas.width, sourceCanvas.height),
315+
);
316+
const targetWidth = Math.round(sourceCanvas.width * scale);
317+
const targetHeight = Math.round(sourceCanvas.height * scale);
318+
319+
const tempCanvas = document.createElement("canvas");
320+
tempCanvas.width = targetWidth;
321+
tempCanvas.height = targetHeight;
322+
const ctx = tempCanvas.getContext("2d");
323+
if (ctx) {
324+
ctx.drawImage(sourceCanvas, 0, 0, targetWidth, targetHeight);
325+
const dataUrl = tempCanvas.toDataURL("image/png");
326+
const base64Data = dataUrl.split(",")[1];
327+
if (base64Data) {
328+
contentBlocks.push({
329+
type: "image",
330+
data: base64Data,
331+
mimeType: "image/png",
332+
});
333+
log.info(
334+
`Added screenshot to model context (${targetWidth}x${targetHeight})`,
335+
);
336+
}
337+
}
338+
} catch (err) {
339+
log.info("Failed to capture screenshot:", err);
340+
}
341+
}
342+
343+
app.updateModelContext({ content: contentBlocks });
302344
} catch (err) {
303345
log.error("Error updating context:", err);
304346
}

0 commit comments

Comments
 (0)