# Kitsuvo MCP fixes and benchmark verification — October 11, 2026

Kitsuvo stdio has the lowest median in all five tested workflows against the pinned Playwright and Chrome DevTools MCP servers, with clear gains for click, fill, warm navigation and complete large-page extraction. This is a local fixture result, not proof of being the fastest MCP everywhere. The small-snapshot median is close; DevTools has the better p95 for that read. Results vary between runs and transports.

## Final measured comparison

Milliseconds **p50 / p95**. Snapshot/action rows have 30 samples, warm navigation 10. Fresh inline page state is included in every action. No snapshot pruning is enabled in this table; complete large-page reads include the final sentinel.

| Workflow | Kitsuvo stdio | Kitsuvo HTTP | Playwright MCP | DevTools MCP |
| --- | ---: | ---: | ---: | ---: |
| Small snapshot | 1.7 / 12.1 | 3.3 / 5.3 | 9.8 / 24.2 | 1.9 / 2.8 |
| Click + fresh snapshot | 2.9 / 11.9 | 4.0 / 5.7 | 541.5 / 606.6 | 230.6 / 244.1 |
| Fill + fresh snapshot | 2.4 / 11.3 | 4.3 / 9.2 | 15.9 / 27.3 | 226.6 / 235.4 |
| Warm navigation + snapshot | 20.4 / 40.1 | 19.6 / 23.0 | 38.0 / 57.3 | 118.1 / 125.5 |
| Complete 600-row snapshot | 10.1 / 14.9 | 14.5 / 24.8 | 45.2 / 51.8 | 86.1 / 112.2 |

| Native workflow | Before p50 ms | After p50 ms | Improvement |
| --- | ---: | ---: | ---: |
| Small snapshot | 3.4 | 1.7 | 2.0× |
| Click + fresh snapshot | 777.4 | 2.9 | 269.7× |
| Fill + fresh snapshot | 832.2 | 2.4 | 348.3× |
| Warm navigation + snapshot | 127.6 | 20.4 | 6.2× |
| Complete 600-row snapshot | 18.0 | 10.1 | 1.8× |

Native ping during a one-second tool wait improved from 980.3 ms to 0.51 ms (only two observations each). Ping and discovery use the responsive protocol reader; page mutations remain ordered.

The final run contains **722 successful timed observations**, with **0 tool failures**. Click counts and filled values passed snapshot and independent page-state assertions. In both rounds Kitsuvo stdio and HTTP returned the destination of the 1,200-ms delayed redirect. Playwright and DevTools returned the old page in that probe and reached the destination later; their lower redirect-call times do not represent completed navigation.

## Implemented changes

- Replaced the unconditional post-action grace with explicit readiness, DOM predicates and navigation hints. Non-navigation clicks and fills return fresh observed state immediately; direct navigation waits remain. SPA predicates take precedence over auto navigation hints. Known popups wait for tab adoption, keeping the original snapshot tab pinned; blocked/pending popups are reported explicitly.
- Reused the page helper per document, with a compact presence check and safe install fallback. Combined state/tab inventory requests and included action snapshots in the same control request. Default full snapshot behavior and large-page budgets remain explicit; optional viewport/none output modes do not contribute to the comparison table.
- Split stdio protocol reading from ordered browser work; bounded admission at 32 and applied queue-inclusive request deadlines. Propagated cancellation to the authenticated control API and checked cancellation/deadlines again immediately before UI dispatch.
- Added bounded cancellable HTTP/cloud queues and client sessions. Cloud sessions bind to the OAuth client and approved browser. Cached tool discovery, propagated cancellation/deadlines over the connector, and included all new modules in Docker and integration distribution manifests.
- Restricted automatic reconnect/retry to eligible reads. Lost mutation responses return an uncertain-outcome error instead of replaying the mutation. Password and covered-target checks run before writes.

## Reliability verification

**13/13 native runtime checks passed**:

- non-navigation click, fill and output suppression
- delayed navigation returns destination
- form submission waits for destination
- popup reports its new tab while keeping the original snapshot
- SPA explicit predicate takes precedence over navigation heuristic
- invalid readiness rejects before mutation
- password write is refused without changing its value
- covered target rejects without mutation
- ping remains responsive behind a wait
- cancelled queued mutation never runs
- active cancellation frees worker before the original wait duration
- expired queued mutation is never dispatched
- lost mutation response is not replayed

Rust agent tests: 34 passed. Node bridge/relay tests: 14 passed, including OAuth isolation/revocation, queued and active cancellation, capacity/deadline ordering, session ownership/termination, cancelled HTTP response cleanup, and shared module consistency. An isolated integration archive build confirmed both runtime module sets are included. The separate queued-cancellation probe records only operation 0; cancelled operation 1 never executed after its notification had time to cross the transport.

## Reproduction and limits

- Same fixture harness and pinned competitors as the baseline: Playwright MCP 0.0.83, Chrome DevTools MCP 1.10.1, SDK 1.32.1. Two rounds reverse server order; 648 × 603 matched viewport; headed WKWebView for Kitsuvo and Chrome for competitors. All raw samples, actual dimensions/user agents and response sizes are in `results.json`.
- Playwright stores implicit snapshots in files; an explicit snapshot is included to compare an inline-state workflow. DevTools uses `includeSnapshot` for click/fill and an explicit snapshot after navigation. This comparison does not establish the fastest acknowledgement-only workflow.
- Kitsuvo release build uses `--locked --no-default-features --features desktop-devtools`, excluding embedded inference. The final run pins a copy at `a pinned temporary build` so other builds cannot replace it between rounds. Final binary SHA-256: `d1ada71a7ee0fb5a737e4b82289145a377859f13be3a110d9bca21cb6926e22b`. This is MCP-path evidence, not validation of the full default build or embedded inference.
- The workspace contains substantial pre-existing edits and other work ran on this shared Apple M5 Max/64-GiB machine. Before/after results come from separate runs; the final comparator table reruns all servers with the final binary. Uncommitted sources and shared CPU scheduling limit attribution of small differences. Source hashes were captured at benchmark admission; `src/agent/commands.rs` changed during the run in concurrent work. The measured executable stayed pinned, and these checks do not validate subsequent source edits. An intermediate shared-workspace build hit an unrelated sidebar borrow error that was already corrected by the concurrent work; the retry succeeded. The earlier result before the popup fix remains in `pre-popup-results.json` and is not the final result.
- This does not cover production deployment, public cloud network latency, real-site task suites, sustained concurrency, Windows native DevTools, screenshots, memory or energy. The local/cloud queue routing tests use stub backends; native cancellation is separately verified against a real browser.
- Cancellation cannot roll back an already dispatched mutation; a client-side abort can resolve before its cancellation notification arrives. Native queued deadline errors are returned when the worker reaches that item, though expired work is not dispatched. Future timers and arbitrary script popups cannot be predicted; require an explicit readiness condition when the next step depends on them. Prevented link/form navigation may consume the auto navigation grace; use a SPA predicate.
- Changes are local and have not been deployed or published. Existing site ZIP assets were preserved; the packaging manifest was fixed and tested using a temporary archive.

```sh
cargo test --locked --no-default-features --features desktop-devtools agent::
cargo build --locked --release --no-default-features --features desktop-devtools
node --test integrations/mcp-http/test/*.test.mjs integrations/mcp-cloud/test/*.test.mjs
node reports/mcp-performance-fixed-2026-10-11/reliability.mjs
BENCH_OUT=reports/mcp-performance-fixed-2026-10-11 node reports/mcp-performance-2026-10-11/benchmark.mjs
```
