takt

Serveur MCP

Le serveur Model Context Protocol de Takt permet à n’importe quel agent IA compatible MCP (Claude Desktop, Claude Code, Cursor, …) d’interroger tes statistiques Takt en langage naturel. Demande « combien de visiteurs sur example.com cette semaine ? » et l’agent appelle pour toi le bon endpoint de lecture.

Il lit tes statistiques, par-dessus l’API de lecture HTTP, et peut gérer tes sites, objectifs, entonnoirs, segments et alertes, ainsi que les membres, les invitations et les accès aux sites de ton équipe, comme le ferait un propriétaire ou un administrateur dans le tableau de bord. Le serveur est hébergé par Takt : tu connectes ton client MCP à une URL distante et tu autorises l’accès depuis ton navigateur en OAuth 2.1 : rien à installer, aucune clé d’API à générer ni à copier.

agent IA  ──HTTP (MCP)──▶  serveur MCP distant de Takt  ──▶  tes analytics

Connexion

Pointe ton client MCP vers l’URL distante https://taktlytics.com/mcp en transport HTTP. Avec Claude Code :

claude mcp add --transport http takt https://taktlytics.com/mcp

À la première utilisation, le client ouvre une page dans ton navigateur : tu te connectes à ton compte Takt (2FA incluse), puis tu choisis sur l’écran de consentement quelles équipes (organisations) et quelles permissions accorder à l’agent. Une fois validé, l’agent a accès en une seule fois à tous les sites autorisés, sans avoir besoin de créer une clé ni une instance par site.

Claude (web et desktop)

Dans Réglages → Connecteurs, choisis Ajouter un connecteur personnalisé, nomme-le Takt et colle https://taktlytics.com/mcp. Claude ouvre ensuite l’écran de consentement Takt décrit plus bas.

ChatGPT

Dans Réglages → Apps et connecteurs, crée un connecteur avec l’URL https://taktlytics.com/mcp et l’authentification OAuth. ChatGPT ouvre le même écran de consentement.

Autres clients

Tout client capable de parler MCP en transport HTTP distant se connecte de la même façon, avec l’URL https://taktlytics.com/mcp. Les clients qui ne savent parler qu’en stdio local peuvent utiliser un pont générique comme mcp-remote :

npx -y mcp-remote https://taktlytics.com/mcp

Exemples de questions

  • Combien de visiteurs a eu example.com cette semaine par rapport à la semaine dernière ?
  • Quelles sources ont amené le plus de trafic sur example.com ces 30 derniers jours ?
  • Quel est le taux de conversion de mon entonnoir d’inscription sur example.com ce mois-ci ?
  • Combien de trafic ChatGPT, Claude et Perplexity envoient-ils vers example.com ?
  • Crée un objectif de conversion sur la page /merci de example.com.

Consentement et permissions

L’écran de consentement te laisse accorder l’accès à toutes tes équipes (présentes et futures) ou choisir équipe par équipe, avec pour chacune les scopes voulus. Y sont proposés les scopes de lecture et d’écriture que consomment les outils ci-dessous, et rien d’autre : par exemple orgs:read, qui donne la liste de tes équipes et ton rôle dans chacune, avec la facturation pour celles dont tu es propriétaire, audit:read pour le journal d’audit, members:read pour les membres et members:write pour leur gestion. Un membre ne peut accorder que la lecture, plus reports:write pour ses propres abonnements aux rapports : les autres scopes d’écriture lui sont verrouillés, et ses autres appels d’écriture sont refusés. Les lectures de gestion (journal d’audit, invitations et réglages d’accès par site d’un membre) sont réservées aux owners et admins : un membre simple n’y accède pas, même si audit:read ou members:read lui a été accordé. list_members reste ouvert aux membres, sans e-mails. sites:write n’existe que par ce consentement OAuth : une clé d’API ne peut pas le recevoir.

