Skip to content

Million-Dollar Homepage playground

read as .md

mcp.ggui.ai/playground/mdh is a first-party hosted MCP service that exposes a globally shared 1000×1000 pixel grid — a tribute to Alex Tew’s 2005 Million-Dollar Homepage. Every signed-in user reads and writes the same canvas. Where the Todos playground demonstrates per-user persistent state, MDH demonstrates globally shared mutable state rendered as generative UI.

Three tools, one canvas, last-write-wins semantics. The agent claims a pixel, the host renders the new region inline, the next user can claim right over the top.

  • Shared mutable state across users: every claim is visible to every other signed-in caller immediately.
  • Generative UI over a sparse data shape: mdh_read_region returns only claimed cells, so the host renders a sparse grid — pure data, no markup decisions baked into the tool.
  • Attribution without ownership: each claimed cell records the writer’s userId, but anyone can overwrite. Identity is recorded; tenure is not.

If you want the deep “why” of the service model behind this, see MCP servicesplayground-mdh is one of three reference services in cloud/mcp-services/.

All three are Cognito-gated. Anonymous calls (no bearer token) return an explicit authentication required error.

ToolInputOutputNotes
mdh_read_region{ x, y, width, height }{ pixels: Pixel[] }Sparse — unclaimed cells omitted. Region capped at 100×100 cells per call.
mdh_claim_pixel{ x, y, color }{ pixel }Single-cell write. color is #RRGGBB hex. Last-write-wins (see warning below).
mdh_get_stats{}{ totalClaimed, uniqueUsers, gridWidth, gridHeight }Cheap aggregate read. gridWidth and gridHeight are always 1000.

A Pixel row is { x, y, color, userId, claimedAt }. Coordinates are integers, 0 <= x < 1000 and 0 <= y < 1000. claimedAt is ISO-8601.

The region cap exists to bound payload size: a 100×100 fully-claimed read returns 10,000 entries. Agents wanting a wider view issue multiple reads — the sparse response means the cost scales with claimed density, not region size.

Cognito-gated. Every handler resolves ctx.userId from the bearer key minted by console.ggui.ai and rejects calls without one. On mdh_claim_pixel, that same userId is stamped on the resulting pixel row — that’s the attribution surface visible to subsequent mdh_read_region callers.

Reads are gated too. The canvas is end-user surface, not a public dataset; anonymous reads are deliberately not exposed at this slice.

The wiring is identical to the Todos playground — same auth header, same OAuth ceremony from MCP-Apps-aware hosts, different URL.

Claude Desktop: Settings → Connectors → Add custom connector, paste:

https://mcp.ggui.ai/playground/mdh

Approve the OAuth ceremony at console.ggui.ai; a new ggui_user_* row appears in /keys/connector. Then try prompts like:

Show me a 50×50 region around the center of the canvas.

Claim the pixel at (500, 500) in red.

How many pixels have been claimed total, and by how many users?

Claude Agent SDK (or any host that takes a remote MCP URL):

import { query } from "@anthropic-ai/claude-agent-sdk";
const apiKey = process.env.GGUI_USER_KEY!; // ggui_user_*
const mcpServers = {
mdh: {
type: "http" as const,
url: "https://mcp.ggui.ai/playground/mdh",
headers: { Authorization: `Bearer ${apiKey}` },
},
};
for await (const msg of query({
prompt: "Claim (500, 500) in #ff0044, then show me a 20×20 region around it.",
options: {
model: "claude-sonnet-4-6",
mcpServers,
allowedTools: [
"mcp__mdh__mdh_read_region",
"mcp__mdh__mdh_claim_pixel",
"mcp__mdh__mdh_get_stats",
],
},
})) {
// consume the SDK message stream
}

The Claude Agent SDK namespaces every MCP tool as mcp__<serverName>__<toolName> — with serverName: "mdh" here, the tool ids land as mcp__mdh__mdh_read_region, mcp__mdh__mdh_claim_pixel, and mcp__mdh__mdh_get_stats. For the full agent-side wiring (system prompt, error handling, streaming), see the Claude Agent example and swap the URL + tool whitelist.

The service is closed-source (@ggui-private/mcp-playground-mdh — not published or mirrored), but its shape is simple enough to describe:

  • a package entry exporting a createPlaygroundMdhHandlers({ grid }) convenience factory,
  • one file per tool (read-region / claim-pixel / get-stats),
  • a PixelGrid interface with an in-memory implementation. The grid is the single source of truth for its own dimensions and surfaces them on the wire via mdh_get_stats.

To build your own globally shared state surface in this shape, use the OSS McpService mount primitive in @ggui-ai/mcp-server — the same seam this service mounts through. The MCP services architecture page covers mount points, the AuthAdapter contract, and how ctx.userId flows from the bearer header to the handler.