Aller au contenu principal
Série A2A · 1 / 4

Connecter un agent IA à Google Ad Manager :
faisabilité & connexion

Oui, on peut brancher un agent A2A sur Google Ad Manager. Le cœur, c'est la connexion OAuth (DCR + PKCE + consentement). MCP vs A2A, l'agent GAM minimal, et le run local — avec captures.

OA
OrbiAds Engineering
Publié le 30 juin 2026 · Lecture 10 min

La question revient souvent : « peut-on vraiment connecter un agent IA à Google Ad Manager, et le faire dialoguer avec d'autres agents ? » La réponse est oui, et ça ne demande pas de réécrire quoi que ce soit. Tout tient dans une seule chose qu'il faut réussir : la connexion. Le reste — exposer l'agent, le déployer, l'orchestrer — est de la plomberie standard que les frameworks d'agents savent déjà faire.

Cet article (1/4 de la série « OrbiAds en A2A ») montre, pas à pas, comment un agent parle à Google Ad Manager via OrbiAds, et comment l'authentification fonctionne réellement.

MCP et A2A : deux protocoles complémentaires

On confond souvent les deux. La distinction est pourtant simple — et c'est elle qui structure toute la suite.

MCP

Agent ↔ outils. Le canal par lequel un agent appelle des outils et des données. Le serveur MCP d'OrbiAds expose 290+ opérations Google Ad Manager derrière un seul endpoint.

A2A

Agent ↔ agent. Le canal par lequel un agent en découvre un autre et lui délègue une tâche.

Notre approche n'invente rien : on emballe le MCP OrbiAds existant dans un petit agent, puis on expose cet agent en A2A. Un agent A2A se comporte alors comme un agent-CLI : un runtime, une instruction (le « skill »), des outils (le MCP), et une boucle.

L'agent GAM minimal

Avec l'Agent Development Kit (ADK) de Google, l'agent tient en quelques lignes : un LlmAgent, un MCPToolset pointé sur OrbiAds, et un tool_filter qui borne les outils exposés. to_a2a() transforme l'agent en service A2A et génère sa carte automatiquement.

from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
from google.adk.a2a.utils.agent_to_a2a import to_a2a

orbiads_mcp = MCPToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://orbiads.com/mcp",
        headers={"Authorization": f"Bearer {TOKEN}"},
    ),
    tool_filter=["check_credentials", "select_gam_network", "inventory"],
)

root_agent = LlmAgent(
    name="gam_inventory_sentinel",
    model="gemini-2.5-flash",          # MODEL = your choice
    instruction="You are a READ-ONLY GAM inventory sentinel. ...",
    tools=[orbiads_mcp],
)

a2a_app = to_a2a(root_agent, port=10000)  # serves /.well-known/agent-card.json

Détail important : to_a2a() expose l'agent comme un skill (pas un par outil). Le tool_filter borne les capacités en interne — l'angle est l'encapsulation (un agent métier net), pas « moins de tokens ».

Le cœur : la connexion OAuth

C'est ici que tout se joue. OrbiAds fonctionne en OAuth délégué utilisateur : l'utilisateur autorise une fois, OrbiAds garde un refresh token chiffré par tenant et rafraîchit les jetons d'accès.

Enregistrement client (DCR) PKCE (S256) Consentement Access + Refresh token

Point clé : OrbiAds n'accepte que authorization_code + refresh_tokenpas de client_credentials (pas de machine-to-machine sans humain). D'où trois cas d'usage :

Client de chat

Ex. Claude Desktop : connexion OAuth native, rien à coder.

Développement (ADK)

Bootstrap d'un jeton une fois via get_token.py, puis le refresh token prend le relais.

Agent déployé

Connecteur Agent Identity 3LO managé (article 2).

Au consentement, Google demande quel compte autorise l'application — c'est l'utilisateur qui autorise, jamais l'agent tout seul :