Les droits sont recalculés à chaque appel : ils sont bornés par ton rôle réel dans chaque organisation, jamais par ce que le client a demandé. Perdre un accès dans une équipe le retire immédiatement à l’agent, sans toucher au consentement.

Réautoriser après un nouveau scope

Un client connecté avant l’ajout d’un scope garde le consentement qu’il a reçu : un outil qui exige un scope absent de ce consentement est refusé avec l’erreur JSON-RPC -32001, qui nomme le scope manquant et dit quoi faire :

  • Scope non accordé : ton rôle le permet, seul le consentement ne le contient pas. Le message est « scope sites:write non accordé à ce client : réautorise le connecteur MCP pour l’ajouter ». Déconnecte puis reconnecte le connecteur (ou relance l’autorisation depuis ton client) : l’écran de consentement propose alors le nouveau scope.
  • Rôle insuffisant : ton rôle dans l’équipe n’ouvre pas ce scope, par exemple un membre qui appelle update_site. Le message est « droits insuffisants : ton rôle ne permet pas le scope sites:write, réautoriser le connecteur n’y changera rien ». Seul un owner ou un admin peut te donner ce droit.

Le champ data de l’erreur porte missingScope (le scope manquant) et reauthorize (true quand une réautorisation suffit), pour qu’un client puisse proposer la reconnexion lui-même.

list_sites et list_orgs couvrent plusieurs équipes, chacune avec son propre consentement. Une équipe dont le consentement n’accorde pas le scope de l’outil (sites:read pour l’un, orgs:read pour l’autre) est écartée. Si au moins une équipe est servie, l’appel réussit avec elles seules ; si aucune ne l’est et qu’au moins une a été écartée faute du scope, il répond ce même -32001 au lieu d’une liste vide. reauthorize ne vaut true que si ton rôle permet le scope dans toutes les équipes écartées.

Tu peux révoquer un accès à tout moment depuis Réglages → Sessions → Applications connectées. Les jetons sont de courte durée et renouvelés automatiquement ; une révocation coupe l’accès immédiatement.

Outils

OutilDescriptionPermission
list_sitesListe tous les sites des équipes autorisées (aucun argument).sites:read
list_orgsListe tes équipes, avec ton rôle ; facturation et offre pour celles dont tu es propriétaire.orgs:read
get_orgDétail d’une équipe : slug, nom et ton rôle ; facturation et offre si tu en es propriétaire (org).orgs:read
get_summaryVisiteurs, sessions, pages vues, taux de rebond, durée moyenne.stats:read
get_timeseriesVisiteurs/pages vues dans le temps, par heure ou par jour.stats:read
get_breakdownTop d’une dimension (pages, sources, pays, appareils…).stats:read
get_realtimeVisiteurs actifs sur les 5 dernières minutes.stats:read
get_goalsConversions par objectif.stats:read
get_funnelsRapports d’entonnoir étape par étape.funnels:read
get_revenueRevenu groupé par devise pour un événement de revenu.stats:read
list_event_propertiesClés de propriétés personnalisées enregistrées pour un événement.stats:read
get_property_breakdownVentile une propriété personnalisée d’un événement par valeur.stats:read
get_ai_visibilityTrafic renvoyé par les assistants IA et passages des robots IA.ai:read
get_search_consoleClics, impressions, CTR, position et top requêtes Google.search_console:read
get_breakdownsPlusieurs dimensions d’un site en un seul appel (de 1 à 14).stats:read
get_search_console_drillDétail Search Console d’une page ou d’une requête.search_console:read
suggest_pagesPages à suivre : sitemap et pages vues sur douze mois.stats:read
export_statsClassement des pages en CSV ou JSON, borné à 999 lignes.stats:read
get_siteRéglages d’un site : domaine, vérification, badge, embed et normalisation d’URL.sites:read
get_install_snippetScript d’installation du tracker, avec ou sans captures automatiques, et ses options avancées : enabled, sample-rate (fraction de 0 à 1), track-query et query-params (qui exige track-query).sites:read
get_site_verificationÉtat de la vérification de propriété : jeton, méthode, dates (propriétaire et administrateur uniquement).sites:read
list_goal_definitionsListe les objectifs définis sur un site, avec leur identifiant.goals:read
list_funnel_definitionsListe les entonnoirs définis sur un site, avec leur identifiant.funnels:read
list_segmentsListe les segments sauvegardés d’un site, avec leur identifiant.segments:read
list_alertsListe les règles d’alerte d’un site (propriétaire et administrateur uniquement).alerts:read
get_google_integrationÉtat de la connexion Google d’un site : propriétés choisies et scopes accordés.integrations:read
get_google_connect_linkAdresse de la page Réglages du site, où la connexion Google se lance depuis le navigateur. L’outil n’entame aucune autorisation.integrations:read
list_ga4_propertiesPropriétés GA4 accessibles avec la connexion Google du site.integrations:read
list_search_console_propertiesPropriétés Search Console accessibles avec la connexion Google du site.integrations:read
list_importsJobs d’import d’un site, du plus récent au plus ancien.integrations:read
get_importStatut, avancement et erreur éventuelle d’un job d’import.integrations:read
list_report_subscriptionsTes abonnements aux rapports email dans une équipe : digest de l’équipe ou rapport d’un site.reports:read
list_audit_logsJournal d’audit de l’équipe, filtrable par acteur et par action. Réservé aux owners et admins.audit:read
list_membersMembres de l’équipe et leur rôle (e-mails pour owner et admin).members:read
list_invitationsInvitations en attente de l’équipe. Réservé aux owners et admins.members:read
get_member_site_accessSites accessibles à un membre. Réservé aux owners et admins.members:read

