Skip to content

hive/web2: the web2 world as one tendril, wrepl - #95

Merged
adiled merged 3 commits into
mainfrom
hive/web2
Oct 25, 2026
Merged

adiled merged 3 commits into
mainfrom
hive/web2

Conversation

@adiled

@adiled adiled commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

hive/web2: the web2 world as one tendril, wrepl

web2 is an attendant serving one fixed tool, wrepl. A reach carries one command line, and every OpenAPI spec and MCP server web2.json names answers it as if it were a CLI. The thrum sees a tendril like any other: OpenAPI, MCP and OAuth stop at this hive, and a harness that takes tools only over MCP gets wrepl as one tool among bash and the forager's own.

help
github help pulls
github pulls/list rust-lang rust --state open --jq '.[].title'
sentry search-issues --query 'is:unresolved'

wrepl

  • help lists the services, <service> help [group | words] a service's commands, and <service> <command> --help a command's flags.
  • Flags come from each command's input schema, typed by it: --name value, --name=value, --flag / --no-flag, a flag repeated for an array. Words with no flag fill the required inputs in order. Spelling is forgiven across kebab, snake and camel case.
  • --json '{…}' gives the whole input, flags laid over it winning; --jq '<filter>' narrows a JSON result (jaq).
  • A mistake answers with what would have worked: did-you-mean for services, commands and flags, the missing required flags, the type a value should be.
  • An answer past maxOutput (32 KiB) keeps its start and its end, as bash does.

Services

  • OpenAPI 3 from a URL or a file beside web2.json, JSON or YAML: each operation a command named by its operationId, grouped by its first tag, its parameters and JSON body fields as flags, local $refs followed. The commands made from a spec are kept for a day, or until web2 refresh.
  • MCP over stdio or streamable HTTP, through rmcp 3.7: one connection per server, opened at first use, closed when idle, opened again when it drops, relisted when the server says its tools changed.
  • An mcpServers block pasted from any harness works as it is. web2 import copies in the servers Claude Code, Claude Desktop, Cursor, VS Code and Codex already know here.
  • web2.json is read again whenever it changes; a service added there is reached on the next call.

Reading and writing

  • A service only reads until web2.json says otherwise: writes, allow (write commands by name or glob, read-*), deny.
  • An OpenAPI operation reads when its method is GET, HEAD or OPTIONS. An MCP tool reads only when its annotations say readOnlyHint: true, as the MCP spec has it.
  • A refused call answers with the key that would turn it on, and a service's help counts what is off.
  • web2 allow, web2 deny and web2 review (each command that is off, turned on or left, one by one) edit web2.json in place, keeping its order, and refuse a change that would break it.

Signing in

  • Tokens live in secrets/credentials.json in web2's state directory, mode 0600 in a 0700 directory, never in an environment, a log or an answer. "env": "VAR" reads one from web2's environment instead.
  • web2 login <service>: a token at a prompt that does not show it, or --token-stdin; an OpenAPI oauth app through the authorization code flow with PKCE and a callback on 127.0.0.1, renewed before it expires; an MCP server's own OAuth, by its discovery and client registration, through rmcp.
  • A spec that names a scheme, with nothing stored, is called without credentials, so anonymous reads still answer; a 401 or 403 says how to sign in.

Not offered

  • No sampling, elicitation or roots. A tool that asks for input mid-call (input_required), or turns into a task, answers that wrepl does not follow it.
  • Legacy SSE MCP servers and Swagger 2.0 are refused with what to do instead.

The hive

  • Its own workspace, depending on thrum-core, hum-thrum and hum-paths only; humd is a dev-dependency, for the bee test.
  • Orchfile, build and install as the bash hive has them. Nothing goes on the PATH; the install prints where web2 is. web2 alone is the same REPL a bloom reaches, for a person at this machine.
  • One row in the hives catalogue.

Peers

Known limit, with its own change to follow

  • The tokens are as safe as the user web2 runs as, and bash on a builder runs as that user. They sit in secrets/ so the builder (soon shell) can keep its shells out of hum's secrets, bee keys included.

