Skip to content

MCP privacy notice

When an AI assistant reads your site's observability data through the MCP server, information about your visitors' requests can leave the site. Visitors are entitled to know. This page explains who is responsible for what, lists exactly which fields leave the site at each exposure grade, and offers a text for your privacy page.

Not legal advice

This page is a technical description and a starting template. It is not legal advice and it does not make a site compliant by itself. Have the final text reviewed by whoever is responsible for data protection on your site, and adapt it to your jurisdiction and your actual setup.

Who is who

  • Visitors are the data subjects. The requests they make are the source of the data.
  • You, the site owner, are the data controller. You decide whether to raise the exposure grade, which AI provider to connect and why. The module only gives you the switch.
  • The AI provider behind an MCP client may be a processor acting on your instructions, or a separate controller with its own purposes, depending on its terms. It may also be outside the EU.
  • The module cannot know which model or provider a client uses. The MCP server answers whoever holds a valid token with the right scope; what that client then does with the answer happens outside Drupal. You have to know it, and write it down.

What leaves the site at each grade

The exposure grade is a site setting (see the data map). The tools never return more than the grade allows, whatever scope a client holds. Field names below are the ones in the data map and in the MCP vocabulary.

Grade 0: nothing

No MCP tool returns data. This is the default.

Grade 1: aggregates by route name

Tools: routes_compare_periods, routes_slowest, cache_explain_misses, queries_slowest, overhead_report (scope observability:read).

What leaves:

  • route: the Drupal route machine name (for example entity.node.canonical), or the fixed value unmatched for requests that matched no route. Never a path.
  • Counts and timings per route and window: request_count, throughput_per_minute, avg_duration_ms, p95_duration_ms, p99_duration_ms.
  • Cache outcomes per route and layer: layer, events, outcomes (hit, miss, uncacheable), uncacheable_reasons, and cacheability counters (avg_tag_count, avg_context_count, max_age_zero, max_age_permanent, max_age_other), plus invalidations counters. Names of cache tags are not returned.
  • Slow database statements, grouped: query_hash, occurrences, avg_duration_ms, max_duration_ms, total_duration_ms, routes, relation_type.
  • Envelope fields: grade, window, unit, minimum_request_count, withheld.

Groups with fewer requests than minimum_request_count are withheld and only counted in withheld, so a single visit cannot appear as a row.

What does not leave: paths, query strings, IP addresses, user ids, user agents, headers, request bodies, exception messages, SQL text.

Grade 2: request detail, filtered

Tools: everything of grade 1, plus traces_list and cache_events_list (scope observability:raw). Grade 2 needs two confirmations: the site-level declaration and the observability:raw scope on the client. A token gets that scope only if the client asks for it when it signs in, and only after the declaration is recorded. Raising the grade does not add it to tokens already issued, and a refresh never adds it.

Row-level fields returned by traces_list:

Field Notes
request_id, started_at, method, route, status_code, duration_ms, is_ajax Internal or technical values.
user_kind anonymous, authenticated or null. The user id is not returned.
query_keys Names of the query parameters, sorted, at most 20; never the values. A name that is odd or looks like a token is [KEY]. The path is never returned: route is the location.
user_agent {browser, os} from a fixed vocabulary; never the raw header.
parent_request_id Value sent by the client, accepted only as ULID or UUID, marked untrusted.
exception class only. The message is never returned.
database query_count, total_query_time_ms, slow_query_count.

Row-level fields returned by cache_events_list: request_id, created_at, layer, status, outcome, uncacheable_reason, method, route, tag_count, context_count, max_age, contexts, tags (untrusted; cache tags name entities, such as node:123 or user:5).

At grade 2 queries_slowest also returns caller (the PHP Class::method) and query_text (the statement with literals replaced by ?, truncated, marked untrusted; absent if the site does not store SQL text).

What never leaves, at any grade:

  • client_ip, whatever the capture mode (anonymized, hashed, full). The only exception is OpenTelemetry in legacy mode, described above.
  • uid.
  • Query string, request body and header payloads.

Text that comes from visitors is returned inside an object {"untrusted": true, "truncated": ..., "text": "..."} and truncated to the exposure.untrusted_text_max_length setting (default 256).

Export and OpenTelemetry

The Prometheus export and OpenTelemetry follow the grade as follows:

  • Prometheus public scrape (/native-observability/prometheus): at grade 0 the endpoint answers 403. From grade 1 on the metrics are labelled by route machine name, method and status code, never by path, and a request without a route name is labelled unknown. Outbound HTTP metrics carry the destination host only. The former route_path_method label strategy no longer exists.
  • OpenTelemetry: a span describes one request, so it is detail. At grade 1 nothing is sent. At grade 2, with the declaration recorded, spans are sent with the name METHOD route_name, the attribute http.route (the route machine name, or unmatched), the method, the status, the duration, the exception class and the request id, without client.address, and with the user ID only if capture.store_uid is on. No span carries a path, a query string, a URL, a referer, a user agent, an exception message or a stack trace.

The Elastic NDJSON export and the operator Prometheus page are admin downloads, pulled by a user with the right permission. They are not automatic outbound flows, so the grade does not govern them.

