panel_list
Lists the panels open in this project.
Returns each panel's id, kind, title, URL, and which agent drives it. Agents are told to call it before opening a browser panel, since one may already be open.
No arguments.
Every agent panel gets two Model Context Protocol servers. They let an agent open a page, put a command in front of you, hand a tangent to a second agent, add to your Next list, and keep notes it can read back later. This page is what they do, and what they will not do.
Checked against Quay v0.17.0. If this page and the app disagree, the app is right, and I would like to hear about it.
These are properties of the tools, not promises about how an agent behaves. There is no argument that turns any of them off.
This one drives a browser panel. It is stockPlaywright MCP, pinned at 0.0.80, pointed at a Chrome DevTools Protocol endpoint Quay opens on loopback: a random high port with a token good for one panel, bound only while that panel is armed. The tools are Playwright's own, and its docs cover them. The pin is deliberate. 0.0.80 renamed one of the arguments, and letting the version float would break skills written against these tools without warning.
Quay's part is the boundary around it: which panel those tools reach, and who decided they could.
When an agent calls panel_open_browser, one function settles what actually happens. There are three outcomes.
| Purpose | Origin | What Quay does | Agent can read it |
|---|---|---|---|
| display | Anywhere | Opens in your browser session. Not pinned, not armed. | No |
| drive | Loopback only | Pinned to loopback and armed to the agent that asked, with no click from you. | Yes |
| drive | Anywhere else | Opens unarmed. The agent is told why, and told to ask you. | No |
Display panels are not armed even on loopback, where arming would have been allowed. Arming is what makes a page readable, and a display panel is not being read.
Arming points an agent's browser tools at one panel. You do it from that panel's toolbar, with the pointer icon. Until you do, the tools have nothing to connect to, and an agent that tries is told to ask you rather than handed an error it can learn nothing from.
Loopback origins are the exception:localhost,127.0.0.1,[::1] and*.localhost can be opened and driven without asking. That is how an agent checks its own work against your dev server. The test reads the URL's parsed host rather than the text, sohttp://localhost@evil.com is a public host, and so is a public host withlocalhost somewhere in its path.
A loopback page's own cookies are readable, including your logged-in session on your own dev app. That is the point of it: an agent checking a signed-in dev build has to be able to see it. What stays out of reach is every other site you are signed into in that identity — your mail, your code host, your billing. If an agent needs to see one of those, you arm that panel yourself, one panel at a time.
It cannot be written to disk, and a test enforces that. Browser panels come back when Quay reopens, still signed in, so an armed flag that survived a restart would hand an agent a page you never re-approved. Arming ends:
One agent drives one page. Arming a second panel for the same agent disarms the first and closes its endpoint, so an agent never holds two live views at once.
The second server opens panels, proposes work, and keeps notes. Eight tools. The sentence every agent reads when it starts: it can create, propose, record and recall its own work; it never signs in as you and never runs a command.
Lists the panels open in this project.
Returns each panel's id, kind, title, URL, and which agent drives it. Agents are told to call it before opening a browser panel, since one may already be open.
No arguments.
Opens a page, either to show you or to read.
The purpose argument decides which kind of panel it is, before the panel exists. Opening a second page reuses the panel the agent already opened instead of stacking up new ones.
Types a command into a shell and stops.
The command lands at the prompt and sits there. You run it, edit it first, or delete it. It is meant for things an agent cannot hold open for you, like a dev server.
Proposes a second agent for a tangent.
The agent writes the brief itself, because the brief is what the new session starts from. You see it, you can edit it, and you confirm before the panel exists. The call returns once you have been asked, so the agent never finds out what you chose and cannot sit there waiting on it.
Proposes something for your Next list.
For work that came up and should not be lost, but is not the job at hand. The modal opens prefilled and editable, and nothing is saved until you confirm. Like the agent panel, it returns as soon as you have been asked.
Three of the eight tools cover Quay Memory: the notes agents keep about their own sessions, so a new session starts out knowing what the last one learned instead of working it out again.
Every other tool that changes something proposes first.memory_capture saves straight away. The line is between your intent and the agent's own record: a memory card is an agent reporting what it just did, and Quay already saves one unconfirmed when a session ends. Two things keep that safe. A newer card supersedes an older one on screen while the older one stays in history, so nothing is lost. And writing a card does not mark the agent as waiting on you, so a session that is still running cannot look finished.
Writes down what the session worked out. Saves immediately.
Meant for the moment something gets decided, ruled out, or discovered, rather than as an end-of-session log. A new card replaces the thread's previous one instead of adding to it, so the agent writes the whole picture each time and the old cards stay in history.
Searches what earlier sessions here figured out.
A question in plain words rather than a grep: “where did we decide how account migration works”. Returns a handle, a title, and the excerpt that matched, never whole cards. Agents are told to check here before re-deciding something or re-investigating a trap.
Reads one card in full.
The whole note a session wrote: objective, status, decisions, gotchas, files touched. The search excerpt exists so an agent can pick the one or two that matter instead of pulling all of them.
Some calls are turned down by design. Each one answers with a sentence rather than a protocol error, because an agent told “method not found” learns nothing and tries again, while an agent told where the boundary is can do something else. Usually that means asking you.
panel_close
“The user closes their own panels — ask them to close it rather than closing it for them.”
Target.createTarget, Target.closeTarget, Browser.close
“This endpoint is one Quay panel; open a new panel yourself.”
Navigating a pinned panel off loopback
“This panel is pinned to loopback origins and cannot navigate there; ask the user for a browser panel they arm themselves.”
There is none. Both servers are set up per panel when the agent starts: Quay mints a token good for that one panel and hands it to Claude Code or Codex in the form each expects. Nothing to install, nothing to add to a config file, and no token that outlives the panel it was made for. Agents started outside Quay have neither server, because neither exists until a panel does.
← All docs