6 Commits

Author SHA1 Message Date
ca105401c4 Release 2026.08.18: keep the docs site out of the sdist
The pre-publish audit caught the source distribution sweeping in the whole
docs-site tree, node_modules included: 7,178 files and 71 MB for a package
whose source is about thirty files. Excluded, which brings it back to 116 KB.

No secrets were exposed (no local .env exists), but this is exactly the case
the unpacked-sdist audit is meant to catch, and PyPI is immutable per version.
2026-08-18 13:22:51 -06:00
f4c2a70bbf Add the mcqemu.warehack.ing docs site
Starlight, diataxis-shaped: a tutorial pair, six how-to guides, a generated
tool reference plus a configuration reference, and four explanation pages
covering architecture, sandbox isolation, see-and-drive, and the failure
handling philosophy.

The tool reference is generated from the running MCP server's own schemas, so
its 33 tools, parameters and defaults cannot drift from the code; the
generator asserts its grouping still covers exactly the live tool set.

Infrastructure follows the warehacking cookie-cutter (multi-stage Dockerfile,
Caddy serving dist with real 404 status, compose profiles for prod and dev,
Makefile with a deploy target pointed at docker-2). Two deviations worth
noting: remark-gfm is added to the MDX pipeline because Astro enables GFM for
.md but not .mdx, so tables silently rendered as run-together paragraphs; and
the card icon palette is pinned to the accent because Starlight's staggered
grid rotates through colours including purple.

Package URLs now point at the Gitea repo and this site.
2026-08-17 18:46:56 -06:00
b5a1c3583b Prepare for publication: CalVer bump, LICENSE, classifiers, repository URL
- version 2026.08.17 in pyproject and __init__, kept in sync by a test
- add the MIT LICENSE file the metadata already claimed; it ships in both
  the sdist and the wheel
- classifiers and Repository URL following the convention used by the other
  MCP servers (git.supported.systems/MCP/<name>)
- tests/test_packaging.py guards the invariants that only bite after upload:
  version drift, an unimportable console-script target, a declared license
  with no file, and a Python floor that moves ahead of what we test
2026-08-17 18:05:05 -06:00
5a2d4703ab Close the remaining review findings: injection, isolation, unbounded work
QEMU command line:
- escape commas in every interpolated path (qopt); a path like
  'data,readonly=on.qcow2' previously injected a drive option
- reject extra_args flags that breach VM isolation (host filesystem
  passthrough, host block devices, spawning chardevs, -runas) and document
  the parameter as operator-only
- detect duplicate host ports across port_forwards instead of failing at
  QEMU launch; auto ports no longer collide with each other

Sandbox isolation:
- sandbox_vm now blocks guest-initiated traffic by default (restrict=on),
  with allow_network=True to opt in. Verified end to end: with identical
  guest network state, a default sandbox reaches neither a host loopback
  service nor the internet, while allow_network=True reaches both
- note in the docstring that the guest agent answers before the guest has
  finished booting

Bounded work per call:
- vm_serial_read seeks a 256KB window from the end instead of reading a
  console log that grows without bound into memory
- cap vm_type_text length and vm_mouse_move deltas
- screenshots get a unique filename and are cleaned up, so a concurrent
  capture cannot swap the frame under vm_click

Identity and liveness:
- attach_vm requires an actual unix socket and stores the resolved path
- attached VMs are judged by connecting, not by a stat that a stale socket
  file would pass
- refuse to act on a PID whose cmdline proves it is a different VM
- a sandbox's base image counts as in use while its overlay is live
- fix a latent NameError in vm_mouse_move's homing branch
2026-08-17 16:17:05 -06:00
7377ad5dd8 Add test suite: fake QMP client, launcher table tests, real qemu-img and boot integration 2026-08-16 21:05:02 -06:00
8e7286c474 Initial mcqemu: FastMCP server with lifecycle, image, snapshot, and guest-agent tools 2026-08-16 21:00:01 -06:00