Metadata-Version: 2.4
Name: sallyport
Version: 0.3.3
Summary: MCP server bridging Claude Code to a browser extension over WS+HMAC
Project-URL: Homepage, https://github.com/ginkida/sallyport
Project-URL: Repository, https://github.com/ginkida/sallyport
Project-URL: Issues, https://github.com/ginkida/sallyport/issues
Project-URL: Changelog, https://github.com/ginkida/sallyport/blob/main/CHANGELOG.md
Author: ginkida
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,anthropic,browser-automation,chrome,claude,claude-code,hmac,mcp,model-context-protocol,security
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Classifier: Topic :: Security
Classifier: Topic :: Software Development
Requires-Python: >=3.10
Requires-Dist: mcp<2.0.0,>=1.0.0
Requires-Dist: websockets<17.0,>=13.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# sallyport

The Python MCP-server half of **[Sallyport](https://github.com/ginkida/sallyport)** —
a security-first bridge between Claude Code (or any MCP client) and your Chrome,
with explicit trust boundaries instead of implicit ones.

```
Claude Code ── MCP/stdio ──▶ daemon (this package) ── WS+HMAC ──▶ extension (MV3) ── CDP ──▶ Chrome
```

The daemon speaks MCP on stdio and hosts an HMAC-authenticated WebSocket server
on `127.0.0.1:10086` that the companion Chrome extension connects into. Every
frame is signed (HMAC-SHA256 + timestamp + nonce); the extension enforces a
per-domain allowlist and a per-domain opt-in for arbitrary JS.

## Install

```sh
pip install sallyport
```

The package installs the `sallyport-daemon` console command.

## Quickstart

```sh
sallyport-daemon doctor          # check Python, secret file + perms, port; print the pairing block
claude mcp add sallyport sallyport-daemon   # register with Claude Code
```

Then load the unpacked extension (or the release zip) from the
[main repository](https://github.com/ginkida/sallyport) and paste the pairing
block into its popup.

- `sallyport-daemon list-tools` — print the tool catalogue (no daemon start)
- `sallyport-daemon serve` — WS-only mode (no MCP) for wire testing
- `sallyport-daemon exec <tool> k=v …` — fire one tool from the shell

## Security

The full threat model, the load-bearing invariants, and known limitations live
in [SECURITY.md](https://github.com/ginkida/sallyport/blob/main/SECURITY.md).
In short: loopback-only bind, HMAC on every frame, a domain allowlist enforced
in the extension, per-domain `evaluate` opt-in, password-field gates, and
daemon-side filesystem sandboxes for `upload`/`save_to_file`.

## License

MIT — see [LICENSE](https://github.com/ginkida/sallyport/blob/main/LICENSE).
