Add polling pattern to patterns guide

Documents the recommended approach for real-time dashboards that need to
poll server tools at regular intervals. Includes both Vanilla JS and
React examples with proper cleanup handling via `app.onteardown` and
`useEffect` cleanup functions respectively.

Also updates the "Tools that are private to Apps" section to mention
polling as a use case for app-only visibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jonathan Hefner 2026-01-28 12:41:28 -06:00
commit 818bd71c9f
No known key found for this signature in database
GPG key ID: 0DA40AFD21043691

View file

@ -22,6 +22,72 @@ import { registerAppTool } from "../src/server/index.js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
/**
* Example: Polling for live data (Vanilla JS)
*/
function pollingVanillaJs(app: App, updateUI: (data: unknown) => void) {
//#region pollingVanillaJs
let intervalId: number | null = null;
async function poll() {
const result = await app.callServerTool({
name: "poll-data",
arguments: {},
});
updateUI(result.structuredContent);
}
function startPolling() {
if (intervalId !== null) return;
poll();
intervalId = window.setInterval(poll, 2000);
}
function stopPolling() {
if (intervalId === null) return;
clearInterval(intervalId);
intervalId = null;
}
// Clean up when host tears down the view
app.onteardown = async () => {
stopPolling();
return {};
};
//#endregion pollingVanillaJs
}
/**
* Example: Polling for live data (React)
*/
function pollingReact(
app: App | null, // via useApp()
) {
const [data, setData] = useState<unknown>();
//#region pollingReact
useEffect(() => {
if (!app) return;
let cancelled = false;
async function poll() {
const result = await app!.callServerTool({
name: "poll-data",
arguments: {},
});
if (!cancelled) setData(result.structuredContent);
}
poll();
const id = setInterval(poll, 2000);
return () => {
cancelled = true;
clearInterval(id);
};
}, [app]);
//#endregion pollingReact
}
/**
* Example: Server-side chunked data tool (app-only)
*/
@ -336,6 +402,8 @@ function visibilityBasedPause(
}
// Suppress unused variable warnings
void pollingVanillaJs;
void pollingReact;
void chunkedDataServer;
void chunkedDataClient;
void hostContextVanillaJs;