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
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
name: protocol schema and ScriptCat mirror
runs-on: ubuntu-latest
env:
SCRIPTCAT_REF: e32bb5a43d3061aa1d380f62328bd249fdf55ac8
SCRIPTCAT_REF: bc6f6bb41abd4521d34e67245cde9b6f41dea024
steps:
- uses: actions/checkout@v5
with:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ The install script verifies the release archive's sha256 and installs `sctl` int

```bash
sctl status # daemon and ScriptCat
sctl scriptcats # paired ScriptCat instances
sctl browsers # paired sctl Browser instances
```

Expand Down Expand Up @@ -120,6 +121,7 @@ browser's logins; see [`docs/cli.md`](./docs/cli.md#endpoint-for-playwright-and-
| `sctl serve` / `connect` / `status` / `mcp` | Run the daemon, pair an extension, show connection status, serve MCP over stdio. |
| `sctl service` | Run the daemon in the background as a user service (launchd, systemd, Task Scheduler). |
| `sctl get` / `grep` / `install` / `edit` / `enable` / `disable` / `delete` | Manage ScriptCat userscripts. |
| `sctl scriptcats` | List paired ScriptCat instances, or forget one. |
| `sctl browsers` | List paired sctl Browser instances, or forget one. |
| `sctl tabs` / `windows` / `groups` | Tabs, windows, and tab groups. |
| `sctl bookmarks` / `reading-list` | Bookmarks and the reading list. |
Expand Down
2 changes: 2 additions & 0 deletions docs/README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ irm https://raw.githubusercontent.com/scriptscat/sctl/main/scripts/install.ps1 |

```bash
sctl status # daemon 与 ScriptCat
sctl scriptcats # 已配对的 ScriptCat 实例
sctl browsers # 已配对的 sctl Browser 实例
```

Expand Down Expand Up @@ -110,6 +111,7 @@ ln -s "$PWD/skills/sctl" ~/.claude/skills/sctl
| `sctl serve` / `connect` / `status` / `mcp` | 运行 daemon、配对扩展、查看连接状态、通过 stdio 提供 MCP。 |
| `sctl service` | 以用户服务的形式在后台运行 daemon(launchd、systemd、任务计划程序)。 |
| `sctl get` / `grep` / `install` / `edit` / `enable` / `disable` / `delete` | 管理 ScriptCat 用户脚本。 |
| `sctl scriptcats` | 列出已配对的 ScriptCat 实例,或忘记其中一个。 |
| `sctl browsers` | 列出已配对的 sctl Browser 实例,或忘记其中一个。 |
| `sctl tabs` / `windows` / `groups` | 标签页、窗口和标签组。 |
| `sctl bookmarks` / `reading-list` | 书签和阅读列表。 |
Expand Down
16 changes: 9 additions & 7 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ explicitly in the foreground or let the user's system service manager own its li
(`internal/client/service`) writes that service definition and drives the manager's own commands; it talks to the
daemon only through the health check and the control token, to tell whether the service's daemon came up.

