diff --git a/examples/arcade-server/.gitignore b/examples/arcade-server/.gitignore
new file mode 100644
index 00000000..b9470778
--- /dev/null
+++ b/examples/arcade-server/.gitignore
@@ -0,0 +1,2 @@
+node_modules/
+dist/
diff --git a/examples/arcade-server/README.md b/examples/arcade-server/README.md
new file mode 100644
index 00000000..557f368a
--- /dev/null
+++ b/examples/arcade-server/README.md
@@ -0,0 +1,83 @@
+# Example: Arcade Server
+
+An MCP Apps server that lets you browse and play classic arcade games from [archive.org](https://archive.org) directly in an MCP-enabled host.
+
+## Overview
+
+This example demonstrates serving **external HTML content** as an MCP App resource. The resource is a static loader that uses the MCP Apps protocol to receive tool arguments, then fetches the processed game HTML from a server endpoint. This pattern allows the same resource to display different games based on tool input.
+
+Key techniques:
+
+- MCP Apps protocol handshake (`ui/initialize` → `ui/notifications/tool-input`) to receive game ID dynamically
+- Server-side HTML fetching and processing per game ID
+- `` tag for resolving relative URLs against archive.org
+- `baseUriDomains` CSP metadata to allow the base tag
+- Rewriting ES module `import()` to classic `
+ `,
+ );
+ }
+
+ // Convert inline ES module scripts to classic scripts
+ html = convertModuleScripts(html);
+
+ // Fetch the emulation script server-side and serve from local endpoint
+ html = await rewriteEmulationScript(html, serverPort);
+
+ return html;
+}
+
+/**
+ * Fetches emulation.min.js server-side, rewrites import() → loadScript(),
+ * caches it, and points the HTML `);
+ } catch {
+ // If fetch fails, leave the original script tag
+ }
+
+ return html;
+}
+
+/**
+ * Converts ES module scripts to classic scripts and rewrites inline
+ * import() calls to use window.loadScript().
+ */
+function convertModuleScripts(html: string): string {
+ return html.replace(
+ /(
+