SteerAds
Google AdsTutorielActualité

MCP Google Ads sur Claude Desktop 2026

Construire un serveur MCP (Model Context Protocol) pour piloter Google Ads en conversational depuis Claude Desktop. Architecture, code TypeScript, OAuth, tools exposees, repo GitHub open-source. Setup pas-a-pas pour PPC managers techniques.

Matt
MattTracking & Data Lead
···12 min de lecture

MCP (Model Context Protocol) lance par Anthropic en novembre 2024 a depasse 200 serveurs publics dans le directory officiel a fin Q1 2026 (modelcontextprotocol.io), avec une adoption qui s'accelere chez les power users de Claude Desktop, Cursor, et Claude Code. Pourtant, moins de 5 serveurs MCP publics existent pour Google Ads en 2026 — c'est l'un des trous les plus gros de l'ecosysteme, et c'est exactement ce que nous allons combler dans ce guide. Ordres de grandeur observes sur le données Google Ads agrégées 2025-2026 : un PPC manager qui adopte un workflow MCP-driven recupere typiquement 25 a 40% de temps operationnel selon la taille du compte, avec un ecart se situant entre 18% et 52% selon les verticals (e-com mature gain le plus eleve, lead gen B2B gain plus modere car cycles longs).

Voici exactement comment construire un serveur MCP Google Ads en TypeScript : architecture, code TypeScript copy-paste, OAuth setup, tools exposees, configuration Claude Desktop. A la fin du guide, vous aurez un setup ou taper "audite mon compte Google Ads" dans Claude Desktop declenche un audit reel via votre serveur MCP. Le repo GitHub github.com/steerads/mcp-google-ads-server contient l'integralite du code documente. Prerequis : Node.js 18+, un compte Google Ads, un developer_token API (voir notre guide setup API Google Ads Python pour la procedure OAuth, identique cote TypeScript). Si vous debutez sur l'automation Google Ads, lisez d'abord notre guide des 10 scripts ready-to-copy. Notre calculateur de gaspillage budget estime le € brûlé/mois par broad sans négatifs ou bounce LP excessif.

Qu'est-ce que MCP et pourquoi pour Google Ads ?