The daemon accepts two kinds of extension connection at once: exactly one active ScriptCat connection (a new
one replaces the previous one), and any number of paired `sctl Browser` instances connecting simultaneously,
each identified by its own instance ID. A call is routed by which peer kind owns its method (scripts.\* to
ScriptCat, tabs.\*/windows.\* to a resolved browser instance) — see
The daemon accepts two kinds of extension connection at once: ScriptCat — any number of paired ScriptCat
instances, each identified by its own instance ID, plus at most one legacy ScriptCat connection that declares no
instance ID (a new legacy connection replaces only the previous legacy one) — and any number of paired
`sctl Browser` instances connecting simultaneously, each identified by its own instance ID. A call is routed by
which peer kind owns its method (scripts.\* to ScriptCat, tabs.\*/windows.\* to a resolved browser instance) — see
[protocol.md](./protocol.md#31-routing-and-target-selection). For ScriptCat's methods, the daemon approves no
write on its own — it forwards the request and blocks until a human decides in the browser, and source reads
go through the same disclosure gate. Browser control methods carry no such human gate by design: any
Expand Down Expand Up @@ -148,6 +149,7 @@ internal/cli/ # subcommand definitions; spans both sides, hence to
get.go grep.go # read verbs
edit.go write.go # write verbs (edit / install / enable / disable / delete)
browsers.go # sctl browsers [list] / sctl browsers forget <name|id>
scriptcats.go # sctl scriptcats [list] / sctl scriptcats forget <name|id>
tabs.go windows.go # sctl tabs list|open|close|activate, sctl windows list
page*.go # sctl page snapshot|click|hover|fill|type|press|select|upload|scroll|goto|back|forward|
# reload|wait|screenshot|eval|dialog|detach (reach /control/page through dispatchPage)
Expand All @@ -170,9 +172,9 @@ internal/daemon/ # ── sctl serve side ──
cdpendpoint/ # raw CDP endpoint: per-browser endpoints, /cdp/ HTTP and WS, Host/Origin/secret checks,
# expiry, hand-over to and from page, the per-client Hook and Browser
auth/ # mutual HMAC handshake, enrollment-code derivation (HKDF), key delivery (AES-GCM)
store/ # persistence (repository role): ScriptCat's long-term key K, plus the
# browsers.json registry of paired sctl Browser instances and their own
# per-instance keys
store/ # persistence (repository role): the legacy ScriptCat's long-term key K, plus the
# browsers.json and scriptcats.json registries of paired sctl Browser and
# ScriptCat instances and their own per-instance keys (one shared implementation)
ratelimit/ # enrollment-attempt rate limiting

internal/client/ # ── sctl mcp / CLI verb side ──
Expand Down
14 changes: 13 additions & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ command line can use the skill in [`../skills/sctl/`](../skills/sctl/SKILL.md).
| `sctl service install\|uninstall\|start\|stop\|restart\|enable\|disable\|status` | Run `sctl serve` in the background as a user service; see [Background service](#background-service-sctl-service). |
| `sctl connect` | Open a one-time enrollment window for ScriptCat or sctl Browser. |
| `sctl mcp [--name <label>]` | Serve ScriptCat and sctl Browser tools over stdio MCP. |
| `sctl status` | Show daemon and extension connection status. |
| `sctl status` | Show daemon status and every paired ScriptCat and sctl Browser instance with its online state. `-o json` keeps `extConnected` (true when any ScriptCat instance is online) and adds a `scriptcats` list. |
| `sctl scriptcats [list]` / `sctl scriptcats forget <name\|id>` | List paired ScriptCat instances (name, ID, status, product, versions; a legacy ScriptCat appears as `scriptcat` with no ID while `pairing.key` exists), or forget one. Forgetting deletes its key and disconnects it; `forget scriptcat` deletes `pairing.key`. |

### ScriptCat scripts

Expand Down Expand Up @@ -95,6 +96,17 @@ control commands run immediately with no approval step (see [`threat-model.md`](
`cookies`, `extensions`, `page`, `debug`, and `cdp` accept `--browser <name|id>` (or `SCTL_BROWSER`) to pick an
instance when more than one is online.

### Choosing a ScriptCat instance

`get`, `grep`, `edit`, `install`, `enable`, `disable`, and `delete` accept `--scriptcat <name|id>` (or
`SCTL_SCRIPTCAT`) to pick a paired ScriptCat instance (see `sctl scriptcats`); an explicit `--scriptcat` wins over the
environment variable. These names are a separate namespace from `--browser`. With exactly one instance online no
target is needed. With several online and no target, `get` lists scripts from every online instance and adds a
`SCRIPTCAT` column naming each script's source instance, while the other verbs fail with `SCRIPTCAT_AMBIGUOUS`
(exit code 3) and the hint `pass --scriptcat <name> or set SCTL_SCRIPTCAT`. `SCRIPTCAT_OFFLINE` and
`SCRIPTCAT_NOT_FOUND` also exit with code 3. With a single instance the `get` table has no extra column. Matching
rules are in [`protocol.md`](./protocol.md) §3.1.

### Exit codes

| Exit code | Meaning |
Expand Down
16 changes: 13 additions & 3 deletions docs/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,19 @@ independently, but both use the same one-time-code flow against the same running

```bash
sctl status
sctl scriptcats
sctl browsers
```

`sctl status` reports whether ScriptCat is connected; `sctl browsers` lists every paired sctl Browser instance
`sctl status` reports whether the daemon is up and which ScriptCat and sctl Browser instances are connected; `sctl scriptcats` lists every paired ScriptCat instance and `sctl browsers` lists every paired sctl Browser instance
with its online/offline state. The one-time code must not be pasted into an AI conversation, issue, log, or MCP
configuration. After enrollment, each extension and the daemon use their own persisted long-term pairing state;
each AI client does not enroll separately, and multiple sctl Browser instances can stay paired and connected at
the same time.

Disabling External Access in ScriptCat, or removing the sctl Browser extension, revokes that extension's side
of the relationship. `sctl browsers forget <name|id>` removes a paired sctl Browser instance from the daemon
side and disconnects it if online. Run `connect` again if you intentionally revoke a pairing and later want to
of the relationship. `sctl browsers forget <name|id>` and `sctl scriptcats forget <name|id>` remove a paired sctl
Browser or ScriptCat instance from the daemon side and disconnect it if online. Run `connect` again if you intentionally revoke a pairing and later want to
reconnect.

## 5. Configure the MCP client
Expand Down Expand Up @@ -223,6 +224,15 @@ results, and error codes that span several tools. [cli.md](./cli.md) describes t
command-line side, and three topics live only there and are linked from here: how sctl dismisses JS dialogs, the
side effects of raw CDP commands, and the Playwright and Puppeteer connection examples.

### ScriptCat instances

Every ScriptCat tool (`scripts_*`) accepts an optional `scriptcat` argument (name or instance-ID prefix, as for
`--scriptcat` in [cli.md](./cli.md)) to pick a paired ScriptCat instance; the browser tools do not take it, and the
ScriptCat tools do not take `browser`. Without a target and with several instances online, `scripts_list` combines
every online instance's scripts and tags each item with `scriptcat` (`name`, and `id` for upgraded instances), while
the other ScriptCat tools return `SCRIPTCAT_AMBIGUOUS` listing the candidates. `SCRIPTCAT_OFFLINE` and
`SCRIPTCAT_NOT_FOUND` are returned as tool errors.

### Browser instances, tabs, and windows

`sctl mcp` always also exposes `browsers_list`, `tabs_list`, `tabs_open`, `tabs_close`, `tabs_activate`, and
Expand Down
Loading
Loading