lime-sites-sdk
Accept AI agent login on your site backend — create a request, get a Core-signed passport over SSE, verify locally with JWKS.
from lime_sites import LimeSite
site = LimeSite() # LIME_SITE_TOKEN — construct inside a running asyncio loop
@site.on_login
async def handle_login(request_id: str, passport: str | None) -> None:
if passport is None:
return # expired
verified = await site.verify_passport(passport, expected_request_id=request_id)
# issue YOUR session cookie from verified.claims
req = await site.create_login_request()
# hand req.request_id to the agent worker → agent.login(request_id)
What the SDK handles: Site Token auth · login request · SSE passport delivery · JWKS verify · optional agent binding.
Docs: Read the Docs · lime.pics/docs · Platform
Installation
pip install lime-sites-sdk
export LIME_SITE_TOKEN=st_... # from https://lime.pics — site portal
Requirements: Python 3.10+ · httpx · PyJWT · cryptography
Config: one secret — LIME_SITE_TOKEN (or site_token=). Never give Site Token to the agent.
Quick start (canonical) — FastAPI site login
from contextlib import asynccontextmanager
from fastapi import FastAPI
from lime_sites import InvalidPassportError, LimeSite
pending_logins: dict[str, object] = {}
site: LimeSite
@asynccontextmanager
async def lifespan(app: FastAPI):
global site
site = LimeSite() # one LimeSite per process / site token
@site.on_login
async def handle_login(request_id: str, passport: str | None) -> None:
if passport is None:
pending_logins.pop(request_id, None)
return
try:
verified = await site.verify_passport(
passport,
expected_request_id=request_id,
)
except InvalidPassportError:
pending_logins.pop(request_id, None)
return
pending_logins[request_id] = verified.claims # set YOUR session
yield
await site.aclose()
app = FastAPI(lifespan=lifespan)
@app.post("/login/start")
async def start_login() -> dict[str, str]:
req = await site.create_login_request()
return {"request_id": req.request_id}
Copy-paste: examples/fastapi-login/.
Agent worker (separate package): lime-agents-sdk → await agent.login(request_id).
Mental model
LimeSite
├── Site login (primary) create_login_request · on_login · verify_passport
├── Agent binding create_binding_request · verify_binding_passport
└── Lifecycle aclose()
| Credential | Header | Used for |
|---|---|---|
| Opaque Site Token | X-Site-Token |
Your backend ↔ LIME only |
| Site passport JWT | delivered on SSE | Session after verify_passport (aud=lime-site-login) |
Site login ≠ agent binding. MCP Bearer (aud=mcp) is not verified here — use lime-mcp-server-sdk.
Rules that prevent foot-guns
| Rule | Why |
|---|---|
One LimeSite per site token per process |
One SSE connection |
| Construct inside a running asyncio loop | Dispatcher uses create_task |
Keep @site.on_login handlers fast |
Events dispatch sequentially |
passport is None → expired |
Clear pending state |
Second scenario — Agent binding
Bind a LIME agent_id to a signed-in human via Connect (aud=lime-binding). No SSE.
req = await site.create_binding_request(redirect_uri="https://yoursite.example/bind/callback")
# persist req.binding_id ↔ user_id, redirect browser to req.connect_url
# callback: verify_binding_passport(passport) → claims["binding_id"] / claims["agent_id"]
Example: examples/binding/. Details in Read the Docs.
Minimal end-to-end loop
With both SDKs installed (lime-sites-sdk + lime-agents-sdk):
import asyncio
from lime_agents import LimeAgent
from lime_sites import LimeSite
async def main() -> None:
received = asyncio.Event()
box: dict[str, str] = {}
site = LimeSite()
@site.on_login
async def handle_login(request_id: str, passport: str | None) -> None:
if passport:
box["jwt"] = passport
received.set()
req = await site.create_login_request()
async with LimeAgent() as agent:
await agent.login(req.request_id)
await asyncio.wait_for(received.wait(), timeout=120)
verified = await site.verify_passport(box["jwt"], expected_request_id=req.request_id)
print(verified.claims)
await site.aclose()
asyncio.run(main())
Example: examples/minimal-loop/.
API surface (summary)
| Method | Description |
|---|---|
create_login_request() |
Start site login → request_id |
@site.on_login |
Handler (request_id, passport | None) |
verify_passport(jwt, …) |
JWKS verify aud=lime-site-login |
create_binding_request(…) |
Start Connect binding |
verify_binding_passport(jwt) |
JWKS verify aud=lime-binding |
aclose() |
Stop SSE / close client |
Env: LIME_SITE_TOKEN (required unless constructor), LIME_API_BASE (optional).
Related packages
| Package | Role |
|---|---|
lime-agents-sdk |
Agent worker: login(request_id) + MCP client |
lime-mcp-server-sdk |
MCP RS: verify aud=mcp Bearer |
Examples
| Path | Purpose |
|---|---|
examples/fastapi-login/ |
Canonical site login |
examples/minimal-loop/ |
Site + agent E2E sketch |
examples/binding/ |
Connect binding sketch |
Contributing
git clone https://github.com/Mawyxx/lime-site-sdk.git
cd lime-site-sdk
pip install -e ".[dev]"
ruff check src tests
mypy src/lime_sites
pytest --cov=lime_sites --cov-fail-under=100
License
MIT — see LICENSE.
Release files for lime-sites-sdk 2.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lime_sites_sdk-2.0.1.tar.gz | 29.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lime_sites_sdk-2.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.9 kB
Release files / lime_sites_sdk-2.0.1.tar.gz
| Download URL | lime_sites_sdk-2.0.1.tar.gz |
|---|---|
| Size | 29.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e036ccd60ebf6e207eb54e84421ce66de6f885675fcd31cadb22c801eb2d8253
|
|
BLAKE2b-256 checksum How to use checksums |
4d242f36e83553af4b304a29564f408cc1fedad42dc964f1894ca1946d6c0996
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / lime_sites_sdk-2.0.1-py3-none-any.whl
| Download URL | lime_sites_sdk-2.0.1-py3-none-any.whl |
|---|---|
| Size | 16.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8216e2a2b03d2fc709479a14cbb5d6d9c693c83ced0478b2ffdd8040eee8751f
|
|
BLAKE2b-256 checksum How to use checksums |
3e9b27288deeb6e2371de9e124dcdbc29d777823197045c97879e9ea62a2d6c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|