VayuPress Docs

ADR-0147 — One page per client; VayuMCP keeps the protocol

Status: Accepted (shipped in v3.15.87) Date: 2026-07-28 Deciders: VayuPress core

Context

/os/connector (VayuMCP, ADR-0139) grew to carry four "Connect a client" accordions: one-click Connect on claude.ai, Claude Desktop, Claude Code CLI, and a proxy/WAF reference. Then ADR-0146 added Buzz, and the obvious next move was a fifth.

That shape has two problems, and they get worse with each client added.

It makes a page about a protocol spend most of its height on one vendor. A reader connecting Cursor scrolled past three Claude sections to find the generic JSON they needed — which was never given its own block, only implied by the Claude Desktop example.

It buries the best route. The one-click path needs no key at all: Claude signs in through this site's own OAuth 2.1 server and the operator approves a scope on screen. There is no token to leak, paste wrongly, or forget to revoke. It was one of four equal-looking accordions.

The Buzz page (ADR-0146) had already demonstrated the alternative: a client gets its own page, in the Monetization design language, walking one audience through one setup. It worked, and it left /os/connector with a Claude section that was now the odd one out.

Decision

Each client with a non-trivial setup gets its own page. /os/connector keeps the endpoint, the grants, the generic configuration, the proxy reference and the list of connected clients.

  • /os/claudecodeClaude Code (new). Three routes in, best first: one-click on claude.ai (open by default, marked Recommended, needs no key), then the Claude Code CLI command, then the Claude Desktop config block.
  • /os/buzz — Buzz agents (ADR-0146, unchanged).
  • /os/connector — the protocol surface, plus signposts to both.

VayuMCP remains the name of the connector. These pages are named for the clients they configure, exactly as the Buzz page is. Nothing is renamed to "Claude Connector" — the naming rule in the contributor notes is about what the connector is called, not about whether a client may have a setup page.

Shared scaffolding, not a third copy

Two pages doing the same job would have meant two copies of the same mint-key-then-fill-the-snippet controller; the Claude page would have made three, and they drift the first time one is fixed. admin_os_mcpclient.go now holds the mechanism once — element IDs, token banner, stat strip, grant tile, snippet renderer, controller — and each page carries only its own prose and capability presets.

The snippet contract changed with it. The old script rebuilt two specific blocks by id from a data-endpoint attribute, so every new snippet had to be taught to the function or it silently kept its placeholder. Snippets now carry their own template in data-tpl with a __KEY__ marker, and the controller rewrites whatever it finds. /os/connector was moved onto the same mechanism.

Two pages, two different defaults — deliberately

The Buzz page leads with Author; the Claude page leads with Full control. That is not an inconsistency to be tidied away:

  • A Buzz agent sits in a shared channel and acts for more than one person, so the safe grant should be the one that looks like the default.
  • The Claude page's common case is an operator connecting their own assistant to their own site, where the point is that it can do the work.

Both are pinned by tests, in both directions, so neither can be "fixed" to match the other without the reason being reconsidered.

Counting

Each page counts only the keys it minted, by label prefix (Claude …, Buzz agent …). A key granted to Claude is not a Buzz agent; an operator auditing which clients can reach their site needs them separated rather than summed. A test asserts the two do not cross-count, including that a Claude full-control key does not raise the warning tone on the Buzz page.

Consequences

Good. Each audience gets a page that is entirely theirs, and the keyless route is now the first thing a Claude operator sees. /os/connector finally has a generic configuration block of its own instead of implying it through a vendor-specific example. Adding the next client is a new file plus a nav card, not another accordion on a crowded page.

The split has to stay split. The risk is a well-meaning edit re-adding Claude instructions to /os/connector, leaving two copies to drift. A test asserts both halves: the page must link to /os/claudecode and /os/buzz, and must not contain claude mcp add or claude_desktop_config.json.

Access. /os/claudecode mints API keys, so it joins connector, apikeys and buzz in osPathMinLevel's admin list. Verified by removing the entry and watching the gate test report level 1 instead of admin — without it the page would have inherited the permissive author default.

No new surface. Same as ADR-0146: no dependency, no secret, no outbound path, no backend route beyond one authenticated GET. Minting still goes through the existing CSRF-protected API-key endpoints.

References

  • ADR-0139 — VayuMCP connector
  • ADR-0140 — VayuMCP OAuth 2.1 (the one-click route)
  • ADR-0146 — Buzz connector, and the per-client page precedent
  • The VayuOS page design house style, in the contributor notes