Legacy mode is set by update 10110 on sites that had the export or OpenTelemetry module enabled before 2.2.0. Both keep sending without a grade, so that an upgrade does not silently stop their pipelines, but with the content of 2.2: no paths and no url.path. In legacy mode OpenTelemetry sends the client IP address as capture.client_ip_mode allows, which is the only case in which an IP address leaves the site. Legacy mode never brings paths back. MCP never uses legacy mode. The status report shows a warning while it is on, and choosing an exposure grade turns it off. Apart from the client IP, legacy mode sends the same content as the grades above: if you use it, list what your exporters actually send in your own notice.

Suggested privacy-notice text

The texts below are templates. Replace everything in [square brackets], remove what does not apply, and have the result reviewed. Use the version for the grade your site declares.

Placeholders: [AI provider], [purpose], [retention], [transfer safeguards], [contact].

Grade 1, English

Analysis of site performance with AI tools

To keep this website fast and reliable, we may use an AI assistant provided by [AI provider] to analyze how the site performs.

The assistant receives only statistics grouped by type of page: for example, how many requests a page type received and how long it took to answer. It does not receive web addresses, IP addresses, user names, or the content of what you type or submit.

We do this for [purpose]. The statistics are kept for [retention].

[Transfer safeguards: the provider may process data outside the European Union. The safeguards in place are: [transfer safeguards].]

To exercise your rights or ask a question, write to [contact].

Grade 1, italiano

Analisi delle prestazioni del sito con strumenti di intelligenza artificiale

Per mantenere il sito veloce e affidabile, possiamo usare un assistente di intelligenza artificiale fornito da [AI provider] per analizzare come il sito risponde.

L'assistente riceve solo dati statistici raggruppati per tipo di pagina: per esempio, quante richieste ha ricevuto un tipo di pagina e in quanto tempo ha risposto. Non riceve indirizzi web, indirizzi IP, nomi utente né il contenuto di ciò che scrivi o invii.

Lo facciamo per [purpose]. Le statistiche sono conservate per [retention].

[Trasferimenti: il fornitore può trattare i dati fuori dall'Unione europea. Le garanzie adottate sono: [transfer safeguards].]

Per esercitare i tuoi diritti o per qualsiasi domanda, scrivi a [contact].

Grade 2, English

Analysis of site requests with AI tools

To find and fix errors and slow pages, we may let an AI assistant provided by [AI provider] read a log of individual requests made to this website. The provider may be located outside the European Union.

For each request the assistant can see: the date and time, the type of page, the names of the parameters in the web address (not their values), the result and the time taken, whether you were logged in (but not who you are), your browser and operating system, and, if an error occurred, the type of error. It does not receive the web address itself or the text of error messages.

The assistant never receives your IP address or your user account number, and it does not receive what you type into forms.

We do this for [purpose]. The data is kept for [retention].

[Transfer safeguards: [transfer safeguards].]

To exercise your rights, including the right to object, write to [contact].

Grade 2, italiano

Analisi delle richieste al sito con strumenti di intelligenza artificiale

Per individuare e correggere errori e pagine lente, possiamo far leggere a un assistente di intelligenza artificiale fornito da [AI provider] il registro delle singole richieste fatte a questo sito. Il fornitore potrebbe trovarsi fuori dall'Unione europea.

Per ogni richiesta l'assistente può vedere: data e ora, tipo di pagina, i nomi dei parametri nell'indirizzo web (non i loro valori), esito e tempo di risposta, se eri collegato con un account (ma non chi sei), il tuo browser e il tuo sistema operativo e, in caso di errore, il tipo di errore. Non riceve l'indirizzo web né il testo dei messaggi di errore.

L'assistente non riceve mai il tuo indirizzo IP né il numero del tuo account, e non riceve ciò che scrivi nei moduli.

Lo facciamo per [purpose]. I dati sono conservati per [retention].

[Garanzie per i trasferimenti: [transfer safeguards].]

Per esercitare i tuoi diritti, compreso il diritto di opposizione, scrivi a [contact].

Metrics and traces sent to monitoring tools, English

Our monitoring tools receive counts and timings per type of page, identified by an internal page-type name. They do not receive web addresses, query parameters, referrers, error messages, or the text you type.

Metriche e tracce inviate agli strumenti di monitoraggio, italiano

I nostri strumenti di monitoraggio ricevono conteggi e tempi per tipo di pagina, identificato da un nome interno. Non ricevono indirizzi web, parametri, pagine di provenienza, messaggi di errore né il testo che scrivi.

If your site stores the full user agent (user agent capture mode full), say so in the grade 2 text: the raw header can reveal device model and build details.

Checklist before declaring grade 2

The site-level declaration has three statements. Check each before you confirm it.

  1. Data may go to remote AI models. Know which MCP clients hold the observability:raw scope, which provider and model each one uses, and where that provider processes data. Grant the scope only to clients you can name.
  2. The privacy notice is updated. The text above, adapted, is live on your privacy page and names the provider, the purpose, the retention and the safeguards.
  3. You accept the controller's responsibility. You decided the purpose and the means, and you answer to visitors and to the supervisory authority for this processing.

Then, outside the module:

  • Add the processing to your record of processing activities.
  • Sign a data processing agreement with the provider, or confirm that its terms make it a controller and decide what that means for you.
  • If the provider processes data outside the EU, complete a transfer assessment and put the safeguards you rely on in the notice.
  • Decide whether a data protection impact assessment is needed for your context.
  • Check that your retention settings (trace_retention_hours and the related ones) match the retention you state in the notice.

This list is a prompt for your own review, not a complete legal checklist.