MCP (Model Context Protocol) est un protocole open-source publie par Anthropic en novembre 2024 pour standardiser la maniere dont les LLM (Claude, mais aussi compatible avec d'autres modeles) consomment des donnees et des outils externes. Pensez-le comme l'equivalent de LSP (Language Server Protocol) pour les IDE : un protocole client-serveur ou le client est une app LLM (Claude Desktop, Claude Code, Cursor, Zed) et le serveur expose des resources (donnees a lire), prompts (templates pre-formates) et tools (fonctions a appeler) via une interface JSON-RPC standardisee.

Pour Google Ads, le benefice est immediat. Au lieu d'aller chercher manuellement les data dans l'interface Google Ads (10 clicks pour pull une stat), vous tapez en langage naturel dans Claude Desktop : "Quels sont mes 5 keywords avec le plus haut CPA cette semaine ?" et Claude appelle automatiquement un tool pull_keyword_performance exposed par votre serveur MCP, lit la reponse, et formule une analyse en langage clair. C'est le PPC manager workflow reimagine en conversational.

Trois benefices concrets observés dans les benchmarks publics sur les setups MCP Google Ads en production :

  1. Time saved sur les requetes ad-hoc : 5 a 15 minutes economisees par session d'analyse (pas de connexion interface, pas de filtrage manuel, pas de copie/colle dans Excel).
  2. Cross-account synthesis : un MCP server peut interroger 10 comptes en parallele et synthetiser les insights — impossible cote Scripts.
  3. Conversational debugging : "pourquoi le CPA de la campagne X a explose hier ?" declenche un audit multi-facteur (CPC, CTR, conv rate, search terms, IS) sans que vous ayez a savoir quels reports consulter.
Insight clé :

Sur les comptes observés dans les benchmarks Google Ads publics, les PPC managers qui adoptent un workflow MCP gagnent 30 a 50 minutes par jour sur les taches d'analyse exploratoire (questions ouvertes, deep dives ad-hoc, troubleshooting). Le ROI se mesure en jours, pas en mois. C'est l'un des plus gros sauts de productivite de la decennie pour le metier — et tres peu d'agences/freelances l'ont mis en place a Q1 2026.

MCP n'est PAS adapte pour : les automations en cron (un MCP server attend qu'un humain interagisse via Claude Desktop, il n'a pas de scheduler), les bulk mutations au-dela de 1 000 entites (pas le bon medium), ou les operations qui demandent une UI riche (graphiques interactifs, drag-drop). Pour ces cas, l'API Python en standalone ou les Google Ads Scripts restent le bon outil.

Architecture : Claude Desktop -> MCP server -> Google Ads API

L'architecture d'un setup MCP Google Ads suit un pattern client-serveur classique decompose en trois couches : un client LLM (Claude Desktop, Cursor, Claude Code) qui orchestre la conversation et la decision d'appeler des tools ; un serveur MCP (votre code) qui expose un catalogue de tools via le protocole JSON-RPC ; et une API metier sous-jacente (ici Google Ads API v17) qui execute les operations reelles. Cette separation rend le serveur reutilisable : un seul code TypeScript, plusieurs clients possibles. Sur les setups que nous deployons, l'effort de developpement initial est de l'ordre de 4 a 8 heures pour un MCP server avec 4 tools, et le ratio temps gagne / temps investi se renverse en moyenne en 2 a 3 semaines d'usage.

Architecture MCP Google AdsClaude DesktopUser prompt en langage naturel"audite mon compte"JSON-RPC stdiotool callsMCP ServerTypeScript local- search_campaigns- get_account_audit- pull_reportHTTPS gRPCOAuth2Google Ads APIv17 (REST/gRPC)developer_token + OAuth

Couche 1 : Claude Desktop. L'app desktop officielle d'Anthropic disponible sur Mac et Windows (claude.ai/desktop). Elle hoste l'experience conversational, decouvre les serveurs MCP installes via le fichier de config, et orchestre les tool calls. Vous parlez a Claude, Claude decide d'appeler vos tools.

Couche 2 : MCP Server (votre code). Un process Node.js (ou Python, Rust, Go — peu importe) qui implemente le protocole MCP via stdin/stdout (mode local stdio) ou HTTP/SSE (mode remote). Le serveur expose une liste de tools, chacun avec un nom, une description, un schema d'arguments. A chaque appel d'un tool par Claude, le serveur execute le code et retourne un resultat structure.

Couche 3 : Google Ads API. La library google-ads-api (port Node.js de la library officielle, maintenue par la communaute) abstrait les appels GAQL et les mutations. Le serveur MCP s'authentifie via OAuth2 + developer_token au demarrage, puis utilise le client pour appeler l'API a chaque tool call.

Le mode stdio local est largement suffisant pour usage individuel : le serveur tourne sur votre machine, Claude Desktop le spawn en subprocess, communication via stdin/stdout JSON-RPC. Pas de reseau, latence proche de zero, credentials jamais exposes ailleurs que sur votre machine. Le mode HTTP/SSE remote devient pertinent pour les equipes qui partagent un MCP server (ex : agence avec 5 PPC managers qui pointent sur le meme serveur). Pour ce guide, on reste sur stdio local.

Le tableau ci-dessous compare les deux transports pour faire le bon choix selon votre setup :

Setup Claude Desktop et configuration MCP

Avant de coder le serveur, configurer Claude Desktop pour qu'il puisse decouvrir des serveurs MCP. Telecharger Claude Desktop depuis claude.ai/desktop, l'installer, se connecter avec un compte Anthropic.

Le fichier de configuration MCP de Claude Desktop est :

  • Mac : ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows : %APPDATA%\Claude\claude_desktop_config.json

Si le fichier n'existe pas, le creer. Voici la structure de base :

{
  "mcpServers": {
    "google-ads": {
      "command": "node",
      "args": [
        "/Users/votreuser/dev/mcp-google-ads-server/dist/index.js"
      ],
      "env": {
        "GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEVELOPER_TOKEN",
        "GOOGLE_ADS_CLIENT_ID": "YOUR_CLIENT_ID",
        "GOOGLE_ADS_CLIENT_SECRET": "YOUR_CLIENT_SECRET",
        "GOOGLE_ADS_REFRESH_TOKEN": "YOUR_REFRESH_TOKEN",
        "GOOGLE_ADS_LOGIN_CUSTOMER_ID": "1234567890",
        "GOOGLE_ADS_DEFAULT_CUSTOMER_ID": "1112223333",
        "READ_ONLY_MODE": "false"
      }
    }
  }
}

Trois cles importantes :

  • command : la commande pour lancer le serveur. Ici node parce que TypeScript compile, mais peut etre python, npx, etc.
  • args : le chemin absolu vers le build du serveur. Eviter les chemins relatifs ou avec ~ non resolu.
  • env : les variables d'environnement passees au serveur. C'est ici qu'on injecte les credentials Google Ads.

Note securite : ce fichier contient vos credentials Google Ads en clair. Ne JAMAIS le commit dans Git, ne JAMAIS le partager. Pour une equipe, considerer un wrapper script qui charge les creds depuis un secret manager au lancement.

Pour valider que Claude Desktop voit bien votre serveur, apres restart de Claude Desktop, ouvrir une nouvelle conversation et taper "quels MCP servers sont disponibles ?". Claude doit lister google-ads avec ses tools (apres le 1er run qui les enumere).

Ecrire un serveur MCP en TypeScript : 4 tools cles

Un tool MCP est l'unite minimale d'extension du LLM : une fonction nommee, decrite en clair, parametree par un schema JSON, qui execute une operation et retourne un resultat structure. Le SDK officiel @modelcontextprotocol/sdk fournit le squelette serveur et le routing des tools ; vous fournissez la logique metier. La regle empirique que nous appliquons sur les setups en production : 6 a 12 tools par serveur MCP, focalises sur des operations atomiques (un tool = un verbe metier), avec une description en moins de 200 caracteres pour que le LLM choisisse correctement. Les 4 tools developpes ci-dessous (search_campaigns, get_account_audit, pull_report, add_negative) couvrent dans la majorite des cas 70 a 80% des questions posees a un PPC manager au quotidien.

mcp-google-ads-server/
├── src/
│   ├── index.ts          # Entry point + MCP server setup
│   ├── google-ads.ts     # Client wrapper Google Ads API
│   ├── tools/
│   │   ├── search-campaigns.ts
│   │   ├── account-audit.ts
│   │   ├── pull-report.ts
│   │   └── add-negative.ts
│   └── types.ts
├── package.json
├── tsconfig.json
└── .env.example

Le package.json minimum :

{
  "name": "mcp-google-ads-server",
  "version": "0.1.0",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "ts-node src/index.ts"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^0.5.0",
    "google-ads-api": "^17.0.0",
    "zod": "^3.22.0"
  },
  "devDependencies": {
    "typescript": "^5.3.0",
    "ts-node": "^10.9.0",
    "@types/node": "^20.10.0"
  }
}

Le entry point src/index.ts initialise le serveur MCP et enregistre les tools :

// src/index.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { searchCampaignsTool } from "./tools/search-campaigns.js";
import { accountAuditTool } from "./tools/account-audit.js";
import { pullReportTool } from "./tools/pull-report.js";
import { addNegativeTool } from "./tools/add-negative.js";

const server = new Server(
  { name: "google-ads-mcp", version: "0.1.0" },
  { capabilities: { tools: {} } }
);

const TOOLS = [
  searchCampaignsTool,
  accountAuditTool,
  pullReportTool,
  addNegativeTool,
];

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: TOOLS.map((t) => ({
    name: t.name,
    description: t.description,
    inputSchema: t.inputSchema,
  })),
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const tool = TOOLS.find((t) => t.name === request.params.name);
  if (!tool) {
    throw new Error(`Unknown tool: ${request.params.name}`);
  }

  try {
    const result = await tool.handler(request.params.arguments);
    return {
      content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
    };
  } catch (err) {
    const msg = err instanceof Error ? err.message : String(err);
    return {
      content: [{ type: "text", text: `Error: ${msg}` }],
      isError: true,
    };
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);
console.error("[MCP] google-ads server started on stdio");

Note : console.error au lieu de console.log parce que stdout est reserve au protocole JSON-RPC. Tout log via stderr pour ne pas polluer le canal de communication. Cette regle est non-negociable : un seul console.log parasite suffit a casser le parsing JSON du client et a faire tomber la conversation. Pour debugger en developpement, le pattern recommande est d'utiliser un logger structure (pino, winston) configure en write-stream sur stderr, avec un niveau de verbosite ajustable via env var. Sur les serveurs en production que nous deployons, on observe couramment 30-60% du temps de troubleshooting initial absorbe par des problemes de stream pollution, qui disparaissent une fois le logger correctement cable.

