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:
parent
6a2905d17d
commit
818bd71c9f
1 changed files with 134 additions and 1 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue