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.1

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.1
File Size Uploaded
lime_sites_sdk-2.0.1.tar.gz 29.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lime-sites-sdk 2.0.1
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

2.0.5

2 release files

2.0.4

2 release files

2.0.3

2 release files

2.0.2

2 release files

This release

2.0.1 This release

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