Summary
The short version, in plain language:
- We do not host your workspace data. Your self-hosted
cc_serverholds it. The public website uses separate analytics described below. - Your data is stored locally. Workspaces, agents, spaces, tickets, memory, code indexes and meeting notes are kept in a local database and files on your machine.
- Some features talk to services you connect. When you link GitHub, Linear, Google Calendar, or an AI coding agent, the relevant data is sent to those providers to make the feature work. They process it under their own privacy policies.
- Your code can be sent to an AI provider. The built-in adapter sends prompts, code, diffs and context to whichever model provider you connect. The Claude Code adapter sends the same kinds of data to Anthropic under your own Claude Code subscription.
- Crash reports are sent in production — and you can turn them off. Released builds send crash, error, performance and session-replay diagnostics to Sentry; you can disable this during onboarding or in Settings → Server → Diagnostics & privacy. See Diagnostics and crash reporting for exactly what this includes.
- App usage analytics are off unless your server's operator turns them on. When on, released builds send pseudonymous usage events (screens, actions, counts, durations) to our Umami instance, never names, content, file paths or email addresses. See App usage analytics.
- The public website uses Umami analytics. Pageviews and named acquisition-link clicks are measured on
usectrl.dev; the app does not load this website tracker.
Who this covers
This policy describes how the Control Center desktop application (the "app") handles information. In this document, "we", "us" and "Control Center" refer to the maintainers of Control Center and "you" refers to the person using the app.
This policy covers the app itself and this documentation website. It does not cover the third-party services you choose to connect (such as GitHub, Linear, Google, or Anthropic) — each of those is governed by its own privacy policy and terms, which you should review.
Data stored on your device
Almost everything the app works with is stored locally on your computer — typically under your operating system's application-support directory. This includes:
- Workspaces, agents and skills — workspace configuration, agent definitions (including personas and instructions) and skill definitions.
- Spaces and messages — messages between you and your agents, including searchable embeddings generated from them.
- Memory and knowledge — memory facts, domain knowledge and workspace policies, with vector embeddings used for semantic search.
- Code indexes and repositories — a code graph (symbols, relationships and file metadata) built from repositories you index and isolated copy-on-write working copies of your repositories created for each space or task.
- Agent run logs — execution traces of agent runs, including reasoning, commands and outputs.
- Tickets, pull requests and reviews — work items, pull-request metadata mirrored from GitHub for offline use and your draft review comments.
- Pipelines — pipeline templates, run state, trigger events and error traces.
- Meeting notes — transcripts, summaries, decisions, action items and the WAV the host writes for each recording. See Meeting capture and transcription.
- Calendar data — calendar account metadata and cached event details from connected Google accounts.
- Newsfeed — your RSS/Atom subscriptions and cached article content.
- Activity and analytics — a local activity log and in-app analytics such as agent performance, streaks and achievements. These are computed and stored on your device and are not uploaded.
- Preferences — non-sensitive settings such as theme, notification, sandbox and log-level preferences.
A note on encryption at rest. Provider credentials (see Connected services) live on your cc_server in an owner-only secrets file. The client keychain holds only this device's pairing credential. The remainder of the data above — the database, run logs, agent and skill files, meeting audio and indexed repository copies — is stored unencrypted on the server host's disk. It is protected by the operating system's user account and file permissions, not by application-level encryption. Anyone with access to that machine or disk could read it, so we recommend full-disk encryption (such as FileVault or BitLocker) on the host where you run cc_server.
What we don't collect
Because Control Center is local-first, several things you might expect from a typical cloud product simply do not happen:
- We do not run a server that receives or stores your workspaces, code, spaces, or notes.
- There is no account to create with us and no automatic cloud sync, backup, or export of your data to us.
- We do not use third-party product-analytics or marketing-tracking SDKs (such as Google Analytics, Mixpanel, Amplitude, Segment, or PostHog) in the app. Its only usage analytics are the opt-in, pseudonymous events described in App usage analytics, sent to our own Umami instance.
- The app does not capture your screen, record video, or access your contacts or address book.
- The app does not scan your filesystem broadly — its file access is scoped to its own application directories and the repositories you explicitly add.
The app exceptions to “stays local” are the connected services, AI processing, crash diagnostics and opt-in usage analytics described below. The public marketing and documentation website has separate analytics, described next.
Website analytics
The public marketing pages and documentation at usectrl.dev load Umami from analytics.alev.dev to count pageviews and named link-click events. The events are release_page_click (requesting the latest GitHub installer for the selected OS; earlier versions opened the release page), demo_open_click (opening the demo link) and install_section_click (following a link to the download section). A click does not establish that a download finished, the app was installed or the demo loaded.
Umami's normal pageview/event information includes the visited page, page title, referrer, browser language, screen size and site hostname; its service also receives the network request. Our extra event properties are limited to the link placement (hero, nav or download) and the OS label shown on a release link (macos, windows, linux or none). We do not send custom account IDs, code, workspace data, link text, URL search parameters or fragments. The tracker is limited to usectrl.dev, excludes search parameters and fragments from tracked URLs, and respects your browser's Do Not Track setting.
Umami's tracking code does not use cookies; the analytics service may process request and session information on the server. Umami's documentation says self-hosted analytics data is retained indefinitely unless manually deleted. We have not verified a different retention setting or a hosting-region guarantee for this installation. To ask about analytics records or their deletion, contact us.
Blocking the analytics script or disabling JavaScript does not stop links from working. This website analytics script is not part of the desktop, web-app or phone clients and does not change the app's own telemetry settings.
App usage analytics
To understand which features help and where people get stuck, the app can send pseudonymous usage events to the Umami instance at analytics.alev.dev. This is separate from website analytics and from crash diagnostics.
- Off until someone opts in. Usage analytics are a setting of your server, not of each device. They stay off until the server's operator turns on Share usage analytics during onboarding or in Settings → Privacy. Once on, the setting applies to every client of that server (desktop, web and phone) and to the server itself. Turning it off stops sending immediately and discards anything still queued.
- Released builds only. Debug and development builds do not send unless a developer explicitly enables it on their own server for testing.
- What is sent. Screen views by route template (for example
/workspaces/:workspaceId, never the concrete address), named product events such as a message sent, an approval answered, a search run, an agent run finished or a pipeline completed, and their counts, durations, token totals, costs, model and adapter identifiers and closed-vocabulary settings. Every event carries the app type (desktop, web, phone or server), app version, platform, language and screen size. - Pseudonymous identifiers. Workspace, space, conversation, agent, run, user and device IDs are replaced by a keyed hash using a secret that stays on your server, so events can be counted and joined without revealing the real identifier. Deleting the server's data creates a new secret and unlinks earlier events.
- What is never sent. Message, ticket, review or meeting content; titles, prompts, shell commands and search queries; names, logins and email addresses; file paths, repository and branch names, hostnames and URLs. The app enforces this with a filter that drops any value that is not a short code-defined token.
- What the analytics service receives. Like any web request, the network request includes your IP address and user-agent. Umami derives a country and region and does not store the IP address; it does not use cookies.
The full list of events and properties is in the manual's usage analytics reference. Retention follows the same Umami installation as website analytics.
Connected services
The app only contacts a third-party service when a feature you use requires it. You authenticate with each service using your own credentials, which are stored on your self-hosted cc_server (an owner-only secrets file, keyed by your user id) — not in a client keychain, and not on any Control Center-operated server. What is shared with each service:
GitHub
Used for pull-request and repository features. The server sends repository names, pull-request numbers, file diffs, commit and review data and requests for user-profile details. Authentication uses a personal access token you paste, or a token from GitHub's device flow when the server has a GitHub App registered. The gh CLI is not an authentication method.
Google Calendar
Used for the calendar feature. With your consent through Google's OAuth device-code flow, the app reads your calendar list and event details (titles, times, attendees, recurrence). It requests the calendar.readonly scope plus openid and email to identify the account. It does not request calendar.events, so RSVP writes fail. Access is per-workspace and can be revoked at any time from your Google account settings.
Linear
Used for the ticketing integration. The app sends issue data — title, description, team, priority, assignee, labels and state changes — to Linear's API, authenticated with a Linear API key you provide.
Newsfeed and other requests
The newsfeed fetches the RSS/Atom feed URLs you subscribe to (only the feed URL is contacted; no personal data is sent) and downloads public ad-blocking filter lists used to strip trackers from feed content. The GIF picker used in pull-request reactions sends your search terms to a third-party GIF service using a shared application key that is not tied to your identity.
AI agents and your code
Control Center dispatches AI coding agents. What leaves your device depends on which adapter you pick and which model provider that adapter talks to:
- Built-in adapter (default). The agent loop runs inside your own
cc_server. Prompts, code, diffs and context are sent to whichever model provider you connected (Anthropic, OpenAI, Codex, Cursor, Kimi Code, and so on) under your own credentials. Point it at a local endpoint (Ollama, LM Studio, a private deployment) and that traffic stays on the host you named. - Claude Code adapter. If you select Claude Code, the agent communicates with Anthropic through the Claude Code CLI under your own Claude Code subscription. The app does not store or manage an Anthropic API key on your behalf for that path.
When either adapter talks to a cloud provider, the data sent for processing can include: your prompts; the agent's composed context (its identity, system prompt, persona, skills and the active workspace policies and memory notes); recent conversation history and summaries; and the source code, pull-request diffs, ticket text and other content the agent reads. The agent retrieves code, diffs and tickets on demand through its tools rather than sending your whole repository, but you should assume that any code or content an agent works on may be transmitted to the provider. Each provider processes this data under its own terms and privacy policy.
Diff-sharing control. The app includes a privacy preference that, when turned off, excludes raw pull-request diff content from review prompts so that only structured metadata is sent to the model. This setting affects review-mode prompts; it does not disable other transmissions described in this policy.
Meeting capture and transcription
The optional meeting-notes feature records and transcribes meetings. Because this involves audio, we describe it in detail:
- Audio capture. When you start a recording, the app captures your microphone and, where supported, the system/loopback audio of remote participants. This requires the relevant operating-system permissions (for example, microphone and audio-capture permission on macOS), which you grant explicitly.
- On-host transcription. Capture streams 16 kHz PCM to your own
cc_server(the same host that holds the rest of the workspace). Speech-to-text, diarization and embeddings run there with models the server downloads at boot — they are not bundled in the client. Raw audio is not sent to Control Center or to a speech vendor; it does leave the recording client if that client is not the server host (web, phone, or a remote desktop). - Raw audio is written for every recording. The host always stores WAVs under
<dataDir>/meetings/<meetingId>/, unencrypted. Deleting a meeting in the app removes the database row, not that directory. Diarization is installed at boot with the speech and embedding models; it is not an opt-in that gates whether audio is kept. - Transcript text and summaries. The transcript, summaries, decisions and action items live in that workspace's database on the server. The built-in
meeting_summarypipeline (and any agent you ask to re-summarize) sends the transcript text — the words spoken — to the model provider you connected. The WAV stays on the host.
You are responsible for obtaining any consent required by the people you record under the laws that apply to you.
Diagnostics and crash reporting
To find and fix crashes and errors, released (production) builds of the app send diagnostic data to Sentry, an error-monitoring service, at a data center in Germany. Together with the opt-in usage analytics, this is the only telemetry the app sends. Please read this section carefully:
- When it runs. Diagnostics are sent only in released production builds. Local development and debug builds send nothing.
- You can turn it off. Diagnostics are on by default, but you can disable them during onboarding or at any time in Settings → Server → Diagnostics & privacy. Turning them off stops further reporting (a restart fully applies the change). The diff-sharing preference described above is a separate control and does not affect diagnostics.
- What is sent. Crash and error reports; application logs and activity breadcrumbs (a trail of the recent actions in the app leading up to an event); your IP address and HTTP request metadata (such as your platform and user-agent); performance traces and profiles, captured for 100% of sessions; and session-replay recordings that capture interface interactions and on-screen content for 10% of all sessions and 100% of sessions in which an error occurs.
Sentry processes this data on our behalf to provide error monitoring. Because session replay and logs can incidentally capture content visible in the app, we keep this data only as long as needed for debugging and we recommend disabling diagnostics if you routinely work with sensitive material. If you have questions or want a diagnostic record removed, contact us.
How your data is protected
- Credentials on your server. API tokens and OAuth credentials live on your
cc_serverin an owner-only secrets file, attached to your user. The client operating-system keychain holds only this device's pairing credential. We recommend full-disk encryption on the server host. - Default local bind. A desktop-spawned
cc_serverlistens on loopback (127.0.0.1) by default. Binding a non-loopback address requires TLS (or an explicit--insecurebehind a terminating proxy). - Sandboxed agents. Agents run in operating-system sandboxes, with credentials passed through scoped environment variables rather than embedded in prompts.
- Workspace isolation. Data is partitioned by workspace as a hard design boundary, so one workspace's data does not surface in another.
- OAuth best practice. Google Calendar sign-in uses an industry-standard device-code OAuth flow with a public client; the server stores the resulting tokens for that user and never returns them to a client.
- Transport security. Network requests to third-party services use HTTPS and authentication headers are never written to logs.
As noted above, the database and files (other than the server secrets file and the client pairing credential) are not encrypted by the app. Securing the server host — with full-disk encryption, a strong account password and timely deletion of data you no longer need — is an important part of protecting this data.
Retention and deletion
Because your app data lives on your own server, you control its retention. Spaces, run logs, transcripts, memory, code indexes and other data persist there until you delete them or remove the app's data. Isolated repository working copies created for a space or task are automatically garbage-collected when that unit ends.
Deleting data through the app removes it from the active database and files, but underlying disk blocks may remain recoverable until overwritten by your operating system. Diagnostic data sent to Sentry is retained according to Sentry's retention settings and deleted thereafter. Website analytics and app usage analytics have separate retention governed by the Umami installation; contact us to ask about deletion.
Your choices and rights
You have meaningful, direct control over your information:
- Choose what leaves your device. Using the local agent adapter, leaving integrations disconnected, turning off diff sharing, disabling diagnostics and leaving usage analytics off all reduce what is transmitted.
- Disconnect services. You can remove stored credentials and revoke access from each provider's account settings (for example, revoking the app's access in your GitHub, Google, or Linear account).
- Access and delete. Your data is in files and a local database you own; you can inspect, export, or delete it directly and removing the app's data directory erases its local storage.
Depending on where you live, you may have rights under laws such as the Swiss Federal Act on Data Protection (FADP) and the EU General Data Protection Regulation (GDPR) — including rights to access, correct, delete, or restrict the processing of your personal data and to object to processing. For data the app holds on your device, you can exercise these directly. For data shared with a connected service, with Sentry or with our Umami instance, you can exercise your rights with that provider, or contact us and we will help where we can. You also have the right to lodge a complaint with your local data-protection authority.
Children
Control Center is a professional developer tool intended for adults. It is not directed to children and we do not knowingly process the personal data of children. If you believe a child has used the app in a way that raises a concern, please contact us.
Changes to this policy
We may update this policy as the app evolves — for example, when we add an integration or change how diagnostics work. When we make material changes, we will update the "Last updated" date above and reflect the changes here. Significant changes may also be noted in the app's changelog. Your continued use of the app after an update means you accept the revised policy.
Contact
Questions, concerns, or privacy requests? The best way to reach the maintainers is through the project's GitHub repository — open an issue at github.com/SamuelAlev/control-center/issues. For requests that involve personal information you would rather not post publicly, mention that in the issue and we will arrange a private channel.