Verified

  • cargo test: 37 unit, 6 end to end against the real binary (an OpenAPI mock, an MCP server over stdio, one over HTTP with a bearer), 1 through a real humd: forager → humd → a nurse reaching wrepl → humd → web2 serve → an MCP server, and back, a config change mid-run included.
  • An OpenAPI OAuth sign-in and renewal against a mock token endpoint, the PKCE verifier checked against its challenge.
  • An MCP server's OAuth end to end against an authorization server shaped as the spec has it (protected resource and server metadata, client registration, PKCE, the issuer), then a call with the stored token.
  • web2 allow / deny / review against a real config, globs included.
  • cargo clippy --all-targets -D warnings, ./build (release, --locked), tools/speech.py.
  • Live: the Swagger Petstore (a relative server URL), GitHub's REST spec (1,242 commands; an anonymous repos/get in under a second), DeepWiki's MCP over HTTP.

web2 is an attendant serving one fixed tool, `wrepl`. A reach carries one
command line, and every OpenAPI spec and MCP server web2.json names answers
it as if it were a CLI: `help`, `<service> help`, `<service> <command>
--help`, then the call, with `--json` for a whole input and `--jq` to
narrow a JSON result. The thrum sees a tendril like any other; OpenAPI,
MCP and OAuth stop at this hive.

- Services: OpenAPI 3 from a URL or a file, JSON or YAML, with local
  `$ref`s followed; MCP over stdio or streamable HTTP through rmcp, kept
  warm and closed when idle, relisted when a server says its tools
  changed. An `mcpServers` block pasted from any harness works as it is,
  and `web2 import` copies in the ones this machine's harnesses know.
- A service only reads until web2.json turns writes on (`writes`,
  `allow`, `deny`). An MCP tool reads only when it says `readOnlyHint`.
- Tokens live in one 0600 file. OpenAPI OAuth signs in with PKCE through
  a callback on 127.0.0.1 and renews itself; an MCP server's own OAuth
  goes through rmcp. A spec's scheme with nothing stored calls without
  credentials, so anonymous reads still answer.
- No sampling, elicitation or roots are offered; a tool that asks for
  input mid-call, or turns into a task, answers that wrepl does not
  follow it.
- web2.json is read again when it changes, and every reach is answered,
  a broken config and a panic included.

It installs nothing on the PATH; `web2` alone is the same REPL a bloom
reaches, for a person at this machine.
…s tested

- `allow` and `deny` take globs (`read-*`). `web2 allow`, `web2 deny` and
  `web2 review` edit web2.json in place, keeping its order, and refuse a
  change that would break it; a service's help counts what is off. Most
  MCP servers do not say which tools only read, so turning theirs on is
  now one line at a terminal.
- Tokens move to `secrets/credentials.json`, a 0700 directory, the one a
  builder's shell is to be kept out of.
- `redirectPort` sets where a sign-in comes back to, and `WEB2_BROWSER`
  the program a sign-in link is handed to.
- The MCP sign-in is tested end to end against an authorization server
  shaped as the spec has it: protected resource metadata, server
  metadata, client registration, PKCE and the issuer, then a call made
  with the stored token.
A reach from a peer humd carries the peer's `from` (#96), and web2 refuses
it unless web2.json says `servePeers: true`: what web2 is signed in to is
this machine's, lent to a peer's blooms only when a person says so. With
the peer's humd trusting remote attendants, that is the two opt-ins a
peer's bloom needs.
@adiled
adiled merged commit 1155cd7 into main Oct 25, 2026
7 checks passed
@adiled
adiled deleted the hive/web2 branch October 31, 2026 13:25
adiled added a commit that referenced this pull request Oct 31, 2026
web2 was left out of release.sh's lockstep list when it landed (#95), so it stayed at 0.1.0 while every other hive moved with Cargo.toml. Its version is what the bee announces (BEE_VERSION), what its MCP client names itself, and its user-agent, so it reported 0.1.0 everywhere. It now carries 0.34.0 and release.sh bumps it with the rest.
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