Skip to content
cd ..

145 SaaS Integrations: Building a Universal Tool Adapter Pattern

// · 5 min read

AgenticMail Enterprise ships with 145 SaaS integrations. 90+ Microsoft 365 tools across 13 services. 16 Gmail tools. Google Workspace, Slack, Salesforce, HubSpot, Jira, Linear, Notion, and dozens more. Building each integration individually would have been insane. Instead, I built a universal tool adapter pattern and then wrote 145 implementations on top of it.

The Adapter Pattern

Every integration in the system is an adapter that implements the same interface. The interface has five components:

Tool Definitions. A structured schema describing what the adapter can do. Each tool has a name, description, input parameters with types and validation rules, and an output schema. These definitions get registered with the agent’s tool system so the agent knows what’s available. They also power the UI: when you browse integrations, you’re looking at rendered tool definitions.

API Executor. The function that actually calls the external API. It handles request construction, response parsing, error mapping, and retry logic. The executor is stateless. It takes a tool call with parameters and returns a structured result. All the complexity of different API styles (REST, GraphQL, SOAP for the legacy ones) is hidden behind the same execution interface.

Credential Resolution. Every adapter declares what credentials it needs (API key, OAuth token, service account, etc.) and the system resolves them from the Vault at execution time. The adapter never stores credentials. It requests them by reference, and the Vault provides them with automatic rotation and expiry handling. If an OAuth token has expired, the Vault refreshes it transparently before the adapter sees it.

OAuth Flow. For integrations that use OAuth (most of them), the adapter defines the authorization URL, scopes needed, token exchange endpoint, and refresh logic. The system handles the full OAuth dance: redirecting the user, capturing the callback, exchanging the code for tokens, and storing them in the Vault. Adding a new OAuth integration means defining these four values in the adapter config.

Rate Limit Handler. Every external API has rate limits, and they all implement them differently. Microsoft uses per user and per tenant limits with Retry After headers. Google uses a quota system with per second and per day limits. Salesforce has daily call limits that vary by edition. Each adapter declares the rate limiting behavior of its target API, and the handler manages a token bucket per instance. When a call would exceed the limit, the handler queues it and retries after the appropriate delay.

Microsoft 365: 90+ Tools Across 13 Services

The Microsoft integration is the largest. 13 services: Outlook Mail, Calendar, OneDrive, SharePoint, Teams, Planner, To Do, People, OneNote, Excel Online, Word Online, PowerPoint Online, and Admin. Each service has between 4 and 15 tools covering the common operations.

An agent can read and send email through Outlook, create calendar events, upload and download files from OneDrive and SharePoint, post messages to Teams channels, create and manage Planner tasks, search the organization directory through People, and manipulate spreadsheets through the Excel Online API.

The Microsoft Graph API is the backbone. Most of these services are accessed through Graph, which means the adapter shares authentication (a single OAuth token with the right scopes covers multiple services) but has separate tool definitions and execution logic per service.

Gmail and Google Workspace

The Gmail adapter has 16 tools covering message operations (read, send, reply, forward, archive, trash, label), draft management, thread operations, and search. The search tool exposes Gmail’s full query syntax so agents can do precise lookups like “from:client@example.com after:2026/01/01 has:attachment.”

Beyond Gmail, the Google Workspace integration covers Calendar, Drive, Docs, Sheets, Slides, and Admin. The pattern is the same: each service gets its own tool definitions and executor, sharing OAuth credentials through the Vault.

Why the Pattern Matters

Without the adapter pattern, 145 integrations would mean 145 different implementations with 145 different approaches to authentication, error handling, rate limiting, and credential management. Debugging would require understanding each integration’s individual quirks. Adding a new integration would mean building everything from scratch.

With the pattern, adding a new integration is a structured process. Define the tools, write the executor (usually the only truly custom code), declare the credential requirements and OAuth parameters, and specify the rate limit behavior. The rest is handled by the framework.

The pattern also makes testing straightforward. Every adapter implements the same interface, so the test harness is generic. Mock the API responses, call the executor, and verify the output matches the schema. The same test runner works for all 145 adapters.

When an agent uses these integrations, it doesn’t know or care about the adapter pattern underneath. It sees tools: “send_gmail_message,” “create_teams_channel_post,” “upload_to_sharepoint.” The adapter pattern is invisible at the agent level. That’s the whole point. The complexity lives in one place so that everything above it is simple.

Source Code

View the full source on GitHub

// share

// subscribe

New posts and updates straight to your inbox. No noise.

cd ..