Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Release publication and catalog notification

Publish only an accepted plugin package bound to its reviewed source/tag and exact archive digest.
Keep an existing public tag and archive immutable. A candidate, draft or notification receipt does
not establish authenticated vendor or installed-host acceptance.

The Validate and package workflow produces candidate artifacts; it does not make a release public. After the accepted release becomes public,
`notify-catalog.yml` requests a complete catalog reconciliation. It also observes public edits,
channel promotion, unpublishing and deletion; those events never authorize catalog withdrawal by
themselves. The central publisher retains verified history and applies its reviewed withdrawal
policy. It verifies actual GitHub release sources rather than trusting an event payload.

## Notification authority

The workflow pins the website's central notification action to a reviewed full commit. Publish that
central commit before enabling a plugin workflow that references it. Review and update this pin
when adopting changes to the notification contract. The caller checks its immutable repository ID,
does not check out package code, and grants its own job token no repository permissions.

Supply `CATALOG_DISPATCH_TOKEN` using existing reviewed authority with Actions write access to
`computer-mcp/computer-mcp.github.io` only. Website Contents write access is unnecessary. The action
can also receive an existing temporary token directly from a publishing job. Neither workflow
creates or persists credentials. Missing or rejected authority fails visibly; the
publisher's independent schedule still reconciles missed notifications.

## Publication and retry

A manual public release emits the release event. Publication performed with a repository's
`GITHUB_TOKEN` does not trigger ordinary release-event workflows. After that publication succeeds,
its automation must explicitly call this reusable workflow as a dependent job:

```yaml
notify-catalog:
needs: publish
uses: ./.github/workflows/notify-catalog.yml
secrets:
CATALOG_DISPATCH_TOKEN: ${{ secrets.CATALOG_DISPATCH_TOKEN }}
```

Here `publish` is the job that actually makes the accepted release public, not the candidate-build
or draft-upload job. When using an existing short-lived token within that publishing job, invoke
the same pinned central action directly after publication instead. Keep token values out of command
arguments, printed output and release metadata.

For an operator-driven publication or a missed/failed notification, explicitly dispatch:

```sh
gh workflow run notify-catalog.yml --repo computer-mcp/plugin-claude --ref main
```

This schedules notification using its configured authority; it does not publish or rewrite a
release. Inspect the notification run and its returned central `run_url`. A successful dispatch
proves request acceptance only. Verify the central run completed successfully and the public index
contains the exact expected release identities and generation. If the release is already public and
notification fails, retry notification without changing or republishing the release. Complete
reconciliation is idempotent and repairs duplicate/missed events.

