Add host-specific MCP onramps for major chat clients

Ship first-class MCP setup examples for Claude Code, Codex, and OpenCode so new users can copy one exact command or config instead of translating the generic MCP template by hand.

Reposition the docs to surface those host-specific examples before the generic config fallback, keep workspace-core as the recommended profile everywhere user-facing, and retain Claude Desktop/Cursor as secondary fallback examples.

Bump the package and catalog to 3.11.0, mark the roadmap milestone done, and add docs-alignment coverage that pins the new examples to the canonical workspace-core server command and the expected OpenCode config shape.

Validation:
- uv lock
- ./.venv/bin/pytest --no-cov tests/test_cli.py
- UV_CACHE_DIR=.uv-cache make check
- UV_CACHE_DIR=.uv-cache make dist-check
This commit is contained in:
Thales Maciel 2026-03-13 13:42:45 -03:00
parent 79a7d71d3b
commit 68d8e875e0
15 changed files with 211 additions and 28 deletions

View file

@ -2,6 +2,17 @@
All notable user-visible changes to `pyro-mcp` are documented here.
## 3.11.0
- Added first-class host-specific MCP onramps for Claude Code, Codex, and
OpenCode so major chat-host users can copy one exact setup example instead of
translating the generic MCP config by hand.
- Reordered the main integration docs and examples so host-specific MCP setup
appears before the generic `mcpServers` fallback, while keeping
`workspace-core` as the recommended first profile everywhere user-facing.
- Kept Claude Desktop and Cursor as generic fallback examples instead of the
primary onramp path.
## 3.10.0
- Aligned the five guest-backed workspace smoke scenarios with the recipe docs

View file

