Site Studio
# ToolsEnabled Site Studio 0.1.2
Edit a static website through any MCP host. Site Studio makes a private working copy, provides a live browser preview, and keeps revision history and named checkpoints. The human controls pause, undo, restore, and export. Your original folder stays unchanged until you explicitly confirm an export to it.
Node.js **22 or newer** is required, together with the local filesystem and process-identity support described under Limits below. There is no npm install step, hosted service, account, model provider, or publishing integration.
## Start
Download and verify the GitHub release archive. From its extracted directory:
```sh
node mcp-web.js --site /absolute/path/to/static-site --data-dir /absolute/path/to/private-state --export-dir /absolute/path/to/finished-site
```
The export parent must already exist. The destination must be a new folder, or the original site folder itself. The state folder must be new or empty, outside the original/export folders and plugin installation, and dedicated to Site Studio. Existing state folders require private permissions (`chmod 700` on Linux/macOS). On Windows, use a directory accessible only to your account.
This command starts the **stdio MCP server** and two loopback listeners: a human dashboard and a separate site preview. A one-time dashboard session link is written to local stderr diagnostics. Before giving the agent work, find and open that private link once; the page removes the fragment secret from the address bar, exchanges it once by POST, and keeps the session token in sessionStorage for that browser tab and exact origin. Dashboard requests carry a required session header. A separate HttpOnly cookie grants preview reads only; it never authorizes dashboard controls. `web_preview` returns only the clean URL and the preview origin, never a session or preview capability. Open the private dashboard link to view the site. MCP JSON stays on stdout. Without `--site`, the included two-page Fieldwork sample opens in a private copy. Without `--data-dir`, state lives in `~/.site-studio/<site-identifier>`. `SITE_STUDIO_ROOT` and `SITE_STUDIO_DATA` are environment alternatives. Without `--export-dir`, export stays disabled.
For browser-only operation, replace `mcp-web.js` with `web-server.js`. One process owns each state directory: do not launch browser-only mode alongside MCP on the same state directory. Close the MCP host or send EOF/SIGINT/SIGTERM/SIGHUP (or SIGBREAK on Windows) to stop; both listeners and the lease are released. Startup import also responds to shutdown between bounded file operations.
## Connect a client
Print the appropriate registration command or configuration:
```sh
node tools/mcp-config.mjs --client claude --site /absolute/path/to/static-site --data-dir /absolute/path/to/private-state --export-dir /absolute/path/to/finished-site
```
Replace `claude` with `codex`, `cursor`, `claude-desktop`, or `deepseek`. Claude Code and Codex receive shell commands; Cursor and Claude Desktop receive `mcpServers` JSON; DeepSeek Harness receives a Cordis plugin row in YAML for placement under `- insert:` in a profile overlay. Run the printed command or merge the configuration into your client. The helper never changes settings. On Windows, printed commands use PowerShell quoting. Use a different state directory for simultaneously running clients.
The archive contains separate Claude Code and Codex plugin manifests. Claude Code uses `.mcp.json` with three explicit folder options; Codex retains the sample-default configuration inline in `.codex-plugin/plugin.json`. The registration helper above remains available for other MCP hosts. This version ships through GitHub Releases; marketplace and directory distribution are deferred. See [Claude installation and packaging](docs/CLAUDE-INSTALL.md).
Try asking your MCP host: “Read the site, update its headline, add a section, and show me the preview.” See [all tools and examples](docs/MCP.md).
## Review and save
Find `Site Studio dashboard session:` in the host's stderr logs: Claude Code on Linux uses `~/.cache/claude-cli-nodejs/<cwd-slug>/mcp-logs-site-studio/<timestamp>.jsonl` for direct registration; plugin registration uses `mcp-logs-plugin-toolsenabled-site-studio-site-studio/` instead; Desktop uses `mcp-server-<NAME>.log` under `~/Library/Logs/Claude` (macOS) or `%APPDATA%\Claude\logs` (Windows); Codex app-server can expose the line on privately captured stderr with `RUST_LOG=codex_rmcp_client=info` (the documented TUI log route remains unverified here); Cursor uses Output → MCP Logs. DeepSeek Harness inherits its launcher’s stderr; a direct Node launch prints it in that terminal. See [host-specific instructions and recovery](docs/CLAUDE-INSTALL.md#open-the-human-dashboard-before-assigning-work).
**Open the link before giving the agent work. Agent file tools can read an unused secret from these logs if permitted.** Never ask the agent to fetch it. Use **Renew dashboard session** in an authenticated dashboard to revoke old capabilities and keep this tab signed in; if access is lost, stop and restart the MCP connection, then open the newly logged link yourself.
Open the one-time dashboard link from local startup diagnostics. Pause, resume, undo, redo, checkpoint restore/delete and export are **not available as MCP tools** and **require the dashboard session**. Select a page; the preview refreshes as edits land. Pause stops agent mutations. Undo, redo, and checkpoint restore always create a new revision. A paused human can still undo or restore. `web_checkpoint` saves an attributed agent checkpoint. The dashboard also has a human Save checkpoint button. The timeline identifies actor and action type. A permanent “Opened working copy (r0)” target remains available after older undo states are pruned. Checkpoint labels cannot use system summaries or invisible control characters.
Choose **Export working copy**, inspect the destination/revision, then **Confirm export**. An edit arriving while confirmation is open makes that confirmation stale. Export never deploys anything. Export to a new destination leaves the source intact. Export to the original folder retains the previous folder beside it as `.site-studio-backup-<identifier>`. The receipt names the backup. Edits made outside Site Studio to the original cause a drift refusal; start a new state directory to import that new original, after saving any needed working-copy content.
Checkpoints, pause state, undo/redo and the working copy survive restarts. An export also holds a destination lease in its parent directory; if an export process crashes, verify that its recorded PID is gone before removing that `.site-studio-export-*.lock` file. After an abnormal exit, startup recovers a stale `lease.json` automatically and prints a one-line notice. It first requires the same platform, hostname and Linux PID namespace, then compares the PID and operating-system process start identity (including the boot ID on Linux). A live owner still refuses a second writer. Immutable recovery claims coordinate contenders. Malformed leases, unavailable checks, scope mismatches and older leases without scope or creation identity refuse safely. For those cases, manually verify that all writers on the original host and namespace have stopped before removing the named lease; keep the working copy and checkpoints. Do not share state between hosts or namespaces. Do not edit `state.json` or working directories directly.
On macOS, a network change can change the hostname. If the Mac crashed before its lease was released and its hostname then changed, startup refuses the scope mismatch even on the same Mac. Close its Site Studio MCP connections and browser-only instances, and manually verify that no Site Studio writer is still using that state directory, including the recorded PID. Then remove only the named `lease.json` and restart with the same `--data-dir`. Keep `state.json`, working directories and checkpoints; do not edit the recorded hostname to bypass the check.
## Supported sites and limits
- Recursive static folders, nested pages, root-relative URLs and binary assets are supported. HTML/HTM, CSS and UTF-8 text are readable; other files are preserved as opaque bytes for export. HTML paired elements and void elements are addressable. This is not a JavaScript runtime, build system, CMS or server-side template editor. Run your site's build first and select its static output.
- Authored HTML/SVG uses conservative allowlists. Scripts, event attributes, executable embeds, forms, raw source replacement and obfuscated URLs are refused. New SVG supports shapes, groups, gradients, definitions and local references; SVG animation and foreignObject are refused. CSS edits support flat rules; nested rules and at-rules are not edited. Complex browser-repaired HTML can have fewer addressable nodes: use well-formed paired markup.
- Existing source bytes, including scripts and external references, are preserved for export. Preview requires a separate rotating read cookie; copying its URL alone grants no access. CSP and sandboxing disable scripts, frames, forms, automatic meta refresh and base overrides. Preview rewriting removes recognized document/element referrer-policy overrides as defense in depth; it is not a general HTML/XML sanitizer or a guarantee against browser parser recovery. The read capability never appears in the URL. Preview cookies are not port-scoped, so other loopback servers remain outside the protection boundary; see [SECURITY.md](SECURITY.md). Malformed opening tags are dropped from previews. SVG preview requires UTF-8 and supports CDATA and bounded literal internal entities, including common Illustrator namespace declarations. External, recursive and parameter entities are not expanded. Other SVG encodings remain exportable. Local HTML links, srcset entries and ordinary CSS url()/quoted imports are rewritten into its preview path prefix. Escaped CSS resource URLs may not render; original bytes are unchanged for export. It does not simulate your site's JavaScript behavior. External image, font and stylesheet loading is blocked by default; the human may explicitly start with `--allow-external` to permit HTTPS references. Changing that policy requires a new state directory. Exported sites retain the behavior of their original files; review them before serving them elsewhere.
- Only regular, singly linked files are accepted. Symbolic links, hard links, special files, hidden paths other than `.well-known`/`.nojekyll`, traversal, Windows device names and ambiguous cross-platform paths refuse the import. Choose a public static output directory, not a project folder containing credentials or version-control state. Filesystem metadata and executable bits are not preserved; exported files are private until you deliberately change permissions for your hosting setup.
- Preview budgets derive from the 2 MiB input-file limit: 8 MiB transformed output, 2 MiB cumulative decoded XML text, 64 KiB per attribute and at most 2,097,152 tokens. Oversize attributes are omitted individually; the rest of the page remains visible. The dashboard shows attribute omissions and whole-file preview failures. These limits do not change export bytes or impose an OS process-memory ceiling.
- Limits: 2 MiB per file, 32 MiB total, 1,000 files and 1,000 directories; 240-character relative paths, with at most 255 UTF-8 bytes per component. Paths reject invisible formatting/control characters and collisions under NFC normalization and Unicode 15.0 full case folding. The store keeps at most 20 undo states, 20 redo states, 10 named checkpoints and 100 timeline entries. Older undo/redo states are pruned under the 96 MiB history target; a 128 MiB state ceiling refuses further growth. Tool string arguments are limited to 8,192 UTF-16 code units (checkpoint labels to 80). MCP input is limited to 256 KiB per message; an oversize frame is discarded through its newline and subsequent requests continue and output to 64 KiB per result. Reads return at most 16,384 characters; file/node listings and search results paginate or state their limit.
- State directories require a local filesystem that supports hard links for atomic lease publication; unsupported filesystems refuse startup. On Windows, `%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe` must be available and able to return process start times within five seconds at each startup. `SystemRoot` must name a fully qualified Windows directory; Site Studio launches that full executable path without searching the current folder or PATH. Linux requires readable `/proc` process identities and PID namespace metadata; macOS requires `/bin/ps`. Native Windows and macOS startup remain unqualified by the Linux test suite. The lease coordinates this product's processes, not arbitrary editors or malicious processes using your OS account. Human-only means no MCP tool grants that authority; a host that separately grants shell/browser access can act outside this tool boundary. The optional [fail-closed guard](docs/MCP.md#optional-host-guard) restricts such tools where the host supports it. A process running as the same user can still act as the user. See [SECURITY.md](SECURITY.md).
- Directory promotion retains a backup when replacing the original. A machine crash during the two directory renames can leave the original at that backup path; keep it and recover manually. This is not a transaction across a remote filesystem or power failure. There is no automatic deployment or remote publication.
## Development and verification
See [testing and package reproduction](docs/TESTING.md) for the complete headless suite, browser prerequisite, stdio lifecycle test and deterministic packaging. See [state compatibility](docs/PROVENANCE.md) and the included [test report](docs/TEST-REPORT.md).
## Privacy and support
Site Studio reads the static site folder you select and maintains its private working copy on your computer. It sends selected tool results to your MCP client; that client and its model provider may process the returned site content. Site Studio has no hosted service or telemetry. External preview resources are blocked unless you explicitly opt in. Review your client's data settings before opening confidential sites. [Privacy policy](https://toolsenabled.ai/legal/privacy/). Support: support@toolsenabled.ai.
Works with Claude Code and provides a bundle for Claude Desktop, whose native installation still needs qualification. ToolsEnabled is not affiliated with or endorsed by Anthropic.
TDQS
Scored across 16 tools
Most tools target distinct resources and actions, but web_read, web_pages, web_find, and web_css all involve reading related content, and web_screenshot_note/web_preview both return revision info. Descriptions help clarify boundaries, though some overlap remains.
All tools share a 'web_' prefix, but conventions are mixed: some are verbs (web_read, web_find), some are nouns (web_pages, web_css, web_timeline), and some are verb_noun (web_set_text, web_add_page). The inconsistent ordering of web_css_set further breaks the pattern.
16 tools is slightly above the ideal 3-15 range, but the domain is rich (reading, writing, CSS, SVG, checkpoints, preview). Each tool appears to earn its place, so the count is reasonable if a bit heavy.
Core CRUD for nodes and attributes is covered, but several lifecycle operations are missing or only available via the dashboard: undo/redo/restore, checkpoint restore/delete, file-level deletion, and CSS file creation. Agents can work around some gaps, but these are notable omissions for a revision-based editor.