Repository navigation
fix(app): name the MCP tool and its input in the permission dock - #60548
Conversation
MCP tools ask with resources ["*"] and have no permission description, so the web and desktop dock showed a bare *. Show the action when there is no description, hide a lone *, and list metadata.input as key: value lines cut at 200 chars.
There was a problem hiding this comment.
The fix works: rendered with the request from #51519, the dock now shows the tool name (demo_greet) and its arguments, where the base shows only *. Requests that have a description and real resources (e.g. edit) look the same as before. A built-in action without a description (e.g. shell) now shows its name as the hint line.
I could only check the dock component on its own, rendered in a simulated DOM (happy-dom), because Chromium can't launch in my sandbox. The e2e test didn't run there and I couldn't take screenshots. Could you add before/after screenshots of the dock for an MCP call? tsc --noEmit in packages/app is clean.
Public API: unchanged (UI component only).
One concern, inline: the tool's arguments go into the same list as the resources while the * is hidden, which hides what "Allow always" actually covers.
| <span data-slot="permission-spacer" aria-hidden="true" /> | ||
| <div data-slot="permission-patterns"> | ||
| <For each={props.request.resources}> | ||
| <For each={[...resources(), ...input()]}> |
There was a problem hiding this comment.
Mixing the input lines into the resource list, and hiding *, changes what the list tells users. For MCP calls, "Allow always" saves save: ["*"], so it approves every future call of this tool with any arguments. But the list now shows only this call's arguments (e.g. issueId: ENG-1), which reads as if "Allow always" covered just this call. Could the input go in its own row (or block), separate from the resources, and could the dock keep showing the scope of "Allow always"? You could also show the * only when there is no input.
There was a problem hiding this comment.
Good catch. With the * hidden, Allow always looked scoped to this call. The input now has its own row. The resources row is back as it was. So the * still shows. The e2e test checks both.
Allow always saves the wildcard for MCP tools, so the resources row stays as it was and the call input gets its own row.
There was a problem hiding this comment.
The earlier point is fixed: the arguments now have their own row, and the resource list still shows *, so it stays visible that "Allow always" covers every call of the tool. I re-rendered the dock in a simulated DOM (happy-dom): the MCP request shows the tool name, the argument lines, then *, and tools with a description look as before. tsc --noEmit in packages/app is clean.
Public API: unchanged.
No new concerns.
|
Congrats on getting this moving — I'd opened the same fix (#60740, closed as a duplicate of this). Two things from testing the equivalent change in production that this PR doesn't cover yet:
On the input rendering: cutting each line at 200 chars truncates longer object args; a max-height + scroll (as in the session-ui patterns row) shows the full arguments without crowding the card. Either way, glad this is moving. |
Thanks, and sorry yours got closed as the duplicate!
|
e108d22 to
ccba959
Compare
There was a problem hiding this comment.
The new commit works, and the * (the scope that "Allow always" saves) is still shown next to the input. I re-rendered the dock in a simulated DOM (happy-dom). An MCP request now shows the tool name, the hook's message, the full arguments in their own row, then *. Tools with a description look as before. tsc --noEmit in packages/app is clean. I couldn't run the e2e test here because Chromium can't launch in my sandbox.
Public API: unchanged (the dock only reads the existing PermissionRequest.message).
No new concerns.
…ion dock The user approves these arguments, so long ones scroll inside the dock instead of being cut at 200 chars. A message set by the permission evaluate hook now shows as a hint row under the tool name.
ccba959 to
dc3fde9
Compare
|
Pushed a small follow-up so this can land (a6a23fd):
Typecheck is clean, |
There was a problem hiding this comment.
The latest commit still works. I re-rendered the dock in a simulated DOM (happy-dom): an MCP request shows the tool name, the hook message, the full arguments, then *, and built-in tools render as before. tsc --noEmit in packages/app is clean. I couldn't run the e2e test here because Chromium can't launch in my sandbox.
Public API: unchanged.
One thing for maintainers: the CSS now makes the permission header title and the description text 13px instead of 14px. That applies to every permission dock, not only MCP calls, so a before/after screenshot of an existing prompt (e.g. edit) would help. Otherwise no new concerns.




Issue for this PR
Closes #51519
Type of change
What does this PR do?
MCP tools ask with
resources: ["*"]and have nosettings.permissions.tool.<action>.description. So the web/desktop dock shows only*. You can't see which tool is asking or what it will do.The dock now shows the action when there is no description. It also shows
request.messagewhen thepermission.evaluatehook sets one. It listsmetadata.input(sent since #51062) askey: valuelines in their own row. Long arguments are not cut: the row scrolls once it is taller than 160px, because the user is approving these exact arguments. The resources row is unchanged, so the*still shows what Allow always covers. Tools with a description look the same as before.The TUI also drops
request.message. I'll fix that in a separate PR.How did you verify your code works?
e2e/regression/session-request-docks.spec.ts. It fails ondevand passes with the fix. It checks the tool name, the hook message, the full input, that a long input scrolls inside the dock, and that the*is still shown.bun run test:e2e -- e2e/regression/session-request-docks.spec.ts --project chromium: 6 passedbun typecheckinpackages/app: no errors;bun run check(pre-push): passedmessage(screenshots below)Screenshots / recordings
Before:

After (MCP call, no description):

After (long input with a hook message, scrolls instead of being cut):


Visual
Checklist
Added by the opencode bot (AI-generated).
Related: #60350, #50234