Skip to content

Record Julia's MCP worked example - #248

Draft
tony wants to merge 3 commits into
mainfrom
feat/julia-mcp-recording-20261103
Draft

tony wants to merge 3 commits into
mainfrom
feat/julia-mcp-recording-20261103

Conversation

@tony

@tony tony commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Why

The MCP worked example on the Julia page (https://libtmux.org/en/julia/latest/) shows "Requests only" because scripts/gen-mcp-transcript.mjs had no Julia entry and site/src/data/mcp-transcripts/julia.json did not exist. Two properties of the Julia server stopped the example from being recorded as written:

  • Its pane tools take a target of { paneId, generation }. The generation is the tmux server's process id and start time (for example <pid>:<start time>), list_panes returns it, and capture_pane refuses any other value. The example's generation: '3f9a1c' was invented; the server answers it with stale_target. A real value differs on every run, so a recording that kept it could not be stable or equal to EXAMPLES.julia.
  • The server borrows a tmux that is already running, and its list_panes names the session and window through contexts and the pane through target. The replay read neither, so even a good recording drew an empty tmux.

What

  • site/src/data/mcp-protocol/julia.json is refreshed to libtmux-julia master (c19e4a164; it described 0.1.0-alpha.1, master reports 0.1.1), and Julia's entry of mcp-tools.json follows it because mcp-reference.test.ts binds the two. No other port's entry changes.
  • scripts/gen-mcp-transcript.mjs gains a julia entry. It installs LibTmux and LibTmuxMCP from the checkout into an environment, writes the launcher that install_cli documents, and borrows a tmux whose first pane runs cat checks.log -, so "what the first pane is displaying" is the log the other ports use. The server runs with the default tool catalog, which holds both tools the example calls.
  • scripts/lib/mcp-session.mjs: a call's arguments may be a function of the earlier steps (withListed, listedValue). The recorder sends capture_pane the generation list_panes returned and stores the example's stand-in everywhere in the recording, so the steps equal EXAMPLES.julia. The leak check also refuses a recording that still holds the real value, and sandbox.rewritten.generation names the stand-in.
  • The page says so, in the same sentence that already names the rewritten project directory: "The server's generation, which differs on every run, is shown as 3f9a1c."
  • site/src/lib/mcp-replay.ts draws a pane from a listing that carries contexts and target, and shows what capture_pane read as the pane's screen. The preview now shows [docs], window 0:cat, pane %0 cat and the two log lines; every drawn word is still checked against the recording.
  • EXAMPLES.julia is unchanged.

The stand-in is a rewrite of recorded data, disclosed on the page and in the data file. The alternative is to drop the generation from the example by configuring a caller pane, which would hide the target flow that is the point of Julia's design. I kept the flow and disclosed the rewrite; say if you prefer the other.

Rebase note

#247 (fix/ruby-core-showcase-refresh-20261103) is changing scripts/gen-mcp-transcript.mjs, scripts/lib/mcp-transcript-checks.mjs and site/src/data/mcp-tools.json. This PR touches the first and third (the SERVERS map, the PRESENT line, the calls/marks/leaks expressions, and Julia's region of mcp-tools.json) and leaves mcp-transcript-checks.mjs alone. Whichever PR merges second must rebase. If mcp-tools.json conflicts, regenerate rather than merge by hand: LIBTMUX_DOCS_CHECKOUT_JULIA=<clone at c19e4a164> node scripts/gen-mcp-tools.mjs --port julia.

Verification

Recording, made at libtmux-julia c19e4a164 with tmux 3.8a on a private socket under /home/d/tmp-wave/heavy.sh:

  • Recorded three times, the third with the final script; all three files are byte-identical, and --check passes. The pane's command is cat in every recording because the pane starts cat checks.log - directly, so list_panes cannot catch a shell on its way to exec, the kind of start-up race rs's split pane had. The log is printed long before the first call, which comes after the Julia server has loaded.
  • All recorder checks pass: no failed step, every id a request names was returned earlier, the last answer states checks finished, and the recording holds no host path, user name, host name or real generation.
  • contracts equal the committed snapshot's for list_panes and capture_pane; the recording holds only while those schemas hold.

Tests (vitest, workers capped, through heavy.sh):

  • mcp-showcase, mcp-transcript-checks, mcp-replay, port-landing-page, the new mcp-session, and every other non-outer mcp-* suite and port-landing: 14 files, 525 tests passed.
  • mcp-protocol.outer, mcp-descriptions.outer, mcp-showcase.outer, mcp-source-bound.outer: 4 files, 57 tests passed.
  • astro check: 0 errors, 0 warnings (needed --max-old-space-size=5120). oxlint reports nothing in the touched files.
  • Julia is in the recorded-results, earlier-revision and replay tests, so changing an input or output schema of list_panes or capture_pane hides the recording. A mutated recording (a changed capture text, no rewritten.generation) fails four tests, and the new mcp-session tests include a control showing the server refuses the stand-in.

Not run: a site build, the publication audit, gen-mcp-tools.mjs --check against the standard sibling checkouts (whose heads differ from the recorded revision), the assembled-tree suites (skipped: nothing assembled) and the full pnpm test outer loop. The preview was checked through the component tests, not in a browser.

tony added 3 commits November 3, 2026 16:57
why: A recording counts only against the server its snapshot describes,
and recording Julia needs the snapshot to be at the revision the
recorder runs. The committed snapshot described libtmux-julia
0.1.0-alpha.1; master reports 0.1.1, with new tool descriptions and
annotations, an `output` field in the error schemas, and a larger
list_panes input.

what:
- Regenerate mcp-protocol/julia.json with gen-mcp-protocol.mjs
  --port julia at libtmux-julia c19e4a164 (master)
- Regenerate Julia's entry of mcp-tools.json with gen-mcp-tools.mjs
  --port julia, because mcp-reference.test.ts binds the catalog to the
  snapshot; no other port's entry changes
why: Julia's worked example showed "Requests only" because the recorder
had no entry for it. Its server also differs from the recorded ports:
it borrows a running tmux, and a pane target carries a `generation`
(the tmux server's process id and start time) that list_panes returns
and capture_pane must send back. The example's stand-in is refused as
`stale_target`, and a real value differs on every run, so the call
could be neither recorded as written nor kept stable.

what:
- Add a julia entry that installs both packages from the checkout into
  an environment, writes the launcher `install_cli` documents, and
  borrows a tmux whose first pane shows checks.log
- Let a call's arguments be a function of the earlier steps, with
  `listedValue` and `withListed` to send the listed value in place of
  the example's stand-in; the step records what was sent
- Store the stand-in in the transcript and in `rewritten.generation`,
  and refuse a recording that still holds the real value
- Require Julia's last answer to state the log's last line
- Test that a call is sent the listed value, that the stand-in is
  refused by a server that checks it, and that a call with nothing
  listed fails instead of going out with the stand-in
why: The Julia page showed "Requests only" because its MCP worked
example had never been recorded. The recording alone would still have
drawn an empty tmux, since Julia's list_panes names the session and
window through `contexts` and the pane through `target`, which the
replay did not read, and a capture's screen went unshown.

what:
- Add mcp-transcripts/julia.json, recorded at libtmux-julia c19e4a164
  (master) by gen-mcp-transcript.mjs --port julia; its `contracts`
  equal the committed snapshot's, its steps equal EXAMPLES.julia, and
  re-recording produced the same bytes
- Draw a pane from a listing that carries `contexts` and `target`, and
  show what capture_pane read as the pane's screen
- Say on the page that the server's generation, which differs on every
  run, is shown as the stand-in the example uses
- Add Julia to the recorded-results, earlier-revision and replay tests,
  so a changed schema or argument for list_panes or capture_pane hides
  the recording; cover the page note, the drawn pane and the linked
  listing

This branch was previously deployed

1 inactive deployment
docs-preview — 302627c3 Deployed Nov 4, 2026 by tony via publish-preview / publish #1151
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant