Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions docs/dao-mcp-server-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,12 @@ When an external lease is active, Dao Agent may continue non-browser work and
chat, but browser tool calls fail with `AGENT_CONTROL_BUSY`.

When Dao Agent is completing a browser tool call, external authorization waits
for that call to finish before acquiring the lease. The transport admits only
one external socket; a second external connection is closed before MCP
initialization. `LEASE_BUSY` applies when the admitted external client cannot
acquire the shared automation lease.
for that call to finish before acquiring the lease. The service keeps up to 32
external clients admitted; when another completes `hello`, the least recently
active idle client (no pending approval or tool call) is closed and its leases
are released so the newcomer is admitted, and `TOO_MANY_CLIENTS` is returned
only when every admitted client is busy. `LEASE_BUSY` applies when the
admitted external client cannot acquire the shared automation lease.

#### Browser Tool Executor

Expand Down Expand Up @@ -438,6 +440,7 @@ request.
Required stable errors include:

- `MCP_DISABLED`
- `TOO_MANY_CLIENTS`
- `AUTHORIZATION_DENIED`
- `AUTHORIZATION_TIMEOUT`
- `AGENT_CONTROL_BUSY`
Expand Down Expand Up @@ -470,9 +473,10 @@ tool-result errors rather than falsely reporting success.

- Dao Agent and external Agent cannot hold the lease concurrently.
- An in-flight tool completes before a lease changes owner.
- A second external socket is rejected by the one-client transport admission
gate; an admitted external client blocked on the shared lease receives
`LEASE_BUSY`.
- Beyond 32 admitted external clients, the least recently active idle client
is evicted and its leases released; when none is idle the newcomer receives
`TOO_MANY_CLIENTS`. An admitted external client blocked on the shared lease
receives `LEASE_BUSY`.
- Denial, approval timeout, revoke, disconnect, and toggle-off release state.
- Browser, Profile, and tab destruction never cause last-active fallback.
- User interaction remains available outside brief per-operation tab locks.
Expand Down
2 changes: 1 addition & 1 deletion docs/feature-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ Flagship feature. C++ services + `dao://dao-agent` WebUI + vendor runtime.
| ☐ | Scoped query, guarded click, and cursor-based network wait | `src/dao/.../automation/dao_{page,devtools}_tools.{h,cc}`, `dao_browser_automation_session.h`, `dao_agent_ui.{h,cc}`, `agent_bridge.ts`, `browser_tool_catalog.json` | 🟡 | Run `DaoMcpPageToolsBrowserTest.QueryElementsSupportsGuardedClick`, `DaoMcpPageToolsBrowserTest.QueryElementsRejectsStaleRefScope`, `DaoMcpDevToolsBrowserTest.WaitsForMatchingNetworkJsonAfterCursor`, `browser_tool_catalog.test.ts`, and `agent_bridge_call_native.test.ts`; verify a scoped exact semantic query returns one result plus document/snapshot/ref tokens, a ref scope accepts only its source document/snapshot tokens, a matching guarded click succeeds atomically, changed text or stale tokens fail without clicking, network tracking returns a cursor, and a later matching JSON response returns only selected paths plus the next cursor |
| ☐ | Sequential Agent browser batches, guarded filling, real keys, and semantic waits | `automation/dao_page_tools.{h,cc}`, `resources/agent/{pi_tool_adapter,agent_bridge,dao_chat_view}.ts`, `browser_tool_catalog.json` | 🟡 | Run `DaoMcpPageToolsBrowserTest.FillByRef*`, `DaoMcpPageToolsBrowserTest.KeyChord*`, `DaoMcpPageToolsBrowserTest.WaitForElement*`, and focused adapter/catalog/bridge/chat WebUI tests; verify bundled runtime ordering and later-browser-action skips after execution, legacy error-only results, or argument-validation failures; stale/readonly/redirected-focus fill rejection; synthetic cancelable beforeinput handlers can reject both replacement and clearing with the old value retained and no input event; handler changes to focus, readonly/disabled state, input type, role preconditions, or target attachment fail closed; handler selection changes still allow complete replacement and clearing with trusted input events; Cmd+A matches cmd+a without implicit Shift, while explicit Shift and standalone uppercase letters remain intact; macOS Cmd+Left/Right moves to line boundaries, Cmd+Up/Down moves to document boundaries, Shift variants select, Cmd+Backspace deletes to the line start, and Cmd+Z/Shift+Z undo/redo; Enter submission and Tab focus movement; cancellation and timeout during a slow keydown handler still deliver keyup to the original target without affecting a newly active tab; exact-count waits including removal, timeout without invalidating refs, cancellation/navigation cleanup, and native bridge wait budgets beyond the default 15 seconds |
| ☐ | Session-scoped Agent/MCP DevTools tools | `src/dao/.../automation/dao_devtools_tools.{h,cc}`, `dao_devtools_client.{h,cc}`, `dao_browser_automation_session.{h,cc}`, `dao_agent_ui.cc`, `agent_bridge.ts`, `browser_tool_catalog.json` | 🟡 | Run `DaoMcpDevToolsBrowserTest.*`, the Page/Tab MCP regression filters, `agent_bridge_call_native.test.ts`, `pi_tool_adapter.test.ts`, and `dao_chat_view.test.ts`; verify enable-window staging commits only after a matching generation/host success, cancellation/failure/rebinding drops pending staging, clear removes committed and pre-clear staged events while preserving the pending attempt and later events, monotonic same-binding domain confirmation across reordered success/failure, aggregate network/console byte budgets below entry caps, UTF-8-safe truncation, strict current-tree `(frame, URL)` size preflight before content fetch, an independent response-size backstop, exact in-budget base64, failed/oversized Script and Document search incompleteness, item/URL-byte/depth/dedup/source/4 MiB scan limits, re-entrant resolver/command destruction, exactly-once cancellation, and target/host/origin/document rebinding |
| ☐ | Default-off process-global local MCP server | `src/dao/.../mcp/dao_mcp_{service,transport,connection,protocol,runtime_files}.*`, `dao_pref_names.*`, `browser_prefs_mcp.cc.patch`, `chrome_browser_main_extra_parts_profiles.cc.patch` | 🔴 | Run `DaoMcpServiceBrowserTest.*`, `DaoMcpProtocolTest.*`, and `DaoMcpRuntimeFilesTest.*`; verify browser-IO-thread listener ownership, owner-only runtime permissions, nonce rotation, same-UID authentication, protocol/version/line limits, 64-request/8 MiB per-connection and bounded aggregate unconsumed-ingress credits, terminal-request logical closing before later same-batch tools, aggregate write backpressure, bounded graceful-close drains, 32-client admission, serialized approval prompts, concurrent different-tab control, same-tab exclusion, idle hello/catalog discovery beyond the approval timeout without a prompt or disconnect, exact last-active-window selection and approval on the first tool call, required first-call `reason` in every MCP tool schema, missing/blank/invalid/oversized reason rejection before approval, optional subsequent reasons stripped before execution, pre-approval catalog access even when connection begins on Dao Settings, re-entrant approval cancellation denial, approval plus lease ordering, cancellation, optional non-tab `tab_id` schema/routing, isolated concurrent tab contexts, default-target compatibility after MCP switch/open, unknown-target fail-closed behavior, and complete per-connection lease/runtime cleanup after disconnect, disable, and shutdown |
| ☐ | Default-off process-global local MCP server | `src/dao/.../mcp/dao_mcp_{service,transport,connection,protocol,runtime_files}.*`, `dao_pref_names.*`, `browser_prefs_mcp.cc.patch`, `chrome_browser_main_extra_parts_profiles.cc.patch` | 🔴 | Run `DaoMcpServiceBrowserTest.*`, `DaoMcpProtocolTest.*`, and `DaoMcpRuntimeFilesTest.*`; verify browser-IO-thread listener ownership, owner-only runtime permissions, nonce rotation, same-UID authentication, protocol/version/line limits, 64-request/8 MiB per-connection and bounded aggregate unconsumed-ingress credits, terminal-request logical closing before later same-batch tools, aggregate write backpressure, bounded graceful-close drains, 32-client admission with least-recently-active idle eviction that releases leases (`EvictsLeastRecentlyActiveIdleClientAtCapacity`, `EvictsIdleApprovedClientAndReleasesLease`) and `TOO_MANY_CLIENTS` rejection when every admitted client is busy (`RejectsHelloWithTooManyClientsWhenAllAreBusy`), serialized approval prompts, concurrent different-tab control, same-tab exclusion, idle hello/catalog discovery beyond the approval timeout without a prompt or disconnect, exact last-active-window selection and approval on the first tool call, required first-call `reason` in every MCP tool schema, missing/blank/invalid/oversized reason rejection before approval, optional subsequent reasons stripped before execution, pre-approval catalog access even when connection begins on Dao Settings, re-entrant approval cancellation denial, approval plus lease ordering, cancellation, optional non-tab `tab_id` schema/routing, isolated concurrent tab contexts, default-target compatibility after MCP switch/open, unknown-target fail-closed behavior, and complete per-connection lease/runtime cleanup after disconnect, disable, and shutdown |
| ☐ | Settings MCP master switch, connection, usage, quick setup, and Stop | `src/dao/.../mcp/dao_mcp_settings_handler.{h,cc}`, `resources/settings/dao_page/dao_page.{html,ts}.patch`, `webui/settings/settings_ui.cc.patch` | 🟡 | Run `DaoMcpInstallCommandTest.*`, `DaoMcpSettingsHandlerTest.*`, `DaoMcpSettingsPageBrowserTest.*`, and `DaoPage`; verify one header/connection/usage/enabled-only-setup card, responsive selector/copy alignment, and text status updates through `dao-mcp-status-changed`. The switch must write process-global Local State rather than `prefs.dao`; profile-scoped usage lists total and per-tool calls, sorts by count, resets independently, counts successful and failed executor entries, and excludes validation, denial, unknown-tool, and pre-execution target failures. Client details and Stop appear only for an active authorized lease. Confirm setup is absent while disabled; when enabled it defaults to Codex and switches to user-scoped Claude Code or Generic MCP. CLI previews stay single-line, Generic MCP preview and clipboard are identical Chromium-native three-space pretty JSON, and malformed Generic JSON fails closed without changing the clipboard. Also verify option-specific feedback, POSIX-safe helper and current user-data-directory arguments, Debug/custom-profile endpoint binding, stale preview rejection, listener cleanup, and absence of the standalone configuration button. |
| ☐ | Native MCP stdio helper and macOS app bundling | `src/dao/.../mcp/helper/`, `dao_mcp_helper_browsertest.cc`, `dao_version.gni`, `chrome/BUILD_mcp_helper.gn.patch` | 🔴 | Run `DaoMcpHelperBrowserTest.*`; verify all 33 tools survive catalog adaptation, MCP `2025-11-25` and Codex-compatible `2025-06-18` negotiation with initialized gating, the `codex/tool-catalog-cache.cacheable=false` compatibility capability, server-wide instructions that prefer Dao MCP, establish the initial target with `list_tabs`, preserve it across follow-ups, route ambiguous open/click/select requests through `query_elements` and guarded `click_by_ref`, and reserve `switch_tab` for explicit browser-tab navigation; verify adapted per-tool descriptions do not repeat tab-discovery guidance, plus string/numeric IDs, object/scalar/list `structuredContent`, real screenshot MIME, `isError` failures, cancellation with no late response, disabled-browser stderr determinism, JSON-only stdout, and executable copies at both the build output and `Dao.app/Contents/Helpers/dao-mcp` |
| ☐ | Local MCP approval, controlled-tab indicator, Stop, and peer-agent busy UX | `dao_mcp_approval_dialog.{h,cc}`, `dao_mcp_control_banner_view.{h,cc}`, `dao_address_bar_view.{h,cc}`, `dao_mcp_service.{h,cc}`, `ui/webui/dao_sidebar_ui.{h,cc}`, `resources/sidebar/{dao_tab_item.ts,sidebar_bridge.ts}`, `dao_agent_ui.{h,cc}`, `pi_tool_adapter.ts` | 🔴 | Run `DaoMcpApprovalDialogTest.*`, `DaoMcpControlBannerTest.*`, `DaoMcpPeerLeaseTest.*`, `tab_item.test.ts`, `pi_tool_adapter.test.ts`, and `dao_chat_view.test.ts`; verify serialized localized prompts with reported client/version, browser-recorded localized request date/time with time zone, sanitized client-provided reason, window, and Profile rendering, preserved reason/time while queued, and bounded scrolling for long reasons, exact native Browser activation when a prompt arrives behind another application, the 60-second unanswered-request timeout, no default Allow action, deny/close/parent destruction exactly once and fail closed, address-bar robot visibility only for the active controlled tab in the authorized normal Browser, a sidebar robot for every controlled tab with the close action revealed on pointer hover or keyboard focus without layout shift, prompt target add/removal updates after switch/open, popup client/target/latest accepted tool/count details with live call updates, no process-ID row in approval dialogs or control popups, no extra page-content row, clickable per-connection Stop, lease release/disconnect transitions without disturbing other clients, chat continuity, different-tab parallelism, and same-tab pre-CDP `AGENT_CONTROL_BUSY` browser-tool failures |
Expand Down
Loading
Loading