Le wrapper Google Ads dans src/google-ads.ts :

// src/google-ads.ts
import { GoogleAdsApi } from "google-ads-api";

let clientInstance: GoogleAdsApi | null = null;

export function getGoogleAdsClient(): GoogleAdsApi {
  if (clientInstance) return clientInstance;

  clientInstance = new GoogleAdsApi({
    client_id: process.env.GOOGLE_ADS_CLIENT_ID!,
    client_secret: process.env.GOOGLE_ADS_CLIENT_SECRET!,
    developer_token: process.env.GOOGLE_ADS_DEVELOPER_TOKEN!,
  });

  return clientInstance;
}

export function getCustomer(customerId?: string) {
  const id = customerId || process.env.GOOGLE_ADS_DEFAULT_CUSTOMER_ID!;
  const loginId = process.env.GOOGLE_ADS_LOGIN_CUSTOMER_ID!;

  const client = getGoogleAdsClient();
  return client.Customer({
    customer_id: id,
    login_customer_id: loginId,
    refresh_token: process.env.GOOGLE_ADS_REFRESH_TOKEN!,
  });
}

Le tool search-campaigns qui expose une recherche GAQL flexible :

// src/tools/search-campaigns.ts
import { z } from "zod";
import { getCustomer } from "../google-ads.js";

const inputSchema = {
  type: "object",
  properties: {
    customer_id: {
      type: "string",
      description: "Google Ads customer ID (10 digits, no dashes). Default if omitted.",
    },
    status_filter: {
      type: "string",
      enum: ["ENABLED", "PAUSED", "REMOVED", "ALL"],
      description: "Campaign status filter. Default: ENABLED.",
    },
    date_range: {
      type: "string",
      description: "GAQL date range: TODAY, LAST_7_DAYS, LAST_30_DAYS, etc.",
    },
    limit: {
      type: "number",
      description: "Max number of campaigns to return. Default: 50.",
    },
  },
};

export const searchCampaignsTool = {
  name: "search_campaigns",
  description:
    "List Google Ads campaigns with their KPI (impressions, clicks, cost, conversions, CTR, CPA) " +
    "filtered by status and date range. Returns top campaigns by spend.",
  inputSchema,
  handler: async (args: any) => {
    const customer = getCustomer(args?.customer_id);
    const status = args?.status_filter || "ENABLED";
    const dateRange = args?.date_range || "LAST_30_DAYS";
    const limit = args?.limit || 50;

    const statusClause =
      status === "ALL" ? "" : `AND campaign.status = '${status}'`;

    const query = `
      SELECT
        campaign.id, campaign.name, campaign.status,
        metrics.impressions, metrics.clicks,
        metrics.cost_micros, metrics.conversions,
        metrics.ctr, metrics.average_cpc
      FROM campaign
      WHERE segments.date DURING ${dateRange} ${statusClause}
      ORDER BY metrics.cost_micros DESC
      LIMIT ${limit}
    `;

    const rows = await customer.query(query);

    return rows.map((r: any) => ({
      id: r.campaign.id,
      name: r.campaign.name,
      status: r.campaign.status,
      impressions: r.metrics.impressions,
      clicks: r.metrics.clicks,
      cost_eur: (Number(r.metrics.cost_micros) / 1_000_000).toFixed(2),
      conversions: r.metrics.conversions,
      ctr_pct: (Number(r.metrics.ctr) * 100).toFixed(2),
      cpc_eur: (Number(r.metrics.average_cpc) / 1_000_000).toFixed(2),
      cpa_eur:
        Number(r.metrics.conversions) > 0
          ? (
              Number(r.metrics.cost_micros) /
              1_000_000 /
              Number(r.metrics.conversions)
            ).toFixed(2)
          : null,
    }));
  },
};

Le tool account-audit qui agrege une vue audit haut-niveau :

// src/tools/account-audit.ts
import { getCustomer } from "../google-ads.js";

export const accountAuditTool = {
  name: "get_account_audit",
  description:
    "Run a high-level audit of the Google Ads account: total spend last 30 days, " +
    "campaign types breakdown, top 5 campaigns by spend, conversion volume, " +
    "average CPA. Returns a structured audit report.",
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Customer ID (default if omitted).",
      },
    },
  },
  handler: async (args: any) => {
    const customer = getCustomer(args?.customer_id);

    // 1. Account totals
    const totals = await customer.query(`
      SELECT
        metrics.cost_micros, metrics.clicks,
        metrics.conversions, metrics.impressions
      FROM customer
      WHERE segments.date DURING LAST_30_DAYS
    `);

    // 2. Top 5 campaigns
    const top5 = await customer.query(`
      SELECT campaign.name, metrics.cost_micros, metrics.conversions
      FROM campaign
      WHERE campaign.status = 'ENABLED'
        AND segments.date DURING LAST_30_DAYS
      ORDER BY metrics.cost_micros DESC LIMIT 5
    `);

    // 3. Campaign types breakdown
    const types = await customer.query(`
      SELECT
        campaign.advertising_channel_type,
        metrics.cost_micros
      FROM campaign
      WHERE campaign.status = 'ENABLED'
        AND segments.date DURING LAST_30_DAYS
    `);

    const totalCost =
      totals.reduce(
        (sum: number, r: any) => sum + Number(r.metrics.cost_micros),
        0
      ) / 1_000_000;
    const totalConv = totals.reduce(
      (sum: number, r: any) => sum + Number(r.metrics.conversions),
      0
    );

    return {
      period: "LAST_30_DAYS",
      total_spend_eur: totalCost.toFixed(2),
      total_clicks: totals.reduce(
        (s: number, r: any) => s + Number(r.metrics.clicks),
        0
      ),
      total_conversions: totalConv.toFixed(1),
      avg_cpa_eur:
        totalConv > 0 ? (totalCost / totalConv).toFixed(2) : null,
      top_5_campaigns: top5.map((r: any) => ({
        name: r.campaign.name,
        spend_eur: (Number(r.metrics.cost_micros) / 1_000_000).toFixed(2),
        conv: r.metrics.conversions,
      })),
      campaign_count_by_type: types.reduce(
        (acc: Record<string, number>, r: any) => {
          const t = r.campaign.advertising_channel_type;
          acc[t] = (acc[t] || 0) + 1;
          return acc;
        },
        {}
      ),
    };
  },
};

Les 2 tools restants (pull_report pour les exports custom et add_negative pour les mutations avec confirm) suivent le meme pattern. Le repo github.com/steerads/mcp-google-ads-server contient l'integralite du code, plus 2 tools additionnels (update_keyword_bid avec confirm, list_audiences).

La distinction read-only vs mutation merite un mot. Les tools search_campaigns, get_account_audit, pull_report sont safe par construction : ils n'alterent pas l'etat du compte, peuvent etre appeles autant de fois que necessaire, et leur cout est limite a la consommation de quota API. Les tools add_negative_keyword, update_keyword_bid, pause_campaign sont mutateurs et impliquent une discipline supplementaire. Le pattern dominant que nous appliquons est double opt-in : un flag global READ_ONLY_MODE=true qui desactive completement les mutations cote serveur, plus une confirmation explicite demandee au LLM avant chaque mutation individuelle. Documente sur la page Google Ads API best practices, ce double-niveau de protection evite les mutations accidentelles dans les sessions de debug ou d'exploration ouvertes.

Authentification OAuth Google Ads dans MCP

L'OAuth Google Ads suit le meme pattern qu'un script Python ou Node.js standalone : developer_token + refresh_token + login_customer_id. La specificite MCP : ces credentials sont passes au serveur via les env du fichier claude_desktop_config.json, charges au demarrage du process.

Pour generer le refresh_token initial, le plus simple est d'utiliser le script officiel google-ads-python (procedure detaillee dans notre guide setup API Python). Une fois le refresh_token genere, il est valable durablement (Google le revoque rarement, sauf changement de password ou revocation manuelle).

Le flow d'auth dans le MCP server :

// src/auth-check.ts
import { getCustomer } from "./google-ads.js";

export async function validateCredentials() {
  const required = [
    "GOOGLE_ADS_DEVELOPER_TOKEN",
    "GOOGLE_ADS_CLIENT_ID",
    "GOOGLE_ADS_CLIENT_SECRET",
    "GOOGLE_ADS_REFRESH_TOKEN",
    "GOOGLE_ADS_LOGIN_CUSTOMER_ID",
  ];

  const missing = required.filter((k) => !process.env[k]);
  if (missing.length > 0) {
    throw new Error(
      `Missing required env vars: ${missing.join(", ")}. ` +
        `Check claude_desktop_config.json.`
    );
  }

  // Test query : verifier que les credentials sont valides
  try {
    const customer = getCustomer();
    const test = await customer.query("SELECT customer.id FROM customer LIMIT 1");
    if (!test || test.length === 0) {
      throw new Error("Empty response from API");
    }
    console.error(`[Auth] OK customer ${test[0].customer.id}`);
  } catch (err) {
    const msg = err instanceof Error ? err.message : String(err);
    throw new Error(
      `Auth failed: ${msg}. Check refresh_token and login_customer_id.`
    );
  }
}