Outils d’écriture

Ces outils modifient la configuration d’un site. Ils sont réservés aux propriétaires et aux administrateurs : pour un membre, l’appel est refusé. Les identifiants (id) viennent des outils list_*. Une ressource d’un autre site, ou d’une autre équipe, est traitée comme introuvable.

OutilDescriptionPermission
create_siteCrée un site dans une équipe (org), non vérifié. Respecte le quota de sites de l’offre.sites:write
update_siteModifie les réglages d’un site, champ par champ.sites:write
delete_siteSupprime un site et ses données. Irréversible.sites:write
check_site_verificationLance le contrôle de propriété du domaine (DNS ou fichier).sites:write
regenerate_site_verification_tokenRemplace le jeton de vérification ; l’ancien cesse de valoir.sites:write
create_goalCrée un objectif (pageview, event ou revenue) sur un site.goals:write
delete_goalSupprime un objectif.goals:write
create_funnelCrée un entonnoir de deux étapes au minimum, avec une fenêtre optionnelle.funnels:write
update_funnelRemplace le nom, la fenêtre et les étapes d’un entonnoir.funnels:write
delete_funnelSupprime un entonnoir.funnels:write
create_segmentCrée un segment sauvegardé à partir de filtres sur les dimensions autorisées.segments:write
update_segmentRemplace le nom et la définition d’un segment.segments:write
delete_segmentSupprime un segment.segments:write
create_alertCrée une règle d’alerte : pic ou chute de trafic, site silencieux ou conversion d’un objectif.alerts:write
update_alertModifie une règle d’alerte.alerts:write
delete_alertSupprime une règle d’alerte.alerts:write
set_search_console_propertyLie le site à une propriété Search Console accessible.integrations:write
clear_search_console_propertyDélie la propriété Search Console du site ; la connexion Google reste active.integrations:write
disconnect_googleRévoque la connexion Google du site et supprime les propriétés choisies. Irréversible.integrations:write
create_import_upload_urlURL signée où déposer un fichier CSV (GA4 ou Plausible), hors de l’outil.integrations:write
create_importLance un import GA4 depuis une propriété connectée, ou depuis un fichier déposé. Un seul import à la fois par site.integrations:write
delete_importSupprime un job d’import et purge les agrégats qu’il a produits. Irréversible.integrations:write
create_report_subscriptionAbonne-toi à un rapport email : digest de l’équipe (sans domaine) ou rapport d’un site (avec domaine). Idempotent.reports:write
delete_report_subscriptionSupprime un de tes abonnements aux rapports email.reports:write

