# Beyond DOM Scraping: Building "THE LAST TERMINAL" with WebMCP

> Source: <https://dev.to/sandeep_chakravartty_219e/beyond-dom-scraping-building-the-last-terminal-with-webmcp-42d6>
> Published: 2026-09-02 18:54:48+00:00

Project Title:THE LAST TERMINAL — WebMCP Escape Room

GitHub Repository:[https://github.com/scha54/WebMCP]

Live Demo:[https://webmcp-blush.vercel.app/]

For the past several years, autonomous browser agents have interacted with web applications primarily through **DOM scraping and visual inspection**. A typical AI browser workflow involves taking high-resolution screenshots, feeding them into a Vision-Language Model (VLM), predicting pixel coordinates or CSS selectors, and firing synthetic click and keypress events.

This approach suffers from critical flaws:

**WebMCP (Web Model Context Protocol)** is an emerging browser standard that solves this. Instead of forcing AI agents to reverse-engineer visual UIs, WebMCP allows web applications to directly register machine-readable **tools** (`navigator.modelContext.registerTool`

).

To demonstrate this paradigm shift, we built **THE LAST TERMINAL**—a polished, browser-based cyberpunk escape room where human players and AI agents collaborate to solve interconnected facility puzzles using shared WebMCP tool capabilities.

The core architectural principle behind **THE LAST TERMINAL** is **Unified Execution Logic**. The application never duplicates business logic for human interactions vs. agent interactions.

```
                 ┌──────────────────────────┐
                 │     WEBMCP AGENT /       │
                 │     DEMO SIMULATOR       │
                 └────────────┬─────────────┘
                              │
                      WebMCP Tool Calls
                              │
                              ▼
 ┌───────────────────────────────────────────────────────────┐
 │                   THE LAST TERMINAL                       │
 │                                                           │
 │  ┌─────────────────────────────────────────────────────┐  │
 │  │                 src/lib/webmcp/                     │  │
 │  │   tools.ts · schemas.ts · registry.ts              │  │
 │  └──────────────────────────┬──────────────────────────┘  │
 │                             │                             │
 │                             ▼                             │
 │  ┌─────────────────────────────────────────────────────┐  │
 │  │                  src/lib/game/                      │  │
 │  │   gameEngine.ts · gameState.ts · puzzles.ts         │  │
 │  └─────────────┬─────────────────────────┬─────────────┘  │
 │                │                         │                │
 │                ▼                         ▼                │
 │  ┌───────────────────────────┐ ┌───────────────────────┐  │
 │  │     Human Visual UI       │ │   Agent Activity      │  │
 │  │  (Facility Map & Systems) │ │   & Tool Trace Log    │  │
 │  └───────────────────────────┘ └───────────────────────┘  │
 └───────────────────────────────────────────────────────────┘
```

When a human user flips physical switches on the Power Control UI, the component triggers:

```
restorePower(['C', 'A', 'D', 'B'], 'human');
```

When an AI agent invokes the WebMCP tool `restore_power`

, the WebMCP execution context routes directly to the identical function:

```
restorePower(['C', 'A', 'D', 'B'], 'agent');
```

Both invocations mutate the central `GameState`

, trigger real-time UI updates, emit Web Audio synthesized feedback, and push a structured entry to the **Agent Activity Feed**.

The application exposes 10 structured tools representing realistic facility subsystems:

| # | Tool Name | Description | JSON Input Schema |
|---|---|---|---|
| 1 | `get_game_state` |
Retrieves system lock statuses, discovered clues, and active view | `{}` |
| 2 | `inspect_system` |
Inspects facility subsystems (`security` , `power` , `archive` , etc.) |
`{ "system": "surveillance" }` |
| 3 | `read_log` |
Reads facility logs by ID (`LOG-2049` ) |
`{ "logId": "LOG-2049" }` |
| 4 | `inspect_surveillance` |
Inspects CCTV camera feeds (`CAM-07` ) for frame anomalies |
`{ "cameraId": "CAM-07" }` |
| 5 | `decode_message` |
Decodes encrypted ciphers into override candidates | `{ "message": "SURVEILLANCE_ANOMALY" }` |
| 6 | `restore_power` |
Restores auxiliary power using quad-switch sequence | `{ "sequence": ["C", "A", "D", "B"] }` |
| 7 | `unlock_security` |
Unlocks security terminal with 4-digit passcode | `{ "code": "7319" }` |
| 8 | `open_archive` |
Mounts archive database vault (requires auxiliary power) | `{}` |
| 9 | `inspect_archive` |
Queries archive records matching search terms | `{ "query": "exit protocol" }` |
| 10 | `unlock_exit` |
Disengages emergency exit pneumatic doors | `{ "code": "7319" }` |

`restore_power`

``` js
export const RESTORE_POWER_SCHEMA = {
  type: 'object',
  properties: {
    sequence: {
      type: 'array',
      items: { type: 'string' },
      description: 'Ordered list of switch labels, e.g. ["C", "A", "D", "B"].',
    },
  },
  required: ['sequence'],
  additionalProperties: false,
};

// WebMCP Tool Definition
{
  name: 'restore_power',
  description: 'Attempt to restore auxiliary power grid using an ordered 4-switch sequence.',
  inputSchema: RESTORE_POWER_SCHEMA,
  execute: (input: { sequence: string[] }, source = 'agent') => restorePower(input.sequence, source),
}
```

WebMCP tools should not be omnipotent "cheat codes." To demonstrate realistic agent reasoning, tools enforce environment prerequisites:

```
export function openArchive(source: ToolCallSource = 'agent') {
  // Prerequisite Guard
  if (currentGameState.power === 'offline') {
    const error = {
      code: 'PREREQUISITE_NOT_MET',
      message: 'Facility archive requires auxiliary power. Restore power first.',
    };
    recordToolCall('open_archive', {}, { error }, false, source);
    return { success: false, error };
  }

  currentGameState.archive = 'unlocked';
  // ... state progression
}
```

If an agent attempts `open_archive()`

while power is offline, WebMCP returns a structured JSON error response code `PREREQUISITE_NOT_MET`

. The agent reads this structured output, inspects logs to discover that power must be restored, and calls `restore_power`

first.

To register tools safely in React environments without re-registering on component re-renders, **THE LAST TERMINAL** implements an initialization guard module in `src/lib/webmcp/registry.ts`

:

``` js
let initialized = false;

export function registerWebMCPTools(): boolean {
  if (typeof window === 'undefined') return false;
  if (initialized) return isWebMCPAvailableInBrowser;

  try {
    // Polyfill window.__webmcp for browser inspection and agent simulators
    (window as any).__webmcp = {
      tools: WEBMCP_TOOLS,
      callTool: async (name: string, input: any, source = 'agent') => {
        const tool = WEBMCP_TOOLS.find((t) => t.name === name);
        return await tool.execute(input, source);
      },
    };

    // Native WebMCP Imperative API
    const nav = navigator as any;
    if (nav.modelContext && typeof nav.modelContext.registerTool === 'function') {
      WEBMCP_TOOLS.forEach((tool) => {
        nav.modelContext.registerTool({
          name: tool.name,
          description: tool.description,
          inputSchema: tool.inputSchema,
          execute: async (input: any) => await tool.execute(input, 'agent'),
        });
      });
      isWebMCPAvailableInBrowser = true;
    }

    initialized = true;
  } catch (e) {
    console.error('Failed to register WebMCP tools:', e);
  }

  return isWebMCPAvailableInBrowser;
}
```

For hackathon judges and developers, transparency is vital. The interface provides two real-time inspection features:

```
   23:51:04  AGENT  → inspect_surveillance("CAM-07")
   23:51:05  SYSTEM ← clue discovered: 7319
   23:51:09  AGENT  → unlock_security("7319")
   23:51:09  SYSTEM ← SECURITY UNLOCKED
```

`human`

, `agent`

, `simulator`

), JSON inputs, return objects, and execution durations.`AudioContext`

to generate retro cyberpunk typing clicks, success chimes, failure buzzers, and power-up sweeps without hosting external MP3 files.

```
git clone https://github.com/scha54/WebMCP.git
cd WebMCP
npm install
# Run isolated Game Engine test suite
npm run test:engine
# Next.js static build check
npm run build

# Deploy to Vercel
vercel --prod
```

WebMCP transforms web applications from passive visual UIs into **agentic APIs**. By exposing structured tools alongside standard visual components, websites become directly operable by AI models with 90%+ token reduction and near-zero latency.

**THE LAST TERMINAL** proves that building WebMCP-compatible web apps is clean, robust, and framework-agnostic.
