[DESK-30518][DESK-28302] - Stop Claude Desktop asking to approve Beeper over and over - #4
[DESK-30518][DESK-28302] - Stop Claude Desktop asking to approve Beeper over and over#4iFixRobots wants to merge 1 commit into
Conversation
|
| '--transport', | ||
| 'http-only', | ||
| '--allow-http', | ||
| '--static-oauth-client-metadata', |
There was a problem hiding this comment.
Latent · --allow-http passed unconditionally allows plaintext OAuth to non-localhost URLs
--allow-http is passed on every invocation. Upstream mcp-remote 0.8.3 only requires this flag for non-localhost, non-HTTPS URLs (it already allows http for localhost); it refuses other http URLs otherwise ("Non-HTTPS URLs are only allowed for localhost or when --allow-http flag is provided"). The old vendored proxy had the same guard (src/lib/utils.ts:760) and never passed --allow-http. So this is a behavior broadening: if a user sets BEEPER_DESKTOP_BASE_URL (exposed via manifest user_config) or the first-arg URL to a non-localhost http:// host, the old build errored but the new build silently proceeds and sends the OAuth flow/tokens over plaintext. It's unneeded for the default localhost URL, so consider dropping it or gating it on a localhost host check.
|
I've reviewed the PR. It's a clean refactor: verified the typecheck, the bun bundle, and a runtime smoke test (args forwarded with One latent finding, posted above: Want me to fix that (drop |
51e41a8 to
7c56868
Compare
…er over and over Replace the copied mcp-remote sources with a thin layer over upstream 0.8.3 that runs in-process: apply the Beeper defaults, rewrite argv, exit when the launching process is gone, complete Beeper's sign-in over loopback instead of a browser, then import upstream's CLI.
7c56868 to
e767cf7
Compare
|
@mattwondra - I could use your eyes to make sure I'm not doing anything super bad here, but I've tested this pretty extensively and I'm covering both upgrades and new setups. The only thing I'm not checking is whether they are downloading the extension while having an older client, but I'm not taking that into consideration. |
Problem
Claude Desktop users keep getting Beeper's "Approve connection" dialog, approve it, and get it again minutes later. Two rageshakes show the same shape: Beeper issues the code, and nobody ever calls the token endpoint.
This extension is a September 2025 copy of upstream
mcp-remote0.1.29 with our defaults patched in, and it has two defects that feed each other:Upstream fixed the first class in August 2026 (#302, #326, #340, #307, #348) and rewrote the coordination behind the second (#325, #262, #315, #329, #330, #331). None of it ever reached us.
Fix
Stop carrying a copy of upstream.
@beeper/mcp-remoteis now a thin layer overmcp-remote0.8.3, bundled into one file at build time:src/setup.tsapplies the Beeper defaults (URL, the client name shown on the dialog, read and write scope, config dir), rewritesprocess.argv, and exits the moment the process that launched it is gone. That last part is ours: upstream still only wires its shutdown hooks after login, so without it a stuck sign-in can leave a proxy behind holding the callback port.src/authorize.tsis what upstream gets when it imports its browser opener (aliased inbuild.ts, upstream's code untouched). For an authorize URL on the configured Beeper origin it does what the consent page used to do, in-process: posts the authorization request to Beeper's callback endpoint, waits for the approval, hands the code to its own loopback callback, and opensclaude://to bring Claude back. No browser tab, no page; Beeper's approval dialog is the whole experience. Anything else still goes to the real opener, so Codex, Cursor and Claude Code keep their browser flow and see Beeper's consent page.src/proxy.tsimportssetupand then upstream's CLI, so everything runs in one process. Everything undersrc/lib, the copied client, the custom pages and the tests go away; updating upstream is a version bump from here on.In-process is not a style choice. Claude Desktop 1.44 runs node extensions inside its own Electron helper, where
process.execPathis Claude's binary and cannot be turned into node. Spawning it launches Claude's helper as an app ("Unable to find helper app"), which shows up as a crash loop and a string of keychain prompts.The default URL is now
http://127.0.0.1:23373, matching what Beeper's own Copy Command hands out and what Beeper advertises as its OAuth resource.Verified against a dev build of beeper/beeper#4685 with the real Claude Desktop 1.44 and Codex: a clean install through Beeper's Download Extension button (zero consent page loads, one dialog, code exchanged 13 ms after Approve), an update from the currently published build (exactly one dialog-only sign-in, because the old build's token folder is not reused), a token revoked mid-session (one dialog, login completes in place, prompt answered, no extension restart), and a Beeper restart under a live session (no dialog). Against a stand-in endpoint the same build also passes the lifecycle checks: a proxy left waiting at the approval exits within two seconds of its parent dying.
A security pass over the wrapper also dropped
--allow-http(upstream already allows plain http for loopback; anything else has to be https), limited the in-process sign-in to the configured Beeper origin so a foreign authorization server gets the browser flow instead, and made the post-sign-inclaude://hop a fixed value rather than something read back from the URL.Users also pick up upstream's year: token files written 0600 instead of world-readable, the callback server bound to 127.0.0.1 instead of every interface, the Windows callback host fix, SDK 1.25, and the newer flags. Existing installs sign in once more after updating. Version 0.1.1.
Needs https://github.com/beeper/beeper/pull/4685 first: without it upstream refuses Beeper's metadata at startup.
Fixes DESK-30518
Fixes DESK-28302