Merge pull request #212 from jonathanhefner/video-resource-server-safeareainsets
Support `safeAreaInsets` + type-checking in video-resource-server
This commit is contained in:
commit
dadbb6ac3d
3 changed files with 35 additions and 17 deletions
|
|
@ -16,7 +16,7 @@
|
|||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "cross-env INPUT=mcp-app.html vite build",
|
||||
"build": "tsc --noEmit && cross-env INPUT=mcp-app.html vite build",
|
||||
"watch": "cross-env INPUT=mcp-app.html vite build --watch",
|
||||
"serve": "bun server.ts",
|
||||
"start": "cross-env NODE_ENV=development npm run build && npm run serve",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* Demonstrates fetching binary content (video) via MCP resources.
|
||||
* The video is served as a base64 blob and converted to a data URI for playback.
|
||||
*/
|
||||
import { App } from "@modelcontextprotocol/ext-apps";
|
||||
import { App, type McpUiHostContext } from "@modelcontextprotocol/ext-apps";
|
||||
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
||||
import { ReadResourceResultSchema } from "@modelcontextprotocol/sdk/types.js";
|
||||
import "./global.css";
|
||||
|
|
@ -16,6 +16,7 @@ const log = {
|
|||
};
|
||||
|
||||
// Get element references
|
||||
const mainEl = document.querySelector(".main") as HTMLElement;
|
||||
const loadingEl = document.getElementById("loading")!;
|
||||
const loadingTextEl = document.getElementById("loading-text")!;
|
||||
const errorEl = document.getElementById("error")!;
|
||||
|
|
@ -83,16 +84,13 @@ app.ontoolresult = async (result) => {
|
|||
ReadResourceResultSchema,
|
||||
);
|
||||
|
||||
log.info(
|
||||
"Resource received, blob size:",
|
||||
resourceResult.contents[0]?.blob?.length,
|
||||
);
|
||||
|
||||
const content = resourceResult.contents[0];
|
||||
if (!content?.blob) {
|
||||
if (!content || !("blob" in content)) {
|
||||
throw new Error("Resource response did not contain blob data");
|
||||
}
|
||||
|
||||
log.info("Resource received, blob size:", content.blob.length);
|
||||
|
||||
showLoading("Converting to data URI...");
|
||||
|
||||
const mimeType = content.mimeType || "video/mp4";
|
||||
|
|
@ -112,5 +110,21 @@ app.onerror = (err) => {
|
|||
showError(err instanceof Error ? err.message : String(err));
|
||||
};
|
||||
|
||||
function handleHostContextChanged(ctx: McpUiHostContext) {
|
||||
if (ctx.safeAreaInsets) {
|
||||
mainEl.style.paddingTop = `${ctx.safeAreaInsets.top}px`;
|
||||
mainEl.style.paddingRight = `${ctx.safeAreaInsets.right}px`;
|
||||
mainEl.style.paddingBottom = `${ctx.safeAreaInsets.bottom}px`;
|
||||
mainEl.style.paddingLeft = `${ctx.safeAreaInsets.left}px`;
|
||||
}
|
||||
}
|
||||
|
||||
app.onhostcontextchanged = handleHostContextChanged;
|
||||
|
||||
// Connect to host
|
||||
app.connect();
|
||||
app.connect().then(() => {
|
||||
const ctx = app.getHostContext();
|
||||
if (ctx) {
|
||||
handleHostContextChanged(ctx);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"declaration": false,
|
||||
"outDir": "dist",
|
||||
"lib": ["ESNext", "DOM"]
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["server.ts", "src/**/*"]
|
||||
"include": ["src", "server.ts"]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue