Skip to content

MCP authorization moves into /mcp, and the callback page gets the brand - #334

Merged
TheGreatAxios merged 4 commits into
mainfrom
cl-5555-mcp-auth-belongs-in-mcp-not-the-transcript
Aug 7, 2026
Merged

MCP authorization moves into /mcp, and the callback page gets the brand#334
TheGreatAxios merged 4 commits into
mainfrom
cl-5555-mcp-auth-belongs-in-mcp-not-the-transcript

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Collaborator

Closes CL-5555 and CL-5556.

/mcp owns authorization now

A remote MCP server needing OAuth dumped a raw authorization URL as a transcript row at session start — unactionable, uncopyable, and gone once it scrolled away.

  • needs-auth no longer writes a transcript row. The transient notice row carries a standing segment naming the servers (mcp granola needs auth (/mcp)) that clears when they connect. Nothing blocks usage; an unauthorized server just has no tools.
  • /mcp becomes a real list surface over every configured server and its live state: connected + tool count, needs auth, failed + reason.
  • Enter on an unauthorized row opens its authorization page in the browser and copies the link, which is what makes it work over SSH.
  • The old /mcp text dump and its getMCPServers command context are gone.

The callback page

The page a provider redirects back to was a browser-default serif on white. One shared callbackPageHtml now serves it for MCP servers and inference providers alike:

  • Terminal palette verbatim from tui-opentui/theme.ts, light scheme via prefers-color-scheme.
  • The mark animates through the same dithered draw/fill timeline as the TUI landing, as an ordered Bayer dither over a travelling sine. Still and filled under prefers-reduced-motion.
  • Headline names the outcome: "Linear connected successfully" / "Granola failed to connect". Server names and error codes are humanized, so no access_denied reaches the page.
  • Entirely inline — a local authorization callback makes no network call.

Also

openListOverlay can suppress its chose (kind): label transcript echo. /mcp opts out: the echo quoted the row's pre-authorization label back permanently, moments after the operator authorized it.

Verification

bun run typecheck, bun run build, bun test — 4313 pass, 0 fail. The notice-row path is asserted against a real painted frame in the headless harness. The callback page was reviewed in a browser.

A remote server that needs OAuth dumped a raw authorization URL as a
transcript row at session start: unactionable, uncopyable, and gone once
it scrolled away.

Needs-auth now takes a standing segment on the transient notice row
("1 mcp needs auth (/mcp)") that clears when the server connects, and
/mcp becomes a real list surface over every configured server and its
live state. Enter on an unauthorized row opens its authorization page in
the browser and copies the link, which is what makes it work over SSH.

The old /mcp text dump and its getMCPServers command context go away.
A bare count sent the operator to /mcp to find out which server it meant,
and with more than one configured it read as a claim about whichever
server they saw there first. The segment now names them, and only falls
back to counting past the second.
The page a provider redirects back to was a browser-default serif on
white saying "Authorization complete" — the only web surface this product
has, and the last thing an operator sees before coming back to the
terminal. One shared renderer now serves it for MCP servers and inference
providers alike, on the terminal's own palette, with the mark animating
through the same dithered draw/fill timeline as the landing. The headline
names what happened: "Linear connected successfully", "Granola failed to
connect". Server names and OAuth error codes are humanized on the way in,
so nothing reaches the page in snake case. Everything is inline — a local
authorization callback has no business making a network call.

Accepting an overlay row also appended "chose (kind): label" to the
transcript, which on /mcp quoted the row's pre-authorization label back
permanently: "granola — needs auth", moments after authorizing it.
openListOverlay can now suppress that echo, and /mcp does, since its
flash already reports the outcome.
@linear-code

linear-code Bot commented Aug 7, 2026

Copy link
Copy Markdown

CL-5555

CL-5556

@TheGreatAxios
TheGreatAxios merged commit 7e5a118 into main Aug 7, 2026
2 checks passed
@TheGreatAxios
TheGreatAxios deleted the cl-5555-mcp-auth-belongs-in-mcp-not-the-transcript branch August 7, 2026 02:20
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