Skip to content

Connect Google Contacts to AI Agents: Automate Contact Workflows

A definitive engineering guide to connecting Google Contacts to AI agents using Truto's /tools API. Learn how to bind tools to LLMs and build autonomous workflows.

Yuvraj Muley Yuvraj Muley · · 9 min read

You want to connect Google Contacts to an AI agent so your system can independently read directories, enrich contact profiles, sync domain users, and clean up address books based on historical context. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to maintain a custom Google People API wrapper.

Giving a Large Language Model (LLM) read and write access to a Google Workspace environment is an engineering headache. You either spend weeks building, hosting, and maintaining a custom connector that understands the quirks of Google's field masks, or you use a managed infrastructure layer that handles the boilerplate for you. If your team uses ChatGPT, check out our guide on connecting Google Contacts to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting Google Contacts to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them to your agent framework.

This guide breaks down exactly how to fetch AI-ready tools for Google Contacts, bind them natively to an LLM using LangChain (or any framework like LangGraph, CrewAI, or Vercel AI SDK), and execute complex directory workflows. For a deeper look at the architecture behind this approach, refer to our research on architecting AI agents and the SaaS integration bottleneck.

The Engineering Reality of the Google Contacts API

Building AI agents is easy. Connecting them to external SaaS APIs is hard. Giving an LLM access to external data sounds simple in a prototype. You write a Node.js function that makes a fetch request and wrap it in an @tool decorator. In production, this approach collapses entirely, especially with an ecosystem as complex as Google Contacts (powered by the Google People API).

If you decide to build this integration yourself, you own the entire API lifecycle. The Google People API introduces several highly specific integration challenges that break standard LLM assumptions.

The personFields Read Mask Trap

Google Contacts does not return flat JSON objects. Because contact records can encompass hundreds of attributes across multiple linked Google accounts, the API requires a readMask (or personFields in REST terms) for almost every read operation.

If an agent wants a contact's email and phone number, it must explicitly pass personFields=names,emailAddresses,phoneNumbers. If you rely on an LLM to generate these field masks natively, it will inevitably hallucinate invalid fields like personFields=email,phone,company, resulting in an immediate 400 Bad Request. Exposing the raw People API to an agent guarantees execution failures.

Data Source Merging and "Other Contacts"

Google categorizes people into strict buckets. There are standard "Contacts" (explicitly added by the user), "Other Contacts" (people the user has interacted with, like auto-saved email recipients), and "Directory" profiles (members of the same Google Workspace domain).

An LLM attempting to search for a coworker might hit the standard /v1/people:searchContacts endpoint and find nothing, completely unaware that it should have queried the directory instead. Teaching an LLM to navigate Google's multi-layered contact taxonomy via prompt engineering wastes context windows and increases latency.

Sequential Mutation Constraints

Google explicitly documents that mutate requests (like deleting contacts or batch updates) must be sent sequentially. Concurrent writes to the same user's address book frequently trigger 409 Conflict or 503 Service Unavailable errors. LLM agent frameworks that parallelize tool calls (like calling multiple delete functions at once) will crash the workflow unless you implement strict queuing mechanisms on your end.

Abstracting the API: Truto's Tooling Architecture

To safely expose Google Contacts to an AI agent, you need a deterministic tool layer. Truto solves this through a structured architectural approach based on Resources, Methods, and Proxy APIs.

Every integration on Truto operates as a comprehensive schema representing the underlying API's behavior. The API is mapped into Resources (e.g., people, other_contacts). Every Resource has Methods defined on them - standard operations like List, Get, Create, Update, Delete, alongside custom operations.

The Methods on these Resources are exposed as Proxy APIs. At this layer, Truto handles the OAuth authentication, normalizes query parameters, and guarantees the data returns in a predefined format. When solving problems agentically, these Proxy APIs act as the perfect toolset because they enforce strict JSON schemas for inputs.

When your agent calls Truto's /integrated-account/:id/tools endpoint, it receives a ready-to-use array of these Proxy APIs formatted as LLM tools. The LLM only ever chooses from a stable list of function names with strongly typed inputs, stripping away the hallucination risks associated with Google's raw endpoints.

High-Leverage Hero Tools for Google Contacts

Rather than exposing 50 raw Google endpoints to your agent, Truto provides tailored, high-leverage tools. Here are the core tools your agent will use to orchestrate Google Contacts workflows.

list_all_people_search_contacts

This tool allows the agent to search a user's primary address book. It requires a query and handles the complex readMask parameter dynamically under the hood, ensuring the API always accepts the request.

"Find the contact record for 'Sarah Jenkins' and return her primary email address and organization details."

get_single_people_search_contact_by_id

Once an agent identifies a specific contact, it needs to fetch the complete, unified profile. This tool uses the specific Google resourceName (ID) to pull a targeted set of personFields without paginating through search results.

"Retrieve the full contact details for the person with ID 'people/c123456789', making sure to include their phone numbers and job title."

list_all_people_other_contacts

"Other Contacts" are auto-saved profiles of people the user has emailed or shared calendar events with, but who are not officially in the address book. This tool searches that specific bucket, which is critical for enrichment and lead generation workflows.

"Search my 'Other Contacts' for anyone matching 'acme.corp' so we can promote them to official contacts."

delete_a_people_search_contact_by_id

This mutation tool safely deletes a contact. Because Truto manages the proxy layer, the tool enforces the sequential mutation requirement by blocking malformed parallel deletes, ensuring clean executions.

"Delete the contact record for 'John Doe' (ID: people/c987654321) as they have requested their data be removed."

list_all_people

This tool searches the broader Google Workspace Directory. It retrieves collections of people objects from the caller's domain, bypassing the personal address book entirely. This is essential for internal HR or IT agent workflows.

"List the profiles of all employees in the engineering department from the company directory."

list_all_oauth_user_info

Before modifying contacts, agents often need context on whose account they are operating within. This tool retrieves the authenticated user's unique identifier, name, and email address directly from Google.

"Who is the authenticated user currently running this workflow, and what is their primary email address?"

For a complete list of available tools and their underlying JSON schemas, review the Google Contacts integration page.

Workflows in Action

AI agents shine when chaining these tools together to execute multi-step logic. Here are two real-world scenarios showing exactly how an agent leverages Truto's Google Contacts tools.

Scenario 1: Automated Contact Enrichment and Promotion

Sales teams often interact with prospects who end up trapped in the hidden "Other Contacts" list. An agent can automate the discovery and promotion of these profiles.

"Search my recent interactions for anyone at 'Stark Industries'. If they exist in Other Contacts but not in my primary Contacts, extract their details and notify me to add them."

Execution Steps:

  1. list_all_people_other_contacts: The agent queries Google for "Stark Industries" in the Other Contacts bucket. It receives back an array of auto-saved emails and minimal metadata.
  2. list_all_people_search_contacts: The agent checks the primary address book to ensure these users aren't already saved.
  3. LLM Synthesis: The agent diffs the two lists, isolating the missing contacts, and outputs a clean JSON array of high-value prospects to the user.

Scenario 2: Offboarding and GDPR Data Cleanup

When a client requests data deletion, an IT agent must scrub their presence from the organization's address books.

"Find all contact records associated with 'alex@example.com' and delete them from my address book permanently."

Execution Steps:

  1. list_all_people_search_contacts: The agent searches the primary address book for the query "alex@example.com".
  2. get_single_people_search_contact_by_id: The agent verifies the returned resourceName matches the exact email address requested, preventing accidental deletion of a different "Alex".
  3. delete_a_people_search_contact_by_id: The agent issues the delete command using the verified ID. It waits for the empty response to confirm successful deletion before notifying the user.

Building Multi-Step Workflows

To build these autonomous loops, you need to bind Truto's tools to your LLM framework. Truto provides SDKs (like truto-langchainjs-toolset) that pull the definitions dynamically.

The Rate Limit Reality: Handling HTTP 429s

Before writing the execution loop, you must understand how Truto handles rate limits.

Truto does not retry, throttle, or apply backoff on rate limit errors.

If your agent goes rogue and hammers the Google People API, Google will return an HTTP 429 Too Many Requests error. Truto immediately passes that 429 error back to the caller. However, Truto normalizes the upstream rate limit information into standardized HTTP headers per the IETF specification:

  • ratelimit-limit: The total requests allowed in the current window.
  • ratelimit-remaining: The number of requests left.
  • ratelimit-reset: The time (in seconds) until the quota resets.

As the developer, you are responsible for catching these 429s in your agent's execution loop, reading the ratelimit-reset header, and implementing the backoff. Do not assume the proxy will absorb the error for you.

sequenceDiagram
    participant Agent as Agent Framework
    participant Truto as Truto API
    participant Upstream as "Upstream API (Google)"
    
    Agent->>Truto: Call list_all_people_search_contacts
    Truto->>Upstream: GET /v1/people:searchContacts
    Upstream-->>Truto: HTTP 429 Quota Exceeded
    Truto-->>Agent: HTTP 429 (ratelimit-* headers)
    
    Note over Agent: Framework catches error<br>Reads ratelimit-reset
    Agent->>Agent: Delay execution
    
    Agent->>Truto: Retry list_all_people_search_contacts
    Truto->>Upstream: GET /v1/people:searchContacts
    Upstream-->>Truto: HTTP 200 OK
    Truto-->>Agent: JSON Response