Consentement OAuth — choix du compte
Consentement OAuth : Google demande quel compte autorise l'application OrbiAds (scope admanager). C'est l'utilisateur qui autorise, pas l'agent.
Consentement OAuth — autoriser
Écran « You're signing back in to OrbiAds » : l'utilisateur confirme et OrbiAds reçoit le jeton d'accès GAM.

Astuce qui sauve des heures : ADK charge le .env du dossier de l'agent, pas les variables du shell — c'est là qu'il faut mettre le jeton écrit par get_token.py.

L'Agent Card : ce que voit le monde A2A

Dès que l'agent tourne, il sert sa carte sur /.well-known/agent-card.json — le contrat public A2A : nom, description, skills, URL. C'est exactement ce qu'un autre agent lit pour décider de déléguer. (L'ancien chemin /.well-known/agent.json reste servi en alias rétro-compatible par le SDK A2A.)

GET /.well-known/agent-card.json
{
  "protocolVersion": "0.3.0",
  "name": "GAM Inventory Sentinel",
  "description": "Read-only Google Ad Manager agent (via OrbiAds).",
  "url": "https://your-agent-endpoint/a2a",
  "version": "1.0.0",
  "provider": { "organization": "OrbiAds", "url": "https://orbiads.com" },
  "capabilities": { "streaming": true },
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain"],
  "skills": [
    {
      "id": "inventory_health",
      "name": "GAM inventory monitoring",
      "description": "Checks the OrbiAds->GAM connection and reports inventory availability (read-only).",
      "tags": ["gam", "inventory", "adops", "read-only"]
    }
  ]
}

L'Agent Card servie par to_a2a() : nom, description, skills, URL — exactement ce qu'un autre agent lit pour décider de déléguer.

Lancer l'agent en local

Deux façons de l'exécuter, selon ce qu'on veut voir :

# serve the agent over A2A (card at :10000/.well-known/agent-card.json)
uvicorn gam_sentinel.agent:a2a_app --port 10000

# or the ADK dev UI to chat and inspect the trace
adk web .   # http://127.0.0.1:8000

Garde-fou indispensable : reste sur un réseau GAM de test (jamais un réseau client réel). Le réseau actif est un état serveur, basculé via network(action='switch_network', …). Nos agents affichent le réseau actif et s'arrêtent s'il est inattendu.

La suite

La connexion est faite et prouvée. Dans l'article 2, on déploie cet agent sur Vertex Agent Engine et on le rend découvrable en A2A.

Le code complet, prêt à cloner

Les 4 agents, le tutoriel pas à pas et les exemples — sur GitHub, sous licence MIT.

FAQ

Questions fréquentes

Quelle différence entre MCP et A2A ?

MCP (Model Context Protocol) relie un agent à des outils et des données — par exemple le serveur MCP d'OrbiAds qui expose 290+ opérations Google Ad Manager. A2A (Agent2Agent) relie des agents entre eux : un agent en découvre un autre et lui délègue une tâche. Les deux sont complémentaires : on emballe le MCP OrbiAds dans un petit agent, puis on expose cet agent en A2A.

Faut-il un Service Account ou une délégation à l'échelle du domaine ?

Non. OrbiAds fonctionne en OAuth délégué utilisateur : l'utilisateur autorise une fois (consentement Google), OrbiAds stocke un refresh token chiffré par tenant et rafraîchit les jetons d'accès. Pas de client_credentials, pas de Domain-Wide Delegation requise pour démarrer.

Comment l'agent obtient-il son jeton OrbiAds ?

Via le flux OAuth standard : enregistrement dynamique du client (DCR), PKCE (S256), écran de consentement, puis échange du code contre un access token + refresh token. Le script get_token.py automatise ces étapes pour un usage en développement.

Qu'est-ce qu'une Agent Card A2A ?

C'est le fichier /.well-known/agent-card.json servi par l'agent. Il décrit son nom, sa description, ses skills et son URL — c'est ce que les autres agents lisent pour savoir comment dialoguer avec lui. Avec l'ADK de Google, to_a2a() la génère automatiquement à partir de l'agent.