Google Workspace Agent
Multi-toolkit agent with Gmail, Calendar, and Drive.
Multi-toolkit agent with Gmail, Calendar, and Drive. Uses DB-backed token storage with shared auth for scope aggregation.
"""
Google Workspace Agent
======================
Multi-toolkit agent with Gmail, Calendar, and Drive.
Uses DB-backed token storage with shared auth for scope aggregation.
Setup:
1. Enable Gmail, Calendar, and Drive APIs at https://console.cloud.google.com
2. Create OAuth 2.0 credentials (Desktop app)
3. Set env vars:
- GOOGLE_CLIENT_ID
- GOOGLE_CLIENT_SECRET
- GOOGLE_TOKEN_ENCRYPTION_KEY (generate with: python -c "from agno.utils.encryption import generate_encryption_key; print(generate_encryption_key())")
First run opens browser for OAuth consent, saves encrypted token to DB.
Subsequent runs load the encrypted token — no re-auth needed.
Run:
.venvs/demo/bin/python cookbook/91_tools/google/workspace/multi_toolkit.py
"""
from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIResponses
from agno.tools.google.auth import AuthConfig
from agno.tools.google.calendar import GoogleCalendarTools
from agno.tools.google.drive import GoogleDriveTools
from agno.tools.google.gmail import GmailTools
from agno.utils.encryption import generate_encryption_key # noqa: F401
# Token encryption: set GOOGLE_TOKEN_ENCRYPTION_KEY env var (recommended)
# Or pass explicitly: AuthConfig(db=db, token_encryption_key=generate_encryption_key())
db = SqliteDb(db_file="tmp/multi_toolkit.db")
auth = AuthConfig(db=db)
agent = Agent(
name="Workspace Agent",
model=OpenAIResponses(id="gpt-5.5"),
tools=[
GmailTools(auth=auth),
GoogleCalendarTools(auth=auth),
GoogleDriveTools(auth=auth),
],
add_datetime_to_context=True,
markdown=True,
)
if __name__ == "__main__":
agent.print_response(
"List my recent emails and today's calendar events", stream=True
)Shared auth combines credentials and scopes; it does not restrict the selected tools to the reading prompt. Gmail's default sending and label tools and Calendar's event-writing tools remain enabled. Reuse the read-only selections in the meeting prep example for a reader. The SQLite database stores tokens here, not conversation history.
Run the Example
Set up your virtual environment
uv venv --python 3.12
source .venv/bin/activateInstall dependencies
uv pip install -U agno cryptography google-api-python-client google-auth google-auth-httplib2 google-auth-oauthlib openai openpyxl python-docx python-pptx sqlalchemyExport environment variables
export GOOGLE_CLIENT_ID="your_google_client_id_here"
export GOOGLE_CLIENT_SECRET="your_google_client_secret_here"
export GOOGLE_PROJECT_ID="your_google_project_id_here"
export GOOGLE_TOKEN_ENCRYPTION_KEY="your_google_token_encryption_key_here"
export OPENAI_API_KEY="your_openai_api_key_here"Configure shared OAuth and token encryption
Enable every Google API listed in the example and create a Desktop OAuth client. Export its client ID, secret, and project ID. The first tool call requests the combined scopes registered by the toolkits sharing auth.
Generate a token-encryption key once:
python -c "from agno.utils.encryption import generate_encryption_key; print(generate_encryption_key())"Set GOOGLE_TOKEN_ENCRYPTION_KEY to that value instead of the placeholder and keep the same key across restarts. Creating a new key each launch prevents reading previously encrypted tokens. With encryption required but no key, tokens are not saved to the database.
This example stores one Google identity in its SQLite token table. An Agno user_id does not select a different Google account. Reuse also depends on valid credentials, granted scopes, and refresh access; revoked or unusable credentials can require consent again.
Run the example
Save the code above as multi_toolkit.py, then run:
python multi_toolkit.pyFull source: cookbook/91_tools/google/workspace/multi_toolkit.py