Exception : un membre peut gérer ses propres abonnements aux rapports avec reports:write.

Les outils de lecture sont annotés en lecture seule. Les outils delete_*, disconnect_google et clear_search_console_property sont signalés comme destructifs : ton client peut le montrer. Les outils d’abonnement aux rapports prennent le slug ou l’identifiant de l’équipe dans org, plus un domain optionnel pour le rapport d’un site.

Le transfert d’un site vers une autre équipe n’est pas exposé au MCP : il reste dans le tableau de bord, avec sa confirmation renforcée. delete_site et regenerate_site_verification_token sont annotés destructifs, ce que ton client peut afficher.

Gestion de l’équipe

Ces outils modifient les membres et les invitations d’une équipe, désignée par son slug ou son identifiant dans org. Ils sont réservés aux propriétaires et aux administrateurs.

OutilDescriptionPermission
create_invitationInvite une adresse e-mail à rejoindre l’équipe.members:write
resend_invitationRenvoie une invitation en attente, avec un nouveau lien.members:write
revoke_invitationRévoque une invitation en attente.members:write
update_memberChange le rôle d’un membre.members:write
remove_memberRetire un membre de l’équipe.members:write
set_member_site_accessDéfinit les sites accessibles à un membre.members:write

update_member, revoke_invitation et remove_member sont marqués destructifs. Repasser un membre au rôle member révoque aussi les clés d’API qu’il a créées sur les sites de l’équipe. Un admin ne promeut pas vers admin ou owner et ne retire pas un owner ou un admin : ces gestes sont réservés au rôle owner. Le dernier owner ne peut être ni retiré ni rétrogradé. Chaque changement de rôle, retrait, réglage d’accès par site et invitation est inscrit au journal d’audit de l’équipe, avec le grant OAuth et le client qui l’ont effectué. Une invitation, un membre ou un site d’une autre équipe répond « introuvable », comme un identifiant inexistant.

La plupart des outils acceptent un filtre temporel : period (day, 7d, 30d, month, 6mo, 12mo), ou une plage explicite from/to (YYYY-MM-DD), plus un tz optionnel (fuseau IANA). Les outils portant sur un site exigent un domain explicite : il n’y a pas de site par défaut, même si le consentement ne couvre qu’un seul site. get_org, create_site et les outils d’équipe (journal d’audit, membres, invitations, accès aux sites, abonnements aux rapports) prennent le slug ou l’identifiant de l’équipe dans org. list_sites et list_orgs ne prennent aucun argument d’équipe et couvrent toutes tes équipes autorisées.

get_search_console exige en plus que le site ait une propriété Search Console rattachée depuis ses réglages ; sans cela l’appel échoue avec un message explicite. Les données Google accusent deux à trois jours de retard.

Les outils Google, en lecture comme en écriture, et les écritures d’import exigent un rôle qui gère le site (propriétaire ou administrateur de l’équipe) ; les lectures d’import exigent l’accès aux statistiques du site. Un rôle insuffisant renvoie une erreur d’outil « droits insuffisants ». Les abonnements aux rapports sont toujours ceux de la personne qui utilise la clé : aucun outil ne permet d’abonner ou de désabonner quelqu’un d’autre.

Les outils de statistiques n’exposent un site qu’une fois celui-ci vérifié. Les outils Google, d’import et de rapports n’exigent pas cette vérification, comme leurs routes HTTP : un site non vérifié reste donc gérable depuis ton client MCP.