Appeler validateCredentials() au demarrage du serveur (apres l'init du transport, avant d'accepter des tool calls). Si l'auth fail, le serveur log l'erreur sur stderr et exit avec code 1 — Claude Desktop verra le serveur comme down et affichera l'erreur a l'utilisateur.

Securite production : si vous deployez le MCP server sur un serveur partage (mode HTTP/SSE), ne JAMAIS hardcoder les creds en plain text. Utiliser un secret manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault) et charger les creds au demarrage. Pour le mode local stdio individuel, le claude_desktop_config.json en clair est acceptable parce qu'il n'est pas committe et que la machine est par definition de confiance.

Use cases : auditer, optimiser, reporter via Claude conversational

Une fois le MCP server installe, le workflow change radicalement. Voici 5 patterns d'usage qui revolutionnent la productivite PPC.

Pattern 1 — Audit conversationnel : "audite mon compte"

User : "Audite mon compte Google Ads, qu'est-ce que tu vois de chelou cette semaine ?"

Claude appelle get_account_audit, recoit les KPI, et formule une analyse structuree : "Sur les 30 derniers jours, vous avez depense 45 230 EUR pour 247 conversions, soit un CPA moyen de 183 EUR. Trois points d'attention : la campagne 'Brand Search FR' represente 38% du spend mais seulement 12% des conversions (CPA dispro), la campagne 'PMax Generic' a un CPA de 412 EUR vs 145 EUR sur Search Brand (incrementality questionable), et 4 campagnes ont un CTR inferieur a 2% qui meritent un asset refresh."

C'est l'audit que vous auriez fait en 30 minutes manuellement, livre en 8 secondes.

Pattern 2 — Deep dive ad-hoc : "pourquoi le CPA a explose hier ?"

User : "Le CPA de la campagne 'Search Generic FR' a double hier, qu'est-ce qui s'est passe ?"

Claude enchaine plusieurs tool calls : pull_report (CPC + CTR + conv rate yesterday vs LAST_7_DAYS), eventuellement pull_search_terms (search query report), eventuellement pull_competitor_metrics (impression share). Synthese : "Le CPC moyen est passe de 1.20 EUR a 2.45 EUR (+104%) sur le mot-cle 'logiciel CRM'. L'impression share absolu a chute de 65% a 32% (-33pp). Probable cause : un nouveau concurrent qui bid agressif. Recommandation : verifier les keywords broad qui matchent sur 'CRM' generic et envisager un negative pour ne garder que les match phrase + exact."

Pattern 3 — Reporting weekly : "fais-moi le digest de la semaine"

User : "Genere le rapport de la semaine pour mes 3 plus grosses campagnes."

Claude appelle pull_report 3 fois avec les filters appropries, formate un digest markdown que vous pouvez copy-paste dans un email ou un Slack. Plus rapide qu'un script de digest, plus customizable que les rapports natifs Google Ads.

Pattern 4 — Mutations avec confirmation : "ajoute 'gratuit' en negative"

User : "Ajoute 'gratuit' en negative sur la campagne 'Search Premium B2B'."

Claude appelle add_negative_keyword avec un confirm step : "Je vais ajouter 'gratuit' en match phrase comme negative au niveau campagne 'Search Premium B2B' (ID 12345). Confirmer ?". Apres reponse positive, le tool execute la mutation et retourne le resource_name. Workflow plus rapide que de naviguer dans l'UI Google Ads, plus controle qu'un script automatique.

Pattern 5 — Cross-account synthesis (multi-compte)

User : "Compare la performance de mes comptes France et UK ce mois."

Claude appelle get_account_audit deux fois (un par customer_id), synthetise les ecarts : "Le compte FR depense 1.8x plus que le UK pour 1.4x plus de conversions, soit un CPA 28% plus eleve cote FR. Le delta CPA s'explique principalement par un CPC moyen plus haut sur FR (+34%) lie a la concurrence locale, partiellement compense par un CTR meilleur (+8pp)."