See the central [catalog publication and notification contract](https://github.com/computer-mcp/computer-mcp.github.io/blob/main/docs/plugin-catalog.md)
for provenance, credentials, retry bounds and deployment semantics.
28 changes: 28 additions & 0 deletions .github/workflows/notify-catalog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Notify official plugin catalog
on:
release:
types: [published, edited, released, unpublished, deleted]
workflow_dispatch:
workflow_call:
secrets:
CATALOG_DISPATCH_TOKEN:
description: Existing receiver-scoped Actions write authority
required: true
outputs:
run_url:
description: Accepted central run; verify its deployment separately
value: ${{ jobs.notify.outputs.run_url }}
permissions: {}
jobs:
notify:
if: github.repository_id == '1384746086'
runs-on: ubuntu-latest
timeout-minutes: 3
outputs:
run_url: ${{ steps.catalog.outputs.run-url }}
steps:
- name: Request complete catalog reconciliation
id: catalog
uses: computer-mcp/computer-mcp.github.io/.github/actions/notify-catalog@fc27dd0f370d028a3e5021e3585274891f696578
with:
token: ${{ secrets.CATALOG_DISPATCH_TOKEN }}
7 changes: 7 additions & 0 deletions Documentation/Architecture/Package.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ This repository owns the Claude Code CLI description and print/stream-json-to-MC

`bin/plugin_runtime.py` is this package's private standard-library runtime for bounded MCP I/O, validation, process supervision and retention. It is shipped with the plugin, not loaded from another plugin or host implementation module. Python 3.13+ must be available on the launch PATH. A separate supervisor lifeline and positive cleanup receipt distinguish process exit from confirmed cleanup. These are internal process mechanisms, not a new host contribution type.

The ordinary MCP work resource projects these same run owners, including
pending startup, uncertain cleanup and retained completed results. Correlation
is bound at run creation and is not an authorization grant. Confirmed worker
and process cleanup are prerequisites for result eviction or explicit release.
Reading a result has no release side effect. The adapter bounds and versions
complete snapshots; the host owns configuration generations and routing.

The documented headless CLI is the selected upstream interface; the full Agent SDK's interactive callbacks and hosted Managed Agents are not substituted or claimed. Tests use deterministic peers and controlled process trees. Scripts validate real native version/help, deterministic archives and the unchanged host in isolated standalone mode. Authenticated backend execution and production activation require separate evidence.
16 changes: 13 additions & 3 deletions Documentation/Reference/Installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The example exposes this plugin's complete MCP tool catalog with no extra prefix

On Computer MCP 1.2.2, plugin activation/selection changes require idle Gateway client admission. Finish or safely pause clients before production installation changes. No host binary replacement or host release is required. Do not restart the active development control connection merely to test installation.

Computer MCP 1.3.0 publishes plugin configuration changes to connected clients atomically. New calls use the current configuration; existing work keeps its owning runtime until release. Installation does not grant access, and later calls use current authorization.

## Build

```sh
Expand All @@ -28,16 +30,24 @@ CI runs deterministic fixture tests and packaging; it does not install a vendor

## Isolated host interoperability

After packaging, validate the exact ZIP with an unchanged installed Computer MCP 1.2.2 binary:
After packaging, validate the exact ZIP against the reviewed Computer MCP binary. Select its release version explicitly; a mismatch fails before package extraction:

```sh
python3 Scripts/validate_host.py \
--host "/Applications/Computer MCP.app/Contents/Resources/computer-mcp" \
--host "/absolute/path/to/candidate/computer-mcp" \
--expected-host-version 1.3.0 \
--archive /output/PLUGIN.zip \
--output /new/evidence/directory
```

Replace `PLUGIN.zip` with the package's actual archive name. This uses a temporary directory and the installed host's archive worker and standalone MCP entrypoint. It does not connect to the production App's control socket or database. Vendor tool execution is replaced with inert fixtures; the native version/help check is a separate command. A new evidence directory is required to avoid overwriting an earlier run.
Replace `PLUGIN.zip` with the package's actual archive name. This uses a temporary directory and the selected host's archive worker and standalone MCP entrypoint. It does not connect to the production App's control socket or database. Vendor tool execution is replaced with inert fixtures; the native version/help check is a separate command. A new evidence directory is required to avoid overwriting an earlier run.

For a separately built candidate host that supports the ordinary MCP work
resource, add `--require-work-ownership`. This also verifies ownership during
background execution, retained cancelled/completed results, and explicit release
on the same connection. The candidate host runs only with isolated configuration
and state. This option is not an authenticated-model or production activation
check.

## Result interpretation

Expand Down
71 changes: 67 additions & 4 deletions Documentation/Reference/Interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@

The native version assertion runs before each adapter execution and each host-projected CLI call. Native command availability does not establish account authentication or backend access. The CLI contribution returns a single native JSON result. The MCP adapter independently consumes print-mode stream-json with verbose and partial-message output; it does not parse the terminal UI or use hosted Managed Agents.

The adapter implements newline-delimited MCP JSON-RPC initialization, tools/list, tools/call, ping and cancellation. Supported MCP dates are 2024-11-05, 2025-03-26 and 2025-06-18. Unsupported proposals receive a supported date, not an unimplemented echo. Tool schemas describe accepted arguments. Tool results use `structuredContent.result`; `isError` indicates a failed operation, distinct from a JSON-RPC protocol error.
The adapter implements newline-delimited MCP JSON-RPC initialization, tools/list, tools/call, resources/list, resources/read, ping and cancellation. Supported MCP dates are 2024-11-05, 2025-03-26 and 2025-06-18. Unsupported proposals receive a supported date, not an unimplemented echo. Tool schemas describe accepted arguments. Tool results use `structuredContent.result`; `isError` indicates a failed operation, distinct from a JSON-RPC protocol error.

## Host risk metadata

Every MCP tool declares `_meta["io.github.computer-mcp/risk"]`. Model execution
and continuation declare `full-shell`: native permission defaults are not a
host-enforced sandbox. Catalog, result, event and pending-request inspection
declare `read-only`. Cancellation and owned-process retirement declare
`destructive`. The host applies these as minimum classifications, intersects
its own grants, and retains approval authority. Standard MCP annotations remain
hints rather than permissions.

## Tools

Expand All @@ -18,8 +28,48 @@ The adapter implements newline-delimited MCP JSON-RPC initialization, tools/list
| `claude.run.result` | Return current state or an explicitly completed final result |
| `claude.run.events` | Read a bounded cursor page of native stream-json events |
| `claude.run.cancel` | Cancel one adapter-owned run and wait through normal cleanup on subsequent result reads |

The host may prefix these names; discover actual projections with tools/list. The adapter retains at most 32 total runs, of which at most four can be active. Run handles and event pages are memory-owned, not a second vendor conversation database. Replacing the adapter invalidates these handles; it does not delete native saved conversations.
| `claude.run.release` | Discard one completed result and its events after process and worker cleanup are confirmed |

The host may prefix these names; discover actual projections with tools/list.
The adapter retains at most 32 total runs, of which at most four can have active
or unconfirmed cleanup. Starting a new run at capacity evicts the oldest completed
result whose process and worker cleanup are confirmed. Explicit `run.release`
discards the same retained result sooner. Active work returns `run_active`;
uncertain cleanup returns `cleanup_unconfirmed` and remains retained. Reading
results/events and requesting cancellation do not release the handle.

Run handles and event pages are memory-owned, not a second vendor conversation
database. Replacing the adapter invalidates these handles; it does not delete
native saved conversations. Explicit release also leaves native persistence
unchanged. Save the native session ID before releasing a result if it is needed
for a later resume.

## Ordinary MCP work resource

Every tool declares `_meta["io.github.computer-mcp/work"]` with `format_version: 1`
and URI `computer-mcp://runtime/work/v1`. The same URI is available through
`resources/list` and `resources/read`; it follows the host's
[provider-work contract](https://github.com/computer-mcp/computer-mcp/blob/master/Documentation/Reference/MCPProtocol.md#downstream-provider-work).
It does not require private Host Services, change native permissions, or itself
enable host configuration changes.

A host supplies `_meta["io.github.computer-mcp/work-invocation"]` as a UUID on
each tool call. Each newly reserved run retains its creation call's UUID.
Arguments cannot supply this identity. Subsequent result, event, cancel and
release calls do not rebind the original acquisition. Ordinary clients may
omit the metadata and still use every tool. While an unbound handle is retained,
work observation returns an error because it cannot prove a complete host-bound
snapshot.

The resource returns a complete bounded snapshot with one instance UUID and a
monotonic revision, containing `kind: claude.run`, the adapter `run_id`,
`acquired_by`, and `state`. Pending version checks, process startup, streaming
execution and retained completed results are `active` owners. A cleanup failure
is `uncertain`, even when `completed` is true. Confirmed completion alone does
not remove retained result access: release or bounded capacity eviction ends
the handle's ownership. Snapshot errors preserve the last valid revision.
The declaration is connection-local; gateway reexports omit it from their wire
tool metadata.

## Session and permission semantics

Expand All @@ -33,7 +83,7 @@ Model, effort, appended system prompt and optional budget are forwarded only whe

Each native frame is bounded to 1 MiB before waiting for a newline. The event buffer retains at most 256 events/256 KiB; it reports overflow, omitted oversized events and stale cursors. Pages expose next_cursor, has_more and missed_events, never an unbounded whole history. The final native event is retained separately with a 128 KiB bound; oversized final data fails rather than masquerading as successful truncated output.

Success requires exactly one valid native result event, a non-error native outcome, a successful process exit, and confirmed process cleanup. A final event followed by a hung process still times out. Missing/duplicate/malformed final events, a nonzero exit, cancellation, timeout or cleanup uncertainty are tool errors. Native errors and the final event remain available in the bounded result. `completed: true` means this adapter run settled, not that its task succeeded; inspect `is_error` and state.
Success requires exactly one valid native result event, a non-error native outcome, a successful process exit, and confirmed process cleanup. A final event followed by a hung process still times out. Missing/duplicate/malformed final events, a nonzero exit, cancellation, timeout or cleanup uncertainty are tool errors. Native errors and the first valid final event remain available in the bounded result, including after later malformed output, timeout, cancellation or cleanup failure. `cleanup_error` records cleanup failure separately from an earlier execution `error`; `cleanup_confirmed` reports the process cleanup outcome. Successful final events require a `success` subtype, native session identity and textual result; unknown extension fields are retained. `completed: true` means this adapter run settled, not that its task succeeded; inspect `is_error` and state.

The default execution timeout is 600 seconds, with a configurable maximum of 1800 seconds. Process setup/cleanup can add bounded latency. Synchronous MCP cancellation targets the corresponding run. For detached runs use run.cancel with the returned run_id. Cancellation kills only the owned vendor process group; it does not erase a persisted conversation or retry the prompt.

Expand All @@ -46,3 +96,16 @@ A private supervisor observes parent/connection shutdown, pins the native group
- The installed native `claude --version` and `claude --help` used to maintain the pinned CLI tree.

Fixture protocol checks, native interface checks, exact-host interoperability and authenticated model execution are recorded separately.

## Continuation binding

Tools that accept an existing adapter handle declare
`_meta["io.github.computer-mcp/continuation"]` with format version 1. The selector
matches kind `claude.run` and primary resource `id` against argument
`run_id` using JSON Pointer `/run_id`. This identifies the actual
connection-owned lifetime; it does not rebind acquisition or grant permissions.
New work and unscoped listings do not claim an existing owner. The declaration
uses ordinary MCP metadata and requires no private Host Services. Hosts validate
and retain it on its originating connection; gateway reexports strip it. Runtime
generation selection remains host-owned, and this declaration alone does not
enable live configuration changes.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ The CLI contribution describes verified non-interactive commands. The native bas

## MCP capabilities

The adapter provides `claude.run`, `claude.run.start`, `claude.run.list`, `claude.run.result`, `claude.run.events` and `claude.run.cancel`. It consumes native print-mode stream-json, including partial messages, and retains the final result, native session ID and explicit error status. Discovery does not launch Claude Code.
The adapter provides `claude.run`, `claude.run.start`, `claude.run.list`, `claude.run.result`, `claude.run.events`, `claude.run.cancel` and `claude.run.release`. It consumes native print-mode stream-json, including partial messages, and retains the final result, native session ID and explicit error status. Release discards a completed result only after cleanup is confirmed. Discovery does not launch Claude Code.

The ordinary MCP work resource reports active runs and retained result handles
with their original acquisition reference. Hosts can account for this work
after its creating tool returns, without private Host Services permission.
Cleanup uncertainty remains owned and cannot be released or evicted.

`permission_mode` defaults to `dontAsk`; `plan` and `acceptEdits` are supported explicit choices. The noninteractive contract does not expose permission-bypass modes or fabricate interactive permission responses. Existing vendor configuration continues to apply. Resume/continue/new-session selection is explicit; cancelling a run does not delete its saved native conversation.

Expand Down
Loading
Loading