overview

@contextune/sdk captures what a user does in the browser (idle time, rage clicks, tab switches, scroll depth) and hands it to your model as structured JSON. Your agent reads the behaviour, not just the text the user typed.

It's MIT-licensed and runs in the browser. The snapshot lives in memory in the user's session; nothing is sent anywhere, and we never see it.

hello-world.tsts
import { AgentContext } from '@contextune/sdk';

AgentContext.init();
const snapshot = AgentContext.getSnapshot();
// inject snapshot into your agent's system prompt

Read the full quickstart →

Using a coding agent? Add with your agent → wires the integration from a single prompt. No key to mint.

how it fits together

Sources (Snowplow / Segment / GA4 / GTM / AgentContext.track()) feed the normaliser. The normaliser sanitises and redacts, then writes events into an in-memory snapshot. Your server reads the snapshot when it calls the model. The boundary between client and server is the dashed line: nothing crosses it except the data you choose to send.

flowchart LR
    User(["User"])

    subgraph Browser["Browser — your app + the SDK"]
        direction TB

        subgraph Sources["Sources"]
            direction TB
            SP["Snowplow JS"]
            SEG["Segment"]
            GA4["GA4"]
            GTM["GTM"]
            CT["AgentContext.track()"]
        end

        Norm["Normaliser<br/>sanitise · redact · shape"]
        Engine["Engine<br/>event log · computed attributes"]
        Snap["In-memory snapshot<br/>behavior · device_info · marketing_params · event_log"]
        App["Your app code"]
    end

    subgraph Server["Your server"]
        direction TB
        LLM["LLM call<br/>snapshot injected as system-prompt context"]
    end

    User -->|interacts| Sources
    SP --> Norm
    SEG --> Norm
    GA4 --> Norm
    GTM --> Norm
    CT --> Norm
    Norm --> Engine
    Engine --> Snap
    Snap -->|"getSnapshot()"| App

    App -.->|"you choose to send it"| LLM
    LLM -->|response| App
    App -->|renders| User

    classDef boundary stroke-dasharray: 6 4,stroke-width:2px;
    class Server boundary;

what the snapshot contains

Every block is optional and toggleable.

next steps