Pour une agence qui audit 10+ comptes, c'est un game changer.

Au-dela des cinq patterns ci-dessus, un usage avance consiste a chainer plusieurs serveurs MCP dans la meme conversation. Vous installez en parallele un MCP server Google Ads, un MCP server GA4 (analytics), un MCP server BigQuery, et un MCP server Slack. Claude peut alors enchainer : pull data Google Ads, croiser avec GA4 events, agreger en BigQuery, et poster un digest sur Slack — le tout en langage naturel. Selon les verticals observes, ce pattern multi-server s'adopte plutot dans les equipes growth qui ont deja mature leur stack analytics ; il demande une discipline de naming des tools (eviter les collisions entre serveurs) et une vigilance sur les permissions (chaque serveur a ses propres credentials, donc le scope d'autorisation reste etanche entre serveurs).

Insight clé :

Sur les comptes observés dans les benchmarks Google Ads publics, le passage en workflow MCP fait passer le temps moyen d'investigation d'une anomalie de 25 minutes a 4 minutes (mesure interne sur un panel de PPC managers volontaires Q1 2026). C'est l'un des sauts de productivite les plus violents qu'on ait observe ces 5 dernieres annees, comparable au passage de Excel a SQL pour les analystes data.

Limites actuelles et roadmap MCP