Filtres et segments

Les outils de statistiques (get_summary, get_timeseries, get_breakdown, get_breakdowns, get_ai_visibility, suggest_pages et export_stats) restreignent les visiteurs comptés avec deux paramètres, qui ne se combinent pas :

  • filters : au plus 20 conditions { "dim", "op", "val", "join" }. dim vaut pages, sources, countries, regions, cities, devices, browsers, os, utm_source, utm_medium, utm_campaign ou ai_assistant. op vaut is ou not, et join vaut and ou or. Les pages d’entrée et de sortie ne se filtrent pas : elles ne servent qu’à ventiler.
  • segmentId : l’identifiant d’un segment enregistré sur ce site. Il exige le scope segments:read en plus de stats:read. Un identifiant inconnu, ou celui d’un segment d’un autre site, est refusé.

Les filtres passent par le même moteur de validation que les segments de l’interface : une condition que Takt refuserait est refusée ici, avant tout calcul. Passer filters et segmentId dans le même appel est refusé.

get_goals, get_funnels, get_revenue et get_property_breakdown n’acceptent pas de segment.

Comparaison à la période précédente

compareToPrevious (booléen) sur get_summary, get_timeseries, get_breakdown, get_breakdowns, get_goals et get_funnels renvoie aussi la période précédente de même durée. Il n’existe pas sur get_revenue ni get_property_breakdown : l’API ne sait pas les comparer.

Exports et ventilations multiples

get_breakdowns ventile plusieurs dimensions en un seul appel (de 1 à 14, sans doublon), avec le même limit pour chacune.

export_stats exporte le classement des pages (libellé, visiteurs, pages vues) en CSV (format csv, par défaut) ou en JSON (format json). L’export est borné à 999 lignes et à 256 Ko de réponse envoyée : au-delà, truncated vaut true et il faut affiner la période ou le segment. Les cellules CSV qui commencent par =, +, -, @, une tabulation ou un retour chariot sont préfixées d’une apostrophe, pour ne pas s’exécuter dans un tableur.

suggest_pages liste les pages à suivre : celles du sitemap et celles vues sur les douze mois qui se terminent à la fin de la période demandée. Chaque suggestion indique si elle vient du sitemap, de Takt, ou des deux.

get_search_console_drill détaille les données Search Console d’une page (valeur : son URL) ou d’une requête (valeur : son texte). Comme get_search_console, il exige une propriété Search Console rattachée au site.

Le serveur MCP est inclus dans tous les plans, sans limite de volume. Chaque appel d'outil est compté comme une requête API de l'équipe visée, à titre informatif. L'ingestion, elle, n'est jamais affectée. Une équipe sans accès au produit (essai terminé, abonnement résilié) répond l'erreur JSON-RPC -32001 « accès restreint ». list_sites et list_orgs couvrent plusieurs équipes : une équipe sans accès est omise de la liste quand une autre est servie. Si aucune équipe n'est servie et qu'au moins une est restreinte, ils répondent -32001 « accès restreint » au lieu d'une liste vide, avant tout refus de scope.

Une limite de débit anti-abus s’applique par connexion MCP : 200 requêtes par 10 secondes et 600 requêtes par minute. Au-delà, la réponse reste en HTTP 200, porte l’en-tête Retry-After et l’erreur JSON-RPC -32003 « trop de requêtes, réessaie dans N s ». Son champ data.retryAfter donne le délai en secondes (10 pour la rafale, 60 pour la minute). Ton client MCP n’a qu’à attendre ce délai avant de rappeler.

En amont, la passerelle applique aussi un plafond par adresse IP, toutes connexions confondues : 20 requêtes par seconde, avec des pointes jusqu’à 150. Au-delà, elle répond en HTTP 429 avec un corps HTML, sans erreur JSON-RPC et sans en-tête Retry-After : attends une seconde avant de réessayer.