Repository navigation
Description
Relocated from dezren39/darwin-nix#155 on 2026-10-28 (placement audit): mcpx's single source lives in developing-today/code (pkgs/mcpx); re-home tracked at #309. Original body below; issue references inside it are historical (dezren39/nix numbering).
Parent: #92
Summary
Design the mcpx home page: the first stop of the 30-second layer (home -> overview -> quick start -> close
the tab). It carries the pitch (why you would install it), a short video, a small intro block, one static
TypeScript example, the download link, two copy-button install commands and a copy-button agent prompt
that rotates among four phrasings. Nothing like it exists: docs/landing.md is a PR landing checklist, not
a landing page, and the only first-screen prose is the top of docs/story.md, which is a long walk, not a
skim.
The design constraint for every choice below is note line 8: someone "skimming while doing 3 different
things will accidentally learn". So: one screen of hero, no reading required to get the three claims, every
command copyable, nothing on the page that is not real.
This issue also flags a defect in the notes: the system-wide install form sudo $(curl <short> | sh) does
not do what it looks like it does (see "System-wide install command").
Original notes
- documentation
- make a book using whatever is the most common and simple modern choice
- specialized agent markdown all pages
- home page has install prompt built into the bot version
- 3 main things, not book sections jsut like levels of detail-
- the 30 seconds look at home page click the overview page, click the quick start page, ctrl+w should be simple enough that even this person skimming while doing 3 different things will accidentally learn
- why you would install it
- code mode
- makes shareable, reusable scripts
- reclaim context, use less tokens
- smarter, cheaper
- tame mcp
- one mcp config
- share endpoint with your tailnet
- corral your scripts, apis, and binaries
- how to install it
- home page has
- short flex video
- simple intro
- short 1-4 sentence paragraph
- surrounded by small title/small here-blocks/bigger word lines
- code block example
- static syntax-highlighted typescript
- exec real editable example click button remote
- wasm, local mcp, daemon/cli-client
- download link
- per-user
curl <short> | sh[copy-button]
- ~system-wide
sudo $(curl <short> | sh)[copy-button]- <
subitem[rand(this.len)]> [copy-button]
hey please one-shot setup mcpx right nowhey install this mcpx thing and comment out all my mcp configreplace mcp with mcpx codemodeguided install mcpx now plz
Current state (what mcpx does today, with file refs)
-
No home page, no site.
dezren39/nixhas no Pages site; the generator is chore(deps): update rust crate actix-files to v0.6.10 - autoclosed #117, deploy fix(deps): update github.com/charmbracelet/ssh digest to ebfa259 - autoclosed #118,
the short domain behind<short>Update github.com/tursodatabase/libsql-client-go digest to 9d5d30a #119. -
No installer and no download. No tags, no GitHub releases, no install script; version hard-coded
0.1.0(pkgs/mcpx/package.nix:19,:61, the default incmd/mcpx/main.go:18, and
Containerfile:40). The only install path today is the flake output (flake.nix:385, app at:494);
since Phase 5: tag event bodies must travel with the event #182 apkgs/mcpx/Containerfilebuilds a local image, but none is published. Channels are designed
in amd host fails at evaluation: no outputHashes for p2panda-core-0.7.1 #158. -
Pitch material exists, scattered.
docs/story.mdabove<!-- table-of-contents-marker -->
(story.md:1-296) has the numbers the pitch needs:mcpx ls"Seven namespaces, 43 tools, 171 tokens";
27 Chrome tools and "not one byte of their schemas is in the agent's context"; "about 4,600 tokens total"
for the whole task, "and left behind a script that costs nothing to run again".package.nixmeta
has a two-paragraph description.AGENTS.mdopens with the three framing lines. -
Each "why" bullet maps to a shipped feature (all
status: standardin story.md unless noted):Note What backs the claim today Ref code mode -> shareable, reusable scripts named scripts on a search path ( .mcpx/scripts/<name>.ts, then~/.config/mcpx/scripts/),mcpx run <name>, generated typed clientstory.md "Named scripts" (:641), AGENTS.md "Scripts" reclaim context -> smarter, cheaper ls/search/types <ns>pull schemas on demand; the story's token countsstory.md:142, :274, "Zero-context discovery" (:298) one mcp config mcpx reads the standard mcpServersobject ("an existing config can be pasted in unchanged",internal/cli/commands.gostarterConfig); one daemon serves CLI, plugin,/v1,/mcpstory.md "One daemon per config" (:728) share endpoint with your tailnet mcpx daemon --address <ip> --port 8899on one host,MCPX_DAEMON_ENDPOINT=http://host:8899on clients (daemon.address,daemon.port,daemon.endpoint;internal/settings/registry.go:343-375). Nothing tailnet-specific; binding beyond loopback prints a one-time warning because the API is unauthenticated (internal/cli/root.go:198-202)story.md "One daemon, many clients" (:2092) corral scripts the named-script search path above; recipes ( mcpx recipes)story.md :641, docs/consumer.md corral APIs mcpx api tools --spec <url>/mcpx api call <op> --spec <url>turn an OpenAPI document into toolsstory.md "Specifications as tools" (:1685) corral binaries paths.adaptersdeclarations turn a CLI into MCP tools;mcpx adapter checkstory.md "Command-line programs as servers" (:1593) Caveat for the last two rows (Bump build/buck/preludes/buck2-prelude from
d956689tof12c8d1#102): adapter tools and OpenAPI operations are attached as
mcpserver.Extraand reachtools/listover/mcpandmcpx serveonly. They are not inmcpx ls, the
generated client or scripts, although story.md says an adapted binary "is callable from a script". The
home page may say "OpenAPI specs and CLI programs become MCP tools"; it must not say "call them from your
scripts" until Bump build/buck/preludes/buck2-prelude fromd956689tof12c8d1#102 / chore(deps): bump build/buck/preludes/buck2-prelude fromd956689to36464cf#83 land.Two story.md inconsistencies the pitch must not inherit: "OpenAPI documents as tools" is still listed
under## Proposedwithstatus: proposed(story.md:2562) although "Specifications as tools" (:1685) is
standard; and "Service installation" (:2498) still asks formcpx completions bash|zsh|fish, which has
shipped asmcpx completion(cmd/mcpx/main.go:144, used bypackage.nixpostInstall). Reported for
the compendium (🎨 Palette: Add ARIA labels and live regions to search panel #150); the home page should claim onlystandardfeatures. -
The name is crowded. At least six unrelated GitHub projects are called mcpx (lydakis/mcpx with its own
Homebrew tap, kwonye/mcpx published as@kwonye/mcpx, Codestz/mcpx, arcadeai-labs/mcpx, lwsinclair/mcpx,
thiagomendes/mcpx), and the unscoped npm namemcpxis a0.0.1-securityplaceholder (npm view mcpx).
This decides the agent-prompt design below.
Page anatomy (proposed, top to bottom)
| # | Block | Content | Notes |
|---|---|---|---|
| 1 | Intro | eyebrow + display lines + chips + 1-4 sentence paragraph | "Intro" below |
| 2 | Video | 10-20 s loop | "Video" below |
| 3 | Install | per-user command, system-wide command, download link, each with a copy button | "Install commands" below |
| 4 | Agent prompt | one of four prompts, copy button | "Rotating prompt" below |
| 5 | Example | static highlighted TypeScript, "run it" affordance | the runnable part is #156 |
| 6 | Why | three short columns: code mode / reclaim context / tame MCP | "Why copy" below |
| 7 | Next | two large links: Overview, Quick start (and a small "now what") | #157 |
Order is a judgement call: install and prompt sit above the fold because the notes' 30-second reader may
never scroll. An alternative puts "Why" at #2 and the video at #6; see Open questions.
Intro: "small title / small here-blocks / bigger word lines"
This is an interpretation of note line 34, to be confirmed:
- small title: an eyebrow (kicker) line above the headline in small caps, e.g.
MCP, in code mode. - small here-blocks: small inline chips or badges beside or under the headline, each a two- or three-word
fact:one config,fewer tokens,scripts you keep. Read as "little blocks that say here is X". - bigger word lines: two or three large display lines that carry the pitch on their own for someone who
reads nothing else, e.g.Tame MCP./Reclaim your context./Keep the scripts. - the paragraph (1-4 sentences) sits under them in body size. Draft, from
package.nixmetaand
AGENTS.md: "mcpx puts every MCP server on your machine behind one command. Agents discover tools when they
need them and call them from TypeScript, so tool schemas and intermediate results stay out of the context
window. What the agent writes is a script you can run again."
Why copy
Three columns, each a display line plus one sentence plus one link into the overview (#157):
- Code mode. Agents write TypeScript against a typed client instead of making one tool call per turn;
the result is a script in.mcpx/scripts/anyone can rerun (mcpx run shot-flow). - Reclaim context. Schemas load on demand: the story's whole task cost about 4,600 tokens, most of it
one deliberatemcpx types. Numbers must be the story's, re-measured per release (docs/release-runbook.md
"Per-release" step 2). "Smarter" is a claim, not a measurement; phrase it as "fewer tool schemas
competing for attention" and link the evidence page in the compendium (Phase 0: baseline, toolchain, dependencies, and small fixes #153) rather than asserting it. - Tame MCP. One
mcpServersconfig for every harness; one daemon other machines on your tailnet can
point at; OpenAPI documents and CLI programs become MCP tools too (served over MCP; not yet callable from
scripts, Bump build/buck/preludes/buck2-prelude fromd956689tof12c8d1#102). Copy for the tailnet line must not promise
more than exists: today it isdaemon.address/daemon.portplusdaemon.endpoint, nothing
Tailscale-aware, so write "point your other machines at one daemon (over Tailscale, WireGuard, a VPN)"
and link the remote-daemon page in level 2 (🎨 Palette: Add aria-labels to search and goto-line inputs #146).
Static TypeScript example
- Source: an excerpt of the story's two-screenshot script (story.md:196-234), not new code. Proposed excerpt
(about 12 lines; lines elided with// …): thetools.chrome_devtoolsbinding,new_page, the snapshot ->
uid->clicksequence with its comment "click needs that, not a selector", and the final
console.log. It shows the three things the pitch claims: typed calls, image bytes that never reach the
model, one printed line. - Warning: that script is Deno-specific. It calls
Deno.mkdirandDeno.writeFile; the generated
client's Deno shim for Bun/Node covers onlyDeno.args,Deno.env.get,Deno.inspectand
Deno.readTextFile(Sync)(internal/codegen/emit.go:348-390). Either the excerpt avoids those calls, or
the page labels it "Deno", or the script is changed tonode:fs(which Deno and Bun both support). - The snippet must be included from a real file that CI runs, not pasted into the page, so it cannot rot.
Needs an include directive in the generator (chore(deps): update rust crate actix-files to v0.6.10 - autoclosed #117). Docs checks run in CI; see the testing trackers under Bump github/codeql-action from 2 to 3 #91 (CI pipeline Bump golang.org/x/crypto from 0.16.0 to 0.17.0 in /sources/launcher #95, integration/environments Bump golang.org/x/crypto from 0.14.0 to 0.17.0 in /sources/chat #97)
(the lead will link it). - Highlight at build time (Shiki, or the generator's own highlighter), not client-side highlight.js, so the
page renders with JavaScript off and the agent twin (Update module github.com/jackc/pgx/v5 to v5.9.2 [SECURITY] #120) gets the same code fence. - A "run it" button belongs to Phase 1: events, storage, crash safety, and the identity store #156; this issue reserves the slot and a copy button that copies an
mcpx run/mcpx execcommand.
Download link
A single "Download" link to the latest GitHub release for the reader's platform needs releases first
(#158). Do not detect architecture from the User-Agent: macOS browsers report Intel on Apple Silicon.
Link to the release page (or a per-OS list) and let install.sh detect with uname. Until releases exist,
the link goes to the install page's nix section (#157).
Install commands and copy buttons
- Per-user:
curl -fsSL <short> | sh. The flags matter and should be on the page as written:-fmakes
an HTTP error fail instead of piping an HTML error page intosh;-sShides progress but keeps errors;
-Lfollows the redirect a short URL will almost certainly be. The script itself must wrap its body in a
function called on the last line so a truncated download runs nothing. Installs to~/.local/bin
(amd host fails at evaluation: no outputHashes for p2panda-core-0.7.1 #158). - "Read it first" variant, one click away (a disclosure under the command, not a separate page):
curl -fsSL <short> -o install-mcpx.sh && less install-mcpx.sh && sh install-mcpx.sh. - System-wide: see the next section. The note's
~in "~system-wide" is read as "roughly / the
alternative"; not a path.
System-wide install command: the notes' form is wrong
sudo $(curl <short> | sh) runs curl <short> | sh unprivileged in a command substitution, captures
the installer's stdout, word-splits and glob-expands it, and executes the result as a command under
sudo. Every progress line the installer prints becomes argv. It only works if the script is designed to
print exactly one command and nothing else, and even then quoting is lost to word splitting. It is not an
established pattern and it will surprise anyone who reads it.
| Command | Runs as root | Verdict | |
|---|---|---|---|
| A | sudo $(curl <short> | sh) |
whatever the script prints | least recommended: fragile (stdout is code), unusual, unreviewable; only viable if the script has a dedicated "print the install command" mode, and then it is a worse --system |
| B | curl -fsSL <short> | sudo sh |
the whole installer, including the download | the common pattern; simple; but runs the network fetch, archive extraction and checksum as root when only the final copy needs it |
| C | curl -fsSL <short> | sh -s -- --system |
only the copy into /usr/local/bin (the script calls sudo install -m 0755 ... itself, or doas) |
recommended: least privilege, one script with one flag, the same command shape as per-user, and the script can explain what it is about to escalate for |
Recommend C, with B shown under "other ways" for environments without sudo in the script's path (running
as root already, containers). --system is designed in #158. The install page (#157) shows the same two
forms, substituted from the same source, and never the notes' form.
Rotating prompt <subitem[rand(this.len)]>
- The four prompts, verbatim, not reworded:
hey please one-shot setup mcpx right now·hey install this mcpx thing and comment out all my mcp config
·replace mcp with mcpx codemode·guided install mcpx now plz. - Random choice client-side. All four are in the HTML; a few lines of inline script pick one per page
view (Math.floor(Math.random() * items.length)) and hide the rest. No-JS fallback: the first one shows
(or all four as a list). No server-side randomness: the site is static (fix(deps): update github.com/charmbracelet/ssh digest to ebfa259 - autoclosed #118) and a CDN would cache one
choice anyway. Optional: clicking the prompt cycles to the next. - The copy payload must carry a URL. Given the crowded name (Current state), an agent that has never
heard of this mcpx and is told "setup mcpx" will search and install one of the other six. So the copied
text is the prompt plus a line with the site's agent entry point, e.g.
hey please one-shot setup mcpx right now+ newline +https://<short>/llms.txt. The URL is visible
under the prompt in small text: copying text the reader did not see is a pattern used by clipboard
attacks and should not be normalised on an install page. This does not reword the prompts; it appends a
pointer. - What the URL must lead to (Update module github.com/jackc/pgx/v5 to v5.9.2 [SECURITY] #120, the bot home page with the install prompt built in, note line 6):
an agent-facing install procedure that handles each prompt's intent:- "one-shot setup": detect OS, install per-user, run
mcpx doctor, add the harness integration
(AGENTS.md / the opencode plugin), verify withmcpx ls. - "comment out all my mcp config": mcpx reads the same
mcpServersobject, and its config search path
already includes.mcp.jsonat every directory level (internal/config/config.go:561), which is Claude
Code's project file name. There is no importer for other hosts' files (opencode, Cursor, Claude
Desktop: no reference to their paths ininternal/), so the agent moves those entries by hand into
~/.config/mcpx/config.jsonor.mcpx.json, then comments them out of the harness config. The
procedure must say to back up first, and must warn that commenting out a project.mcp.jsonhides
those servers from mcpx too, so they move to.mcpx.jsonbefore they are commented out. - "replace mcp with mcpx codemode": the same, plus AGENTS.md or the plugin, so the agent stops calling MCP
tools directly (AGENTS.md "Do not" list). - "guided install": interactive; the agent asks before each step.
mcpx prompt(from Bump build/buck/preludes/buck2-prelude fromd956689to6f75473#41) is not usable
for this on first install: it needs a sampling answerer and configured recipes, neither of which exists
yet on a fresh machine (internal/cli/manual.gopromptDetail). The agent is the guide.
- "one-shot setup": detect OS, install per-user, run
Quick start and now what
Two large links to #157's overview and quick start, and one smaller "now what" into level 2 (#94).
Nothing else in the footer area competes with them.
Approaches: the short flex video
| Tool | Reproducible | Size | Notes | |
|---|---|---|---|---|
| A | screen recording (QuickTime, OBS) | no | large | least recommended |
| B | asciinema .cast + player |
partially | tiny | text, not video |
| C | charmbracelet VHS .tape rendered in CI |
yes | small | recommended |
- A, screen recording. Easiest the first time and wrong every time after: the CLI output changes, the
recording shows stale columns and tokens, and re-recording is manual. Large files, a real desktop
(notifications, fonts) in frame, and nothing checks it. - B, asciinema. Records a real terminal as a text
.cast(kilobytes), renders with the asciinema player
(JS), text is selectable, andaggconverts to GIF. Honest and small. But a recording is still captured
once by hand unless driven by a script, the player needs JS (no-JS fallback is nothing), and it plays
like a terminal, not a hero video. - C, VHS (recommended). A
.tapefile in the repo (Type "mcpx ls",Enter,Sleep 2s, ...) renders
to webm/mp4/gif with deterministic timing, fonts and size (Output hero.webm), and runs in CI through
charmbracelet/vhs-action. Re-render per release so the video never shows stale output; because it runs
the real binary against a fixture config, it doubles as a smoke test. The tape's commands are the agent
twin's transcript (Update module github.com/jackc/pgx/v5 to v5.9.2 [SECURITY] #120). Cost: VHS needsttydandffmpegin CI (both in nixpkgs), and the demo
needs fixture MCP servers that behave identically every run.
Embed rules regardless of tool:
<video muted loop playsinline preload="metadata" poster="hero.png">with a webm (VP9/AV1) source and an
mp4 (H.264) fallback. Not a GIF: typically several times larger for the same clip.- prefers-reduced-motion: the
autoplayattribute cannot be disabled from CSS. Omitautoplayand
start playback from a few lines of script only when
matchMedia('(prefers-reduced-motion: no-preference)').matches; otherwise show the poster with controls.
With JS off the poster and controls show. Pause when scrolled out of view (IntersectionObserver). - Budget: 10-20 s, at most ~1 MB for the webm, 1280x720 or smaller, captions not needed if every frame is
terminal text, butaria-labeldescribing the sequence. - Content: what the video shows is open (below). The story's two-screenshot flow is the strongest flex but
needs Chrome in CI.
Where the home page comes from (constraints on #117, not a second decision)
#117 owns the generator choice and currently recommends mdBook for the book plus one hand-written
index.html for the home page, because mdBook renders index.md as chapter one with a sidebar and has
no hero layout. Everything in this issue fits that shape. What the home page needs from it:
- One source for two outputs. The hand-written page and its agent twin (
index.md, Update module github.com/jackc/pgx/v5 to v5.9.2 [SECURITY] #120) drift
unless one is generated from the other. Prefer a small build step that rendersindex.htmlfrom a
markdown-plus-front-matter source (prompts, commands, paragraph), so copy edits happen once. - Include a file region into a code block, for the example and the install commands, so the page shows
the same bytes CI runs. - Build-time highlighting for the example (mdBook's own pages use client-side highlight.js; the home
page need not). - Copy buttons on arbitrary blocks, small inline JS, a
<video>element, all working or degrading
cleanly with JS off. - The
<short>values substituted at build from one place (Update github.com/tursodatabase/libsql-client-go digest to 9d5d30a #119), not typed into the page. - Shared CSS with the book or a deliberately different look is chore(deps): update rust crate actix-files to v0.6.10 - autoclosed #117's open question 4; the 30-second
path crosses from the home page into book pages, so at minimum header, fonts and colours should match.
Open questions
- Is the "small title / small here-blocks / bigger word lines" interpretation right?
- Hero order: install above the fold (proposed) or "why" first?
- Video content: the story's browser flow (needs Chrome in CI) or a fixture-only flow (
ls->search->
execprinting one line)? Is 10-20 s right? - Should the example be the story excerpt (Deno-specific today) or a runtime-neutral script?
- Copy payload: prompt +
llms.txtURL (proposed), or prompt + the human install page URL? - Should the page show a runtime prerequisite (deno, bun or node 22.6+ on
PATH;mcpx doctorfails
without one,internal/cli/doctor.go:47-60)? Releases outside nix do not bundle a runtime (amd host fails at evaluation: no outputHashes for p2panda-core-0.7.1 #158); the
container image ships bun. - Does Update dependency @playwright/test to v1.64.1 #79's
script.typecheckdefault change what the example's "run it" command prints on first run?
Ease · Impact · Related
Ease: M (design and copy; the template work is small once #117 is chosen; the VHS pipeline is
another S-M). Impact: high (the page most people will ever see).
Depends on / related: #117 (generator constraints above), #118, #119 (<short>),
#120 (copy payload target, bot home page), #156 (the run button), #157 (overview, quick start,
install page), #158 (download link, install.sh, --system), #150/#153 (story.md status
inconsistencies; evidence for "smarter"), #146 (remote daemon page), #41 (closed, fixed in #58: mcpx prompt, not a first-run
guide), #44 (closed, fixed in #53: plugin without the binary), #48 (other harnesses the prompts may land in), #79 (typecheck
default), #94 (level 2), #102 and #83 (adapter and OpenAPI tools are not in the script client).
Security/auth deferred; see tracker.
Activity
developing-today commentedon Oct 28, 2026
CODE-801
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#155 (verbatim, oldest first):
@dezren39 · 2026-09-30T07:20:20Z
Integration pass. Placed in the DAG rooted at #181.
@dezren39 · 2026-09-30T11:49:05Z
Issues pass (2026-09-30, at 05c78b2).
Containerfile:40. Since Phase 5: tag event bodies must travel with the event #182 apkgs/mcpx/Containerfilebuilds a local image, but none is published. The runtime-prerequisite open question notes that the image ships bun.d956689to880be56#53.registry.go:343-375andconfig.go:561. Addedroot.go:198-202for the one-time "API is unauthenticated" warning.d956689to6f75473#41 is marked closed, fixed in chore(deps): bump rustix from 0.38.3 to 0.38.21 in /build/nix/setup #58.dezren39 commentedon Oct 29, 2026
🤖 Agent note · done
Triage verdict (task 2768, 2026-10-29)
Not a duplicate. Neighbours checked: #1894 (level-1 30-second layer — parent tracker), #1888 (book tracker), #1947 (agent-markdown twin of every page + the bot home page carrying the install prompt — adjacent: #1874 owns the human home page and the four rotating prompt phrasings; #1947 owns the twin/bot rendering of them). No other open issue designs the home page itself.
Scope confirmed against current
pkgs/mcpxon main:docs/landing.mdexists (8,848 B) and is, as the issue states, a PR landing checklist — not a landing page;docs/story.md(118,058 B),package.nix(6,740 B),cmd/mcpx/main.go(6,032 B) all present. No home page or site exists. No scope correction needed.Dependencies (code numbering) gate the full build, not the content: site generator #1939 undecided; download/install channels in #1881 not yet built; short-domain/deploy pieces outstanding. The defect the issue flags in the notes — the system-wide
sudo $(curl <short> | sh)form not doing what it looks like — belongs to #1881's install-channels scope; it is recorded here so it is not lost, and is excluded from the follow-up below.Follow-up enqueued: queue task 3098 (
small_fix, deduperepo-health:v1:fix:developing-today/code:issue:1874) — the unblocked first slice the issue itself proposes: the home page content source (markdown + front-matter) underpkgs/mcpx/docs/— pitch/claims, intro, file-included TypeScript example, install commands with<short>as one build-time placeholder, and the four rotating agent prompts verbatim. Later slices named, not dropped: HTML/template + generator integration (#1939), the video pipeline, real install/download wiring (#1881).111 remaining items
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off