Improve consistency and organization of examples for AI learning

- Add `.gitignore` files to all 19 examples (`node_modules/`, `dist/`)
- Replace custom `log` objects with standard `console` methods
- Add `ontoolcancelled` handler to all `basic-server-*` examples
- Add host styling integration (`applyDocumentTheme`, `applyHostFonts`,
  `applyHostStyleVariables`) to non-React `basic-server-*` examples
- Add section headers for better code organization in feature examples
- Update READMEs with Build System section explaining single-file
  bundling

These changes make examples more consistent and easier to adapt.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jonathan Hefner 2026-01-12 17:06:44 -06:00
commit 4140565b77

View file

@ -13,6 +13,10 @@ import ForceGraph, { type LinkObject, type NodeObject } from "force-graph";
import "./global.css";
import "./mcp-app.css";
// =============================================================================
// Helpers & Types
// =============================================================================
// Helper to resolve CSS variables for canvas rendering
function getCSSColor(varName: string): string {
return (
@ -49,7 +53,9 @@ type ToolResponse = {
error: string | null;
};
// Graph state
// =============================================================================
// Graph State & DOM References
// =============================================================================
const graphData: GraphData = { nodes: [], links: [] };
let selectedNodeUrl: string | null = null;
let initialUrl: string | null = null;
@ -65,7 +71,9 @@ const zoomInBtn = document.getElementById("zoom-in")!;
const zoomOutBtn = document.getElementById("zoom-out")!;
const resetBtn = document.getElementById("reset-graph")!;
// Initialize force-graph
// =============================================================================
// Force-Graph Initialization
// =============================================================================
const graph = new ForceGraph<NodeData, LinkData>(container)
.nodeId("url")
.nodeLabel("title")
@ -111,7 +119,9 @@ function handleResize() {
window.addEventListener("resize", handleResize);
handleResize();
// Node management functions
// =============================================================================
// Graph Data Management
// =============================================================================
function addNode(
url: string,
title: string,
@ -170,7 +180,9 @@ function updateGraph(): void {
graph.graphData({ nodes: [...graphData.nodes], links: [...graphData.links] });
}
// Popup management
// =============================================================================
// Popup Management
// =============================================================================
function showPopup(node: NodeData, x: number, y: number): void {
popupTitle.textContent = node.title;
@ -215,7 +227,9 @@ function hidePopup(): void {
selectedNodeUrl = null;
}
// Event handlers
// =============================================================================
// UI Event Handlers
// =============================================================================
function handleNodeClick(node: NodeData, event: MouseEvent): void {
// Toggle popup if clicking same node
if (selectedNodeUrl === node.url) {
@ -245,7 +259,9 @@ zoomOutBtn.addEventListener("click", () => {
graph.zoom(currentZoom / ZOOM_FACTOR, 200);
});
// Initialize App SDK
// =============================================================================
// MCP Apps SDK Integration
// =============================================================================
const app = new App({ name: "Wiki Explorer", version: "1.0.0" });
// Reset button - clears graph and reloads from initial URL