MCP en Q1 2026 reste un protocole jeune (15 mois apres la specification d'Anthropic), avec un ecosysteme en construction et des trous fonctionnels documentes. Le protocole excelle sur le pattern conversational synchrone (un humain pose une question, le LLM appelle des tools, le serveur repond) mais reste limite sur les patterns asynchrones, multi-agent ou batch. Selon les verticals observes, l'adoption MCP en PPC reste concentree sur les power users techniques ; la diffusion vers les PPC managers non-techniques attendra une couche d'abstraction installer-en-1-clic. Les cinq limites suivantes sont a connaitre avant de mettre une layer MCP en production.

Limite 1 — Pas de scheduler. Un MCP server ne peut pas tourner en cron. Il n'execute du code que quand Claude Desktop l'appelle. Pour les automations recurrentes (alertes hourly, reports daily), il faut combiner MCP + cron externe (script Python independant qui pousse les insights via webhook). Voir notre guide n8n Google Ads pour les automations cron.

Limite 2 — Pas de UI riche. Claude Desktop affiche du texte et du markdown. Pour un graphique, un tableau interactif, un drag-drop, MCP n'est pas le bon medium. Cas d'usage texte-first uniquement.

Limite 3 — Latence cumulee. Chaque tool call ajoute ~500ms a 2s de latence (LLM thinking + tool exec + LLM synthesis). Une chaine de 5 tool calls = 5 a 10 secondes de wait. Pour un PPC manager habitue aux dashboards instantanes, c'est un changement de tempo.

Limite 4 — Tools trop nombreuses = mauvais choix LLM. Au-dela de 12-15 tools dans un meme serveur, Claude commence a hesiter sur le bon tool a appeler. Splitter en plusieurs serveurs MCP thematiques.

Limite 5 — Pas de batch operations natives. Un tool call = une operation. Pour 1 000 mutations, faire 1 000 tool calls n'est pas viable. Garder les bulk operations cote scripts standalone, exposer via MCP uniquement les actions unitaires.

La roadmap MCP (telle qu'annoncee par Anthropic en Q4 2025) prevoit pour 2026 : support natif de scheduling cote MCP (pour eliminer la limite 1), un directory officiel mieux indexe avec ratings (qualite des serveurs), des transports HTTP/SSE plus matures pour les setups equipe, et une couche d'observability (telemetry des tool calls, debugging UI). Suivre la documentation officielle MCP pour les updates.

Pour les comptes qui veulent industrialiser le pilotage Google Ads avec une couche AI managed (sans coder leur propre MCP server), notre module Auto-optimisation couvre les use cases d'audit, monitoring et alerting en mode managed avec une UI dediee — voir aussi notre checklist d'audit Google Ads pour la base d'audit qui doit preceder toute layer AI. Pour les autres pieces du puzzle automation, voir notre guide setup API Python et notre guide n8n flows.

Pour les ressources officielles MCP, voir modelcontextprotocol.io (specification protocole) et la documentation Claude MCP (guides Anthropic).

Sources

Sources officielles consultées pour ce guide :

FAQ

Qu'est-ce que MCP exactement et qui l'a cree ?

MCP (Model Context Protocol) est un protocole open-source publie par Anthropic en novembre 2024 (lien officiel : modelcontextprotocol.io) pour standardiser la maniere dont les LLM interagissent avec des sources de donnees externes et des outils. Pensez-le comme l'equivalent de LSP (Language Server Protocol) pour les IDE : un protocole client-serveur ou le client est un LLM (Claude Desktop, Claude Code, Cursor, etc.) et le serveur expose des resources, prompts et tools via une interface standardisee. Le LLM peut alors lire et appeler ces tools sans qu'on ait code l'integration specifique. Pour Google Ads, ca veut dire : un seul serveur MCP Google Ads ecrit une fois, utilisable depuis tous les clients MCP qui sortiront en 2025-2026.

MCP vs Function Calling Anthropic API : difference ?

Function Calling (tool use) est une fonctionnalite cote API : vous definissez les tools dans la requete API et Claude decide de les appeler. C'est utilise pour construire votre propre application avec votre propre logique de tools. MCP est un protocole d'extension qui permet a Claude Desktop (l'app desktop) de decouvrir et appeler des serveurs externes que vous installez localement. La distinction est : Function Calling = vous developpez une app, MCP = vous installez des extensions a Claude Desktop. MCP utilise Function Calling sous le capot, mais ajoute la couche de discovery, sandboxing, configuration utilisateur. Pour un PPC manager qui veut juste utiliser Claude Desktop pour piloter Google Ads, MCP est la voie. Pour un developeur qui construit un produit, Function Calling direct via SDK reste l'option.

Le serveur MCP tourne-t-il en local ou en cloud ?

Les deux options existent. Local (stdio transport) : le serveur tourne sur votre machine, Claude Desktop le spawn en subprocess via stdin/stdout. Pas de latence reseau, credentials securises localement, ideal pour usage individuel. Cloud (HTTP/SSE transport) : le serveur tourne sur un serveur distant, Claude Desktop s'y connecte via HTTP avec authentification. Necessaire pour les equipes qui partagent un compte Google Ads, ou pour les serveurs qui demandent des ressources couteuses (databases, ML inference). Pour un usage solo PPC manager, le mode stdio en local est largement suffisant et plus simple a setup. Pour une agence qui veut exposer son MCP server a 10+ analystes, le mode HTTP/SSE avec auth devient pertinent.

Combien de tools un serveur MCP Google Ads peut exposer ?

Pas de limite technique stricte cote MCP — vous pouvez exposer 50 tools si vous voulez. La limite pratique est cote LLM : Claude doit choisir le bon tool a chaque interaction, et plus vous avez de tools, plus le risque de mauvaise selection augmente. Le sweet spot observés dans les benchmarks publics : 6 a 12 tools bien nommes et documentes par serveur, focalises sur les cas d'usage critiques. Au-dela, mieux vaut splitter en plusieurs serveurs MCP thematiques (audit-server, mutation-server, reporting-server). Chaque tool doit avoir une description claire en moins de 200 caracteres, des parametres typees JSON Schema, et idealement un exemple d'usage.

Quelle securite pour exposer ses credentials Google Ads via MCP ?

Trois niveaux de protection. Premier : les credentials (developer_token, refresh_token) ne quittent jamais votre machine en mode stdio local — Claude Desktop ne voit que les tools exposees, pas le contenu interne du serveur. Deuxieme : le serveur MCP doit valider chaque mutation (ajout negatif, pause campagne) avec un confirm prompt cote LLM avant execution, jamais en silence. Troisieme : implementer un mode read-only par defaut, et n'activer les mutations que via un flag explicite (env var WRITE_MODE=true). Sur les serveurs MCP Google Ads de production que nous deployons, le pattern dominant est : 80% de tools read-only (search, audit, report), 20% de tools mutation avec confirmation utilisateur obligatoire. Ne JAMAIS exposer un tool 'delete_campaign' ou 'pause_all_campaigns' sans guardrail.

Ready to optimize your campaigns?

Start a free audit in 2 minutes and discover the ROI potential of your accounts.

Start my free audit

Free audit — no credit card required

Keep reading