# Dominus 2 Rewrite Plan

> Historical architecture baseline. The shipped 2.7 implementation extends this
> plan with a guided setup CLI, a Studio settings/rules panel, Open Cloud tools,
> and explicitly opted-in generated Luau execution.

## Product direction

Dominus 2 is a Roblox Studio MCP server, not a standalone AI chat CLI. The MCP
host supplies the model and consent UI. Dominus supplies a small, strongly typed
set of Studio inspection, mutation, documentation, and verification tools.

## July 2026 compatibility target

- Target the stable MCP 2025-11-25 protocol through the official TypeScript SDK.
- Use `registerTool`, strict input schemas, output schemas, `structuredContent`,
  text fallbacks, `isError`, and accurate tool risk annotations.
- Keep stdio as the MCP transport. It limits the MCP server itself to the process
  that launched it and avoids exposing another localhost HTTP endpoint.
- Use optional MCP Sampling only for the explicit parallel coordinator. Detect the
  client capability first and keep every normal Studio tool independent of it.
- Do not adopt the legacy experimental Tasks API. Long Studio calls remain normal
  cancellable tool calls until the July Tasks extension is final and broadly
  supported by clients and the TypeScript SDK.

Official references:

- https://modelcontextprotocol.io/specification/2025-11-25/server/tools
- https://ts.sdk.modelcontextprotocol.io/server
- https://modelcontextprotocol.io/docs/tutorials/security/security_best_practices
- https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/

## Architecture

1. MCP host starts `dominus-mcp` over stdio.
2. Dominus owns or securely relays to one loopback WebSocket bridge on port 18088.
3. The installer embeds a persistent random bridge token into that user's local
   Studio plugin, allowing automatic authentication without a manual pairing flow.
4. Every Studio window receives a unique connection ID. MCP callers select that
   ID, so two windows editing the same place cannot overwrite each other's target.
5. Studio instances are returned as session-scoped instance references with path
   segments for display and fallback. Dot-separated names are not identifiers.
6. Mutations run through a command allowlist and ChangeHistoryService recordings.
   Failed batches are cancelled and automatically undone.
7. Script writes require the revision hash returned by the read operation.
8. Arbitrary Luau execution is isolated behind a Studio-side opt-in that defaults
   off plus `confirm=true` on every request; typed mutation/build tools remain the
   default path.
9. Broad tasks can opt into an MCP-native coordinator. It partitions immediate
   child branches, sends bounded read-only evidence to concurrent Sampling workers,
   validates scoped proposals, and owns the only atomic Studio write.

## MCP tool surface

- `dominus_status`, `dominus_select_studio`
- `studio_get_tree`, `studio_inspect`, `studio_get_selection`
- `studio_read_script`, `studio_update_script`
- `studio_apply`, `studio_delete_instances`
- `studio_build_ui`, `studio_snapshot_ui`
- `studio_run_test`, `studio_get_output`
- `roblox_search_api`, `roblox_get_api`
- `run_parallel_task` for Sampling-capable MCP clients

The intended agent loop is inspect, plan, apply, read back, test. Tool descriptions
and the server prompt make that workflow explicit without embedding another LLM
inside the MCP server.

## Safety limits

- Loopback-only listener and authenticated controller/plugin handshakes.
- One MiB WebSocket payload limit, handshake timeout, request timeout, and bounded
  tool arrays/depth/source lengths.
- Dedicated mutation tools are preferred. The isolated `loadstring` path is
  reachable only through the explicit generated-Luau opt-in and confirmed MCP
  tool.
- Explicit destructive tool for deletion.
- Parallel workers are proposal-only; stable refs must match supplied evidence,
  writes must remain in owned scopes, and overlapping proposals are rejected.
- Atomic UI replacement: build and validate off-tree before replacing the live UI.
- Output watcher filters every Dominus-prefixed message to prevent feedback loops.

## Verification

- Transport tests cover authentication, credential rejection, wrong-target responses,
  disconnect isolation, duplicate place sessions, and payload rejection.
- Protocol and MCP tests cover schema validation and structured result shapes.
- Static plugin checks plus `rojo build` verify the packaged plugin model.
- Final gates: TypeScript typecheck, targeted Vitest, full Vitest, build, and
  `npm pack --dry-run`.
