MCP.so
ログイン
S

Sallyport

@ginkida

Sallyport について

概要はまだありません

基本情報

カテゴリ

その他

トランスポート

stdio

公開者

ginkida

投稿者

Serik Ospanov

設定

以下の設定を使って、このサーバーを MCP 対応クライアントに追加してください。

{
  "mcpServers": {
    "sallyport": {
      "command": "sallyport-daemon"
    }
  }
}

ツール

24

No allowlist check — listing is free.

Checks the *destination* URL against allowlist. `waitFor={selector?,text?,absent?,timeoutMs?}` polls after the load until the page is actually usable (SPAs render long after "loaded").

Hard reload via `bypassCache=true`. Allowlist-gated; refs invalidate.

`tabId` required — no implicit fallback (closing the wrong tab loses work).

Accessibility tree with stable `@eN` refs (per-tab), pruned of layout noise. Cross-checks against a DOM walk (same refs) when the a11y tree looks suspiciously sparse — Telegram Web K and similar SPAs. `mode=auto\

Whole-page or by ref. No raw JS. Capped at 20 000 chars by default (`maxChars` overrides; cut results carry `truncated`/`totalChars`).

Cheap one-element probe (CSS or `@eN`) — `{exists, visible, tag, text, box?, inViewport?}` without a full snapshot. Verify an action's effect or re-check a ref in one round-trip. Never errors on a missing node: returns `{exists:false, reason}` (`not_found`/`unknown_ref`/`detached`), so it is safe to poll. Does **not** read input `.value` (no password readback). Structured CDP only.

Recent page console errors/warnings + uncaught exceptions for a tab (`{enabled, entries:[{ts,level,text,origin}]}`) — tell "the handler threw and the page is wedged" from "merely slow". **Opt-in** (popup setting, off by default; returns `{enabled:false}` when off). Capture starts at first attach (no replay); entries are **origin-filtered to the allowlist**. Pure CDP event capture, no `evaluate`.

Recent XHR/fetch responses for a tab (`{enabled, entries:[{ts,method,url,status,type,contentType,size,body?}]}`) — **the data behind canvas dashboards** (Metrika, Chart.js, WebGL) that have no readable DOM. Pull exact JSON instead of screenshot + vision. **Opt-in** (popup "capture API responses", off by default). Bodies only for textual content-types, capped; no auth headers captured; entries **origin-filtered to the allowlist**; `filter` narrows by URL substring. Pure CDP event capture, no `evaluate`.

DOM `.click()`. CSS selector or `@eN` ref. Optional `waitFor` polls for the click's effect in the same call.

Real `Input.dispatchMouseEvent` as a full hover→press→release sequence. Auto-aims around partial overlays; a fully covered target reports `covered`/`hitTarget`/`hitTargetRef`. Explicit `x`/`y` (viewport CSS px) as manual aim. `button` left/middle/right, `clickCount` 1–3, optional `waitFor`.

Hover the pointer over an element/point without clicking (the `mouseMoved` preamble only). For CSS `:hover`-only menus, tooltips, row-action UIs. `selector`/`@eN` (auto-aimed, reports `covered`/`hitTargetRef`) or viewport `x`/`y`; optional `waitFor` to hover→wait-for-menu. Strictly weaker than `mouse_click`; the `:hover` state is transient.

Blocks password fields without `allowPassword=true`. `method=insertText` clears the field and types via CDP with real input events (for SPA editors that ignore programmatic values). Optional `waitFor`.

Choose an option in a native `<select>` (the OS popup can't be driven via CDP). Sets the value in the DOM and fires `input`/`change` instead of opening the menu. One of `value`/`label`/`index`; array for `<select multiple>`. `wrong_element` for non-`<select>` targets — custom JS comboboxes (react-select, MUI) stay on `click`/`find`/`reveal`. Optional `waitFor`.

Raw text input via CDP. Blocks when focus is on a password field without `allowPassword=true`.

`Mod+A`, `Shift+Tab`, etc. `Mod` = `Cmd` on macOS, `Ctrl` elsewhere. Same password-field gate as `key_type`.

PNG/JPEG as a native MCP image block. `maxWidth` downscales, `region={x,y,width,height}` crops (viewport-relative CSS px). Hidden tabs fail fast with `tab_not_visible`; `bringToFront=true` activates the tab first (steals focus).

Poll (250 ms) until a selector/`@eN` ref is visible and/or page text contains a substring; `absent=true` waits until it is GONE. `timeoutMs` ≤ 30 s; timeout returns `{found:false}`, not an error. Replaces blind sleeps. Prefer the embedded `waitFor` on the preceding action when there is one.

Deterministic scrolling — the predicate-less companion to `reveal`. `selector` → `scrollIntoView`; or scroll the page (or a `selector` container) by `dx`/`dy` (negatives = up/left) or `to='top'\

Per-domain opt-in. Returns `{type, value}`.

`fetch()` with page cookies/auth. Returns `{status, contentType, headers, mode, data}`. Allowlist-gated.

Attach local files to `<input type=file>` via `DOM.setFileInputFiles`. Paths must be absolute, `..`-free, **and resolve under `~/Downloads/sallyport/`** (override via `SALLYPORT_DOWNLOAD_DIR`) — same sandbox as `save_to_file`, with symlink escapes blocked by `Path.resolve()`. Target must really be a file input. Allowlist-gated.

**Daemon-local** — writes base64 to `~/Downloads/sallyport/<filename>` (override via `SALLYPORT_DOWNLOAD_DIR`). Sandboxed: no path separators or `..`.

**Daemon-answered** health check: `{connected, mode, version, port, pendingCalls, uptimeS, lastCalls, lastError, lastHandshakeError}`. `mode` is `broker` (explicit owned `tabId` required per call) or `standalone` (active-tab fallback). `lastCalls` is a ring of recent tool **outcomes** (`{tool, ok, ms, code?}` — never the args) and `lastError` the latest failure, so a loop can attribute a stall to a specific tool/code; when `connected` is false, `lastHandshakeError` says why the extension leg failed to attach (wrong secret, clock skew, no hello). No browser round-trip and never queues behind a running call — use it as preflight before browser work.

概要

What is Sallyport?

Sallyport is a secure browser-automation bridge between Claude Code (or any MCP client) and your Chrome browser. It uses a daemon and extension architecture with explicit security boundaries, including HMAC-SHA256 signed frames and domain allowlisting, as an alternative to implicit-trust tools like Kimi WebBridge.

How to use Sallyport?

Install the daemon via pip install sallyport, build and load the unpacked Chrome extension from this repo, then pair the extension with the daemon using the generated secret. Register Sallyport as an MCP server in Claude Code and add domains to the extension’s allowlist to start automating.

Key features of Sallyport

  • HMAC-SHA256 signed frames with replay protection (nonce cache, timestamp drift ≤ 30 s)
  • Domain allowlist in chrome.storage.local, patterns like example.com or *.example.com
  • evaluate is opt-in per domain; other tools use structured CDP only
  • Defense-in-depth: fill refuses <input type=password> unless allowPassword=true
  • Operational visibility: every tool call is audited (last 500 entries) with one-click pause
  • No content scripts or <all_urls> permissions; uses debugger API exclusively
  • Per-tab accessibility refs (@e1, @e2), serialized tool calls via daemon-side lock

Use cases of Sallyport

  • AI-driven browser testing with explicit security boundaries
  • Automated web scraping on allowlisted domains without raw JavaScript
  • Multi‑agent browser sessions (broker mode) sharing one real Chrome profile
  • Safe, audited web automation in shared or compromised environments

FAQ from Sallyport

How does Sallyport differ from Kimi WebBridge?

Sallyport replaces implicit trust (any process reaching 127.0.0.1:10086) with HMAC-SHA256 signed frames, domain allowlists, opt-in evaluate, and an audit log, adding explicit security boundaries at every layer.

What are the runtime dependencies for Sallyport?

The daemon requires Python ≥ 3.10. The extension is MV3 Chrome (TypeScript, built with esbuild). No other external services or databases are needed.

Where does Sallyport store its data?

The HMAC secret lives in ~/.config/sallyport/secret (chmod 600). The domain allowlist and audit log are stored in chrome.storage.local. No external servers or cloud storage are involved.

What transports and authentication does Sallyport use?

The daemon speaks MCP over stdio to the client, and communicates with the extension via WebSocket on 127.0.0.1:10086. Authentication is HMAC-SHA256 based on a shared 32-byte secret pasted into the extension popup.

Are there any known limitations or attack surfaces?

Anyone with read access to ~/.config/sallyport/secret can drive the browser within the allowlist. The browser debugger API is ultimately the browser debugger — Sallyport limits which domains it operates on and who can drive it.

コメント

「その他」の他のコンテンツ