feat(python): uvx-installable Python sealg CLI alongside the Rust client

Merged
MI
2mo ago
+1175-0

Summary

Adds a pure-Python sealg client in python/, exposing the same CLI surface as the Rust binary in this repo (doctor | list | call), packaged so it installs via uvx/pip. It's a thin MCP-over-HTTP client that forwards tools/list / tools/call to the per-user gateway endpoint, where all policy and enforcement live — it carries no policy of its own.

It exists alongside the Rust sealg for environments that reach for uvx/pip rather than a native binary. Co-locating it here (rather than in the gateway repo) means the drift guard reads the Rust source directly — no cross-repo checkout, no token, no fallback.

Verified end-to-end earlier against the live demo gateway: initialize (protocol 2025-06-18), tools/list, tools/call for both isError:true→exit 6 and isError:false→exit 0, the conversation-id session flow, and the HTTPS_PROXY + CA-bundle path.

Changes

  • python/sealg/ — the package.
    • client.py: GatewayConfig + GatewayClient (initialize/list/call, SSE+JSON parsing, additive CA trust, env-key vs proxy-injected auth, API-key redaction; follows redirects and treats only 2xx as success, matching reqwest).
    • cli.py: typer CLI mirroring the Rust surface and exit codes (0/1/6); doctor reports resolved env + a reachability probe.
    • contract.py: single source of truth for every shared wire constant.
    • tests/test_wire.py: config/parse/redaction/redirect tests ported from the Rust suite.
    • pyproject.toml ([project.scripts] sealg), README.md, .env.example.
  • scripts/check_wire_contract.py + prek.toml hook + .github/workflows/python-cli.yaml — the in-repo drift guard. It parses the Rust constants in crates/engine/src/gateway/{config,client}.rs and crates/cli/src/gateway_cmd.rs, compares them to python/sealg/contract.py, and fails if the protocol version, headers, env keys, /mcp/{key}/ path shape, or exit codes diverge. Runs on pre-commit and in a dedicated CI job.

Testing

  • uv run pytest python/tests — 15 tests
  • uv run ruff format --check + ruff check + ty check (against a venv with the package installed)
  • python3 scripts/check_wire_contract.py — Python and Rust constants agree
  • uvx --from ./python sealg doctor builds and runs

Related

Supersedes the copy previously staged in edison-watch/edison-watch#1396 (that PR keeps only the design-doc note pointing here).

🤖 Generated with Claude Code

https://claude.ai/code/session_01EpwFmgQPfugKFF9zugay6Y


Generated by Claude Code


Summary by cubic

Adds a uvx/pip-installable Python sealg CLI alongside the Rust binary, mirroring doctor, list, and call with exit codes 0/1/6. It forwards MCP requests to the gateway, so policy and enforcement stay gateway-side.

  • Supports JSON and SSE responses, session and conversation headers, proxy-injected authentication, additive CA-bundle trust, and redirects capped at 10; credential headers are stripped on cross-origin redirects.
  • Redacts the API key from URLs and non-2xx error bodies; doctor now distinguishes a reachability failure from a failed tools/list probe.
  • Includes package docs, environment config, and tests for config resolution, protocol parsing, HTTP handling, and redaction.
  • Adds pre-commit and CI wire-contract checks against the Rust client; CI pins ruff==0.16.5 and ty==0.0.77.