Privacy policy

This page describes what mcp-analytics stores, why, and how you can exercise your GDPR rights. Last updated July 2026.

1. Controller

Spreenovate GmbH, Prenzlauer Allee 186, 10405 Berlin, Germany.
Managing directors: Fabian Hallstein, Alexander Kamphorst.
Contact: info@mcp-analytics.com.

We have not appointed a Data Protection Officer because the company is below the German DPO threshold (§ 38 BDSG).

2. Two roles to keep apart

mcp-analytics has two very different relationships with personal data:

(a) You, the mcp-analytics account holder

We store your email address and an API token. Legal basis: contract performance (Art. 6 (1)(b) GDPR). The email is used for transactional messages only (verification link, occasional service notices, plan-limit warnings). No marketing.

(b) Visitors of your sites

When a visitor loads a page that includes our tracking snippet, we record pseudonymous event data. You are the controller for that data; we are your processor (Art. 28 GDPR). The full Data Processing Agreement sets out the processor obligations, sub-processor list, retention, breach notification timelines, and audit rights.

3. What we collect from your visitors

The data set per pageview / event:

Raw IP addresses are not persisted in the analytics database. The IP is used in-memory to compute the visitor/session hash and is then discarded. Geo data (country/region/city) is reserved in the schema but currently empty.

One narrow exception: if an IP repeatedly sends invalid payloads (unknown site IDs) to our ingest endpoint, we record that IP in a separate abuse_events table for anti-abuse purposes (legal basis: Art. 6 (1)(f) GDPR, legitimate interest in service availability). These records are not used for analytics and are not joined with visitor data.

For bot detection, the ingest service additionally keeps transient, day-scoped abuse counters in memory (in all privacy modes, including strict): a salted hash of IP and User-Agent — the same daily-rotating primitive as above, never the raw IP — counts same-day repeat fetches so that scrapers posing as browsers can be labelled as bots. These counters are never written to disk or to the analytics database, cannot be joined with stored events, and become permanently unlinkable at 00:00 UTC when the daily salt rotates (immediately on service restart), after which the inert counter data is purged from memory within approximately 26 hours (legal basis: Art. 6 (1)(f) GDPR, legitimate interest in measurement accuracy and abuse prevention).

4. How visitors are counted (and why no banner)

The strict and balanced privacy modes (balanced is the default for new sites) compute server-side identifiers as:

session_id = SHA-256(daily_salt + site_salt + ip + user_agent + site_id) (balanced appends a "|session" suffix)

visitor_id = SHA-256(daily_salt + site_salt + ip + user_agent + site_id + "|visitor") (balanced only; in strict mode no visitor identifier is computed at all)

The daily_salt rotates at 00:00 UTC and is part of every hash, in every mode. The IP is used in-memory for these hashes and then dropped; it is not written to the analytics database. The User-Agent is stored separately as a string (used for bot classification, not for re-identification).

Result: visitors cannot be re-identified across days in either mode; no cookie, no localStorage, no fingerprint that survives midnight UTC. The German DSK and the EDPB consider this sufficient anonymisation to skip the cookie banner requirement (ePrivacy / TTDSG § 25). The all mode opts into a 2-year first-party cookie and shifts consent responsibility to you (the site owner).

Do-Not-Track signals are honoured as a hard opt-out in strict and balanced; in all mode the site owner decides.

5. Where the data lives

6. Retention

7. Your rights

You have the right to:

8. Cookies on this site

The mcp-analytics website (the one you are reading) does not set any tracking cookies. Rails sets a single transactional session cookie (_mcp_analytics_session) only after you submit a form. It expires when you close the browser.