Addendum to plan Step 1, which stays open: the four bullets are still `ubesvart` and the step's Verify still exits 1. Nothing measured changed. The previous instruction was one sentence -- "upload via Customize -> Plugins, run probe-versjon, check whether probe-tools appears" -- which assumed the reader already knew where each of those lives and what counts as an answer. The walkthrough now lives in the file the answers get written into, rather than in a chat message that scrolls away. Every UI path and caveat is sourced from research/03, not invented: the install-from-file and drag-into-chat routes, connectors appearing under the plugin's connectors page rather than as skills, the stale-cache issue (#69020) that makes the 0.0.1 version check load-bearing, and the upload-does-not- survive-relaunch report (#65426). Two distinctions are called out because getting them wrong would produce a confident wrong answer: - `- python3:` measures the SANDBOX interpreter, not the host's. Cowork runs shell commands in the VM or in the cloud. It is still the right thing to measure, but it says nothing about the virtualenv Step 2 built. - `- Host-MCP:` does run on the host, since local MCP servers were moved out of the sandbox in May 2026. A `ja` there is what decision 7 rests on, so it requires both that the connector is listed and that probe_ping answers -- "present but mute" is recorded as nei with a note, because absent and mute point at different causes. Section A is ordered first on purpose: cloud sessions are documented not to run local MCP servers, so `sky` plus a `ja` on Host-MCP would contradict the documentation and is a more interesting result than either answer alone. The verify command in section F was executed as written from the rendered document, not just pasted in: exit 1, as it must be while the probe is open. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
11 KiB
Cowork probe
Plan Step 1 (M1). An empirical record of what this operator's Cowork installation actually does, measured before any code depends on it.
Operator decision 7 — Python as a CLI plus a host-side stdio MCP server — is void if host-side servers never appear in a Cowork session. That is not knowable from Claude Code, so it is measured here first, and the milestone that depends on it carries a written degradation branch either way.
Status: unanswered. All four questions require the operator sitting in a Cowork session on this Mac. The executor session built the probe vehicle and this checklist; it did not and could not answer them. The verify command for this step is written so an unanswered checklist fails:
test "$(grep -cE '^- (Sesjonsmodus|Host-MCP|python3|CLAUDE_PLUGIN_ROOT): +(lokal VM|sky|ja|nei)\b' docs/cowork-probe.md)" = 4
A bullet still reading ubesvart does not match, the count drops below four,
and the command exits non-zero. That is the intended behaviour until the
operator has run the probe.
Results
Overwrite ubesvart with one of the allowed answers, and put the date of the
measurement in the Measured column. A nei is a result, not a failure — it
selects the degradation branch below.
- Sesjonsmodus: ubesvart
- Host-MCP: ubesvart
- python3: ubesvart
- CLAUDE_PLUGIN_ROOT: ubesvart
| Bullet | What the operator does in Cowork | Allowed answer | Measured |
|---|---|---|---|
- Sesjonsmodus: |
Open a Cowork session and read whether it is a local VM or cloud | lokal VM or sky |
|
- Host-MCP: |
Upload jobbsok-probe.plugin via Customize -> Plugins; does probe-tools appear as a connector, and does probe_ping return? |
ja or nei |
|
- python3: |
Run the probe-versjon skill; does it succeed in invoking python3, and which version does it report? |
ja or nei, followed by the reported version |
|
- CLAUDE_PLUGIN_ROOT: |
Run probe-versjon; does it print a resolved absolute path, or the literal variable name? |
ja or nei |
What is already known, and what is not
Measured 2026-09-04 from Claude Code, before the probe was built:
- Cowork is installed and available on this Intel Mac.
- The session mode is not readable from disk.
cowork_settings.jsoncarries onlyextraKnownMarketplaces; the desktop config carriescoworkNetworkModeand a trusted-folder list, and neither states where a session runs. So- Sesjonsmodus:cannot be answered by reading files — it has to be read off a live session. - The other three each require a plugin installed in a live Cowork session. Nothing about them is decidable from Claude Code.
The probe vehicle
jobbsok-probe — a throwaway test plugin, deliberately not the jobbsok
plugin itself. jobbsok's own .mcp.json (Step 12) and packaging script
(Step 13) land eleven steps later, and this probe must not wait for them.
It holds exactly four files, under tests/fixtures/cowork-probe/:
| File | What it is for |
|---|---|
.claude-plugin/plugin.json |
Manifest. Name jobbsok-probe, version 0.0.1. The version is what probe-versjon echoes, so a mismatch reveals a cached build. |
skills/probe-versjon/SKILL.md |
A skill that reports the manifest version, the resolved ${CLAUDE_PLUGIN_ROOT}, and whether it can invoke python3. Answers three of the four questions. |
.mcp.json |
Declares one stdio server, probe-tools. Its appearance in the session is the whole - Host-MCP: question. |
probe_tools.py |
Standard-library JSON-RPC server exposing one tool, probe_ping, returning the interpreter actually running it. No third-party imports: a server that failed on a missing dependency would answer a different question than the one asked. |
Verified from Claude Code 2026-09-04: the server completes an initialize
handshake, lists probe_ping, returns an interpreter version on
tools/call, and rejects an unknown tool name. What is unverified is whether
Cowork ever starts it.
Building the archive
Run from the repository root. The file list is explicit, and that is the point:
cd tests/fixtures/cowork-probe && \
zip -X /tmp/jobbsok-probe.plugin \
.claude-plugin/plugin.json \
.mcp.json \
probe_tools.py \
skills/probe-versjon/SKILL.md
Never zip -r over the repository root. A recursive archive of the repo would
ship .git, STATE.md, .claude/ and the virtualenv into an uploaded plugin.
The include list above names the four files and can carry nothing else.
Running the probe, step by step
Everything below happens in Claude Cowork on this Mac, not in Claude Code.
Where a UI path is named it comes from Anthropic's own documentation
(research/03-cowork-plugin-compatibility.md, dimensions 1 and 6); where the
wording in the app turns out to differ, trust the app and note what you saw --
a changed menu label is itself a finding worth recording.
A. Read the session mode -> answers - Sesjonsmodus:
Open Cowork and find its session-location setting (Cowork -> Settings). You are looking for whether sessions run on this machine or in the cloud.
- On this machine: shell commands execute in a dedicated local Linux VM (Apple Virtualization.framework), which needs working hardware virtualization; Claude runs a readiness check for exactly that.
- In the cloud: code runs on Anthropic's servers. This has been the default since 2026-07-07, so do not assume local just because the Mac is capable.
Write lokal VM or sky.
Do this one first, because it very likely decides question B below:
Anthropic's documentation states that local MCP servers do not run in cloud
sessions. If you answer sky here and ja to - Host-MCP:, that combination
contradicts the documentation and is a much more interesting result than either
answer alone -- say so in the Measured column.
B. Install the probe plugin (needed for C, D and E)
Two documented routes; either is fine.
- Customize -> Plugins, choose the install-from-file / upload option, and pick
/tmp/jobbsok-probe.plugin. - Or drag the
.pluginfile into the Cowork chat. Anthropic's own plugin packaging skill says a.pluginfile appears in the chat as a rich preview with a button to accept it.
Known wrinkle, not your mistake if it happens: uploaded plugins have been reported not to survive an app relaunch (claude-code#65426, June 2026). If the plugin disappears later, re-upload it rather than concluding anything about the probe.
C. Confirm you are testing the build you just uploaded
In the Cowork chat, type / (or +) to list available skills, and run
probe-versjon.
The first thing it reports is the manifest version. It must be 0.0.1.
If it reports anything else, Cowork served a cached build rather than the one you uploaded (claude-code#69020, open) -- and then every answer below is about some other build. Uninstall, re-upload, and re-run before continuing. This check exists because a stale cache produces confident, wrong measurements.
D. Read the skill's output -> answers - python3: and - CLAUDE_PLUGIN_ROOT:
Both come from that same probe-versjon run.
- python3: -- did the skill succeed in running
python3 -c 'import sys; print(sys.version)', and what did it print?
Write ja followed by the version, or nei followed by the error text.
One thing to be precise about, because it changes what the answer means: in
Cowork, shell commands run inside the sandbox (the local VM, or the cloud
environment), not on your Mac. So this measures the sandbox's python3,
not the host's. That is the right thing to measure here -- it tells us whether
a skill-invoked script can run in Cowork at all -- but it is not evidence about
the interpreter that scripts/bootstrap.sh just built a virtualenv for.
- CLAUDE_PLUGIN_ROOT: -- did the skill print a resolved absolute path, or
the literal unexpanded string ${CLAUDE_PLUGIN_ROOT}? Write ja or nei.
An absolute path is the pass; anything literal or empty is nei.
E. Look for the connector -> answers - Host-MCP:
This is the load-bearing one: it is the entire Cowork half of operator decision 7, and the reason this probe is the first step of the build.
A server declared in .mcp.json does not show up as a skill. In Cowork it
appears as a Connector. Two checks, and both must hold:
- Is it listed? Customize -> Plugins, open
jobbsok-probe, and look at its connectors page. Isprobe-toolsthere? - Does it answer? In the chat, ask Claude to call the
probe_pingtool. It should return JSON containingpython_versionandpython_executable.
Write ja only if both hold. If probe-tools is listed but never answers,
write nei and note that it appeared but did not respond -- a connector that
does not respond is not a working host-side server, and the difference between
"absent" and "present but mute" points at different causes.
Unlike D, this one does run on your Mac: Anthropic moved local MCP servers
out of the sandbox in May 2026 and runs them as ordinary host software. So a
ja here means the host Python, the host filesystem and ~/jobbsok-workspace
are all reachable from Cowork -- which is what decision 7 is built on.
F. Record and verify
Edit the four bullets under "Results" above, replacing ubesvart, and fill in
the Measured column with today's date. Then, from the repository root:
test "$(grep -cE '^- (Sesjonsmodus|Host-MCP|python3|CLAUDE_PLUGIN_ROOT): +(lokal VM|sky|ja|nei)\b' docs/cowork-probe.md)" = 4
Exit 0 means the probe is complete and plan Step 1 can be closed. Exit 1 means at least one bullet is still unanswered or was written in a form the grep does not recognise -- check that the answer follows the label directly, with a space, and starts with one of the four allowed words.
Degradation branch
Written now, so the answer does not get decided under pressure later.
If - Host-MCP: is nei — host-side stdio servers do not appear in this
Cowork installation:
- Operator decision 7's Cowork half is unavailable. Nothing changes for Claude Code, where the scripts are invoked directly.
- Every script-backed skill degrades to reading files that the Claude Code CLI produced. The skills stay useful; they stop being able to compute.
Verifiser i Coworkfor the affected milestones means "the skills load and read files produced from Claude Code" — not "the connector answers".- The degradation is recorded in
STATE.md.
This is risk H12's mitigation, and it is why the probe is the first step of the build rather than a later check.
If - python3: is nei — a skill cannot invoke python3 in a Cowork
session: the same degradation applies, and more broadly, since it removes the
CLI half too. Escalate to the operator before building further on decision 7.
If - CLAUDE_PLUGIN_ROOT: is nei — the variable does not resolve: every
intra-plugin path in the plan is affected, not just this milestone's. Escalate;
do not paper over it with hardcoded paths.
If - Sesjonsmodus: is sky — sessions run in the cloud, and host-side
servers cannot reach this machine at all. - Host-MCP: should then read nei,
and its branch applies. If the two disagree, the disagreement is the finding.