Privacy
What Kasper Agent keeps on your computer, what it sends over the network, and to whom.
Kasper Agent is local-first, but it is not offline-only. Agent workspaces, conversations, attachments, browser data, and team data stay on the computer that runs Kasper Agent. The optional Kasper Agent account service stores the minimum central data needed for email sign-in, account avatars, remote host configuration, memberships, invitations, and logical sessions.
The optional browser client at /app connects to the computer that runs Kasper Agent. Conversation
and attachment data travel through the existing encrypted host connection, not through the
account Worker. The browser keeps chat pages, drafts, search results, and file previews in memory;
it does not create a persistent offline chat cache. Files that the user downloads are saved by
their browser. The host must stay online. An owner or admin can manage members and invitations from
the browser; these requests go to the account Worker, as they do from the desktop app. A signed-in
user can also change the display name and avatar and disconnect account sessions from the browser;
these requests and the avatar image go to the same account Worker as from the desktop app. Host
settings, such as MCP servers and the server's hosted sites, travel through the encrypted host
connection. A hosted site belongs to the server that published it. When the computer that runs
Kasper Agent is a registered server, its site requests to the account Worker also send that server's id and
machine token. The account Worker already holds both, and uses them only to find the server and its
plan's site limit.
A Grok Bot export that a member imports into a joined server, from the desktop app or the browser, goes
to the computer that runs that server through the same encrypted host connection, not through the
account Worker. The host keeps the file only until the import ends, is cancelled, or expires.
When an owner or admin signs in to an MCP server, a provider or a connector of a joined server, or
opens a sign-in link that an agent of that server showed, the sign-in page can open in the browser
of their own computer. That computer then sends the address the page returns to, which holds the
sign-in code, to the host through the same encrypted host connection, not through the account
Worker. A Slack or Discord install sends its sealed grant to the host on the same path; the user's
computer cannot open it. Neither computer logs the code, and the host keeps the grant.
To show each server's state, the browser also keeps a status connection to each host of the account
that no tab has open, as the mobile app does; the host then shows the member as present. Host logos
come from the account Worker to members of the host, and the browser can cache them.
Browser email sign-in uses a persistent host-only Secure, HttpOnly, SameSite=Lax cookie
(__Secure-kasperagent.session_token) that holds the session token and its signature.
Browser JavaScript cannot read the account credential. Trusted host public keys are stored in
local storage separately for each account. The shared file preview can also store its panel width.
The sidebar stores pinned agent and channel ids, collapsed section ids, and the selected channel id
for each account and host. The server rail stores the order of host ids for each account. The
browser also stores the chosen interface language and whether the completion sound is on. It stores
no message content.
Signing out revokes that credential's remote sessions and tells other open tabs to clear private
state. Host identity pins remain so a later sign-in cannot silently trust a replacement host key.
The web client adds no chat analytics events. When analytics is on, at sign-in it sends the saved
first website visit of the browser, described in "Product analytics", to the account service. It does not send email codes, credentials,
message content, file content, or search queries to telemetry.
Product analytics and error reports are off. The desktop app, the browser app, the mobile app, the website and the account service send no analytics events and no error reports: no analytics service is set up, and the builds have no analytics key. The rest of this part, "Product analytics" and "Error and warning reports" tell what Kasper Agent sends when analytics is on again. This document changes before that. Development builds, previews, tests, and Storybook never send analytics.
When analytics is on, production builds of Kasper Agent desktop, the configured mobile app, and the website use a self-hosted OpenPanel service for product analytics. The production account service also sends OpenPanel an event when a paid plan or a hosted server changes: a Checkout starts or expires, a plan starts, changes, is cancelled or ends, a payment succeeds or fails, a payment is refunded or disputed, the Customer Portal opens, or a hosted server is set up, fails to set up, stops after no use, starts, changes its machine, stops at the end of its plan, is renewed or is deleted. Each event has your account ID and only fixed values: the action, the plan, the billing period, the currency, the amount that Stripe reports, the server size, the start reason and an error code. It has no email, name, Stripe ID or server ID. The desktop analytics setting does not stop these events, because the account service sends them and not your computer.
The account service also records a return from Checkout without payment and later payment recovery. Verified paid invoices produce a revenue event in USD, with the original amount, currency, and dated exchange rate. Refunds and disputes produce an event with the same USD amount, currency, and dated exchange rate. Daily totals contain recurring revenue, overdue recurring revenue, paid accounts, paid servers, and scheduled cancellations. These totals have no account ID. The service stores payment facts and a delivery ledger in D1 to prevent duplicate revenue events. It does not send Stripe identifiers, server identifiers, or Checkout return tokens to OpenPanel. An account deletion clears its profile reference and stops pending account event delivery. The account service also sends an event when it makes a new account (with the app used to sign in) and when it saves the first website visit of an account. A payment event and a revenue event include that first visit when the account has one.
AI conversation context
When a provider session is replaced, Kasper Agent sends a bounded excerpt of the current conversation to the selected provider. The agent can request older messages from that same conversation through local history tools. Requested text and selected saved work steps are then sent to that provider. These tools exclude messages before the latest context reset and cannot search another conversation. Channel history keeps its existing membership and task checks. Messaging history stays within its current link. The full conversation stays in local SQLite storage. No history text is sent to the account service or analytics by these tools.
Local scripts
Local scripts is off by default for each agent. When enabled, scripts that run as the same OS user on the host can read a local token and use the loopback API. They can send messages, run routines, read pending questions and approvals, and submit answers or approval decisions. Kasper Agent redacts secrets in API responses. Secret questions and browser takeovers return notices only and must be completed in Kasper Agent. Kasper Agent does not send these API responses to the account service or analytics. A script can send the data elsewhere under its own configuration.
Agent and host usage
The Usage view stores numeric token counts, activity counts, provider and model identifiers, internal session and turn identifiers, timestamps, and cost estimates in the host's local SQLite database. Collection starts when this feature is installed. It does not import old provider transcripts or store message contents, credentials, or raw provider responses in analytics records.
Authenticated members of a host team can read aggregate usage for that host's agents through the Team API, including from mobile. Desktop can also show the combined totals for all agents on one host, with an optional agent filter. A host-wide response carries the combined totals, one row per day, one row per model, one aggregate row per agent, identified by the agent's internal id, and one row per day and provider with that provider's token count and cost estimate for the day. Agent names are not part of the analytics payload; the client shows them from the agent list it already reads. These records are separate from product analytics and are not sent to OpenPanel or stored by the account service or Signal service. Conversation clearing retains usage; agent deletion removes it. A duplicate agent starts with no usage history.
Authenticated members of a host team can also see that host's storage through the Team API: how much disk space each location, agent and chat uses, and the name, size, type, date and chat title of each sent or generated file. The response contains no file paths, and workspace and download files are counted only as totals. Only owners and admins can delete a file or clear caches and logs. A deleted file is removed from the host's disk; the message that sent it stays and shows that the file is not available.
Costs are API-equivalent estimates in USD, not subscription charges. Missing usage, unknown prices, and incomplete billing inputs remain marked as unavailable or partial.
Product analytics
Product analytics is off now, and nothing in this section is sent. When it is on again, the
production website records anonymous page views using only fixed paths: /, /join, the
download pages, the news and guide indexes, and published articles. It also records download clicks,
clicks on allowlisted public links, invitation validity, and open-app actions on invitation pages.
The production desktop app records application, sign-in, onboarding, agent, message, turn, prompt,
approval, queue, routine, team, browser, search, Remote Desktop, update, marketplace, memory,
provider, voice transcription, reaction, maintenance, Hosted Site, and confirmed
application-version-change actions. Event properties are limited to metadata such as counts, result
states, timing, provider, model, reasoning effort, application version, operating system, and coarse
failure codes.
The configured production mobile app records app opens and foreground returns, sign-in QR pairing and camera-permission outcomes, host connection attempts and losses, conversation-load outcomes, message and prompt-answer submissions, attachment operations, agent/routine/memory actions, server selection/join/leave, search result counts, pin/unpin, hide/unhide, Usage views and sign-out. Mobile properties include app version/build, iOS or Android, result, timing, bounded connection stage, counts, coarse attachment size buckets, and provider/model/reasoning metadata where available. Mobile never sends scanned QR values, install-referrer URLs or route identifiers. It does not emit host lifecycle events again. Agent/host token and cost reports remain separate local data.
Analytics events do not contain message or direct-message text, prompts, replies, generated content,
search queries, embedded-browser URLs, paths or page titles, file names, local paths, commands, raw
error messages, or local identifiers for agents, threads, turns, messages, servers, and team members.
Website page views carry the five standard campaign tags utm_source, utm_medium, utm_campaign,
utm_content, and utm_term when a visitor arrives through a campaign link. Each tag is sent only
as a lowercase label of at most 64 characters made of letters, digits, dots, hyphens, and
underscores; any other value is dropped rather than shortened. No other query parameter, hash, or
invitation value is sent. Session replay and automatic interaction capture are disabled.
When a user signs in, OpenPanel receives the Kasper Agent account ID and normalized account email so UI
actions can be associated with the account that started them. The email is stored on the OpenPanel
profile and is not copied into individual event properties. Agent lifecycle events are emitted once
by the local host and associated with the host owner's account; clients that observe a remote host do
not emit the lifecycle again. Sign-in attempts and website activity remain anonymous until an account
has been verified. Landing-page attribution includes an allowlisted source category, an allowlisted
platform name (or unknown), and the referring domain when available. A recognized utm_source tag
takes precedence over the referring domain for platform classification; unrecognized tags are not
sent. Attribution excludes referrer paths, query parameters, fragments, credentials, ports, and
campaign URLs other than the allowlisted tags described above. Website page and article events carry
the path of a news article, guide or comparison published on kasperagent.com, together with the collection name, the
reading position reached (start, half, or end), and the section of the page a link was clicked in.
That path is a published article address and nothing else: it is matched against the site's own list
of articles, so no other part of a visited URL can be reported through it. Reading position is taken
from where the article sits on screen, never from how long it was open. Referrals from kasperagent.com and its subdomains are omitted.
The production website also saves the first visit of the browser in its localStorage: the source
category, the platform name, the first website page, the day, and the allowlisted campaign tags.
It saves no referrer, IP address or identifier. A later visit does not change it, and it is not used
after 90 days. When you sign in on the web, or open the page after a desktop checkout in the same
browser, the browser sends it to the account service. The account service keeps the first one that
it gets on your account and sends it to OpenPanel with your account ID. To remove it from a
browser, clear the site data of kasperagent.com. OpenPanel can also derive
session, device, browser, operating-system, network, and approximate geographic metadata from a
request. The analytics service runs on Kasper Agent's self-hosted infrastructure and receives events
through analytics.kasperagent.com.
When analytics is on, it is enabled in production by default. Desktop users can disable it under Settings →
General → Permissions → Share product analytics. The preference is stored locally and disables both UI
analytics and lifecycle analytics emitted by the local host. Website analytics does not use the
desktop preference. Mobile has its own phone-wide Settings → Privacy → Share product analytics
preference, independent of desktop and host collection. It defaults to enabled in a
configured production build, is read before collection starts, and remains disabled if the stored
preference cannot be read. Disabling it drops pending mobile events; it does not remove previously
received events or retract an in-flight request. There is no persistent offline analytics queue.
Development and preview mobile builds do not collect product analytics. Mobile sign-in uses the
same account ID and normalized email profile traits described above. Before mobile sign-in, up to
100 sanitized events stay in process memory for at most 30 minutes from the first buffered event.
They are sent once with their original timestamps after an account becomes available. Opt-out,
expiry, and process exit discard unclaimed events. The oldest event is removed when the buffer is
full. Sign-out ends the old account's operation scopes; later signed-out activity can be associated
with the next account that signs in. No anonymous mobile event is sent before that association.
The local host also records how the agents are used:
- Websites. When a page in the embedded browser reaches a new registrable domain, the host sends
that domain (for example
linkedin.comforwww.linkedin.com) and whether the user or an agent opened it. It never sends the subdomain, path, query, fragment or page title. A subdomain under a shared suffix is reduced to that suffix, souser.github.iois sent asgithub.io. IP addresses, single-label names,localhost, and names with no public suffix (for example.local,.lan,.internalor.home.arpa) are not sent. - Tools. When a turn completes, the host sends one count per kind of tool the agent used (for
example command, file change, web search, browser, or MCP), how many of those calls failed (Claude
does not report failed tool calls, so its count is 0), and
the plugin: the slug of an Kasper Agent catalog plugin,
builtinfor Kasper Agent's own tools, orcustom. The tool name is sent only for Kasper Agent's own tools and catalog plugins. The name, address and command of a server the user added, the tool arguments and the tool results are not sent. - Routine runs. The host sends the outcome of a routine run, whether it was scheduled or manual, and its schedule type (for example daily or weekly). The routine name and instruction are not sent.
- Setup. At most once a day, the host sends counts of agents, enabled routines, custom MCP servers, local skills and community skills; the slugs of enabled catalog plugins and of curated skills and agents; the providers in use; and whether Computer Use is enabled.
- Resource use. At most once a day, the host sends a summary of the previous day: the memory and CPU use of Kasper Agent's process groups (main, windows, browser tabs, GPU, the database and voice processes) and of each provider's CLI and its child processes, by provider id; the main process responsiveness; agent database statement times and counts; counts of processes that stopped unexpectedly, by reason; and the computer's memory and processor class, architecture, and whether it is a server. Memory is rounded to 50 MB. Process IDs, program names, command lines and paths are not sent. A day that ends while analytics is off is not sent.
- Agent source. Turn events say whether the agent came from a curated listing, a community listing, or neither, and name only a curated listing. Marketplace events name only a curated skill, agent or catalog plugin.
Hosted Site analytics records only the operation, entry point, result, and bounded failure code. It does not contain the site's URL, hostname, title, source path, site ID, or content. A one-time backfill may update the email trait of an existing OpenPanel profile matched to a current account; it does not create profiles for accounts without existing analytics activity.
OpenPanel event and profile data has no automatic retention limit. It remains stored until it is removed manually or the analytics project is deleted. OpenPanel analytics does not change where agent workspaces, conversations, attachments, browser data, and team data are stored.
Data stored by the central account service
The account service runs on the Kasper Agent server (kasper-server), behind the Cloudflare proxy.
It keeps structured records in its D1 database and files in its R2 storage: account avatars, host
logos, published hosted site files, marketplace skill bundles and icons, and the images of published
agent templates. On that server, D1 is a SQLite database and R2 is a file store, both on the server's
disk. The server makes a copy of both once each day and keeps each copy for 14 days. The server keeps
no web request log.
The service stores:
- an account ID, normalized email address, identity key, optional name, optional avatar URL, and creation and update times;
- email sign-in challenges with the email address, hashes of the challenge ID, one-time code, and source IP address, attempt counts, and lifecycle times;
- account sessions with a session ID, account ID, token hash, creation time, last-use time, expiration time, and optional revocation time;
- rate-limit keys as hashes, their fixed window start time, and the attempt count;
- short-lived team authentication tickets with a ticket hash, account ID, team server ID, lifecycle times, and optional consumption time;
- remote host records with the owner, name, optional logo, device public key, and authorization epoch;
- remote memberships and invitations with roles, states, hashed invitation tokens, and lifecycle times;
- logical remote session records with the account, host, originating account-session hash, start, end, and expiration times;
- the current account avatar file and its content type when the user uploads an avatar.
- optional host logo files and their content types when the owner uploads a logo.
- the first website visit of an account, when a browser sends it: the source category, platform name, first website page, day, allowlisted campaign tags, whether it came from a sign-in or a checkout, and the save time. Deleting the account removes it.
- webhook routes: for each webhook routine of a host, the opaque route ID, the host ID, the owner account ID, the link time, and the revocation time. When the routine stops using a route, or the host is deleted, the service sets the revocation time and the route stops working. The service keeps the row with these fields permanently, so that the old public URL never belongs to another host. It does not store the routine, the secret, or request bodies.
- published agent templates: the agent name, title, instructions, avatar, routine names, schedules
and instructions, marketplace skill references, the
SKILL.mdtext of local skills, the local agent ID, a share card image made from these fields, and creation and update times. Anyone with the link can read a template, and sites such as X show the share card when the link is posted. Unpublish removes the template content and its images. The service keeps the link ID, the account ID, the local agent ID and the unpublish time, so publishing the same agent again gives back the same link. Deleting the account removes them. Templates do not include workspace files, memories, conversations, or integration credentials. - billing records when the account starts a paid plan: the Stripe customer ID, and for each subscription the Stripe subscription ID, plan, billing period, currency, price, status, period end, and whether it ends at the period end. The service also keeps the ID, type and receive time of each Stripe webhook event for 7 days, to ignore a repeated event. These records hold no card data.
- hosted sites: the hostname, title, description, framework, state, owner account ID, lifecycle times, and for each deployment the file list, sizes and content types. The published site files are in R2. Anyone can read a published site. Deleting a site removes its files.
- marketplace skills: the owner account ID, name, description, category, review state, version records, install counts, and the skill bundle and icon in R2.
- reports about a hosted site: the hostname, the reason, the optional details text, a keyed hash of the source address (of its /64 for IPv6) for each day, the review state and the creation time.
The service does not store plaintext one-time codes, account session tokens, or team authentication tickets in D1. It returns a new plaintext secret only to the client that requested it. The desktop app encrypts its account session token with the operating-system storage protection before it writes the token to disk.
The desktop app also keeps, for each joined server, the ID of its logical remote session and the
Signal address, so that the next start asks only for a new ticket. The file
(kasperagent-remote-sessions-v1.bin) is encrypted with the same storage protection and is not written
when that protection is unavailable. It names only the account that signed in. A session ID gives no
access without that account's session token. The app removes the file at sign-out or when another
account signs in, when it starts with no account signed in, and forgets a server's session when it
disconnects from the server or removes it. When the app quits, the session stays open in the account
service for the next start; signing out or disconnecting the device's sign-in ends it, as before.
Settings → General → Fast connection to servers turns this off. Off, the app removes the file at
once, keeps nothing on disk, and ends each session when it quits. Turned on during a run, it keeps the
sessions that are open at that time. The setting is on by default and is stored
in kasperagent-remote-session-reuse-preference-v1.json.
Account avatar URLs are public, long-lived resources. A person who has the complete URL can request the avatar without an account session.
Hosted servers
Each account can buy hosted servers. A hosted server is a Linux Kasper Agent computer that runs in a boat sandbox. The sandbox holds the server's workspaces, conversations, attachments, browser data and team data, the same as your own computer would. The server stops 15 to 30 minutes after its last use and starts again when you press a key or click in an app that shows it, when a Slack, Discord or Telegram message addresses Kasper Agent, or a few minutes before its next scheduled routine run. Use means that an agent works, a remote desktop is open, a file moves, or you sent a message, made a change, typed or used a shared browser view in the last 5 minutes. An app that has focus (a focused window or tab, or the phone app in the foreground) also counts, for at most 30 minutes after your last message, change or typing, or after you return to the app. The app tells only the server that it has focus; the account service gets no new data. An app that is only open without focus does not count. To show whether a server is asleep, the app asks the account service for its state. This request stores nothing. When boat stops the sandbox, boat keeps a snapshot of its disk until the server starts again. Deleting the server deletes the sandbox. A hosted server updates itself: it downloads the newest release from GitHub Releases, as an installed build does, installs the Ubuntu packages that the release needs from the Ubuntu package servers, and starts it at its next start, or when a member with update access installs it from Server Settings.
For each hosted server, the account service stores the owner, name, size and the size of a pending plan change, the plan, billing interval and currency, the open Stripe Checkout session ID, desired and reported state, a reason code when the server fails to start, the reason for its last start, the boat sandbox ID, a hash of the setup claim with its expiry and first-use times, the ID of the account session that the server signed in with, the time of its last use, the end of its boat stop timer, the time of its next scheduled routine run (not the routine or its instructions), and creation, update and deletion times. After a server is deleted, its record stays so that the service never loses track of a sandbox. It also stores the ID and receive time of each boat webhook delivery for 7 days. The account service does not receive the server's conversations, files or commands, and its boat key cannot read them.
The account service gives each sandbox a name in boat, so that an operator can find a server in the
boat dashboard: kasperagent-, the plan, your account email with each other character as -, and the
first 8 characters of the server ID, such as kasperagent-starter-ada-example-com-1a2b3c4d. boat keeps
the name with the sandbox.
Central data retention
The account service runs a maintenance task once each day. The task removes:
- sign-in challenges after they expire or are consumed;
- account sessions after they are revoked (older already-expired sessions are also removed);
- team authentication tickets after they expire or are consumed;
- rate-limit records after their 15-minute window ends.
These technical records are normally removed within 24 hours after they become inactive. A failed maintenance run can keep them until a later successful run. The task logs only aggregate deletion counts. It does not log account IDs, email addresses, IP addresses, tokens, or ticket values.
Replacing or deleting an account avatar or host logo removes the previous R2 object on a best-effort
basis. Account/device sessions and logical remote sessions deliberately have no time-based expiration.
Logout or device revocation ends access; removing a team membership ends access to that team.
Revoking an account/device credential disconnects its active remote sessions, without disconnecting
other authorized devices. Older remote sessions without a device binding are disconnected account-wide
on revocation. Short-lived QR codes and connection tickets still expire.
Settings → Profile → Account sessions lets you list and disconnect other desktop or mobile sign-ins.
Only device/session labels, IDs, sign-in times and last-activity times are returned, never credentials.
Mobile Settings can update your account name and photo through the same account API and list or
disconnect account sessions. The appearance preference is stored only on the phone.
After a profile change, the account API sends Signal a signed notification identifying the account.
Signal notifies only that account’s connected devices, without including the profile or credentials.
Devices check the profile and joined-server directory on a cold launch and every 15 minutes while active.
Returning from the background does not trigger an automatic check. On mobile, Notification Center and
other iOS inactive transitions do not count as leaving the app and do not reset the timer. Profile change notifications
can trigger an earlier refresh. These authenticated requests retrieve
account identity (name, email and avatar URL), not conversations or workspace content.
Mobile hidden and pinned chat preferences are stored on the phone, separately per account and server. Conversation read/unread changes are stored on the desktop host and shared with your other connected devices.
The mobile app keeps a support log of up to 1,000 events in the phone's system cache: app version, system and device model, app state changes, connection steps with server IDs and error text, the desktop app version and protocol support of each server, the method, address without query, status and time of its requests, including Team API requests to the desktop, and app warnings and errors. It does not record message text, files, request bodies or headers, and it masks tokens, keys and email addresses. The app never sends the log. Settings → Support shows it and lets you save the file or clear it.
Mobile chat uses a local symbol beside links. It does not fetch website icons or Markdown images when displaying a conversation. Link destinations are contacted only when you choose to open them.
Mobile chat can send selected files to the conversation's desktop host through the existing encrypted team connection. Text pasted into the input is processed only after the user pastes it. A text paste longer than 4,000 characters becomes a text attachment. Selected documents can also have a temporary copy in the phone's system cache. Attachments added while editing a queued message are saved in the phone's app document storage, with references in the saved edit, so they survive an app restart. Those draft copies are removed when the attachment is removed or the edit is saved or cancelled. A message that the phone has not delivered yet, for example while the server is offline, is saved with its text, reply target and files in the phone's app document storage, separately per account, so it survives an app restart. The phone sends it when the server is online again, and removes the copy when the host confirms it, or when you edit or cancel it. Nothing else receives it. Sign-out does not remove the copy: it is sent after you sign in to the same account again. A message to an agent or server that you no longer have stays on the phone, because no chat shows it to cancel; removing the app removes it. Uploads are limited to 10 MB per file on mobile; successful uploads become managed attachments on the host. Camera capture uses an in-chat preview. Photo selection uses the phone's system interface. Image attachment previews are downloaded from the desktop host through the same encrypted connection. Other attachments are downloaded when you choose Open or save. The phone creates a temporary file for the system share sheet and removes it when that sheet closes. The app you select can keep its own copy. The account service does not receive these files. When you share text, a link, an image or a file from another app to Kasper Agent, the phone keeps a copy of each file in its app cache until the chat that you choose has read it, or until you close the share sheet. Nothing is sent until you send the message. To find out whether a shared link points to an image, the phone requests the link from its website and reads only the response headers. When the link is an image, the phone downloads it and attaches it in place of the link. It stops a download after 10 MB, and a larger image stays a link.
Mobile dictation uses the phone's speech recognition only after you press the microphone. It asks for on-device recognition. On iOS, this applies when the phone supports it for your language. On Android, it applies when the language model is installed. Otherwise, or when on-device recognition fails before it recognizes any speech, the phone's recognition service, Apple or Google, receives the audio. The recognized text goes into the message field and is sent only when you send the message. Kasper Agent does not store or send the audio.
Email delivery and infrastructure providers
Kasper Agent sends sign-in, team invitation, and welcome messages through its own mail server on the
Kasper Agent server (Maddy, mail.kasperagent.com). It delivers each message directly to the email
provider of the recipient, which receives the recipient address and the message content. The mail
server keeps a message only until it is delivered. Its log records the recipient address and the
delivery result of each message; the server keeps only the newest 30 MB of that log. A sign-in message contains the
one-time code and its expiration time. A team invitation can contain the inviter address, team name,
role, and invite URL. When the first cloud server plan of an account starts, a welcome message goes
to the account address. It contains the plan name and the server name. The HTML version of a message loads the Kasper Agent logo from kasperagent.com when
the mail client shows images. The image address is the same in every message and identifies no
recipient.
The contact form on kasperagent.com/contact sends your message to the Kasper Agent mailbox on the same
mail server. The message contains the email address, topic and text that you enter, and the name and
company when you enter them. The account service stores none of these values. To limit how many
messages one address can send, it keeps a hash of your IP address in its rate-limit records. The Kasper Agent team receives the message
in its mailbox and uses your address only to answer you.
The account service processes account and configuration API requests; Cloudflare passes them to it. Neither carries Team API, file, message, command, Remote Desktop media, or Remote Desktop input traffic. It forwards sealed iPhone Live Activity updates and iPhone notifications that it cannot read; see iPhone Live Activity and iPhone notifications. For an agent's Slack app, it exchanges the Slack sign-in and serves the install page; see Slack connections. It does the same for the Discord app; see Discord connections. For the Kasper Agent Telegram bot, it records which computer answers each chat; see Telegram connections. Cloudflare and the email provider can keep their own security, delivery, and network logs under their own policies. These provider logs are outside the Kasper Agent application database and its daily maintenance task.
The public status page at status.kasperagent.com is on GitHub Pages. GitHub serves it and keeps its
own request logs under its own policy. The page has no analytics and no cookies, and it loads
nothing from other sites. No automatic job checks the Kasper Agent services or updates the page now.
When a maintainer runs the check script by hand, it sends plain requests that carry no account or
user data. Incidents on the page come from issues with the status label in the public Kasper Agent
repository. When a maintainer runs the status webhook script by hand, it sends the public incident
and service state to webhook addresses that the Kasper Agent team sets, such as a team chat channel. It
sends no account or user data.
Paid server plans use Stripe. You enter card and billing details on Stripe's pages, not in Kasper Agent.
Stripe sends the account service the subscription state, the plan, its price, the period, and the
account and server IDs that the subscription names, never the card number. When you choose a plan
for a new hosted server, the account service sends Stripe your account email and account ID (to
make the Stripe customer), and the server ID, the plan, the billing period and the currency (to
open Stripe Checkout, checkout.stripe.com). When you delete a hosted server, the account service
tells Stripe to cancel its plan. When you manage billing,
the account service sends Stripe your Stripe customer ID, and the subscription ID of the plan you
change or cancel, to open the Stripe Customer Portal (billing.stripe.com). Stripe keeps the
customer, invoices and payment records under its own policy, also after the subscription ends.
Billing is off, and Stripe receives nothing, when the account service has no Stripe key.
Data stored on the Kasper Agent computer
Saved agent memories, their inclusion settings, and their full-text search index stay in the local SQLite database. Essential memories enter the agent's provider instructions within a fixed size limit. Other saved memories reach the provider only when the agent retrieves them with a memory tool. Search runs locally and does not use an external search or embedding service. Memory content is not included in analytics; provider output uses the application's secret redaction. When an agent saves, changes or forgets a memory, its chat shows a marker with the start of the memory text, redacted. The marker is kept with the conversation in the local database, and the devices that can read the conversation (the phone and the web client) receive it with the chat. They can already read the agent's memories.
~/KasperAgent/Agentscontains one workspace per agent. A profile written by a release before the bot-to-agent rename holds them under~/KasperAgent/Bots; the application moves them on first launch.~/KasperAgent/Sharedcontains managed transfers shared between agents, and~/KasperAgent/Shared/Data/agent-data.dbholds the records the agents keep for themselves between tasks. Every agent on this computer can read and write every table in that file, and the user can delete any table in agent settings.~/KasperAgent/Downloadscontains files downloaded by the embedded browser.~/Library/Application Support/Kasper Agentcontains the Kasper Agent SQLite database, agent metadata, conversations, message queues, direct messages, reactions, read state, attachment drafts and indexes, team configuration, local team members and sessions, the shared browser profile, cookies, application preferences, and the provider CLIs Kasper Agent downloads. The downloaded CLIs are kept in one store for the whole computer, which no other profile data shares.- The local team configuration contains team member profiles, password hashes and salts when local password sign-in is used, invite and session token hashes, and the team identity key pair.
~/.codexis owned by Codex CLI and contains its login and thread data. Kasper Agent does not copy or manage Codex credentials.~/.claudeis owned by Claude CLI and contains its login and session data. Kasper Agent does not copy or manage Claude credentials.- The MCP sign-ins are kept in
~/Library/Application Support/Kasper Agent, encrypted by the operating system's secret storage in the same way as provider API keys. One record per server address holds the client registration and the access and refresh tokens. Removing the server in settings, or choosing Sign out on it, deletes its record. These values are redacted from logs, exports and diagnostics. The port and secret of the local MCP sign-in server are kept in~/Library/Application Support/Kasper Agent/kasperagent-mcp-oauth-proxy-v1.json, encrypted in the same way. - The GitHub connection (Server settings > Connectors) is kept in
~/Library/Application Support/Kasper Agent/kasperagent-github-connector-v1.json, encrypted by the operating system's secret storage. It holds the GitHub access and refresh tokens, the account name, ID and avatar address, and the port and secret of the local GitHub MCP server. - The ElevenLabs API key for dictation is kept in
~/Library/Application Support/Kasper Agent/voice-api-key.json, encrypted by the operating system's secret storage. The app window never receives the key back. Remove key in Settings → Voice deletes the file. The key is redacted from logs, exports and diagnostics. While the connection is on,provider-state/githubin the same folder holds the access token and the Kasper Agent GitHub App's installation tokens in plain text, with mode 0600, forghandgitin agent tools. Kasper Agent deletes that folder when you disconnect and when the app closes; after a crash it stays until the next start. The tokens are redacted from logs, exports and diagnostics. - The Bitwarden connection keeps a CLI session key in process memory only. Kasper Agent does not
save it to a file. Disconnect, eight hours without vault use, and app exit stop this connection.
The log redactor can retain values in memory until exit to mask later messages.
The Bitwarden CLI keeps its own encrypted vault cache. Kasper Agent reads login items in the folder
Shared with Kasper Agent. Agents receive item ids, titles, and usernames; passwords and authenticator codes go through the main process to the browser page. This folder is an Kasper Agent access rule; the CLI session key can decrypt the wider vault. Use a separate Bitwarden account if you need the password manager itself to enforce that separation. - The 1Password connection (Marketplace > 1Password) is kept in
~/Library/Application Support/Kasper Agent/kasperagent-onepassword-connector-v1.json, encrypted by the operating system's secret storage. It holds the service account token and the account ID only. Kasper Agent keeps the list of logins (titles and web addresses) in memory, never on disk. A password or a one-time code is read from 1Password when the browser fills it, goes only to that page, and is never sent to an agent, a provider, a log or a team member. The token and each filled value are redacted from logs, exports and diagnostics. An owner or admin of a joined server can paste a service account token for that server in Server settings › Connectors. The token goes once, over the encrypted connection, to the server, which keeps it in the same file on its own disk. The computer that sent it does not keep it, and no answer from the server carries it. ~/Library/Application Support/Kasper Agent/logs/trace.ndjsonis a local trace of IPC calls, provider turns, main-process failures, and the steps of each connection to a joined server. Each line holds a time, the IPC channel name, the turn origin, the failure origin (uncaughtExceptionorunhandledRejection) or the connection step (such asremote-connect:ticket), the duration, and the outcome word. A connection step does not name the server. The failure's error text goes only to the redacted log. The trace holds no payloads, messages, URLs, paths, or identifiers, and it goes through log redaction before it is written. It is kept to two files of 2 MB each and is never sent.~/Library/Application Support/Kasper Agent/logs/resources.ndjsonholds one line a minute: the memory and CPU use of each Kasper Agent process group and provider id, the main process delay, the number of agent database statements, active turns and browser tabs. It holds no process IDs, program names, command lines or paths. It is kept to two files of 1 MB each and is never sent.~/Library/Application Support/Kasper Agent/kasperagent-resource-summary-v1.jsonholds the totals of today and of the previous day for the daily analytics summary and the diagnostics export.~/Library/Application Support/Kasper Agent/kasperagent-push-notifications-v1.jsonholds, for each member iPhone that gets notifications from this host, the session ID, the member ID, the Apple push token, the secret that seals the notifications, the interface language, and the notification choices. Only the user can read the file, and it is not in the diagnostics export or the data export. See iPhone notifications.
Attachments copied into Kasper Agent remain in managed storage after their original file is moved or deleted. All agents share the embedded browser profile, including cookies and website sessions. Websites receive the browser's Chromium user agent. HTTPS sites and local loopback HTTP sites also receive basic client hints with the Chromium major version, operating-system name, and desktop flag. Google account requests retain the Electron version token for sign-in compatibility.
Remote Team API
When the owner publishes Kasper Agent, the app starts an authenticated Team API on a localhost port. The client and host use a separate Kasper Agent Signal service to establish WebRTC. Signal carries only short-lived authentication, SDP, and ICE messages. Team API data uses WebRTC DataChannels. Remote Desktop media and input use a separate WebRTC connection. A paste in the Remote Desktop viewer sends the member's clipboard text to the host, which puts it on the host's clipboard. The live browser view sends compressed images of the host's browser tab, and the watching member's pointer and key input, over that same media connection. ICE uses a direct peer-to-peer path when possible. If a direct path is not possible, encrypted WebRTC traffic uses an Kasper Agent coturn relay.
Agents, conversations, queues, direct messages, attachments, browser data, prompts, approvals, and Remote Desktop data remain on the host. The central account service does not copy them into D1 or R2. The Signal service does not proxy them or write them to logs. The host does not need a public inbound port, except for a WhatsApp number, whose messages come from Meta to the host itself; see WhatsApp connections. The things Signal passes to a host are the Slack events of an agent's Slack app, the Discord mentions of the Discord app, the updates of the Kasper Agent Telegram bot, and the requests to webhook routines, in transit; see Slack connections, Discord connections, Telegram connections, and Webhook routines. For Discord and Telegram, Signal also carries the host's answers to the platform.
An owner or admin of a joined server can manage its host from their own computer, or from the
browser client at /app. A provider API key, a custom endpoint key or header, the code that a
provider sign-in page shows, and a new server logo then travel from that computer or browser to the host over the same encrypted team connection. The
browser does not store a key. The host stores them as it stores a change made on the host.
No response returns a key, and neither computer writes request bodies to its logs. For a sign-in on
another device, the host sends the provider's sign-in link, and for Codex, Grok and Cline its
one-time code, to that computer or browser, which shows them and opens the link only when the admin
asks. The provider's CLI on the host receives the login; no token travels to the admin.
Other network connections
Network traffic can also occur when:
- the local Codex App Server connects to OpenAI;
- the local Claude Agent SDK connects to Anthropic through Claude CLI;
- a user or an agent visits a page in the embedded browser;
- a user submits text that is not a web address in the browser address bar, which sends the query to Google Search;
- a locally installed Codex plugin connects to its service;
- an agent looks for a skill on GitHub (
search_skill_sources,fetch_skill_source). Kasper Agent sends the agent's search words and the repository and folder addresses toapi.github.com, and downloads the skill files fromraw.githubusercontent.com. The requests carry no account, token or other credential, and nothing about the user's agents, conversations or files. A fetched skill is installed only after the user approves it, unless the agent has Full access and approves its own actions; - an MCP server the user enabled is reached at its own address, and, when that server asks for a
sign-in, Kasper Agent connects to the server's authorization service to register itself, to exchange
the grant the browser returns, and to renew the token. When the user signs out of the server or
removes it, Kasper Agent sends the tokens it deleted to that same service once, to revoke them.
Agents reach a server that Kasper Agent signed in to through a local server on
127.0.0.1, which adds the token to each call, so the token does not go to the agent's process. Nothing about the user's agents, conversations or files is sent in those requests. The registration names Kasper Agent's logo atkasperagent.com; an authorization service that shows it on its sign-in page can make the browser load it fromkasperagent.com; - the user presses Install on the 1Password page. Kasper Agent downloads the 1Password CLI release that it
pins from
cache.agilebits.com, checks its SHA-256, and keeps it in~/Library/Application Support/Kasper Agent/provider-state/1password-cli. The request carries no user data; - the user dictates for the first time, or presses Download in Settings → Voice. Kasper Agent
downloads the speech model that it pins, Parakeet or Whisper turbo, from
huggingface.co, checks its size and SHA-256, and keeps it inruntimesin the application data folder. The request carries no user data. Dictation audio from these models stays on the computer, and the chosen model and language are saved invoice-preference.jsonin the same folder; - the user selects ElevenLabs Scribe v2 Realtime in Settings → Voice and dictates. While the
microphone records, Kasper Agent streams the audio and the chosen language to
api.elevenlabs.iowith the user's own API key, and receives the text. Nothing else is sent: no conversation, file or agent instruction. ElevenLabs handles the audio and the text under its own policy and the user's ElevenLabs plan. The local models send nothing; - the user connects Bitwarden. Kasper Agent runs the installed
bwCLI to sync with the server already configured in that CLI, including a self-hosted server. It syncs before listing or filling logins. These calls send no Kasper Agent conversations, files, or agent instructions to Bitwarden; - the user connects 1Password. Connect runs the user's own 1Password CLI (
op) on this computer to create the vault "Shared with Kasper Agent" and a service account that can read only it. Kasper Agent then reads that vault from 1Password's servers with the token: the vault names, the login titles and web addresses, and, when an agent signs in to a site, that login's username and password or code. Nothing about the user's agents, conversations or files is sent to 1Password; - the user connects GitHub in Server settings. Kasper Agent asks
github.comfor a sign-in code and a token, renews the token, and reads the account name and the repositories of the Kasper Agent GitHub App fromapi.github.com. The GitHub page in Server settings loads the account picture from the address that GitHub gives, on GitHub's image host. Agents then reach the GitHub MCP server atapi.githubcopilot.comand GitHub itself throughghandgit, with that token. So that GitHub shows the Kasper Agent app as the author of an agent's work, Kasper Agent sends that token to the central account service (api.kasperagent.com) about once an hour, and when you open the repository list. The service uses it only to ask GitHub which repositories you can push to, and gets back short-lived installation tokens for those repositories. It does not store or log either token, and it gets no chats, files or commands. Agents reach the GitHub MCP server through a local server on127.0.0.1, which adds the right token to each call; - an installed build checks GitHub Releases for updates;
- Kasper Agent checks for new provider CLI releases when it starts, every 3 hours, and when you
select
Check for updates. WithUpdate provider tools automaticallyon, which is the default, it then downloads each new release from the same source that a click on Update uses. It asksapi.github.comfor Codex,registry.npmjs.orgfor Claude, OpenCode and Cline,x.ai/clifor Grok, andraw.githubusercontent.com/agentclientprotocol/registryanddl.google.com(for the download size) for Gemini, and the same registry anddownloads.cursor.com(for the download size) for Cursor, and it reads a list of blocked versions fromraw.githubusercontent.com/AhmedAlNeaimy/kasperagent. These requests contain no account, agent, conversation or file data; - an agent shows a visual reply, an agent checks its page with
html_preview, or a user opens an HTML attachment, shared file or workspace file in the file preview. The page is HTML that the agent or the file wrote. It runs its scripts in a sandbox and can load scripts, styles, fonts and images from any address, such as a CDN. The server that holds those files gets the request and the network address of the computer, but no Kasper Agent cookies. The page cannot read the app, the conversation or other files.html_previewdraws the page in a hidden window that has its own session in memory. The web client gets the page through the host connection and runs it in a sandboxedsrcdocframe with an opaque origin, so the page cannot read the web client's storage or its host keys; the browser sends no referrer for its requests. The mobile app does not run the page: it shows the page as its file; - a user opens an explicitly labeled external support or setup link;
- a Slack workspace is connected. See Slack connections;
- a Discord server is connected. See Discord connections;
- a Telegram chat is connected. See Telegram connections;
- a WhatsApp number is connected. See WhatsApp connections.
Webhook routines
An administrator can give a routine a webhook trigger. The routine then gets a public URL and a signing secret. The host stores the trigger and the encrypted secret in its local SQLite database. The signing secret is encrypted with the operating system's secret storage. It is shown one time. Management screens do not return saved secrets.
Requests to a webhook routine pass through Kasper Agent's Signal service to the connected host. Signal uses the sender's IP address in memory for rate limits. The account service keeps only the route metadata above. Neither cloud service stores or logs request bodies. The host verifies the request signature before it accepts the event. If the host is offline, the sender receives an error and must retry. There is no cloud event queue.
The host keeps a receipt of each request for 7 days, to ignore a repeated delivery. A receipt has the delivery ID, the event type, the result, and the run ID, but not the request body. The event is added to the run instruction, which the host stores with the run. Event data can reach the routine's model provider, as other routine input does.
Change a routine to a schedule, or delete it, to stop its URL. Deleting a routine deletes its receipts.
Slack connections
A workspace member installs the Kasper Agent Slack app in their workspace from Kasper Agent on their computer. The account service exchanges that install with Slack, because the app's secret lives there. It records which Kasper Agent computer answers the workspace: the Slack workspace ID, the computer, the Kasper Agent account that connected it, and the Slack app and bot user IDs. It keeps no Slack token and no message. It gives the bot token to the computer encrypted to a key that only that computer has.
Slack sends the workspace's events, which contain the Slack messages in the channels Kasper Agent is in
and its direct messages, to Kasper Agent's Signal service (signal.kasperagent.com). Signal checks Slack's
signature and reads only the app ID and the workspace ID, to find the computer, and the type,
channel type, thread and bot ID of the event, to know whether it addresses Kasper Agent. It passes each
request to that computer over its Signal connection, in transit only: it does not store or log the
message. The answers go from the computer to the Slack Web API directly.
- Stored on the host. The bot token is encrypted by the operating system's secret storage, like provider API keys, and redacted from logs, exports and diagnostics. The database holds the workspace name and IDs, which agent is its Slack Orchestrator, and one row per Slack thread that an agent answers. The messages of that thread are kept as a conversation of that agent, with the Slack display name of each author, and files people send are kept with the agent's attachments. The database also holds the short facts about the workspace that its agents save (workspace memories); every conversation of that workspace shows them to the agent that answers. Disconnect revokes and removes the token and keeps the conversations and the workspace memories; deleting an agent removes its conversations and keeps the workspace memories.
- Read from Slack. The messages that mention Kasper Agent, the replies in a thread an agent answers, its direct messages, the files in them, the display names of their authors and of the people they mention, the names of the channels, earlier messages of a thread as context, and, when an agent asks for them, the newest messages of the channel or thread it answers in. Kasper Agent joins every public channel of the workspace, and Slack sends every message of each channel that Kasper Agent is in; the computer keeps only the messages that address Kasper Agent or continue a conversation.
- Given to the Slack Orchestrator. Every new Slack request goes first to the orchestrator agent, which runs on its provider like any other agent and passes the work to a teammate with the facts it needs.
- Sent to Slack. The agents' answers and the files they attach, short status posts ("Working on it…"), reactions, and approval requests with the command, folder and reason the provider gave, redacted. A failed request posts a fixed sentence, never the provider's error. Any agent, also in the user's own chat or a routine run, can post text, redacted, to a channel that Kasper Agent is a member of, and list those channels' names.
Anyone who can post in the Slack workspace, guests and Slack Connect members included, can give the agents work. The agents run on the host with the access the user gave them. A hosted server that sleeps starts for a message that addresses Kasper Agent. Until it connects, Signal keeps that message in memory for at most 10 minutes, encrypted to a key that only that server has, so Signal cannot read it; a restart of Signal deletes it.
Discord connections
A member of a Discord server with the Manage Server permission installs the Kasper Agent Discord app in that server from Kasper Agent on their computer. The account service exchanges that install with Discord, because the app's secret lives there, and revokes the Discord sign-in token that it gets at once. It records which Kasper Agent computer answers the Discord server: the Discord server ID, the computer and the Kasper Agent account that connected it. It keeps no Discord token and no message.
Discord has one bot token for every server, so only Kasper Agent's Signal service (signal.kasperagent.com)
holds it. Unlike Slack, both directions go through Signal:
- To the computer. Signal keeps the bot's connection to Discord. Discord sends it the messages of the channels Kasper Agent can view, with text only for the messages that mention Kasper Agent. Signal passes on only those messages and the presses of Kasper Agent's buttons: the message text, the author's ID and name, the channel, the message it replies to, and the addresses of its files. The computer downloads the files from Discord directly.
- From the computer. The computer sends its posts, edits, reactions, files and name lookups to Signal, which makes each call to Discord for it, only in the Discord servers linked to that computer. To give context, the computer asks Signal for the earlier messages of a channel after the first message of a conversation, and, when an agent asks for them, for the newest messages of the channel it answers in. It also asks for the names of the people that a message mentions.
Signal does not store or log a message, a file or a token; it keeps the server and channel names and IDs in memory to check each call. It answers a direct message to Kasper Agent with one fixed sentence and passes nothing on.
- Stored on the host. The Discord server's name and ID, which agent is its Discord Orchestrator, and one row per conversation that an agent answers, kept as a conversation of that agent with the Discord display name of each author. Files people send are kept with the agent's attachments. Workspace memories are kept as for Slack. Disconnect removes the link and keeps the conversations and the workspace memories; deleting an agent removes its conversations.
- Given to the Discord Orchestrator. As for Slack.
- Sent to Discord. As for Slack: the answers, attached files of at most 10 MB, status posts, reactions, and redacted approval requests. A post never pings anyone. As for Slack, any agent can post redacted text to a channel or thread of the server, and list their names through Signal.
Anyone who can post in a channel that Kasper Agent can view can give the agents work. The agents run on the host with the access the user gave them. A hosted server that sleeps starts for a message that addresses Kasper Agent. Until it connects, Signal keeps that message in memory for at most 10 minutes, encrypted to a key that only that server has, so Signal cannot read it; a restart of Signal deletes it.
Telegram connections
One Kasper Agent Telegram bot serves every user. Its token is only in Kasper Agent's Signal service
(signal.kasperagent.com); no computer has it. The user connects a chat from Kasper Agent on their computer:
the account service gives a one-use code, and the browser opens a t.me link with it. When the user
adds the bot to a group, or starts a direct chat with it, Telegram sends the code in that chat.
Signal then asks the account service to link the chat to the computer. The account service records
the Telegram chat ID, the bot ID, the computer, the Kasper Agent account and the time of the link, and a
hash of each code until it is used or expires. It keeps no chat name and no message.
Telegram sends each update of a linked chat, which contains the messages that mention the bot or reply to it, the messages of a direct chat, and button presses, to Signal. Signal checks Telegram's secret header and reads only the chat ID, a link code and the ID of a button press, to find the computer. It passes each update to that computer over its Signal connection, in transit only: it does not store or log it. The computer's answers, status posts, reactions and files go to Telegram through Signal, because only Signal has the token. Signal accepts only a fixed list of Bot API calls, only for the chats linked to that computer, and returns only message IDs to it. Files go through Signal with short-lived signed addresses, in transit only.
- Stored on the host. The bot ID, the bot username, the chat ID and the chat name are encrypted by the operating system's secret storage and redacted from logs, exports and diagnostics. The database holds the chat name and IDs, which agent is the Telegram Orchestrator, and one row per conversation that an agent answers. The messages of that conversation are kept as a conversation of that agent, with the Telegram name of each author, and files people send are kept with the agent's attachments. The names of authors and the last messages of a chat are also kept in memory for context, until Kasper Agent quits. Workspace memories are kept for each chat, as for Slack. Disconnect makes the bot leave the chat, unlinks it and keeps the conversations and the workspace memories; deleting an agent removes its conversations.
- Read from Telegram. The messages that mention the bot, replies to it and the other messages of a reply chain that Telegram sends, the messages of a direct chat, the message that a request answers, the files in them, the names of their authors and the name of the chat. With privacy mode on, which is Telegram's default for a bot, Telegram sends a bot only messages that mention it, replies to it and commands.
- Given to the Telegram Orchestrator. Every new Telegram request goes first to the orchestrator agent, which runs on its provider like any other agent and passes the work to a teammate with the facts it needs.
- Sent to Telegram. The agents' answers and the files they attach, short status posts ("Working on it…"), reactions, and approval requests with the command, folder and reason the provider gave, redacted. A failed request posts a fixed sentence, never the provider's error. As for Slack, any agent can post redacted text to a linked chat.
Anyone who can post in a linked chat can give the agents work. The agents run on the host with the access the user gave them. A hosted server that sleeps starts for a message that addresses Kasper Agent. Until it connects, Signal keeps that message in memory for at most 10 minutes, encrypted to a key that only that server has, so Signal cannot read it; a restart of Signal deletes it.
Plugin pages on kasperagent.com show each listing's own icon. The page asks kasperagent.com for that
picture, and the website fetches it there from the address the plugin catalog holds, so reading a
plugin page does not connect your browser to the plugin developer's servers.
Account usage shown in Kasper Agent is requested through the local Codex App Server. Kasper Agent does not send that usage to its maintainer.
WhatsApp connections
The user connects a WhatsApp Business number of their own Meta app, through Meta's WhatsApp Cloud API
(graph.facebook.com). Kasper Agent's own services take no part: the account service and Signal do not
see the number, its messages or its credentials.
- Setup. The setup dialog sends the app ID, the app secret, the WhatsApp Business account ID and the access token to the host, which uses them to call Meta: it lists the account's numbers, adds a number, asks Meta to send the number a code by SMS or voice call, checks the code, and registers the number with its two-step verification PIN. The PIN and the code are sent to Meta only and are not stored.
- Webhook. Meta sends each message, button press and delivery status of the number to a webhook
on the host: a loopback server that a public address reaches. The address is the user's own, or a
Cloudflare quick tunnel that Kasper Agent starts with the user's
cloudflaredprogram, so the messages pass through Cloudflare's tunnel service, encrypted with TLS. Kasper Agent tells Meta the current address of each number on each start. The host refuses every call whoseX-Hub-Signature-256does not match the app secret. - Stored on the host. The access token, the app secret, the app and account IDs, the phone number
ID and the allowed numbers are encrypted by the operating system's secret storage and redacted from
logs, exports and diagnostics. The webhook's port, its verify token and the user's own address are
in
kasperagent-whatsapp-webhook-v1.json. The database holds the number's name, which agent is its WhatsApp Orchestrator, and one row per chat that an agent answers. The messages of that chat are kept as a conversation of that agent, with the WhatsApp profile name and number of each author, and files people send are kept with the agent's attachments. Names and the last messages are also kept in memory for context, until Kasper Agent quits. Disconnect removes the number's address at Meta, deletes the token and the app secret, and keeps the conversations. - Read from WhatsApp. The messages that people send to the number, their files, locations and shared contacts, their profile names and numbers, and reply button presses. Messages from numbers that are not allowed reach no agent.
- Given to the WhatsApp Orchestrator. Every new WhatsApp chat goes first to the orchestrator agent, which runs on its provider like any other agent.
- Sent to WhatsApp. The agents' answers and the files they attach, read receipts, the typing indicator, reactions, and approval requests with the command, folder and reason the provider gave, redacted. A failed request sends a fixed sentence, never the provider's error. Any agent can send redacted text to a chat of the number. Meta stores and handles these messages under its own terms.
Anyone whose number is allowed, or anyone at all when the user allows it, can give the agents work. The agents run on the host with the access the user gave them.
Agent access
Agents currently use danger-full-access with approvalPolicy: never. They can read and modify local
files, run programs, use the network, and control the embedded browser without an Kasper Agent confirmation
dialog. This is an explicit product behavior, not a host security boundary. Keep backups and do not
give an agent a task you would not allow a local command-line tool to perform.
On first launch, Kasper Agent explains this access and does not start the agent services until you explicitly accept it. The acceptance record stays in Kasper Agent's local application-support directory.
Computer Use is provided by cua-driver, a local binary that Kasper Agent ships and starts as its own
child process. It starts only when you open the Computer Use panel or an agent uses the function, and
it stops when Kasper Agent stops. Because Kasper Agent starts it directly, macOS attributes the Screen Recording
and Accessibility grants to Kasper Agent, and macOS keeps control of the prompts. Windows and Linux ask for
no such grant. Screen contents and accessibility trees that an agent reads through the driver go to
that agent's provider, the same as any other message content.
The driver is third-party software with its own product analytics, which its vendor turns on by default and which are not Kasper Agent's. They would send the driver version, the operating system, a random installation identifier, and a bucketed record of each tool call to that vendor. They never send screen contents, window or application names, typed text, or the content of a tool result.
On its own the driver also asks GitHub for a newer release each time it starts.
Kasper Agent stops both calls, always. Every copy of the driver Kasper Agent starts gets
CUA_DRIVER_RS_TELEMETRY_ENABLED=0 and CUA_DRIVER_RS_UPDATE_CHECK=0, so it sends the vendor
nothing and asks GitHub nothing. Kasper Agent pins the driver version it packages, so a release check
could only offer you an update Kasper Agent would refuse. The driver reads the environment before its own
configuration, and Kasper Agent sets both variables last, so nothing can turn them back on for a driver
Kasper Agent started. Kasper Agent writes no file, so a driver you run yourself keeps the settings you gave
it.
Full access also permits that agent to publish, update and delete public hosted sites without another confirmation. Publishing makes the selected site content publicly accessible. At Workspace only or Ask first, hosted-site changes require confirmation. Site ownership and source validation still apply.
Exports
The account menu can export a local ZIP containing agent profiles, conversation snapshots, queues, and managed message attachments. It intentionally excludes CLI credentials, browser cookies, and agent workspace files.
The diagnostics export contains application and CLI versions, capability states, aggregate queue counts, a summary of the local trace: counts, outcomes, and durations for each IPC channel, turn origin, and failure origin, and the resource summary: the last sample and the memory, CPU, responsiveness, database statement and crash figures of today and the previous day. It contains no conversations, visited URLs, account email, file contents, or local file paths.
Delete local data
Quit Kasper Agent, then remove the Kasper Agent folders listed above. Removing
~/Library/Application Support/Kasper Agent also removes the embedded browser's cookies and logins.
Removing ~/KasperAgent removes agent workspaces, transfers, downloads, and the records the agents kept. Kasper Agent does not delete
~/.codex or ~/.claude; use each CLI's own controls if you also want to remove its local data.
Review folders before deleting them and keep a backup of anything you need.
Questions
Use GitHub Discussions for privacy questions. Report vulnerabilities privately as described in SECURITY.md, without attaching credentials, conversations, or unrelated private files.
When you ask Kasper Agent to generate or revise an agent profile, it sends your setup prompt, the current profile draft (when present), and available sidebar section names and identifiers to the selected AI provider through its local CLI. This request does not include conversation history, saved memories, or workspace files. The draft is reviewed before Kasper Agent saves it; generating a draft does not create an Kasper Agent conversation or change an existing agent. The provider's own data and CLI retention policies still apply.
When you change an agent's provider, the new provider receives the chat history with its first message. That history includes the work steps that the previous provider recorded: commands, the end of their output, changed file paths, tool names, searches and progress notes. Kasper Agent removes known secrets from these steps first. Command output can contain file contents. Reasoning, diffs and attachment contents are not sent.
Publishing an agent template from the chat makes its instructions, skills, and routines public to
anyone with the link at kasperagent.com/agents/<id>, with your account name as the creator. Kasper Agent
stops the publish when a text field looks like a secret. Workspace files and memories are not sent.
An owner or admin of a server can also publish, update or unpublish an agent of that server from the
browser client. The host sends the template content and the agent's avatar to that browser for the
preview, and publishes with the account signed in on the host, so that account is the creator.
Marketplace submissions from the desktop app show the publisher’s current account photo publicly on the listing. Account photo updates appear on the listing; removing the account photo removes it from the listing. Private memories and integration credentials are not included.
OpenCode
Kasper Agent downloads the OpenCode CLI and its license (from the opencode-ai package) from
registry.npmjs.org, then starts it with opencode acp. Prompts, attachments, and tool
results go to that local process. OpenCode can send them to the model provider selected in its
configuration. OpenCode's free models are the default, and they reach OpenCode Go with no account,
so a first OpenCode turn leaves this computer without a sign-in.
An OpenCode Go key is optional and unlocks the paid catalog. Kasper Agent encrypts it with the operating
system's secret storage, writes it to a file that only your user account can read, and passes it
to the local OpenCode process. To show the remaining Go quota in Usage, Kasper Agent also sends the key
to opencode.ai/zen/go/v1/usage; that request contains no conversation, file, or model data, and
the response contains only the used percentage and reset time of each Go limit. Kasper Agent does not
send that usage to its maintainer. No screen, log, data export, or diagnostics report contains the
key; the data export lists it under scope.excludes. Kasper Agent does not copy OpenCode credentials or
upload its session files. OpenCode manages its own login and resume state.
Gemini
Kasper Agent downloads Google's Antigravity ACP server from dl.google.com when you select Download on
the Gemini row. Each provider update check also asks dl.google.com for the size of the newest
download, also when you do not use Gemini. Google's license does not let Kasper Agent include it in the application. Kasper Agent
starts the server as a local process. Prompts, attachments, and tool results go to that process,
and the server sends them to Google. Connect opens Google's sign-in page in your browser. On this
computer, Sign in saves a Gemini API key instead: Kasper Agent encrypts it in its existing provider
credential store, gives it to the server as GEMINI_API_KEY, and redacts it from logs. The server
sends the key to Google. The server keeps its login and session files in ~/.gemini, or in $GEMINI_HOME. Kasper Agent does not
read, copy, or upload these files. Google's terms apply: https://antigravity.google/terms.
Gemini agents stay on this computer: Kasper Agent does not show them to team members.
Cursor
Kasper Agent downloads the Cursor CLI from downloads.cursor.com when you select Download on the Cursor
row. Each provider update check also asks downloads.cursor.com for the size of the newest
download, also when you do not use Cursor. Kasper Agent starts the CLI as a local process. Prompts,
attachments, and tool results go to that process, and the CLI sends them to Cursor. Sign in opens
Cursor's sign-in page in your browser, or the CLI uses CURSOR_API_KEY from the environment that
started Kasper Agent. Kasper Agent gives that key only to the local CLI, in its environment, and does
not store it. The CLI keeps its login and session files
in ~/.cursor (on Linux, the login is in ~/.config/cursor). Kasper Agent does not read, copy, or
upload these files. Cursor's terms apply: https://cursor.com/terms-of-service. Team members see
the host's Cursor agents, as for the other providers, when their app supports Cursor.
Cline
Kasper Agent downloads the Cline CLI from registry.npmjs.org, and its license file from github.com,
when you select Download on the Cline row. Kasper Agent starts the CLI as a local process. Prompts,
attachments, and tool results go to that process, and the CLI sends them to Cline and to the model
provider you select in Cline. The provider of a free model can use your prompts to train models.
Sign in opens Cline's sign-in page in your browser, or the CLI uses CLINE_API_KEY from the
environment that started Kasper Agent. Kasper Agent gives that key only to the local CLI, in its environment,
and does not store it. The CLI keeps its login and session files in ~/.cline, or in $CLINE_DIR.
Kasper Agent does not read, copy, or upload these files. Cline's terms apply:
https://cline.bot/tos. Team members see the host's Cline agents, as
for the other providers, when their app supports Cline.
Local model servers
When Server settings shows the Providers section of this computer, and once on the onboarding
provider step, Kasper Agent looks
for model servers on this computer. It sends GET <address>/models to
http://127.0.0.1:11434/v1 (Ollama), http://127.0.0.1:1234/v1 (LM Studio), and each address you
add under Local detection. These requests
contain no key, header, conversation or file data, and Kasper Agent does not follow a redirect. A found
server is only listed; Kasper Agent saves nothing until you select Add.
When you add or edit an endpoint, Load models sends the key and headers you typed to that address.
For a saved endpoint, Kasper Agent sends the stored key and headers only to the same origin as the saved
address. Local detection can be turned off in Settings. Its switch, addresses, folders and hidden
rows are in kasperagent-provider-detection-v1.json in the app profile.
Custom agents
A custom agent is an ACP program that you name. Kasper Agent starts it as a local process, and prompts, attachments, and tool results go to that process. What the program sends
to the network is its own choice. Check agent starts it once, sends only initialize, and stops it.
To find agents, Kasper Agent looks up the names of known agents on your PATH and in the folders you
add under Local detection. It does not start a file that it finds.
The command, arguments, and environment names are in custom-agents.json in the app profile. The
environment values are encrypted with the operating system's secret storage, go only to that
process, and are not in a screen, log, data export, or diagnostics report; the data export lists
them under scope.excludes. Custom agents stay on this computer: Kasper Agent does not show them to
team members.
Shared desktop channels
Channel names, purposes, participating agents, linked conversation references, messages, tasks, assignment records, history summaries, and human read positions are stored in the host's SQLite database. All authenticated members of that server can read and use its channels. Agent membership selects participating agents; it is not a separate human access boundary.
The selected lead's provider receives relevant channel content for routing and history summaries in separate sessions without work tools. Assigned agents receive the channel purpose, responsibilities, request, relevant source messages, shared history summary, recent messages, and attachment references. Agents can retrieve earlier channel messages and other conversations on that server when needed. Unrelated conversations are not sent automatically. Provider session internals remain internal. The provider's own data policies apply to content it receives.
Archiving a channel stops its work and retains its transcript. Restore makes the channel available again. These actions do not remove agents, their memories, or linked conversations. Channel traffic between desktop clients and a host uses the existing host transport. The account API and Signal service do not store channel chats or make routing decisions. This feature adds no mobile chat interface.
Mobile queue drafts
A phone stores the text and attachment references of an active queue edit in its secure local storage, and keeps a copy of each file the edit adds in its own application storage, so it can recover the edit after navigation or restart. These copies stay on the phone and are removed when the edit is saved or cancelled. The host keeps the original message and a persistent edit hold until the edit is saved, cancelled, or the message is deleted.
The desktop editor also keeps its active queue edit, attachment references, and edit identity in local application storage. This lets it recover the held draft after restart. Neither client releases the host hold merely because the editor closes or disconnects. The host also preserves attachment drafts released by edit cancellation or message deletion until they are sent or discarded. This lets a disconnected desktop recover its saved composer backup after host restart.
iPhone Live Activity
The iPhone app can show the state of the agents on the Lock Screen and in the Dynamic Island. While the app runs, the phone makes this view itself from the data that it receives over the encrypted host connection.
When iOS stops the app in the background, the active host updates the view through Apple Push Notification service (APNs). For this, the phone gives that host, over the encrypted host connection, the push token of the Live Activity, a 32-byte secret for that host, its interface language, and the file names of the agent pictures that it saved on the phone. The phone makes each host secret from one random phone secret, so one host cannot seal an update or sign a button for another host. The phone keeps its secret in its secure storage and makes a new one when the user signs out. The host keeps these values in memory only, for the session that gave them. It forgets them when the phone removes them, when the session ends, when the member is removed or disabled, when Apple refuses the token, after 12 hours, and when the host stops.
Each update contains the text that the view shows: agent names, the current task, the last reply, a question and its options, or a command that waits for approval. The host seals the update with keys made from the secret (an HMAC-SHA256 keystream and an HMAC-SHA256 tag) and sends it to the Kasper Agent account service, which sends it to Apple. The account service and Apple receive only the push token, the sealed bytes, the time, the priority, the time when the content becomes out of date, and, for an update that shows an event that would notify the member, the sound name. They cannot read the content. The widget on the phone opens it and shows nothing with a wrong tag. The account service stores nothing from these requests and does not log them. It makes the Apple request itself. An update with a sound lights up the screen and has "Kasper Agent" as its only text, so a host cannot use it to send an ordinary notification. Apple can keep its own delivery logs under its own policy.
The buttons in the view open the app. A button that changes host state, such as Approve or an
answer, has a signature made with a key that only the phone and the host have, so another app
cannot start the action with an kasperagent:// link. The app shows the command again before it
approves it.
Settings > Notifications > Live Activities turns this off. The phone then removes its token from the host.
iPhone notifications
The iPhone app can show a notification when an agent finishes a task, stops with an error, or needs an answer, an approval, or a step in the browser, while the app is not on screen. The host does not send one while the member uses a desktop app. For this, it keeps in memory the time of the last send, answer or typing of each session, and on its own computer it reads whether the Kasper Agent window has focus and how long the computer has had no input. While the phone shows the Live Activity of that host, the host sends no notification. With Play sound on, the Live Activity update lights up the screen and plays the sound instead. For this, the phone gives each connected host, over the encrypted host connection, the Apple push token of the app (none when notifications are off and only the Live Activity plays the sound), the 32-byte secret for that host (the one of the Live Activity), its interface language, and the choices of the user: the events of that server, a mute end, whether the notification shows a preview, and the sound, or none, and when its Live Activity of that host started. The host keeps these values in a file that only the user of that computer can read, so it can notify the phone after a restart. It removes them when the phone removes them, when the member is removed or disabled, and when the account service or Apple refuses the phone.
Each notification contains the agent name and a short text. With previews on, the text is the start of the agent reply, the question, or the command or reason of an approval, at most 200 characters, with secrets hidden as in desktop notifications. With previews off, it only says what happened, such as "Finished working.". The host seals the notification with keys made from the secret, as it seals a Live Activity update, and sends it to the Kasper Agent account service with the account session of the phone. The account service sends nothing when that session has ended, when the device signed out, or when the membership was removed. Otherwise it sends the notification to Apple with "Kasper Agent" as its only text. The account service receives only the push token, the session ID, the sealed bytes, the sound name, and the time. Apple receives the same values without the session ID. They cannot read the agent name or the text. The account service stores nothing from these requests and does not log them. Apple can keep its own delivery logs under its own policy.
On the phone, the notification extension of the app opens the notification with keys that the app keeps in its App Group, and iOS shows the agent name and the text. A notification that the extension cannot open shows the app name only, so the account service, Apple, or a host that does not have the keys of the phone cannot make it show text. A host that has the keys can show text only in the name of its own server. Signing out removes the keys from the phone, asks each connected host to remove the registration, and makes a new phone secret. A host that does not get the request sends nothing more, because the account service refuses the ended session.
Notifications only inform: they have no buttons, also on a paired Apple Watch. The app keeps its sign-in, the keys of the hosts and the server list choices in the iOS keychain with access after the first unlock since the phone started, on this device only.
Settings > Notifications turns this off, and sets the preview and the sound. The events and the mute of each server are in the same place and in the server settings.
Android notifications
The Android app gets no push notifications. It has no Firebase library and no other Google push service, so no notification data goes to Google. The app shows agent events only while it is open, over the encrypted host connection.
Mobile app updates
When it starts, a store build of the mobile app asks updates.kasperagent.com, the Kasper Agent server
behind the Cloudflare proxy, for a newer version of its JavaScript. The request contains the platform, the native
version of the build, the release channel, the ids of the update that runs and of the update in the
store build, a random id that the app makes once for each install, and the text of the last app crash
when there is one. It contains no account, server, conversation or file data. The server does not log
or store these values. Cloudflare sees the IP address of each request. Each update is signed with a
key that only Kasper Agent has, and the app runs no update without a valid signature.
Optional macOS Host Manager
An administrator can install a local Host Manager for several native macOS users. It reads only registered UIDs, process IDs, application versions, restart readiness, timestamps, and health booleans through separate local status directories. It does not read or back up tenant homes, workspaces, databases, provider directories, browser data, or conversations. It requests release metadata and application downloads from the fixed Kasper Agent GitHub repository; those requests expose the host's network address to GitHub. It sends no tenant status or tenant content to GitHub.
The separate, optional administrator account-setup command creates new local Standard users and
empty private homes. It saves generated login passwords in a root-only file under
/private/var/root for the administrator to retrieve. It does not transmit those credentials or
include them in logs. The installed administrator CLI shows each password once on the controlling terminal after setup,
then removes the recovery file. A failed setup retains that root-only file for administrator recovery.
The administrator controls secure password delivery. Host verification reads home metadata only
and tests cross-user access using harmless temporary files outside tenant homes.
Remote desktop setup diagnostics
When an authenticated server member checks remote desktop setup, the host sends its computer name, macOS account name, permission and service results, active session count, and check time to that member. A live test also sends a temporary four-digit code and mouse and keyboard test results. These results stay in memory and are not sent to analytics. Screen video uses the existing remote desktop connection. Permission approval remains in macOS System Settings on the host.
Secure browser authentication
Passwords, email/SMS codes, and authenticator codes entered in a secure chat card are sent to the shown HTTPS site for one submission. Connected desktop, mobile and browser clients send the value through the authenticated Team API to the computer running the browser. The handoff does not add the value to chat, provider tool arguments, diagnostics, analytics, or a credential store. Input and submission values are held in memory for the operation; cancellation and submission clear the input.
Kasper Agent blocks agent browser access while consent is pending. Before entering a submitted value, it blocks image capture and live browser streams, and stops and discards the active browser recording before entry. After entry, protection stays until the browser replaces the document. After a same-page submission, Kasper Agent clears the filled fields and, when the value no longer appears in the page title, address, text, field values, or attributes, keeps the page, so a later login step on the same page stays available. Page code can still hold the value, so page evaluation and recording stay blocked in that tab and its connected popup or opener tabs until the page navigates. Otherwise Kasper Agent loads the current URL as a new document with a GET request instead. Failed submission or reload requires manual takeover. Recording does not restart automatically, and the tab's back/forward history is cleared after replacement to prevent restoring the sensitive document. The destination site receives the value and controls its own processing. This protection does not isolate credentials from the operating system or agents with unrestricted machine access. Values pasted into ordinary chat are not covered by secure handoff.
Error and warning reports
Error and warning reports are off now, and nothing in this section is sent. When they are on again, production desktop, browser app, and mobile clients report safe failure categories to the same self-hosted OpenPanel service. Reports can include the app version, platform, provider, model, operation, severity, and a fixed cause code. They also record whether a problem appeared as a toast, shared alert or chat banner, or native error/warning alert. These reports do not include displayed text, raw exceptions, stack traces, prompts, messages, file names, paths, commands, or credentials. A random report ID helps identify repeated delivery attempts; it is not a conversation or file ID. A reported cause describes the error observed by Kasper Agent and might not explain its root cause.
Validated reports wait in local files on the host and mobile, or IndexedDB in desktop and browser clients. Each queue is limited to 1,000 reports, 1 MiB, and seven days. Reports are removed after OpenPanel accepts them, when they expire, or when the queue reaches its limits. Network failures can cause retries and duplicate delivery. Queue failures do not block the application.
Turning off analytics or changing accounts clears pending reports and cancels active sends. Requests already received by OpenPanel cannot be recalled. Anonymous error reports remain anonymous. The browser app has its own local analytics setting in account settings, separate from desktop and mobile. Collection is enabled by default; a malformed or unreadable setting keeps it disabled. Existing OpenPanel retention rules apply after delivery.
Remote host release checks
When a server administrator checks an Kasper Agent release, the host requests the public stable release manifest from GitHub for its operating system and architecture. The request includes no account data, chats, files, commands, or credentials. GitHub receives the host IP address as part of the connection. Connected administrators receive the installed version, release version, check status, and installation method.
Pi, Muse, and ACP registry setup
Pi and Muse run on the host selected for the agent. They receive the conversation input, attached images, tool definitions, and enabled MCP server configuration needed for a turn. Provider account files remain under each provider's control. An explicit Meta API key is encrypted in Kasper Agent's existing provider credential store. Log in with code for Muse starts a local Muse process, with no shell, no file writes and no Meta API key, that asks Meta for a code. You confirm the code on Meta's page, and Muse keeps the account in its own files. Settings responses and settings-change events contain no provider credentials; the event carries only the agent ID.
ACP registry search fetches the catalog from cdn.agentclientprotocol.com; search text is matched
on the host. Installation downloads the selected distribution from its published source. Pi update
checks use api.github.com. Muse update checks use api.meta.ai, and manifests and binaries come
from lookaside.facebook.com. Download requests reveal the host IP address and requested artifact.
Registry install records remain on the host, separate from conversations and credentials.
An authorized remote administrator can install, update, cancel, or remove a registry runtime on the host through the encrypted Team connection. Removal does not delete agent configuration, credentials, or conversations. The existing cloud service does not store those files.