# lean-ctx-client (Python SDK) Thin, **dependency-free** Python client for the lean-ctx HTTP `/v1` contract. Standard library only (`urllib`) — installs and runs anywhere, no transitive dependencies. It speaks the wire protocol only; it never links the engine or re-implements compression. Mirrors the TypeScript and Rust `lean-ctx-client` SDKs. ## Install ```bash pip install lean-ctx-client # from this repo: pip install ./clients/python ``` ## Usage ```python from leanctx import LeanCtxClient, run_conformance client = LeanCtxClient("http://127.0.0.1:8080") # Discovery caps = client.capabilities() # GET /v1/capabilities api = client.openapi() # GET /v1/openapi.json # Tools listing = client.list_tools(limit=10) text = client.call_tool_text("ctx_read", {"path": "README.md"}) # Live events (SSE) for event in client.subscribe_events(): print(event["kind"], event["payload"]) ``` ## Methods | Method | Endpoint | |--------|----------| | `health()` | `GET /health` | | `manifest()` | `GET /v1/manifest` | | `capabilities()` | `GET /v1/capabilities` | | `openapi()` | `GET /v1/openapi.json` | | `list_tools(offset=, limit=)` | `GET /v1/tools` | | `call_tool(name, arguments, ...)` | `POST /v1/tools/call` | | `call_tool_text(name, arguments, ...)` | `POST /v1/tools/call` + text extraction | | `subscribe_events(...)` | `GET /v1/events` (SSE) | | `context_summary(...)` | `GET /v1/context/summary` | | `search_events(q, ...)` | `GET /v1/events/search` | | `event_lineage(event_id, ...)` | `GET /v1/events/lineage` | | `metrics()` | `GET /v1/metrics` | ## Shared conformance kit `run_conformance(client)` runs the language-agnostic SDK conformance checks against a live server and returns a scorecard. It mirrors the TypeScript SDK's `runConformance` and the server-side `lean-ctx conformance`, keeping all clients in lockstep on the same contract. ```python card = run_conformance(client) assert card.all_passed, [c for c in card.checks if not c.passed] ``` The kit covers **every** `/v1` route (`COVERED_ROUTES`): its `route_coverage` check fails when the server advertises a route this SDK does not cover, and `engine_compat` fails when the server speaks an `http_mcp` contract version outside `SUPPORTED_HTTP_CONTRACT_VERSIONS`. The published matrix lives at `docs/reference/sdk-conformance-matrix.md` (regenerated by `scripts/sdk-conformance.sh` against a real server in the `sdk-conformance` CI job). ### SemVer coupling The SDK's major version follows the engine's `http_mcp` contract major (CONTRACTS.md § Versioning rules): a `v2` contract ships as SDK `2.x`, and `1.x` keeps speaking `v1`. ## Framework adapters Expose the lean-ctx tool surface to popular agent frameworks. Each framework is an **optional** dependency, imported lazily — installing `lean-ctx-client` pulls in none of them. The OpenAI adapter is a pure transformation and needs no extra package. ```python from leanctx import LeanCtxClient from leanctx.adapters import ( to_openai_tools, run_openai_tool_call, # no extra dep to_langchain_tools, # pip install "lean-ctx-client[langchain]" to_llamaindex_tools, # pip install "lean-ctx-client[llamaindex]" to_crewai_tools, # pip install "lean-ctx-client[crewai]" ) client = LeanCtxClient("http://127.0.0.1:8080") # OpenAI function calling tools = to_openai_tools(client) # ... pass tools to client.chat.completions.create(...), then: text = run_openai_tool_call(client, tool_call) # LangChain / LlamaIndex / CrewAI lc_tools = to_langchain_tools(client) ``` ## Errors - `LeanCtxConfigError` — invalid arguments / configuration (no I/O performed). - `LeanCtxTransportError` — request never produced a response (network/DNS/TLS). - `LeanCtxHTTPError` — non-2xx response, with `status`, `method`, `url`, `error_code`, and parsed `body`. ## Non-goals - No engine linkage and no re-implemented compression/indexing logic. - Stability over surface: only the documented `/v1` contract is exposed. ## Development ```bash cd clients/python python -m pytest ```