Privacy
Privacy policy
Daintree is a local-first desktop app built by one person. Daintree has no backend that receives your code, your prompts, or your agent output: they stay on your machine unless you turn on an optional feature (voice input, the GitHub integration, or the MCP server) that talks to a third party with your own credentials. This page documents exactly what data the website and the app collect, the third parties involved, and the controls you have over each.
The short version
- Your source code, prompts, and agent output never reach a Daintree server. No release of the app has one. The Daintree Assistant, still in testing, will be the single exception, and choosing it will be a choice.
- App telemetry, voice input, the GitHub integration, and the MCP server are all off by default and opt-in. When telemetry is on, it scrubs file paths and credentials before sending, and every accepted error event is captured (there is no sampling).
- Voice input is optional and uses your own OpenAI API key: audio and transcription text go directly to OpenAI, never through Daintree.
- Credentials you enter (a GitHub token, an OpenAI key, an MCP key) are stored as plain-text JSON in a local config file with owner-only permissions, not in the OS keychain.
- The app is distributed through the Microsoft Store; Microsoft handles your Store account, download, and install data under its own privacy statement.
- The website uses Vercel Web Analytics, which is cookieless and does not track you across sites.
- The newsletter is optional, double opt-in, and only collects your email address. Unsubscribe at any time.
- The site sets no first-party tracking cookies. Signing in sets a session cookie, which is strictly necessary and not used for tracking.
- Fonts are served from our own domain, with no third-party font CDN.
- Daintree itself is free to download and Apache 2.0 licensed.
Who is responsible for your data
Daintree is developed and maintained by Greg Priday in South Africa, and has been since 2025 (originally under the name "Canopy"). Greg Priday is the responsible party and the designated Information Officer for the purposes of POPIA Section 56.
For privacy questions, data requests, or anything in this policy, email privacy@daintree.org. A postal address for formal correspondence is available on request via the same address.
This page is the canonical privacy policy submitted to Microsoft Store Partner Center for the Daintree desktop app listing. It describes the data the app and website collect. Personal data that Microsoft processes when you find, buy, download, or update the app through the Store (your Microsoft account, purchase and install records, ratings and reviews, and Store diagnostics) is handled by Microsoft as an independent controller under the Microsoft Privacy Statement. Daintree does not receive those identifiers.
The website (daintree.org)
The website is a marketing and documentation site with one account-backed area: a Daintree account, used to buy and manage a Daintree Assistant subscription. There is no comment system and no contact form. Personal data reaches us in three places: the optional newsletter signup, creating an account, and buying a subscription. Everything else on the site is readable without identifying yourself.
Analytics
We use Vercel Web Analytics to count page views and basic engagement. Vercel Analytics is cookieless and does not build advertising profiles. To distinguish unique visits within a single day, Vercel computes a hash from the request IP, user agent, and a per-project salt; that hash resets every 24 hours and the raw IP is not stored. The data we see is aggregate: pages visited, referrers, approximate country, OS family, browser family, and device type.
Accounts and sign-in (Supabase)
Creating a Daintree account is optional and is needed only to buy or manage an Assistant subscription. Authentication is operated by Supabase, which stores your email address, the sign-in method you used, and timestamps for account creation and last sign-in. We do not ask for a name, a phone number, or a password: sign-in is either a one-time link emailed to you, or an identity provider you already have.
If you sign in with Google, GitHub, or another provider, that provider tells us your email address, a stable account identifier, and the basic profile fields it includes by default - typically a display name and an avatar URL - which Supabase stores alongside the account. The provider shows you what it is sharing before you agree. We do not receive your password, and we do not gain access to your repositories, files, or contacts. You can revoke the connection at any time from that provider's own account settings, and deleting your Daintree account removes the copy we hold.
Signing in sets a session cookie so the site knows it is still you between page loads. It is strictly necessary for the account area, is not used for analytics or advertising, and expires when the session does. Signing out removes it.
Account data is retained while the account exists. Email privacy@daintree.org to delete it; deletion removes the account and its profile record. Records we must keep for tax and accounting purposes - invoices and payment records held by our payment provider - survive account deletion, because we are legally required to retain them.
Payments (Polar)
Assistant subscriptions are sold through Polar, which acts as merchant of record. That means Polar, not Daintree, is the seller on the transaction and handles payment processing, tax, invoicing, and refunds. Your card details go to Polar and its payment processor and are never sent to or stored by Daintree.
We send Polar your email address and your Daintree account identifier so a purchase can be matched to your account. Polar sends back which product you subscribed to, the subscription's status and renewal date, and the amount billed. We store that subscription state so this website can tell you what you are paying for. You can review invoices and cancel at any time from the billing portal linked in your account.
What we keep about a subscription
Polar notifies us when a subscription starts, renews, changes or ends. We keep the subscription's identifier, which product it is for, its status, renewal date and billed amount. When you open your account page we ask Polar directly; this stored copy is a fallback, used only if Polar cannot be reached, so that a paying customer is not told they have no plan because of an outage. We deliberately do not keep the full notification: those can carry a billing address, a tax identifier and free-text comments, and we do not need a second copy of any of it. Only the notification's identifier, its type and its timestamp are recorded, which is what lets us recognize a duplicate.
The desktop app does not read any of this yet. Signing in to the Assistant from inside Daintree has not shipped, so a subscription bought today is recorded against your account on this website and is not visible to the app.
Newsletter signup (MailerLite)
If you choose to subscribe to the newsletter at /newsletter, your email address is sent to MailerLite, which manages the subscriber list and sends the emails. We collect only your email: no name, no phone number, no other fields. MailerLite stores subscriber data on Google Cloud infrastructure in the European Union.
Subscriptions use double opt-in: MailerLite sends a confirmation email, and your address is only added to the list if you click the link inside it. As part of that flow, MailerLite logs the IP address and timestamp of your signup and your confirmation; this is standard anti-abuse and consent-record practice and is governed by MailerLite's privacy policy. Newsletter emails include open and click tracking by default. Every email includes an unsubscribe link, and you can also email us to be removed.
Bot protection (Cloudflare Turnstile)
The newsletter form is protected by Cloudflare Turnstile to prevent automated abuse. Turnstile is loaded only when you visit /newsletter; it does not run on any other page. When loaded, the widget sets short-lived cookies on challenges.cloudflare.com (typically __cf_bm, valid for around 30 minutes, and cf_clearance if a challenge is solved) and inspects browser-level signals (TLS characteristics, user agent, and rendering details) to score the request as human or bot. Turnstile does not use this data for advertising or cross-site tracking, and Cloudflare retains the underlying signals only for as long as needed to operate the bot-protection service. We rely on legitimate interest in keeping the newsletter form free of automated abuse as the basis for processing here.
Site search
The site search is powered by SearchSocket with an Upstash Search backend. When you submit a query, the query text is sent to Upstash to retrieve matching pages. Queries may be logged for service operations and product improvement, but they are not associated with any user identifier: there is no account or session linking searches to a person.
Caching
We use Upstash Redis on the server to cache release metadata and to hold a short observability log of deliveries to our own GitHub webhook. Nothing about site visitors goes into either: no visitor data, no IP addresses. The webhook log does contain what GitHub sends us about public repository activity - which can include a contributor's GitHub username and the text of a commit or issue - and is kept only for troubleshooting. It holds the fifty most recent deliveries and expires seven days after the last one, so an entry can persist for longer than seven days while deliveries keep arriving, and the whole log disappears a week after they stop. Because we call Upstash exclusively from our server, Upstash never sees your IP address or anything else about your visit.
Hosting and server logs
The site is hosted on Vercel. Like any web host, Vercel keeps standard request logs (timestamps, request paths, IP addresses, user agents) for short, platform-managed periods (on Vercel's free tier, runtime logs are retained for roughly an hour) to operate the platform and protect against abuse. Daintree's own application code does not write IP addresses or other user-identifying data into application logs.
Browser storage
The site writes a small amount of data to your browser. The first three never leave it and identify nobody:
- sessionStorage remembers whether the homepage hero animation and the header logo animation have already played in your current tab, so they do not replay on every navigation, and holds the documentation sidebar's expanded and collapsed sections so the docs stay how you left them.
- localStorage remembers which operating system's download you last looked at, so the download button offers the right build next time.
Signing in is different, and we will not pretend otherwise. Supabase sets a session cookie that does identify you - that is its whole job - and it is sent with requests so the site knows the account is yours. It is strictly necessary for the account area, is used for nothing else, and is removed when you sign out. Starting a sign-in also sets a verifier cookie, which is what ties the link or the provider round trip to the browser that began it. It is single-use, tied to that one attempt, identifies nobody, and grants nothing on its own. A sign-in you complete consumes it. A sign-in you abandon or that is refused before it returns can leave one behind, and it is managed by the authentication library rather than by us, so we will not claim a tidier lifecycle than we control: assume such a cookie can persist until you clear your browser's cookies, which removes it. See Accounts and sign-in above.
Clearing your browser storage removes all of it.
Embedded media
Fonts are served from our own domain. There is no third-party font CDN in the page. Some blog and documentation pages embed YouTube videos. The YouTube player is loaded only when you press play; if you do, YouTube applies its own data practices to that traffic.
The desktop app (Daintree)
Daintree is an Electron desktop app that runs entirely on your machine. It is a workspace around AI coding CLIs you already have: Claude Code, Codex, Antigravity, OpenCode and others. The app's design principle is that your code never leaves your machine because of Daintree itself: no Daintree backend ingests your files, prompts, or agent output. The optional features described below (voice input, the GitHub integration, and the MCP server) send specific data to third parties only when you turn them on, and only ever using your own credentials. Everything in this section is opt-in and disabled by default unless stated otherwise.
One component we build will be an exception. The Daintree Assistant has a purpose-built engine that can back the in-app Assistant panel, and it routes its model traffic through a service we operate on the way to a model provider. You provide no model-provider API key: the service uses a credential Daintree controls, and Daintree pays the provider for those model calls. It is in private testing, is not part of any current release, and choosing it will always be a choice; when it ships it will carry its own data policy and this section will describe it in the present tense. The Assistant panel as it works today runs whichever coding CLI you point it at, and adds no endpoint of ours.
Distribution via the Microsoft Store
Daintree is distributed through the Microsoft Store (alongside direct downloads). When you install or update through the Store, Microsoft processes your Store account, download and install records, update delivery, ratings and reviews, and Store-level diagnostic data as an independent controller under the Microsoft Privacy Statement. Daintree does not receive your Microsoft account identifier or those Store records. The app's own update check (described under Auto-updates below) is a separate mechanism that talks to updates.daintree.org, independent of Store-managed updates.
AI agent traffic
Daintree launches AI coding tools as local subprocesses. The CLI talks to its provider (Anthropic, Google, OpenAI, etc.) directly using your credentials and your terms with that provider. Daintree is not in the network path. We never see your prompts, completions, model responses, or API keys. If you have privacy questions about what an agent sends to its provider, those answers belong to the provider, not Daintree.
GitHub integration (optional)
The GitHub integration is optional and inactive until you supply a GitHub personal access token in Settings. When configured, the app uses your token to query the GitHub API for repository statistics, issues, pull requests, vulnerability alerts, and pull-request review threads tied to the projects you work on. This traffic goes directly from your machine to GitHub under your token and your GitHub terms; Daintree has no server in between. The token is stored locally (see Local data on disk) and is never transmitted to Daintree. Remove the token at any time to disable the integration.
MCP server (optional, off by default)
Daintree includes a built-in MCP server that is disabled by default. When you enable it, it exposes app capabilities to external AI agents that connect to it, which changes the local security surface of your machine. Only enable it if you understand and want that. The MCP server auto-generates a bearer API key on first start; that key is stored locally in the same config file as other credentials. The MCP server keeps a local audit log of activity (on by default when the server is configured, capped at 500 records by default and configurable in Settings); the audit log stays on your machine and is not transmitted to Daintree.
Telemetry: off by default
The app has three telemetry levels, set in Settings → Privacy & Data. The default is off, and nothing is sent until you explicitly choose otherwise:
off: no events are transmitted. This is the default.errors: scrubbed error events are sent to Sentry, with file paths and credential patterns removed first.full: adds a small set of named onboarding and activation events (for exampleonboarding_step_viewed,onboarding_completed,onboarding_abandoned,activation_first_agent_task_started,activation_first_agent_task_completed,activation_first_parallel_agents).
Before any event leaves the app:
- Home directory paths are replaced with
~in stack traces and breadcrumbs. - API keys, OAuth tokens, JWTs, and PEM blocks are matched against a scrubber pattern list (GitHub, Anthropic, OpenAI, AWS, Google, Stripe, Slack, npm, Azure, and generic Bearer tokens) and redacted.
- URL query strings are stripped of
access_token,refresh_token,client_secret, andcode. - Scrubbing walks each event up to ten levels deep; the event's tags, user, and extra-context fields are left untouched because Daintree never populates them with personal data (it makes no
setUser()calls).
There is no sampling: once telemetry is enabled, every event that passes the scrubber is sent (the Sentry SDK's default 100% capture rate). The scrubber runs first, so events it cannot safely process are dropped before transmission. Native crash dumps (minidumps) are never sent to Sentry. The minidump integration is filtered out and Electron's crash reporter runs with uploadToServer: false, so any crash dump is written locally only.
The Sentry SDK does not transmit your IP address or any user identifier with events; no device identifier, install ID, or anonymous user ID is generated by Daintree for telemetry. Sentry's servers receive the connection's network IP at HTTP transport time (this is unavoidable for any internet request), and the Daintree project in Sentry is configured to discard IP addresses at the storage layer. Sentry retains accepted events for 30 days on the free tier we use. Settings → Privacy & Data also includes a preview view that shows you what would be sent without actually sending it.
Auto-updates
Daintree checks updates.daintree.org at startup and roughly every four hours to see if a new version is available. The check is an HTTP request for a release manifest; the only data sent is what's in standard request headers (your IP address, the app version, your operating system family, and a user agent). No personal information is transmitted. You can switch between stable and nightly channels in Settings.
Voice input (completely optional)
Voice input is a completely optional feature. It is disabled by default, requires you to bring your own OpenAI account and API key, and is never loaded or activated unless you explicitly enable it in Settings.
When enabled, the app streams microphone audio directly from your machine to OpenAI's realtime transcription endpoint (wss://api.openai.com/v1/realtime) using your own API key. Voice correction is a separate toggle, also disabled by default: when you turn it on, the raw transcription text is sent to OpenAI's responses endpoint (https://api.openai.com/v1/responses) to clean up the transcript. Both flows use your own OpenAI credentials and connect directly to OpenAI: Daintree does not proxy, see, or store the audio or the text. What OpenAI does with that data is governed entirely by your account-level agreement with OpenAI. In the language of POPIA and GDPR, OpenAI acts as a processor for you (the controller) in this flow, and Daintree is not in the data path at all.
Local data on disk
The app stores its configuration in a local JSON file (config.json) inside its user-data directory: ~/Library/Application Support/Daintree/ on macOS, ~/.config/Daintree/ on Linux, or %APPDATA%\Daintree\ on Windows. This includes app settings, recent projects, worktree and panel layouts, keybinding overrides, per-project workspace configuration, and, if you choose to provide them, your GitHub personal access token, OpenAI API key, MCP server API key, and any forge credentials (credentials for Code Forge providers such as GitLab, Bitbucket, or Gitea). None of this is ever transmitted to Daintree.
These credentials are stored as plain-text JSON, not encrypted and not in the operating-system keychain. This is a deliberate choice: it's the same security model as a ~/.gitconfig or a CLI's own config file, and Daintree explicitly opts out of the OS keychain (it runs Chromium with --use-mock-keychain) so it never silently holds your secrets in a system credential store. On macOS and Linux the config file's permissions are tightened to 0o600 (readable and writable only by your user account). Protect this file the way you'd protect any local config that holds tokens.
The app keeps local logs in its user-data directory. Log retention is configurable in Settings → Privacy & Data (7, 30, or 90 days, or kept indefinitely) and defaults to 30 days. The MCP server's audit log (when the server is enabled) is stored separately and capped at 500 records by default. Daintree's built-in crash reporter runs with uploadToServer: false, so any native crash dumps are written locally and never uploaded. You can clear the app's HTTP cache, reset all stored data, or uninstall the app at any time.
For the deeper technical reference, see Security & Privacy in the docs and the Trust & Security page.
Your controls in the desktop app
Daintree is built so that every data-relevant feature is off by default. Here is the complete list of settings that affect what data the app collects, transmits, or keeps on disk, and where to change each one.
For voice input, voice correction, the GitHub integration, and the MCP server, you also retain account-level controls at the respective provider (OpenAI, GitHub) over how that provider handles the data it receives.
Third-party services we rely on
Daintree depends on a small number of third-party services. Each one has its own privacy policy, linked below. If you sign in with an identity provider - Google, GitHub, or another you choose - that provider is also involved, under its own policy and the permissions it shows you before you agree.
This is the complete set of third parties that Daintree itself sends data to. There is no advertising network, no data broker, and no analytics vendor beyond what's listed here. Separately, the AI coding CLIs you launch through Daintree communicate directly with their own providers (Anthropic, Google, OpenAI, and so on) under your credentials and those providers' terms. Daintree is not in that data path.
What we don't do
A short, deliberate list of things you might reasonably expect a website privacy policy to mention, and which simply don't apply here:
- No advertising network, retargeting pixel, or marketing analytics vendor.
- No behavioral profiling, fingerprinting, or building of visitor profiles. (Cloudflare Turnstile inspects browser-level signals on the newsletter page only, strictly to score bot vs. human.)
- No selling or sharing of personal data with third parties beyond the providers listed above.
- No cross-site tracking. The site sets no first-party tracking cookies, and Vercel Analytics resets its identifier hash daily.
- No password for you to invent, reuse, or have stolen from us: we never store one. Accounts exist only for subscriptions, and browsing, downloading, and reading the docs never require one.
- Daintree itself does not read, upload, or transmit your code, prompts, agent output, or local files to any Daintree server. Opt-in features (voice input, the GitHub integration, and the AI CLI tools you run) send specific data to their respective providers under your own credentials and those providers' terms, never through Daintree.
- No automated decision-making or scoring that produces legal or similarly significant effects.
Lawful basis for processing
For each processing activity described above, this is the lawful basis we rely on under POPIA Section 11 and GDPR Article 6. Providing personal information to Daintree is always voluntary; the only consequence of declining is that the relevant feature does not work for you (you don't receive the newsletter, telemetry stays off, voice input doesn't activate).
- Newsletter signup: your consent (POPIA s11(1)(a) / GDPR Art 6(1)(a)).
- Accounts and sign-in: performance of a contract (POPIA s11(1)(b) / GDPR Art 6(1)(b)). We cannot give you an account without holding the address it belongs to.
- Assistant subscriptions and payment: performance of a contract, and for invoices and payment records a legal obligation under tax and accounting law (POPIA s11(1)(c) / GDPR Art 6(1)(c)), which is why those survive account deletion.
- App telemetry, when you enable it: your consent. Off by default; you can withdraw at any time in Settings.
- Voice input, when you enable it: your consent, plus your direct contractual relationship with OpenAI.
- GitHub integration, when you enable it: your consent, plus your direct contractual relationship with GitHub.
- MCP server, when you enable it: your consent. Off by default; enabling it is an explicit, reversible choice in Settings.
- Microsoft Store distribution: Microsoft acts as an independent controller under its own privacy statement for Store account, download, and install data; our basis for distributing through the Store is our legitimate interest in delivering the app.
- Vercel Web Analytics: our legitimate interest in understanding aggregate site usage (POPIA s11(1)(f) / GDPR Art 6(1)(f)). The processing is cookieless and uses no cross-site identifiers, which we believe makes the impact on your privacy minimal.
- Cloudflare Turnstile bot protection: our legitimate interest in keeping the newsletter form free of automated abuse.
- Server-side caching, hosting, and standard request logs: our legitimate interest in operating and securing the website.
- Auto-update checks and crash telemetry transport: our legitimate interest in delivering a working, secure desktop app.
Your rights
Daintree is operated from South Africa and is therefore subject to the Protection of Personal Information Act (POPIA). If you are in the European Union, the United Kingdom, or another jurisdiction with similar data-protection rules, those rules apply to your data as well.
You have the right to:
- Access the personal information we hold about you. In practice that is your newsletter email address if you've subscribed; and, if you have an account, the address and profile fields it was created with, plus the subscription state described above.
- Correct any information that is inaccurate.
- Delete your information: for the newsletter, via the unsubscribe link or by emailing us. For an account, email us and we remove the account, its profile and its stored subscription state. Invoices and payment records held by Polar survive, because tax law requires them to.
- Object to processing or withdraw consent at any time. Withdrawing consent does not affect the lawfulness of past processing.
- Lodge a complaint with the South African Information Regulator or your local data-protection authority.
To exercise any of these rights, email privacy@daintree.org. We aim to respond within 30 days.
The South African Information Regulator can be contacted directly at:
- Email (general enquiries): enquiries@inforegulator.org.za
- Email (POPIA complaints): POPIAComplaints@inforegulator.org.za
- Postal: JD House, 27 Stiemens Street, Braamfontein, Johannesburg, 2001
- Web: inforegulator.org.za
Children
Daintree is a tool for software developers. It is not directed at children, and we do not knowingly collect personal information from anyone under 13 (or under 16 in the EU/UK). If you believe a child has provided personal information through the website, please contact us and we'll delete it.
International data transfers
The third-party services we use are operated from a small set of jurisdictions, primarily the United States and the European Union. Where personal information is transferred to one of those providers, we rely on the corresponding mechanism that the provider itself maintains:
- US-based providers (Vercel, Cloudflare, Sentry, Upstash, Supabase, Polar, OpenAI, GitHub, Microsoft) rely on the transfer mechanism each provider maintains: participation in the EU-U.S. Data Privacy Framework and its UK Extension where applicable, and/or Standard Contractual Clauses through their published Data Processing Agreements.
- EU-based providers (MailerLite stores subscriber data on Google Cloud in the EU) operate under GDPR directly.
OpenAI and GitHub receive data only when you explicitly enable voice input or the GitHub integration, and in those flows they receive it directly from your machine under your own credentials. For purposes of POPIA Section 72, we rely on the published privacy commitments and DPAs of these providers, all of which afford a level of protection that is substantially similar to POPIA's principles. The data Daintree itself hands off remains small: an email address for the newsletter, an anonymous search query, an opt-in scrubbed error report, and - if you create an account - the address and profile fields it was made with, plus the subscription state Polar reports back. Identity providers you choose to sign in with receive the request directly from your browser, under the permissions they show you.
Security
The Daintree desktop app's security model (Electron sandboxing, IPC validation, code signing, telemetry scrubbing, and so on) is documented in detail on the Trust & Security page and in the security reference. Locally stored credentials live in a config file with owner-only permissions (0o600 on macOS and Linux) and are not placed in the OS keychain; native crash dumps are written locally and never uploaded. The website is a SvelteKit deployment with HTTPS enforced, almost entirely prerendered, with a small number of server routes for the newsletter, accounts, and billing. Its server-side credentials - the MailerLite key, the Supabase service key, and the Polar access token - live in environment variables and are never exposed to the browser. Session tokens are verified against Supabase's signing keys on every request rather than trusted from the cookie they arrive in.
Changes to this policy
If this policy changes, the effective date at the top of the page will be updated. For substantive changes (new third parties, new categories of data collected) we'll also note the change in a release announcement or in the newsletter, where applicable.
Contact
Privacy questions, data requests, or general feedback: privacy@daintree.org. To report a security issue, use security@daintree.org.