Skip to main content

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.

PyPI version Python versions License: MIT CI Documentation

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-sdkawait 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 Noneexpired 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.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lime-sites-sdk 2.0.2
File Size Uploaded
lime_sites_sdk-2.0.2.tar.gz 29.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lime-sites-sdk 2.0.2
File Interpreter ABI Platform
lime_sites_sdk-2.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 46.0 kB

Release files / lime_sites_sdk-2.0.2.tar.gz

Download URL lime_sites_sdk-2.0.2.tar.gz
Size 29.9 kB
Tags Source
SHA-256 checksum
How to use checksums
175bd64ef74fcff87c89fc3b9961c37e27ec5d4a765c6870169fcf24546d537f
BLAKE2b-256 checksum
How to use checksums
50a9bbb9bcda94477497917087b07f37d338ecc497fc4cc0d16ea70682d9098f
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.2-py3-none-any.whl

Download URL lime_sites_sdk-2.0.2-py3-none-any.whl
Size 16.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
75ae64258e1512ce8e6962acd3d3a97608194bc4bbf22b22b47e191d68fbf359
BLAKE2b-256 checksum
How to use checksums
3080d129ca7cc30298cb27b6635e636384e90f4ad8bc05603e2a3e684ba6f33c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

2.0.5

2 release files

2.0.4

2 release files

2.0.3

2 release files

This release

2.0.2 This release

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page