vmware-pilot 2.2.0__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/.claude-plugin/plugin.json +1 -1
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/.mcp.json +1 -1
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/PKG-INFO +89 -5
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/README-CN.md +85 -5
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/README.md +87 -3
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/RELEASE_NOTES.md +103 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/SECURITY.md +4 -3
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/openclaw.plugin.json +1 -1
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/package.json +1 -1
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/pyproject.toml +2 -2
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/server.json +2 -2
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/SKILL.md +15 -9
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/evals/evals.json +1 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/references/agent-guardrails.md +9 -6
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/references/capabilities.md +9 -9
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/references/cli-reference.md +6 -5
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/references/integration-patterns.md +12 -9
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/references/setup-guide.md +62 -11
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/references/templates.md +31 -16
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/regression/test_template_steps_name_real_tools.py +3 -2
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/fixtures/companion_tools.json +58 -1
- vmware_pilot-2.4.0/tests/test_approval_roles.py +180 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_approver_is_caller.py +1 -1
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_custom_approval_gate.py +5 -3
- vmware_pilot-2.4.0/tests/test_dispatcher.py +296 -0
- vmware_pilot-2.4.0/tests/test_dispatcher_review.py +452 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_executor.py +13 -6
- vmware_pilot-2.4.0/tests/test_last_step_clone_failure.py +78 -0
- vmware_pilot-2.4.0/tests/test_open_lows_2026_10_18.py +106 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_own_tools_gated.py +3 -1
- vmware_pilot-2.4.0/tests/test_policy_roles.py +32 -0
- vmware_pilot-2.4.0/tests/test_pre_2_4_0_review.py +113 -0
- vmware_pilot-2.4.0/tests/test_real_run_2026_10_17.py +460 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_safe_error_passthrough.py +12 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_templates.py +27 -20
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/uv.lock +8 -8
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/__init__.py +1 -1
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/cli.py +8 -1
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/custom_loader.py +4 -0
- vmware_pilot-2.4.0/vmware_pilot/dispatcher.py +261 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/executor.py +308 -43
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/lifecycle_gate.py +71 -11
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/_catalog.py +3 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/_shared.py +22 -5
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/server.py +45 -2
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/tools/authoring.py +16 -2
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/tools/lifecycle.py +131 -28
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/tools/query.py +2 -2
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/models.py +30 -0
- vmware_pilot-2.4.0/vmware_pilot/policy_roles.py +27 -0
- vmware_pilot-2.4.0/vmware_pilot/reversibility.py +67 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/vm.py +97 -28
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/.clawhubignore +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/.gitignore +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/Dockerfile +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/docs/architecture-audit-2026-04-30.md +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/docs/aria-pilot-boundary.md +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/examples/mcp-configs/claude-code.json +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/references/workflow-design.md +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/scripts/list_available_tools.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/skills/vmware-pilot/scripts/validate_workflow.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/smithery.yaml +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/__init__.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/conftest.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/__init__.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/__init__.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/_family.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/_scores.json +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/_scoring.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/_skill.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/conftest.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/test_entity_reachability.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/test_error_actionability.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/test_tool_description_quality.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/capability/test_tool_manifest_budget.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/regression/__init__.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/regression/_family_write_surface.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/regression/test_approval_gate_coverage.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/regression/test_capability_grader.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/regression/test_catalog_covers_the_family.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/regression/test_cli_writes_guarded.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/eval/regression/test_environment_resolver_isolation.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/fixtures/snapshot_companion_tools.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_confirm_needs_approval.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_executor_preview_is_not_success.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_final_review_fixes.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_models.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_no_destructive_ops.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_old_tool_names_translated.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_review.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_server.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/tests/test_templates_pass_confirm.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/approval_gate.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/__init__.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/__main__.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/mcp_server/tools/__init__.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/renames.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/review.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/__init__.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/_aiops_params.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/_common.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/_gated.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/baseline.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/k8s.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/monitoring.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/network.py +0 -0
- {vmware_pilot-2.2.0 → vmware_pilot-2.4.0}/vmware_pilot/templates/storage.py +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "vmware-pilot",
|
|
4
4
|
"displayName": "VMware Pilot",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.4.0",
|
|
6
6
|
"description": "Multi-step workflow orchestration for VMware MCP skills with approval gates and rollback.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Wei Zhou",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vmware-pilot
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: VMware workflow orchestration — multi-step state machine with approval gates
|
|
5
5
|
Project-URL: Homepage, https://github.com/vmware-skills/VMware-Pilot
|
|
6
6
|
Project-URL: Repository, https://github.com/vmware-skills/VMware-Pilot
|
|
@@ -9,7 +9,7 @@ Project-URL: Changelog, https://github.com/vmware-skills/VMware-Pilot/blob/main/
|
|
|
9
9
|
Author-email: Wei Zhou <wei-wz.zhou@broadcom.com>
|
|
10
10
|
License-Expression: MIT
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
|
-
Requires-Dist: mcp[cli]<2.0,>=1.
|
|
12
|
+
Requires-Dist: mcp[cli]<2.0,>=1.30
|
|
13
13
|
Requires-Dist: pyyaml<7.0,>=6.0
|
|
14
14
|
Requires-Dist: typer<1.0,>=0.12
|
|
15
15
|
Requires-Dist: vmware-policy<2.0,>=1.21.0
|
|
@@ -89,20 +89,21 @@ pip install --no-index --find-links dist vmware-pilot
|
|
|
89
89
|
| `create_workflow` | Create custom workflow from step list (refused if a destructive step has no approval gate before it) |
|
|
90
90
|
| `run_workflow` | Execute workflow, pauses at approval gates |
|
|
91
91
|
| `get_workflow_status` | Query state + diff report + audit log |
|
|
92
|
-
| `approve` | Human approval, continue execution |
|
|
92
|
+
| `approve` | Human approval, continue execution. Refused while steps before the gate are `not_executed`, until `acknowledge_not_executed=True` says you ran them |
|
|
93
93
|
| `rollback` | Explicit, best-effort undo of steps pilot recorded as succeeded — never automatic. Previews (`blast_radius`) unless `confirm=True` |
|
|
94
94
|
| `cancel_workflow` | Cancel a workflow — move it to the terminal CANCELLED state. Previews (`blast_radius`) unless `confirm=True` |
|
|
95
95
|
|
|
96
96
|
## Built-in Templates (15)
|
|
97
97
|
|
|
98
98
|
`n` is the number of VMs (or drift items); ranges depend on which optional parameters are set.
|
|
99
|
-
`clone_and_test`
|
|
99
|
+
`clone_and_test` needs `snapshot_name` (the snapshot to clone from), resizes staging while it is
|
|
100
|
+
powered off, and has 8 steps when `change_spec` is a guest command (an extra gate before it runs
|
|
100
101
|
in staging). `investigate_alert`'s approvals are synthesis checkpoints; its steps are all reads.
|
|
101
102
|
See `skills/vmware-pilot/references/templates.md` for parameters and steps.
|
|
102
103
|
|
|
103
104
|
| Template | Steps | Approval | Skills Used |
|
|
104
105
|
|----------|:-----:|:--------:|-------------|
|
|
105
|
-
| `clone_and_test` |
|
|
106
|
+
| `clone_and_test` | 7-8 | Yes | aiops, monitor |
|
|
106
107
|
| `incident_response` | 4 | Yes | monitor, aiops |
|
|
107
108
|
| `investigate_alert` | 4 (8 with `deep_dive`) | Yes | monitor, aria |
|
|
108
109
|
| `plan_and_approve` | 3 | Yes | aiops |
|
|
@@ -146,6 +147,89 @@ update it. Requires vmware-policy ≥ 1.19.0. Details: [RELEASE_NOTES.md](RELEAS
|
|
|
146
147
|
> corporate proxy (`invalid peer certificate: UnknownIssuer`). The installed entry point above
|
|
147
148
|
> touches the network zero times; set `UV_NATIVE_TLS=true` if you must use `uvx`.
|
|
148
149
|
|
|
150
|
+
### Pilot runs the steps itself: `--dispatch`
|
|
151
|
+
|
|
152
|
+
By default pilot executes nothing: `run_workflow` returns each step in `pending_dispatch` and your agent performs it.
|
|
153
|
+
Add `--dispatch` (or set `VMWARE_PILOT_DISPATCH=stdio`) and pilot runs each step itself, in that skill's own MCP
|
|
154
|
+
server (`vmware-<skill>-mcp`, which must be installed), so the skill's policy rules, confirmation gate and audit
|
|
155
|
+
apply as usual. Nothing after an approval gate runs before `approve`, and workflows reach `completed`.
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{"mcpServers": {"vmware-pilot": {"command": "vmware-pilot", "args": ["mcp", "--dispatch"]}}}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
stdio only: pilot refuses to start with `--dispatch` and `--transport https`/`http` (the skill servers it starts would
|
|
162
|
+
have no caller identity, so roles could not apply). A step that takes longer than `VMWARE_PILOT_DISPATCH_TIMEOUT`
|
|
163
|
+
seconds (default 1800) is recorded `interrupted` — its effect is unknown — and rollback waits for you to check it.
|
|
164
|
+
`run_workflow` and `approve` take as long as the steps they run: set your MCP client's tool timeout above your
|
|
165
|
+
longest step. If a call does time out, Pilot carries on and answers nothing else until the step ends; then
|
|
166
|
+
`get_workflow_status` shows the outcome. Never perform those steps yourself.
|
|
167
|
+
|
|
168
|
+
<!-- usage: remote-and-exposure -->
|
|
169
|
+
## Remote access (HTTPS) and limiting tools
|
|
170
|
+
|
|
171
|
+
By default `vmware-pilot mcp` speaks stdio to one local client and offers every tool. Two options change that
|
|
172
|
+
(vmware-policy ≥ 1.21.0).
|
|
173
|
+
|
|
174
|
+
**Serve over HTTPS** so clients on other machines can connect. Every caller needs a bearer token:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
vmware-audit token create alice # prints the token once; give it to alice
|
|
178
|
+
vmware-audit token list # names only
|
|
179
|
+
vmware-audit token revoke alice # refused from its next request, no restart
|
|
180
|
+
vmware-pilot mcp --transport https --host 0.0.0.0 --port 8443 \
|
|
181
|
+
--cert /etc/vmware-mcp/server.pem --key /etc/vmware-mcp/server-key.pem \
|
|
182
|
+
--public-name mcp.example.com
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Connect a client (Claude Code shown; any MCP client that supports streamable HTTP and custom headers works):
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
claude mcp add --transport http vmware-pilot https://mcp.example.com:8443/mcp \
|
|
189
|
+
--header "Authorization: Bearer $VMWARE_MCP_TOKEN"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"mcpServers": {
|
|
195
|
+
"vmware-pilot": {
|
|
196
|
+
"type": "http",
|
|
197
|
+
"url": "https://mcp.example.com:8443/mcp",
|
|
198
|
+
"headers": { "Authorization": "Bearer ${VMWARE_MCP_TOKEN}" }
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
- The server will not start without a token, refuses Host/Origin values outside `--public-name`, and checks
|
|
205
|
+
before it binds that unauthenticated requests get 401. Use a certificate your clients trust for those names.
|
|
206
|
+
- Behind a TLS-terminating reverse proxy on the same machine use `--transport http --host 127.0.0.1
|
|
207
|
+
--public-name mcp.example.com` and pass the `Authorization` header through.
|
|
208
|
+
- Behind a load balancer or gateway on another machine, keep `--transport https` (a self-signed certificate is
|
|
209
|
+
fine), list in `--public-name` the host name the balancer sends as `Host`, and have it forward `Authorization`.
|
|
210
|
+
Its health probe can use `GET /healthz`, which needs no token and returns only `{"status": "ok"}`
|
|
211
|
+
(vmware-policy ≥ 1.23.0).
|
|
212
|
+
- Send `traceparent` or `X-Request-ID` with each request to have it stored on the audit row;
|
|
213
|
+
`vmware-audit log --correlation-id ID` then finds the calls behind one platform request.
|
|
214
|
+
- The audit log records each caller as `token:<name>`. Calls naming different targets run in parallel; calls that
|
|
215
|
+
name no target run one at a time, so name the target when several people share a server.
|
|
216
|
+
- **Everyone who can reach the endpoint acts with this server's account.** Tokens identify callers; they grant
|
|
217
|
+
nothing on the platform. Run one endpoint per privilege level.
|
|
218
|
+
- **Several people or roles on one endpoint:** run `vmware-audit roles enable` once, then give each token a role (`vmware-audit token create NAME --role reader`, or a role in `roles.yaml` naming tools and targets; vmware-policy ≥ 1.24.0). A role limits what the token may call on this endpoint; it cannot grant more than the account has. See vmware-policy's README, "Roles for network callers".
|
|
219
|
+
|
|
220
|
+
**Offer only read tools, plus the writes you choose:**
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
vmware-pilot mcp --expose read --allow-write cancel_workflow
|
|
224
|
+
# or: VMWARE_PILOT_MCP_EXPOSE=read VMWARE_PILOT_MCP_ALLOW_WRITE=cancel_workflow vmware-pilot mcp
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Tools not offered do not appear in the client's tool list. A bad value or an unknown write tool stops the server
|
|
228
|
+
(exit 2). This limits what clients are offered; it is not authorization, so the account itself should be
|
|
229
|
+
least-privilege.
|
|
230
|
+
|
|
231
|
+
Details: `skills/vmware-pilot/references/setup-guide.md` ("Serving MCP over HTTPS", "Limiting which tools are offered").
|
|
232
|
+
|
|
149
233
|
## License
|
|
150
234
|
|
|
151
235
|
MIT
|
|
@@ -43,19 +43,19 @@ vmware-pilot mcp # 启动 MCP server(stdio)
|
|
|
43
43
|
| `create_workflow` | 从步骤列表直接创建自定义工作流(若破坏性步骤之前没有审批门控则拒绝) |
|
|
44
44
|
| `run_workflow` | 执行工作流,在审批门控处暂停 |
|
|
45
45
|
| `get_workflow_status` | 查询状态 + 差异报告 + 审计日志 |
|
|
46
|
-
| `approve` |
|
|
46
|
+
| `approve` | 人工审批,继续执行。审批点之前仍有 `not_executed` 步骤时拒绝,直到 `acknowledge_not_executed=True` 表明这些步骤已由你执行 |
|
|
47
47
|
| `rollback` | 显式、尽力而为地逆序撤销 pilot 记录为成功的步骤——从不自动执行。不带 `confirm=True` 时只预览(`blast_radius`) |
|
|
48
48
|
| `cancel_workflow` | 取消工作流,置为终态 CANCELLED。不带 `confirm=True` 时只预览(`blast_radius`) |
|
|
49
49
|
|
|
50
50
|
## 内置模板(15 个)
|
|
51
51
|
|
|
52
|
-
`n` 为虚拟机(或漂移项)数量;区间取决于设置了哪些可选参数。`
|
|
53
|
-
`
|
|
54
|
-
|
|
52
|
+
`n` 为虚拟机(或漂移项)数量;区间取决于设置了哪些可选参数。`clone_and_test` 需要
|
|
53
|
+
`snapshot_name`(克隆所用的快照),在 staging 关机状态下调整规格;`change_spec` 为 guest 命令时
|
|
54
|
+
有 8 步(在 staging 中执行命令前多一道审批)。`investigate_alert` 的审批是综合判断检查点,其步骤全部为只读。参数与步骤详见 `skills/vmware-pilot/references/templates.md`。
|
|
55
55
|
|
|
56
56
|
| 模板 | 步骤数 | 审批 | 使用的技能 |
|
|
57
57
|
|------|:------:|:----:|-----------|
|
|
58
|
-
| `clone_and_test` |
|
|
58
|
+
| `clone_and_test` | 7-8 | 是 | aiops, monitor |
|
|
59
59
|
| `incident_response` | 4 | 是 | monitor, aiops |
|
|
60
60
|
| `investigate_alert` | 4(`deep_dive` 时 8) | 是 | monitor, aria |
|
|
61
61
|
| `plan_and_approve` | 3 | 是 | aiops |
|
|
@@ -97,6 +97,23 @@ CLI 命令也不变。技能目录同时跟随 vmware-vks 的改名(`get_super
|
|
|
97
97
|
> (`invalid peer certificate: UnknownIssuer`)。上面的入口点走 PATH,完全不联网;
|
|
98
98
|
> 若必须用 `uvx`,请设置 `UV_NATIVE_TLS=true`。
|
|
99
99
|
|
|
100
|
+
### 由 Pilot 自己执行步骤:`--dispatch`
|
|
101
|
+
|
|
102
|
+
默认情况下 Pilot 不执行任何步骤:`run_workflow` 把每一步放在 `pending_dispatch` 里返回,由你的 agent 去执行。
|
|
103
|
+
加上 `--dispatch`(或设置 `VMWARE_PILOT_DISPATCH=stdio`)后,Pilot 会在对应 skill 自己的 MCP server
|
|
104
|
+
(`vmware-<skill>-mcp`,需已安装)里执行每一步,因此该 skill 的策略规则、确认门和审计照常生效。审批点之后的步骤
|
|
105
|
+
在 `approve` 之前不会执行,工作流可以走到 `completed`。
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{"mcpServers": {"vmware-pilot": {"command": "vmware-pilot", "args": ["mcp", "--dispatch"]}}}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
仅限 stdio:`--dispatch` 与 `--transport https`/`http` 同时使用时 Pilot 拒绝启动(它启动的 skill server 没有调用者
|
|
112
|
+
身份,角色无法生效)。超过 `VMWARE_PILOT_DISPATCH_TIMEOUT` 秒(默认 1800)的步骤记为 `interrupted`——效果未知——
|
|
113
|
+
回滚会等你确认后再进行。
|
|
114
|
+
`run_workflow` 和 `approve` 的耗时等于它们执行的步骤:请把 MCP 客户端的工具超时设得比最长的步骤更长;万一调用超时,
|
|
115
|
+
Pilot 会继续执行,并在该步骤结束前不响应其他调用;之后用 `get_workflow_status` 查看结果——不要自己去执行这些步骤。
|
|
116
|
+
|
|
100
117
|
## 审计与安全
|
|
101
118
|
|
|
102
119
|
所有操作通过 vmware-policy(`@vmware_tool` 装饰器)自动审计:
|
|
@@ -105,6 +122,69 @@ CLI 命令也不变。技能目录同时跟随 vmware-vks 的改名(`get_super
|
|
|
105
122
|
- 查看最近操作:`vmware-audit log --last 20`
|
|
106
123
|
- 查看被拒绝的操作:`vmware-audit log --status denied`
|
|
107
124
|
|
|
125
|
+
<!-- usage: remote-and-exposure -->
|
|
126
|
+
## 远程访问(HTTPS)与限制工具
|
|
127
|
+
|
|
128
|
+
默认情况下 `vmware-pilot mcp` 通过 stdio 服务一个本地客户端,并提供全部工具。以下两个选项可以改变这一点
|
|
129
|
+
(需 vmware-policy ≥ 1.21.0)。
|
|
130
|
+
|
|
131
|
+
**通过 HTTPS 提供服务**,让其他机器上的客户端连接。每个调用者都需要一个 bearer token:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
vmware-audit token create alice # 只显示一次,交给 alice
|
|
135
|
+
vmware-audit token list # 只列名字
|
|
136
|
+
vmware-audit token revoke alice # 下一个请求起即拒绝,无需重启
|
|
137
|
+
vmware-pilot mcp --transport https --host 0.0.0.0 --port 8443 \
|
|
138
|
+
--cert /etc/vmware-mcp/server.pem --key /etc/vmware-mcp/server-key.pem \
|
|
139
|
+
--public-name mcp.example.com
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
连接客户端(以 Claude Code 为例;任何支持 streamable HTTP 和自定义请求头的 MCP 客户端都可以):
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
claude mcp add --transport http vmware-pilot https://mcp.example.com:8443/mcp \
|
|
146
|
+
--header "Authorization: Bearer $VMWARE_MCP_TOKEN"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"mcpServers": {
|
|
152
|
+
"vmware-pilot": {
|
|
153
|
+
"type": "http",
|
|
154
|
+
"url": "https://mcp.example.com:8443/mcp",
|
|
155
|
+
"headers": { "Authorization": "Bearer ${VMWARE_MCP_TOKEN}" }
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
- 没有 token 时服务不会启动;`--public-name` 之外的 Host/Origin 一律拒绝;绑定端口前会自检,确认未认证请求得到 401。
|
|
162
|
+
证书要用客户端信任、且覆盖这些名字的证书。
|
|
163
|
+
- 在同一台机器上由反向代理终结 TLS 时,用 `--transport http --host 127.0.0.1 --public-name mcp.example.com`,
|
|
164
|
+
并让代理透传 `Authorization` 头。
|
|
165
|
+
- 负载均衡或网关在另一台机器上时,保持 `--transport https`(自签证书也可以),在 `--public-name` 里写上负载均衡
|
|
166
|
+
转发时带的 `Host` 名,并让它透传 `Authorization`。健康检查可以用 `GET /healthz`:不需要 token,只返回
|
|
167
|
+
`{"status": "ok"}`(需 vmware-policy ≥ 1.23.0)。
|
|
168
|
+
- 每个请求带上 `traceparent` 或 `X-Request-ID`,它会记进审计记录;用 `vmware-audit log --correlation-id ID`
|
|
169
|
+
就能查到平台上某一次请求对应的调用。
|
|
170
|
+
- 审计日志把每个调用者记为 `token:<名字>`。指定不同 target 的调用并行执行;不指定 target 的调用逐个执行,
|
|
171
|
+
所以多人共用一个 server 时请写明 target。
|
|
172
|
+
- **能连到这个端点的人,都以该 server 配置的账号操作。** token 只用来识别调用者,不在平台上授予任何权限。
|
|
173
|
+
每个权限级别单独起一个端点。
|
|
174
|
+
- **一个端点给多人或多种角色用:** 先运行一次 `vmware-audit roles enable`,再给每个 token 指定角色(`vmware-audit token create 名字 --role reader`,或在 `roles.yaml` 里定义可用的工具和 target;需 vmware-policy ≥ 1.24.0)。角色只能限定这个 token 在本端点上能调用什么,不能超出账号本身的权限。详见 vmware-policy README 的「网络调用者的角色」一节。
|
|
175
|
+
|
|
176
|
+
**只提供读工具,加上你选定的写工具:**
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
vmware-pilot mcp --expose read --allow-write cancel_workflow
|
|
180
|
+
# 或:VMWARE_PILOT_MCP_EXPOSE=read VMWARE_PILOT_MCP_ALLOW_WRITE=cancel_workflow vmware-pilot mcp
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
未提供的工具不会出现在客户端的工具列表里。取值错误或写工具名不存在时服务直接退出(exit 2)。
|
|
184
|
+
这只限制提供给客户端的工具,不是授权;账号本身仍应遵循最小权限。
|
|
185
|
+
|
|
186
|
+
详见 `skills/vmware-pilot/references/setup-guide.md`("Serving MCP over HTTPS"、"Limiting which tools are offered")。
|
|
187
|
+
|
|
108
188
|
## 许可证
|
|
109
189
|
|
|
110
190
|
MIT
|
|
@@ -72,20 +72,21 @@ pip install --no-index --find-links dist vmware-pilot
|
|
|
72
72
|
| `create_workflow` | Create custom workflow from step list (refused if a destructive step has no approval gate before it) |
|
|
73
73
|
| `run_workflow` | Execute workflow, pauses at approval gates |
|
|
74
74
|
| `get_workflow_status` | Query state + diff report + audit log |
|
|
75
|
-
| `approve` | Human approval, continue execution |
|
|
75
|
+
| `approve` | Human approval, continue execution. Refused while steps before the gate are `not_executed`, until `acknowledge_not_executed=True` says you ran them |
|
|
76
76
|
| `rollback` | Explicit, best-effort undo of steps pilot recorded as succeeded — never automatic. Previews (`blast_radius`) unless `confirm=True` |
|
|
77
77
|
| `cancel_workflow` | Cancel a workflow — move it to the terminal CANCELLED state. Previews (`blast_radius`) unless `confirm=True` |
|
|
78
78
|
|
|
79
79
|
## Built-in Templates (15)
|
|
80
80
|
|
|
81
81
|
`n` is the number of VMs (or drift items); ranges depend on which optional parameters are set.
|
|
82
|
-
`clone_and_test`
|
|
82
|
+
`clone_and_test` needs `snapshot_name` (the snapshot to clone from), resizes staging while it is
|
|
83
|
+
powered off, and has 8 steps when `change_spec` is a guest command (an extra gate before it runs
|
|
83
84
|
in staging). `investigate_alert`'s approvals are synthesis checkpoints; its steps are all reads.
|
|
84
85
|
See `skills/vmware-pilot/references/templates.md` for parameters and steps.
|
|
85
86
|
|
|
86
87
|
| Template | Steps | Approval | Skills Used |
|
|
87
88
|
|----------|:-----:|:--------:|-------------|
|
|
88
|
-
| `clone_and_test` |
|
|
89
|
+
| `clone_and_test` | 7-8 | Yes | aiops, monitor |
|
|
89
90
|
| `incident_response` | 4 | Yes | monitor, aiops |
|
|
90
91
|
| `investigate_alert` | 4 (8 with `deep_dive`) | Yes | monitor, aria |
|
|
91
92
|
| `plan_and_approve` | 3 | Yes | aiops |
|
|
@@ -129,6 +130,89 @@ update it. Requires vmware-policy ≥ 1.19.0. Details: [RELEASE_NOTES.md](RELEAS
|
|
|
129
130
|
> corporate proxy (`invalid peer certificate: UnknownIssuer`). The installed entry point above
|
|
130
131
|
> touches the network zero times; set `UV_NATIVE_TLS=true` if you must use `uvx`.
|
|
131
132
|
|
|
133
|
+
### Pilot runs the steps itself: `--dispatch`
|
|
134
|
+
|
|
135
|
+
By default pilot executes nothing: `run_workflow` returns each step in `pending_dispatch` and your agent performs it.
|
|
136
|
+
Add `--dispatch` (or set `VMWARE_PILOT_DISPATCH=stdio`) and pilot runs each step itself, in that skill's own MCP
|
|
137
|
+
server (`vmware-<skill>-mcp`, which must be installed), so the skill's policy rules, confirmation gate and audit
|
|
138
|
+
apply as usual. Nothing after an approval gate runs before `approve`, and workflows reach `completed`.
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{"mcpServers": {"vmware-pilot": {"command": "vmware-pilot", "args": ["mcp", "--dispatch"]}}}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
stdio only: pilot refuses to start with `--dispatch` and `--transport https`/`http` (the skill servers it starts would
|
|
145
|
+
have no caller identity, so roles could not apply). A step that takes longer than `VMWARE_PILOT_DISPATCH_TIMEOUT`
|
|
146
|
+
seconds (default 1800) is recorded `interrupted` — its effect is unknown — and rollback waits for you to check it.
|
|
147
|
+
`run_workflow` and `approve` take as long as the steps they run: set your MCP client's tool timeout above your
|
|
148
|
+
longest step. If a call does time out, Pilot carries on and answers nothing else until the step ends; then
|
|
149
|
+
`get_workflow_status` shows the outcome. Never perform those steps yourself.
|
|
150
|
+
|
|
151
|
+
<!-- usage: remote-and-exposure -->
|
|
152
|
+
## Remote access (HTTPS) and limiting tools
|
|
153
|
+
|
|
154
|
+
By default `vmware-pilot mcp` speaks stdio to one local client and offers every tool. Two options change that
|
|
155
|
+
(vmware-policy ≥ 1.21.0).
|
|
156
|
+
|
|
157
|
+
**Serve over HTTPS** so clients on other machines can connect. Every caller needs a bearer token:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
vmware-audit token create alice # prints the token once; give it to alice
|
|
161
|
+
vmware-audit token list # names only
|
|
162
|
+
vmware-audit token revoke alice # refused from its next request, no restart
|
|
163
|
+
vmware-pilot mcp --transport https --host 0.0.0.0 --port 8443 \
|
|
164
|
+
--cert /etc/vmware-mcp/server.pem --key /etc/vmware-mcp/server-key.pem \
|
|
165
|
+
--public-name mcp.example.com
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Connect a client (Claude Code shown; any MCP client that supports streamable HTTP and custom headers works):
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
claude mcp add --transport http vmware-pilot https://mcp.example.com:8443/mcp \
|
|
172
|
+
--header "Authorization: Bearer $VMWARE_MCP_TOKEN"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"mcpServers": {
|
|
178
|
+
"vmware-pilot": {
|
|
179
|
+
"type": "http",
|
|
180
|
+
"url": "https://mcp.example.com:8443/mcp",
|
|
181
|
+
"headers": { "Authorization": "Bearer ${VMWARE_MCP_TOKEN}" }
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
- The server will not start without a token, refuses Host/Origin values outside `--public-name`, and checks
|
|
188
|
+
before it binds that unauthenticated requests get 401. Use a certificate your clients trust for those names.
|
|
189
|
+
- Behind a TLS-terminating reverse proxy on the same machine use `--transport http --host 127.0.0.1
|
|
190
|
+
--public-name mcp.example.com` and pass the `Authorization` header through.
|
|
191
|
+
- Behind a load balancer or gateway on another machine, keep `--transport https` (a self-signed certificate is
|
|
192
|
+
fine), list in `--public-name` the host name the balancer sends as `Host`, and have it forward `Authorization`.
|
|
193
|
+
Its health probe can use `GET /healthz`, which needs no token and returns only `{"status": "ok"}`
|
|
194
|
+
(vmware-policy ≥ 1.23.0).
|
|
195
|
+
- Send `traceparent` or `X-Request-ID` with each request to have it stored on the audit row;
|
|
196
|
+
`vmware-audit log --correlation-id ID` then finds the calls behind one platform request.
|
|
197
|
+
- The audit log records each caller as `token:<name>`. Calls naming different targets run in parallel; calls that
|
|
198
|
+
name no target run one at a time, so name the target when several people share a server.
|
|
199
|
+
- **Everyone who can reach the endpoint acts with this server's account.** Tokens identify callers; they grant
|
|
200
|
+
nothing on the platform. Run one endpoint per privilege level.
|
|
201
|
+
- **Several people or roles on one endpoint:** run `vmware-audit roles enable` once, then give each token a role (`vmware-audit token create NAME --role reader`, or a role in `roles.yaml` naming tools and targets; vmware-policy ≥ 1.24.0). A role limits what the token may call on this endpoint; it cannot grant more than the account has. See vmware-policy's README, "Roles for network callers".
|
|
202
|
+
|
|
203
|
+
**Offer only read tools, plus the writes you choose:**
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
vmware-pilot mcp --expose read --allow-write cancel_workflow
|
|
207
|
+
# or: VMWARE_PILOT_MCP_EXPOSE=read VMWARE_PILOT_MCP_ALLOW_WRITE=cancel_workflow vmware-pilot mcp
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Tools not offered do not appear in the client's tool list. A bad value or an unknown write tool stops the server
|
|
211
|
+
(exit 2). This limits what clients are offered; it is not authorization, so the account itself should be
|
|
212
|
+
least-privilege.
|
|
213
|
+
|
|
214
|
+
Details: `skills/vmware-pilot/references/setup-guide.md` ("Serving MCP over HTTPS", "Limiting which tools are offered").
|
|
215
|
+
|
|
132
216
|
## License
|
|
133
217
|
|
|
134
218
|
MIT
|
|
@@ -1,3 +1,97 @@
|
|
|
1
|
+
## v2.4.0 — runs its own steps on request; honest gates and rollback (first real-vSphere run)
|
|
2
|
+
|
|
3
|
+
### Behaviour changes for existing callers
|
|
4
|
+
|
|
5
|
+
* `approve` refuses a gate whose earlier steps were handed out (`not_executed`) until
|
|
6
|
+
`acknowledge_not_executed=True` — this applies to the default MCP server and to workflows saved by 2.3.0 that are
|
|
7
|
+
already awaiting approval. An automated `approve` caller must pass the flag after performing the steps.
|
|
8
|
+
* `clone_and_test` requires `snapshot_name` (it used to clone from a snapshot literally named `current`).
|
|
9
|
+
* Rollback reports a step without an undo as `not_reversible` (was `skipped`); approval gates and catalog reads are no
|
|
10
|
+
longer listed. A rollback whose undo failed or whose effect is unknown returns `action: "rollback_incomplete"` with
|
|
11
|
+
`outcome: "failed"` and an `error` naming them (it said `rolled_back`).
|
|
12
|
+
* `cancel_workflow` keeps handed-out steps `not_executed` (was rewritten to `skipped`).
|
|
13
|
+
* With vmware-policy 1.24.2, Pilot's own refusals and failed outcomes (`run_workflow`/`approve` ending
|
|
14
|
+
`outcome: "failed"`, refusals carrying `error`, an incomplete rollback) are `isError` frames; previews,
|
|
15
|
+
`awaiting_approval` and `dispatch_required` are not.
|
|
16
|
+
|
|
17
|
+
### Details
|
|
18
|
+
|
|
19
|
+
* A step result's `kubeconfig` (a bearer token from VKS `issue_*_kubeconfig` under `--dispatch`) is masked in
|
|
20
|
+
`workflows.db` like a password. With `--dispatch`, a skill's failed call keeps its own error envelope (`hint`
|
|
21
|
+
included) instead of a flattened JSON string.
|
|
22
|
+
|
|
23
|
+
Found running Pilot workflows on vCenter 8.0.3 for the first time, through the MCP server and through an embedder
|
|
24
|
+
that dispatched steps to the 2.4.0 skill servers.
|
|
25
|
+
|
|
26
|
+
* **`clone_and_test` works on real vSphere.** It cloned from a snapshot literally named `current` (almost no VM
|
|
27
|
+
has one) and resized the clone after powering it on, which vCenter refuses (`MemoryHotPlugNotSupported`) on any
|
|
28
|
+
VM without hot-add. Now `snapshot_name` is **required** (no default; the error names `list_vm_snapshots`), the
|
|
29
|
+
clone is made powered off, staging is resized while off and then powered on, and the check is vmware-monitor
|
|
30
|
+
`investigate_vm` on the staging VM instead of `get_alarms` for the whole vCenter. A guest command runs after
|
|
31
|
+
power-on. 7 steps (8 for a guest command). Pilot still does not wait `monitor_minutes`: the approval message
|
|
32
|
+
asks the approver to, says a running production VM is resized in place (needs hot-add), and that the production
|
|
33
|
+
change is not rolled back. The clone step no longer claims a rollback (powering a clone off does not remove it).
|
|
34
|
+
* **`approve` refuses a gate whose earlier steps nobody ran.** Through the MCP server (no dispatcher) every step
|
|
35
|
+
before the gate is `not_executed`, and the gate used to pass under "Staging VM … tested". It now refuses and
|
|
36
|
+
lists them in `not_executed_before_gate`; `acknowledge_not_executed=True` records them as `reported_done`
|
|
37
|
+
(performed outside Pilot) and they are not handed out again. Pilot never saw their results: through MCP a later
|
|
38
|
+
step that references one is handed out with the reference unresolved (fill it from that step's result), and
|
|
39
|
+
an embedder that dispatches it refuses it. An embedder with a dispatcher is unaffected unless it resumes a workflow
|
|
40
|
+
that was first run without one — then the same refusal applies. The acknowledgement is the caller's
|
|
41
|
+
statement, not a check: Pilot records who sent it, not what the steps returned.
|
|
42
|
+
SKILL.md now says plainly who executes steps: through MCP the agent does, and a workflow never reaches
|
|
43
|
+
`completed` that way.
|
|
44
|
+
* **Rollback says what it cannot undo.** A step with no rollback is reported `not_reversible` (it was `skipped`,
|
|
45
|
+
"no rollback defined"); a rollback that does not remove what the step created — a clone powered off — is
|
|
46
|
+
`partial` with `left_behind`, and the step is `partially_rolled_back`. The preview carries the same:
|
|
47
|
+
`leaves_behind` on such entries and `left_in_place_note`. Approval gates are no longer listed as skipped.
|
|
48
|
+
* **Failure is read from the frame, not from prose.** Besides `isError` and a top-level `error` on a plain
|
|
49
|
+
dict, a top-level `error` in an MCP result's structured content and a one-row `[{"error": ...}]` list now fail
|
|
50
|
+
the step, the last step included. A string is never read as failure, even one starting `Error: ` — decided,
|
|
51
|
+
as in vmware-policy, because tools return console text that can start that way. A skill must set `isError`;
|
|
52
|
+
AIops's linked clone returned its failure as prose in 2.4.0 and is fixed there (it now raises).
|
|
53
|
+
* **Pilot can run the steps itself: `vmware-pilot mcp --dispatch`** (or `VMWARE_PILOT_DISPATCH=stdio`), off by
|
|
54
|
+
default (HLD §19, D-26). Each step runs in that skill's own MCP server (`vmware-<skill>-mcp`), so its policy,
|
|
55
|
+
confirmation gate and audit apply; nothing after an approval gate runs before `approve`; workflows reach
|
|
56
|
+
`completed`. stdio only — refused with `--transport https`/`http`, and a call with a network caller is refused.
|
|
57
|
+
Only the family's skills (not `pilot`) are started, without a shell. A step that exceeds
|
|
58
|
+
`VMWARE_PILOT_DISPATCH_TIMEOUT` (default 1800 s) is recorded `interrupted` (effect unknown), as is a step whose
|
|
59
|
+
skill server died after the call was sent; a server that never starts fails the step with its reason. Every
|
|
60
|
+
step's skill is resolved before step 0 runs; settings are checked at start (`VMWARE_PILOT_DISPATCH` must be
|
|
61
|
+
`stdio` or unset). A step already handed out in `pending_dispatch` is never run again by a `--dispatch` Pilot.
|
|
62
|
+
Results are stored as the tool's own data, so `__from_step_N__:key` works; a reference to a key the step did
|
|
63
|
+
not return is refused (it used to send the whole result in its place). Failure is read from the frame:
|
|
64
|
+
skills' failed calls arrive as `isError` once they run vmware-policy with `vmware_policy.frame` (vmware-policy
|
|
65
|
+
1.24.2). With an older Policy, 13 of 14 skills sent failures with `isError: false`; Pilot catches the
|
|
66
|
+
`{"error": ...}` envelope itself, but a string-shaped failure (mostly AVI's) reads as success.
|
|
67
|
+
Pilot's tools are synchronous: set the MCP client's tool timeout above the longest step.
|
|
68
|
+
* A guest command (`run_vm_guest_command`, `_with_output`) that exits non-zero now fails the step (it was recorded
|
|
69
|
+
as success); one that timed out or whose process vanished (`exit_code` -1) is `interrupted` — it may still be
|
|
70
|
+
running. A clone left `partially_rolled_back` is still listed by a second rollback; an undo whose effect is
|
|
71
|
+
unknown marks its step `interrupted`. The rollback preview lists a rollback attached to a read step.
|
|
72
|
+
* `investigate_vm` added to the design catalog (101 tools).
|
|
73
|
+
* Two new step statuses, `reported_done` and `partially_rolled_back`. Pilot 2.3.0 does not know them: reading a
|
|
74
|
+
workflow that has them, its `rollback` / `cancel_workflow` refuse ("unrecognised status") rather than guess.
|
|
75
|
+
* The rollback preview gains `not_reversible_outside_pilot` (steps handed to the caller with no undo — a clone,
|
|
76
|
+
a production resize; tools the catalog marks read-only left out) with a note; through MCP those used to appear nowhere in the
|
|
77
|
+
preview. The cancel preview gains `handed_out_to_caller`: steps already in `pending_dispatch`, which cancel
|
|
78
|
+
can neither stop nor undo — they used to be listed as `would_skip`, and cancel now keeps them `not_executed`
|
|
79
|
+
on the record instead of rewriting them to `skipped`.
|
|
80
|
+
|
|
81
|
+
## v2.3.0 — roles for network callers (HLD §18)
|
|
82
|
+
|
|
83
|
+
* Workflows record their creator (`created_by`: the network caller `token:<name>`, or the OS user). Workflows saved
|
|
84
|
+
before this release have none.
|
|
85
|
+
* With vmware-policy ≥ 1.24.0 and roles enabled, `approve` follows the caller's role: `approve: none` cannot
|
|
86
|
+
approve, `approve: others` cannot approve a workflow its own token created (nor one with no recorded creator),
|
|
87
|
+
`approve: any` can. The token also needs a role that allows the `approve` tool itself. Whoever edits a draft
|
|
88
|
+
(`update_draft`) or confirms it (`confirm_draft`) is recorded in `authors` and counts as its creator for
|
|
89
|
+
`others`; so is whoever saved a custom template, for workflows made from it (the YAML records `authors`).
|
|
90
|
+
A refusal is audited as `denied` with `rule=role:<name>`.
|
|
91
|
+
* Approval is an audited attestation, not a gate on execution: this server does not run other skills' steps, it
|
|
92
|
+
returns them (`pending_dispatch`) and each skill's server checks the caller's own role there.
|
|
93
|
+
* Declares role metadata (no tool takes a target). README and setup guide: one endpoint for several people or roles.
|
|
94
|
+
|
|
1
95
|
## v2.2.0 — serve MCP over HTTPS
|
|
2
96
|
|
|
3
97
|
`vmware-pilot mcp` can now serve the network as well as stdio (HLD §16, via vmware-policy 1.21.0):
|
|
@@ -8,6 +102,15 @@ vmware-pilot mcp --transport https --host 0.0.0.0 --port 8443 \
|
|
|
8
102
|
--cert server.pem --key server-key.pem --public-name mcp.example.com
|
|
9
103
|
```
|
|
10
104
|
|
|
105
|
+
Connect a client and manage callers (Claude Code shown; any MCP client with streamable HTTP and custom headers works):
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
claude mcp add --transport http vmware-pilot https://mcp.example.com:8443/mcp \
|
|
109
|
+
--header "Authorization: Bearer $VMWARE_MCP_TOKEN"
|
|
110
|
+
vmware-audit token list # names only
|
|
111
|
+
vmware-audit token revoke alice # refused from its next request, no restart
|
|
112
|
+
```
|
|
113
|
+
|
|
11
114
|
* Every request needs `Authorization: Bearer <token>`; the server will not start without a token, refuses Host or
|
|
12
115
|
Origin values outside `--public-name`, and checks itself (unauthenticated requests must get 401) before it
|
|
13
116
|
binds. `--transport http` binds loopback only, for a TLS-terminating reverse proxy.
|
|
@@ -32,14 +32,15 @@ A workflow pauses at each `require_approval` step until `approve()` is called wi
|
|
|
32
32
|
1. **Review before every run** — `run_workflow` reviews the plan and refuses one whose destructive step (skill-catalog risk high/critical, or a destructive name) or unclassifiable step has no gate before it
|
|
33
33
|
2. **Custom workflows are rejected, not warned** — for a custom YAML, `create_workflow`, or AI-designed workflow, that same finding makes `create_workflow_from_template`, `create_workflow` and `confirm_draft` refuse to save it and `run_workflow` refuse it even with `force=True`; only built-in templates keep the audited `force=True` override
|
|
34
34
|
3. **Credentials and guest commands count as destructive** — `vks issue_tkc_kubeconfig` and `issue_supervisor_kubeconfig` return a live Supervisor credential, and the aiops guest tools (`run_vm_guest_command`, `run_vm_guest_command_with_output`, `upload_vm_guest_file`, `provision_vm_guest`) run arbitrary commands or write files inside a VM as the account the caller names; all are gated like a delete
|
|
35
|
-
4. **The gate is in pilot's workflow, not in the target skill** —
|
|
35
|
+
4. **The gate is in pilot's workflow, not in the target skill** — by default pilot executes nothing itself; the calling agent performs each step through the companion skill, which applies its own policy rules
|
|
36
|
+
5. **`--dispatch` makes the gate hold for workflows run through pilot** — pilot then runs each step in that skill's own MCP server (same policy, confirmation gate and audit) and nothing after a gate runs before `approve`. It does not stop an agent from calling a skill directly. stdio only: refused with a network transport, because the skill servers it starts would have no caller identity and roles could not apply
|
|
36
37
|
|
|
37
38
|
### Rollback (explicit, best-effort — never automatic)
|
|
38
39
|
|
|
39
40
|
- A failed step stops the workflow (`failed`); remaining steps are marked `skipped` and nothing is undone automatically
|
|
40
41
|
- `rollback()` and `cancel_workflow()` preview by default: without `confirm=True` they return `blast_radius` (steps undone, left applied, or skipped) and change nothing; `confirm=True` refuses when the state does not allow the transition, a step status is unrecognised, the record cannot be read, or a step was left `running`/`interrupted` (unknown effect) — the last only lifts with an explicit `acknowledge_unknown_effects=True` after the step is checked in the target system
|
|
41
|
-
- `rollback()` must be called deliberately. It reverses, last first, only the steps pilot recorded as `success`, dispatching each step's `rollback_tool` — which only happens when an embedder supplied a dispatcher. On the MCP server
|
|
42
|
-
- Steps without a `rollback_tool` are reported `
|
|
42
|
+
- `rollback()` must be called deliberately. It reverses, last first, only the steps pilot recorded as `success`, dispatching each step's `rollback_tool` — which only happens when pilot runs with `--dispatch` (or an embedder supplied a dispatcher). On the MCP server without `--dispatch` the steps the agent performed are recorded `not_executed`, so `rollback()` reverses nothing but approval gates; the agent must call each performed step's `rollback_tool` itself
|
|
43
|
+
- Steps without a `rollback_tool` are reported `not_reversible` (their change stays); an undo that does not remove what the step created is `partial`; a failed undo does not stop the rest and sets `blocked_reason: rollback_failed`
|
|
43
44
|
- Rollback results are kept on the workflow record and each `rollback` call is audited to `~/.vmware/audit.db`
|
|
44
45
|
- A dispatched step or undo that returns a top-level `action: preview` (a companion tool called without `confirm=True`) is recorded `failed`, never `success`; built-in templates pass `confirm=True` to those tools only in steps that come after an approval gate (a test fails any template that does so earlier)
|
|
45
46
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vmware-pilot"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.4.0"
|
|
8
8
|
description = "VMware workflow orchestration — multi-step state machine with approval gates"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -12,7 +12,7 @@ requires-python = ">=3.10"
|
|
|
12
12
|
authors = [{ name = "Wei Zhou", email = "wei-wz.zhou@broadcom.com" }]
|
|
13
13
|
dependencies = [
|
|
14
14
|
"vmware-policy>=1.21.0,<2.0",
|
|
15
|
-
"mcp[cli]>=1.
|
|
15
|
+
"mcp[cli]>=1.30,<2.0",
|
|
16
16
|
"pyyaml>=6.0,<7.0",
|
|
17
17
|
"typer>=0.12,<1.0",
|
|
18
18
|
]
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/vmware-skills/VMware-Pilot",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.
|
|
10
|
+
"version": "2.4.0",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"identifier": "vmware-pilot",
|
|
15
|
-
"version": "2.
|
|
15
|
+
"version": "2.4.0",
|
|
16
16
|
"runtimeHint": "uvx",
|
|
17
17
|
"packageArguments": [
|
|
18
18
|
{
|