Example: Binding Tools in LangChain

Here is a complete, framework-agnostic architectural pattern using TypeScript and LangChain to fetch Truto tools, bind them to an OpenAI model, and execute a multi-step workflow with error handling.

import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";
import { AgentExecutor, createOpenAIToolsAgent } from "langchain/agents";
import {
  ChatPromptTemplate,
  MessagesPlaceholder,
} from "@langchain/core/prompts";
 
async function runGoogleContactsAgent() {
  // 1. Initialize the LLM
  const llm = new ChatOpenAI({
    modelName: "gpt-4o",
    temperature: 0,
  });
 
  // 2. Fetch Google Contacts tools for the specific integrated account
  const toolManager = new TrutoToolManager({
    trutoToken: process.env.TRUTO_API_KEY,
    integratedAccountId: "google-contacts-account-id-123"
  });
  
  // Pull the Proxy API schemas from Truto
  const tools = await toolManager.getTools();
  
  // 3. Set up the Agent Prompt
  const prompt = ChatPromptTemplate.fromMessages([
    ["system", "You are an elite executive assistant managing Google Contacts. Use the provided tools to search, organize, and delete contacts as requested. If a tool fails with an error, read the error message carefully."],
    ["user", "{input}"],
    new MessagesPlaceholder("agent_scratchpad"),
  ]);
 
  // 4. Bind tools and create the executor
  const agent = await createOpenAIToolsAgent({
    llm,
    tools,
    prompt,
  });
 
  const executor = new AgentExecutor({
    agent,
    tools,
    // Frameworks handle basic retries, but checking for 429s 
    // should be done via a custom HTTP client interceptor or 
    // custom tool error handler reading the ratelimit-* headers.
    maxIterations: 10, 
  });
 
  // 5. Execute the Workflow
  console.log("Executing Agent Workflow...");
  const result = await executor.invoke({
    input: "Search my contacts for 'Stark Industries'. If you find anyone, get their full profile details.",
  });
 
  console.log("Agent Output:", result.output);
}
 
runGoogleContactsAgent().catch(console.error);

By leveraging Truto's /tools endpoint, the agent framework dynamically inherits the descriptions, input schemas, and authentication context for Google Contacts. The LLM simply sees a list of available functions and decides which to execute based on your prompt.

Moving from Prototypes to Production

Giving AI agents access to corporate directories and personal address books requires strict control. Hardcoding raw API wrappers pushes vendor-specific quirks - like Google's readMask requirements and overlapping source directories - directly into your LLM's context window. That leads to blown context limits, hallucinated parameters, and broken workflows.

By routing agent requests through Truto's Proxy APIs, you enforce strict schema validation before the request ever leaves your infrastructure. The agent operates within a predictable, sanitized toolset, while you retain total control over the OAuth lifecycle and rate-limit handling.

Stop wasting engineering cycles trying to teach ChatGPT the nuances of the Google People API. Give your agents reliable tools, handle the 429s deterministically, and focus on building the actual workflow logic.

FAQ

How do I give my AI agent access to Google Contacts?
Use Truto's `/tools` endpoint to dynamically fetch Proxy APIs for Google Contacts formatted as LLM tools. You can bind these tools to your agent framework (like LangChain or LangGraph) using `.bindTools()`, allowing the LLM to search, read, and delete contacts.
Does Truto automatically handle Google People API rate limits?
No. Truto passes HTTP 429 (Too Many Requests) errors directly back to the caller. It normalizes the upstream rate limit data into standard `ratelimit-limit`, `ratelimit-remaining`, and `ratelimit-reset` headers. Your agent or application logic is responsible for catching the error and implementing retries based on the reset time.
Why shouldn't I just use the raw Google People API with my LLM?
The Google People API requires complex parameters like `personFields` (read masks) and strict sequential mutates. LLMs frequently hallucinate these fields or attempt parallel operations, causing API requests to fail. Truto abstracts these quirks behind stable, strictly-typed tool schemas.
Can the agent access Google Workspace Directory profiles?
Yes. Truto provides distinct tools like `list_all_people` for directory profiles, separate from personal address book tools (`list_all_people_search_contacts`), ensuring the agent queries the correct data bucket without confusing the data sources.

More from our Blog