@ -23,7 +23,7 @@ It exposes the same runtime in three public forms:
- Stable workspace walkthrough GIF: [docs/assets/workspace-first-run.gif](docs/assets/workspace-first-run.gif)
- Terminal walkthrough GIF: [docs/assets/first-run.gif](docs/assets/first-run.gif)
- PyPI package: [pypi.org/project/pyro-mcp](https://pypi.org/project/pyro-mcp/)
- What's new in 3.10.0: [CHANGELOG.md#3100](CHANGELOG.md#3100)
- What's new in 3.11.0: [CHANGELOG.md#3110](CHANGELOG.md#3110)
- Host requirements: [docs/host-requirements.md](docs/host-requirements.md)
- Integration targets: [docs/integrations.md](docs/integrations.md)
- Public contract: [docs/public-contract.md](docs/public-contract.md)
@ -60,7 +60,7 @@ What success looks like:
```bash
Platform: linux-x86_64
Runtime: PASS
Catalog version: 3.10.0
Catalog version: 3.11.0
...
[pull] phase=install environment=debian:12
[pull] phase=ready environment=debian:12
@ -156,19 +156,42 @@ policy, or disk tools.
uvx --from pyro-mcp pyro mcp serve --profile workspace-core
```
Minimal MCP config:
Copy-paste host-specific starts:
- Claude Code: [examples/claude_code_mcp.md](examples/claude_code_mcp.md)
- Codex: [examples/codex_mcp.md](examples/codex_mcp.md)
- OpenCode: [examples/opencode_mcp_config.json](examples/opencode_mcp_config.json)
- Generic MCP config: [examples/mcp_client_config.md](examples/mcp_client_config.md)
Claude Code:
```bash
claude mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core
```
Codex:
```bash
codex mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core
```
OpenCode `opencode.json` snippet:
```json
{
"mcpServers": {
"mcp": {
"pyro": {
"command": "uvx",
"args": ["--from", "pyro-mcp", "pyro", "mcp", "serve", "--profile", "workspace-core"]
"type": "local",
"enabled": true,
"command": ["uvx", "--from", "pyro-mcp", "pyro", "mcp", "serve", "--profile", "workspace-core"]
}
}
}
```
If `pyro-mcp` is already installed, replace the `uvx --from pyro-mcp pyro`
command with `pyro` in the same host-specific command or config shape.
Profile progression:
- `workspace-core`: recommended first profile for normal persistent chat editing
@ -226,7 +249,7 @@ uvx --from pyro-mcp pyro env list
Expected output:
```bash
Catalog version: 3.10.0
Catalog version: 3.11.0
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.
@ -343,7 +366,7 @@ machine consumption, use `--id-only` for only the identifier or `--json` for the
workspace payload. Use `--seed-path` when
you want the workspace to start from a host directory or a local `.tar` / `.tar.gz` / `.tgz`
archive instead of an empty workspace. Use `pyro workspace sync push` when you want to import
later host-side changes into a started workspace. Sync is non-atomic in `3.10.0`; if it fails
later host-side changes into a started workspace. Sync is non-atomic in `3.11.0`; if it fails
partway through, prefer `pyro workspace reset` to recover from `baseline` or one named snapshot.
Use `pyro workspace diff` to compare the live `/workspace` tree to its immutable create-time
baseline, and `pyro workspace export` to copy one changed file or directory back to the host. Use
@ -577,7 +600,10 @@ Recommended MCP tool profiles:
- Python one-shot SDK example: [examples/python_run.py](examples/python_run.py)
- Python lifecycle example: [examples/python_lifecycle.py](examples/python_lifecycle.py)
- Python workspace example: [examples/python_workspace.py](examples/python_workspace.py)
- MCP client config example: [examples/mcp_client_config.md](examples/mcp_client_config.md)
- Claude Code MCP setup: [examples/claude_code_mcp.md](examples/claude_code_mcp.md)
- Codex MCP setup: [examples/codex_mcp.md](examples/codex_mcp.md)
- OpenCode MCP config: [examples/opencode_mcp_config.json](examples/opencode_mcp_config.json)
- Generic MCP client config: [examples/mcp_client_config.md](examples/mcp_client_config.md)
- Claude Desktop MCP config: [examples/claude_desktop_mcp_config.json](examples/claude_desktop_mcp_config.json)
- Cursor MCP config: [examples/cursor_mcp_config.json](examples/cursor_mcp_config.json)
- OpenAI Responses API example: [examples/openai_responses_vm_run.py](examples/openai_responses_vm_run.py)

View file

@ -22,7 +22,7 @@ Networking: tun=yes ip_forward=yes
```bash
$ uvx --from pyro-mcp pyro env list
Catalog version: 3.10.0
Catalog version: 3.11.0
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.
@ -116,12 +116,21 @@ $ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID app --secret-env
$ uvx --from pyro-mcp pyro workspace create debian:12 --network-policy egress+published-ports
$ uvx --from pyro-mcp pyro workspace service start WORKSPACE_ID app --ready-http http://127.0.0.1:8080/ --publish 18080:8080 -- ./start-app
$ uvx --from pyro-mcp pyro mcp serve --profile workspace-core
$ claude mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core
$ codex mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core
```
For most chat hosts, `workspace-core` is the recommended first MCP profile.
Move to `workspace-full` only when the host truly needs shells, services,
snapshots, secrets, network policy, or disk tools.
Host-specific MCP starts:
- Claude Code: [examples/claude_code_mcp.md](../examples/claude_code_mcp.md)
- Codex: [examples/codex_mcp.md](../examples/codex_mcp.md)
- OpenCode: [examples/opencode_mcp_config.json](../examples/opencode_mcp_config.json)
- Generic MCP config: [examples/mcp_client_config.md](../examples/mcp_client_config.md)
`pyro demo` proves the one-shot create/start/exec/delete VM lifecycle works end to end.
Once that stable workspace flow works, continue with the five recipe docs in
@ -259,7 +268,7 @@ State: started
Use `--seed-path` when the workspace should start from a host directory or a local
`.tar` / `.tar.gz` / `.tgz` archive instead of an empty `/workspace`. Use
`pyro workspace sync push` when you need to import later host-side changes into a started
workspace. Sync is non-atomic in `3.10.0`; if it fails partway through, prefer `pyro workspace reset`
workspace. Sync is non-atomic in `3.11.0`; if it fails partway through, prefer `pyro workspace reset`
to recover from `baseline` or one named snapshot. Use `pyro workspace diff` to compare the current
`/workspace` tree to its immutable create-time baseline, `pyro workspace snapshot *` to create
named checkpoints, and `pyro workspace export` to copy one changed file or directory back to the

View file

@ -85,7 +85,7 @@ uvx --from pyro-mcp pyro env list
Expected output:
```bash
Catalog version: 3.10.0
Catalog version: 3.11.0
debian:12 [installed|not installed] Debian 12 environment with Git preinstalled for common agent workflows.
debian:12-base [installed|not installed] Minimal Debian 12 environment for shell and core Unix tooling.
debian:12-build [installed|not installed] Debian 12 environment with Git and common build tools preinstalled.
@ -243,6 +243,30 @@ For most chat-host integrations, start with `workspace-core`:
uvx --from pyro-mcp pyro mcp serve --profile workspace-core
```
Copy-paste host-specific starts:
- Claude Code: [examples/claude_code_mcp.md](../examples/claude_code_mcp.md)
- Codex: [examples/codex_mcp.md](../examples/codex_mcp.md)
- OpenCode: [examples/opencode_mcp_config.json](../examples/opencode_mcp_config.json)
- Generic MCP config: [examples/mcp_client_config.md](../examples/mcp_client_config.md)
Claude Code:
```bash
claude mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core
```
Codex:
```bash
codex mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core
```
OpenCode uses the `mcp`/`type: "local"` config shape shown in
[examples/opencode_mcp_config.json](../examples/opencode_mcp_config.json). If
`pyro-mcp` is already installed, replace the `uvx --from pyro-mcp pyro`
command with `pyro` in the same host-specific command or config shape.
Use profile progression like this:
- `workspace-core`: recommended first profile for normal persistent chat editing
@ -296,7 +320,7 @@ the identifier programmatically, use `--id-only` for only the identifier or `--j
workspace payload. Use `--seed-path`
when the workspace should start from a host directory or a local `.tar` / `.tar.gz` / `.tgz`
archive. Use `pyro workspace sync push` for later host-side changes to a started workspace. Sync
is non-atomic in `3.10.0`; if it fails partway through, prefer `pyro workspace reset` to recover
is non-atomic in `3.11.0`; if it fails partway through, prefer `pyro workspace reset` to recover
from `baseline` or one named snapshot. Use `pyro workspace diff` to compare the current workspace
tree to its immutable create-time baseline, `pyro workspace snapshot *` to capture named
checkpoints, and `pyro workspace export` to copy one changed file or directory back to the host. Use

View file

@ -63,12 +63,15 @@ Profile progression:
- `pyro mcp serve --profile workspace-core` for the normal persistent chat loop
- `pyro mcp serve --profile workspace-full` only when the model truly needs advanced workspace tools
Starter config:
Host-specific onramps:
- [examples/mcp_client_config.md](../examples/mcp_client_config.md)
- [examples/claude_desktop_mcp_config.json](../examples/claude_desktop_mcp_config.json)
- [examples/cursor_mcp_config.json](../examples/cursor_mcp_config.json)
- [docs/use-cases/README.md](use-cases/README.md)
- Claude Code: [examples/claude_code_mcp.md](../examples/claude_code_mcp.md)
- Codex: [examples/codex_mcp.md](../examples/codex_mcp.md)
- OpenCode: [examples/opencode_mcp_config.json](../examples/opencode_mcp_config.json)
- Generic MCP config: [examples/mcp_client_config.md](../examples/mcp_client_config.md)
- Claude Desktop fallback: [examples/claude_desktop_mcp_config.json](../examples/claude_desktop_mcp_config.json)
- Cursor fallback: [examples/cursor_mcp_config.json](../examples/cursor_mcp_config.json)
- Use-case recipes: [docs/use-cases/README.md](use-cases/README.md)
## Direct Python SDK

View file

@ -6,7 +6,7 @@ goal:
make the core agent-workspace use cases feel trivial from a chat-driven LLM
interface.
Current baseline is `3.10.0`:
Current baseline is `3.11.0`:
- the stable workspace contract exists across CLI, SDK, and MCP
- one-shot `pyro run` still exists as the narrow entrypoint
@ -63,7 +63,7 @@ The remaining UX friction for a technically strong new user is now narrower:
7. [`3.8.0` Chat-Host Onramp And Recommended Defaults](llm-chat-ergonomics/3.8.0-chat-host-onramp-and-recommended-defaults.md) - Done
8. [`3.9.0` Content-Only Reads And Human Output Polish](llm-chat-ergonomics/3.9.0-content-only-reads-and-human-output-polish.md) - Done
9. [`3.10.0` Use-Case Smoke Trust And Recipe Fidelity](llm-chat-ergonomics/3.10.0-use-case-smoke-trust-and-recipe-fidelity.md) - Done
10. [`3.11.0` Host-Specific MCP Onramps](llm-chat-ergonomics/3.11.0-host-specific-mcp-onramps.md)
10. [`3.11.0` Host-Specific MCP Onramps](llm-chat-ergonomics/3.11.0-host-specific-mcp-onramps.md) - Done
11. [`4.0.0` Workspace-Core Default Profile](llm-chat-ergonomics/4.0.0-workspace-core-default-profile.md)
Completed so far:
@ -90,12 +90,12 @@ Completed so far:
transcript separation for files that do not end with a trailing newline.
- `3.10.0` aligned the five guest-backed use-case smokes with their recipe docs and promoted
`make smoke-use-cases` as the trustworthy verification path for the advertised workspace flows.
- `3.11.0` added exact host-specific MCP onramps for Claude Code, Codex, and OpenCode so new
chat-host users can copy one known-good setup example instead of translating the generic MCP
config manually.
Planned next:
- `3.11.0` adds exact host-specific onramps for Claude, Codex, and OpenCode so
a new chat-host user can copy one known-good config or command instead of
translating the generic MCP example by hand.
- `4.0.0` flips the default MCP profile from `workspace-full` to
`workspace-core` so the no-flag server entrypoint finally matches the
recommended docs path, while keeping explicit opt-in access to the full

View file

@ -1,6 +1,6 @@
# `3.11.0` Host-Specific MCP Onramps
Status: Planned
Status: Done
## Goal

View file

@ -0,0 +1,20 @@
# Claude Code MCP Setup
Recommended profile: `workspace-core`.
Package without install:
```bash
claude mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core
claude mcp list
```
Already installed:
```bash
claude mcp add pyro -- pyro mcp serve --profile workspace-core
claude mcp list
```
Move to `workspace-full` only when the chat truly needs shells, services,
snapshots, secrets, network policy, or disk tools.

20
examples/codex_mcp.md Normal file
View file

@ -0,0 +1,20 @@
# Codex MCP Setup
Recommended profile: `workspace-core`.
Package without install:
```bash
codex mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core
codex mcp list
```
Already installed:
```bash
codex mcp add pyro -- pyro mcp serve --profile workspace-core
codex mcp list
```
Move to `workspace-full` only when the chat truly needs shells, services,
snapshots, secrets, network policy, or disk tools.

View file

@ -2,6 +2,15 @@
Recommended default for most chat hosts: `workspace-core`.
Use the host-specific examples first when they apply:
- Claude Code: [examples/claude_code_mcp.md](claude_code_mcp.md)
- Codex: [examples/codex_mcp.md](codex_mcp.md)
- OpenCode: [examples/opencode_mcp_config.json](opencode_mcp_config.json)
Use this generic config only when the host expects a plain `mcpServers` JSON
shape.
`pyro-mcp` is intended to be exposed to LLM clients through the public `pyro` CLI.
Generic stdio MCP configuration using `uvx`:
@ -42,7 +51,7 @@ Primary profile for most agents:
Use lifecycle tools only when the agent needs persistent VM state across multiple tool calls.
Concrete client-specific examples:
Other generic-client examples:
- Claude Desktop: [examples/claude_desktop_mcp_config.json](claude_desktop_mcp_config.json)
- Cursor: [examples/cursor_mcp_config.json](cursor_mcp_config.json)

View file

@ -0,0 +1,9 @@
{
"mcp": {
"pyro": {
"type": "local",
"enabled": true,
"command": ["uvx", "--from", "pyro-mcp", "pyro", "mcp", "serve", "--profile", "workspace-core"]
}
}
}

View file

@ -1,6 +1,6 @@
[project]
name = "pyro-mcp"
version = "3.10.0"
version = "3.11.0"
description = "Stable Firecracker workspaces, one-shot sandboxes, and MCP tools for coding agents."
readme = "README.md"
license = { file = "LICENSE" }

View file

@ -19,7 +19,7 @@ from typing import Any
from pyro_mcp.runtime import DEFAULT_PLATFORM, RuntimePaths
DEFAULT_ENVIRONMENT_VERSION = "1.0.0"
DEFAULT_CATALOG_VERSION = "3.10.0"
DEFAULT_CATALOG_VERSION = "3.11.0"
OCI_MANIFEST_ACCEPT = ", ".join(
(
"application/vnd.oci.image.index.v1+json",

View file

@ -2807,21 +2807,73 @@ def test_cli_workspace_shell_open_prints_id_only(
def test_chat_host_docs_and_examples_recommend_workspace_core() -> None:
readme = Path("README.md").read_text(encoding="utf-8")
install = Path("docs/install.md").read_text(encoding="utf-8")
first_run = Path("docs/first-run.md").read_text(encoding="utf-8")
integrations = Path("docs/integrations.md").read_text(encoding="utf-8")
mcp_config = Path("examples/mcp_client_config.md").read_text(encoding="utf-8")
claude_code = Path("examples/claude_code_mcp.md").read_text(encoding="utf-8")
codex = Path("examples/codex_mcp.md").read_text(encoding="utf-8")
opencode = json.loads(Path("examples/opencode_mcp_config.json").read_text(encoding="utf-8"))
claude_cmd = (
"claude mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core"
)
codex_cmd = (
"codex mcp add pyro -- uvx --from pyro-mcp pyro mcp serve --profile workspace-core"
)
assert "## Chat Host Quickstart" in readme
assert "pyro mcp serve --profile workspace-core" in readme
assert claude_cmd in readme
assert codex_cmd in readme
assert "examples/opencode_mcp_config.json" in readme
assert "recommended first profile for normal persistent chat editing" in readme
assert "## Chat Host Quickstart" in install
assert "pyro mcp serve --profile workspace-core" in install
assert claude_cmd in install
assert codex_cmd in install
assert "advanced 3.x compatibility surface" in install
assert claude_cmd in first_run
assert codex_cmd in first_run
assert "Start most chat hosts with `workspace-core`." in integrations
assert "examples/claude_code_mcp.md" in integrations
assert "examples/codex_mcp.md" in integrations
assert "examples/opencode_mcp_config.json" in integrations
assert '`Pyro.create_server(profile="workspace-core")` for most chat hosts' in integrations
assert "Recommended default for most chat hosts: `workspace-core`." in mcp_config
assert "Use the host-specific examples first when they apply:" in mcp_config
assert "claude_code_mcp.md" in mcp_config
assert "codex_mcp.md" in mcp_config
assert "opencode_mcp_config.json" in mcp_config
assert claude_cmd in claude_code
assert "claude mcp list" in claude_code
assert "workspace-full" in claude_code
assert codex_cmd in codex
assert "codex mcp list" in codex
assert "workspace-full" in codex
assert opencode == {
"mcp": {
"pyro": {
"type": "local",
"enabled": True,
"command": [
"uvx",
"--from",
"pyro-mcp",
"pyro",
"mcp",
"serve",
"--profile",
"workspace-core",
],
}
}
}
def test_content_only_read_docs_are_aligned() -> None:

2
uv.lock generated
View file

@ -715,7 +715,7 @@ crypto = [
[[package]]
name = "pyro-mcp"
version = "3.10.0"
version = "3.11.0"
source = { editable = "." }
dependencies = [
{ name = "mcp" },