# How to integrate Google Sheets MCP with Mastra AI

```json
{
  "title": "How to integrate Google Sheets MCP with Mastra AI",
  "toolkit": "Google Sheets",
  "toolkit_slug": "googlesheets",
  "framework": "Mastra AI",
  "framework_slug": "mastra-ai",
  "url": "https://composio.dev/toolkits/googlesheets/framework/mastra-ai",
  "markdown_url": "https://composio.dev/toolkits/googlesheets/framework/mastra-ai.md",
  "updated_at": "2026-05-06T08:14:27.288Z"
}
```

## Introduction

This guide walks you through connecting Google Sheets to Mastra AI using the Composio tool router. By the end, you'll have a working Google Sheets agent that can add a new sheet named 'q3 sales', update all rows where status is 'pending', create a pie chart of expenses by category through natural language commands.
This guide will help you understand how to give your Mastra AI agent real control over a Google Sheets account through Composio's Google Sheets MCP server.
Before we dive in, let's take a quick look at the key ideas and tools involved.

## Also integrate Google Sheets with

- [ChatGPT](https://composio.dev/toolkits/googlesheets/framework/chatgpt)
- [OpenAI Agents SDK](https://composio.dev/toolkits/googlesheets/framework/open-ai-agents-sdk)
- [Claude Agent SDK](https://composio.dev/toolkits/googlesheets/framework/claude-agents-sdk)
- [Claude Code](https://composio.dev/toolkits/googlesheets/framework/claude-code)
- [Claude Cowork](https://composio.dev/toolkits/googlesheets/framework/claude-cowork)
- [Codex](https://composio.dev/toolkits/googlesheets/framework/codex)
- [Cursor](https://composio.dev/toolkits/googlesheets/framework/cursor)
- [VS Code](https://composio.dev/toolkits/googlesheets/framework/vscode)
- [OpenCode](https://composio.dev/toolkits/googlesheets/framework/opencode)
- [OpenClaw](https://composio.dev/toolkits/googlesheets/framework/openclaw)
- [Hermes](https://composio.dev/toolkits/googlesheets/framework/hermes-agent)
- [CLI](https://composio.dev/toolkits/googlesheets/framework/cli)
- [Google ADK](https://composio.dev/toolkits/googlesheets/framework/google-adk)
- [LangChain](https://composio.dev/toolkits/googlesheets/framework/langchain)
- [Vercel AI SDK](https://composio.dev/toolkits/googlesheets/framework/ai-sdk)
- [LlamaIndex](https://composio.dev/toolkits/googlesheets/framework/llama-index)
- [CrewAI](https://composio.dev/toolkits/googlesheets/framework/crew-ai)

## TL;DR

Here's what you'll learn:
- Set up your environment so Mastra, OpenAI, and Composio work together
- Create a Tool Router session in Composio that exposes Google Sheets tools
- Connect Mastra's MCP client to the Composio generated MCP URL
- Fetch Google Sheets tool definitions and attach them as a toolset
- Build a Mastra agent that can reason, call tools, and return structured results
- Run an interactive CLI where you can chat with your Google Sheets agent

## What is Mastra AI?

Mastra AI is a TypeScript framework for building AI agents with tool support. It provides a clean API for creating agents that can use external services through MCP.
Key features include:
- MCP Client: Built-in support for Model Context Protocol servers
- Toolsets: Organize tools into logical groups
- Step Callbacks: Monitor and debug agent execution
- OpenAI Integration: Works with OpenAI models via @ai-sdk/openai

## What is the Google Sheets MCP server, and what's possible with it?

The Google Sheets MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your Google Sheets account. It provides structured and secure access to your spreadsheets, so your agent can perform actions like creating new sheets, updating data, generating charts, and automating spreadsheet workflows on your behalf.
- Spreadsheet creation and management: Instantly create new Google Sheets and add new worksheets (tabs) to existing spreadsheets whenever you need extra space or organization.
- Bulk data reading and updating: Retrieve specific data ranges, aggregate column data, or update multiple rows and cells at once—perfect for reporting or syncing external data.
- Automated chart generation: Direct your agent to build charts from selected data, making visualization and analysis faster and easier right inside your sheets.
- Smart filtering and data cleanup: Have the agent clear filters, remove cell contents, or append rows and columns to keep your sheets tidy and up to date.
- Dynamic data manipulation: Use advanced features like batch updates with data filters and aggregate operations to transform, filter, or summarize spreadsheet data efficiently.

## Supported Tools

| Tool slug | Name | Description |
|---|---|---|
| `GOOGLESHEETS_ADD_SHEET` | Add Sheet to Spreadsheet | Adds a new sheet (worksheet) to a spreadsheet. use this tool to create a new tab within an existing google sheet, optionally specifying its title, index, size, and other properties. |
| `GOOGLESHEETS_AGGREGATE_COLUMN_DATA` | Aggregate Column Data | Searches for rows where a specific column matches a value and performs mathematical operations on data from another column. |
| `GOOGLESHEETS_APPEND_DIMENSION` | Append Dimension | Tool to append new rows or columns to a sheet, increasing its size. use when you need to add empty rows or columns to an existing sheet. |
| `GOOGLESHEETS_BATCH_GET` | Batch get spreadsheet | Retrieves data from specified cell ranges in a google spreadsheet; ensure the spreadsheet has at least one worksheet and any explicitly referenced sheet names in ranges exist. |
| `GOOGLESHEETS_BATCH_UPDATE` | Batch update spreadsheet | Updates a specified range in a google sheet with given values, or appends them as new rows if `first cell location` is omitted; ensure the target sheet exists and the spreadsheet contains at least one worksheet. |
| `GOOGLESHEETS_BATCH_UPDATE_VALUES_BY_DATA_FILTER` | Batch Update Values by Data Filter | Tool to update values in ranges matching data filters. use when you need to update specific data in a google sheet based on criteria rather than fixed cell ranges. |
| `GOOGLESHEETS_CLEAR_BASIC_FILTER` | Clear Basic Filter | Tool to clear the basic filter from a sheet. use when you need to remove an existing basic filter from a specific sheet within a google spreadsheet. |
| `GOOGLESHEETS_CLEAR_VALUES` | Clear spreadsheet values | Clears cell content (preserving formatting and notes) from a specified a1 notation range in a google spreadsheet; the range must correspond to an existing sheet and cells. |
| `GOOGLESHEETS_CREATE_CHART` | Create Chart in Google Sheets | Create a chart in a google sheets spreadsheet using the specified data range and chart type. |
| `GOOGLESHEETS_CREATE_GOOGLE_SHEET1` | Create a Google Sheet | Creates a new google spreadsheet in google drive using the provided title. |
| `GOOGLESHEETS_CREATE_SPREADSHEET_COLUMN` | Create spreadsheet column | Creates a new column in a google spreadsheet, requiring a valid `spreadsheet id` and an existing `sheet id`; an out-of-bounds `insert index` may append/prepend the column. |
| `GOOGLESHEETS_CREATE_SPREADSHEET_ROW` | Create spreadsheet row | Inserts a new, empty row into a specified sheet of a google spreadsheet at a given index, optionally inheriting formatting from the row above. |
| `GOOGLESHEETS_DELETE_DIMENSION` | Delete Dimension (Rows/Columns) | Tool to delete specified rows or columns from a sheet in a google spreadsheet. use when you need to remove a range of rows or columns. |
| `GOOGLESHEETS_DELETE_SHEET` | Delete Sheet | Tool to delete a sheet (worksheet) from a spreadsheet. use when you need to remove a specific sheet from a google sheet document. |
| `GOOGLESHEETS_EXECUTE_SQL` | Execute SQL on Spreadsheet | Execute sql queries against google sheets tables. supports select, insert, update, and delete operations with familiar sql syntax. tables are automatically detected and mapped from the spreadsheet structure. |
| `GOOGLESHEETS_FIND_WORKSHEET_BY_TITLE` | Find worksheet by title | Finds a worksheet by its exact, case-sensitive title within a google spreadsheet; returns a boolean indicating if found and the complete metadata of the entire spreadsheet, regardless of whether the target worksheet is found. |
| `GOOGLESHEETS_FORMAT_CELL` | Format cell | Applies text and background cell formatting to a specified range in a google sheets worksheet. |
| `GOOGLESHEETS_GET_SHEET_NAMES` | Get sheet names | Lists all worksheet names from a specified google spreadsheet (which must exist), useful for discovering sheets before further operations. |
| `GOOGLESHEETS_GET_SPREADSHEET_BY_DATA_FILTER` | Get Spreadsheet by Data Filter | Returns the spreadsheet at the given id, filtered by the specified data filters. use this tool when you need to retrieve specific subsets of data from a google sheet based on criteria like a1 notation, developer metadata, or grid ranges. |
| `GOOGLESHEETS_GET_SPREADSHEET_INFO` | Get spreadsheet info | Retrieves comprehensive metadata for a google spreadsheet using its id, excluding cell data. |
| `GOOGLESHEETS_GET_TABLE_SCHEMA` | Get Table Schema | This action is used to get the schema of a table in a google spreadsheet, call this action to get the schema of a table in a spreadsheet before you query the table. analyze table structure and infer column names, types, and constraints. uses statistical analysis of sample data to determine the most likely data type for each column. call this action after calling the list tables action to get the schema of a table in a spreadsheet. |
| `GOOGLESHEETS_INSERT_DIMENSION` | Insert Dimension in Google Sheet | Tool to insert new rows or columns into a sheet at a specified location. use when you need to add empty rows or columns within an existing google sheet. |
| `GOOGLESHEETS_LIST_TABLES` | List Tables in Spreadsheet | This action is used to list all tables in a google spreadsheet, call this action to get the list of tables in a spreadsheet. discover all tables in a google spreadsheet by analyzing sheet structure and detecting data patterns. uses heuristic analysis to find header rows, data boundaries, and table structures. |
| `GOOGLESHEETS_LOOKUP_SPREADSHEET_ROW` | Look up spreadsheet row | Finds the first row in a google spreadsheet where a cell's entire content exactly matches the query string, searching within a specified a1 notation range or the first sheet by default. |
| `GOOGLESHEETS_QUERY_TABLE` | Query Spreadsheet Table | This action is used to query a table in a google spreadsheet, call this action to query a table in a spreadsheet. execute sql-like select queries against spreadsheet tables. supports where conditions, order by, limit clauses. call this action after calling the get table schema action to query a table in a spreadsheet. |
| `GOOGLESHEETS_SEARCH_DEVELOPER_METADATA` | Search Developer Metadata | Tool to search for developer metadata in a spreadsheet. use when you need to find specific metadata entries based on filters. |
| `GOOGLESHEETS_SEARCH_SPREADSHEETS` | Search Spreadsheets | Search for google spreadsheets using various filters including name, content, date ranges, and more. |
| `GOOGLESHEETS_SET_BASIC_FILTER` | Set Basic Filter | Tool to set a basic filter on a sheet in a google spreadsheet. use when you need to filter or sort data within a specific range on a sheet. |
| `GOOGLESHEETS_SHEET_FROM_JSON` | Create sheet from JSON | Creates a new google spreadsheet and populates its first worksheet from `sheet json`, which must be non-empty as its first item's keys establish the headers. |
| `GOOGLESHEETS_SPREADSHEETS_SHEETS_COPY_TO` | Copy Sheet to Another Spreadsheet | Tool to copy a single sheet from a spreadsheet to another spreadsheet. use when you need to duplicate a sheet into a different spreadsheet. |
| `GOOGLESHEETS_SPREADSHEETS_VALUES_APPEND` | Append Values to Spreadsheet | Tool to append values to a spreadsheet. use when you need to add new data to the end of an existing table in a google sheet. |
| `GOOGLESHEETS_SPREADSHEETS_VALUES_BATCH_CLEAR` | Batch Clear Spreadsheet Values | Tool to clear one or more ranges of values from a spreadsheet. use when you need to remove data from specific cells or ranges while keeping formatting and other properties intact. |
| `GOOGLESHEETS_SPREADSHEETS_VALUES_BATCH_CLEAR_BY_DATA_FILTER` | Batch Clear Values By Data Filter | Clears one or more ranges of values from a spreadsheet using data filters. the caller must specify the spreadsheet id and one or more datafilters. ranges matching any of the specified data filters will be cleared. only values are cleared -- all other properties of the cell (such as formatting, data validation, etc..) are kept. |
| `GOOGLESHEETS_SPREADSHEETS_VALUES_BATCH_GET_BY_DATA_FILTER` | Batch Get Spreadsheet Values by Data Filter | Tool to return one or more ranges of values from a spreadsheet that match the specified data filters. use when you need to retrieve specific data sets based on filtering criteria rather than entire sheets or fixed ranges. |
| `GOOGLESHEETS_UPDATE_SHEET_PROPERTIES` | Update Sheet Properties | Tool to update properties of a sheet (worksheet) within a google spreadsheet, such as its title, index, visibility, tab color, or grid properties. use this when you need to modify the metadata or appearance of a specific sheet. |
| `GOOGLESHEETS_UPDATE_SPREADSHEET_PROPERTIES` | Update Spreadsheet Properties | Tool to update properties of a spreadsheet, such as its title, locale, or auto-recalculation settings. use when you need to modify the overall configuration of a google sheet. |

## Supported Triggers

| Trigger slug | Name | Description |
|---|---|---|
| `GOOGLESHEETS_AGGREGATE_METRIC_CHANGED_TRIGGER` | Aggregate Metric Changed | Triggers when an aggregate metric (SUM/COUNT/AVG/MIN/MAX) changes in a Google Sheets spreadsheet. This trigger monitors an aggregate calculation on a target column (optionally filtered by a search column/value) and fires when the calculated result changes. |
| `GOOGLESHEETS_CELL_RANGE_VALUES_CHANGED_TRIGGER` | Cell Range Values Changed | Triggers when values in a specified A1 range change in Google Sheets. This trigger monitors a specific cell or range of cells and fires when any values change. |
| `GOOGLESHEETS_CONDITIONAL_FORMAT_RULE_CHANGED_TRIGGER` | Conditional Format Rule Changed | Triggers when conditional formatting rules change in a Google Spreadsheet. Detects when rules are added, updated, or removed. Uses snapshot-based diffing to detect changes between polls. |
| `GOOGLESHEETS_DATA_VALIDATION_RULE_CHANGED_TRIGGER` | Data Validation Rule Changed | Triggers when data validation rules change (added/updated/removed) in a Google Spreadsheet. Uses snapshot-based diffing to detect changes between polls. |
| `GOOGLESHEETS_DEVELOPER_METADATA_CHANGED_TRIGGER` | Developer Metadata Changed | Triggers when developer metadata entries change (new/updated/removed) in a Google Spreadsheet. Uses snapshot-based diffing to detect changes between polls. |
| `GOOGLESHEETS_FILTERED_RANGE_VALUES_CHANGED_TRIGGER` | Filtered Range Values Changed | Polling trigger that monitors Google Sheets filtered ranges for value changes. Uses snapshot-based diffing to detect when values matching a data filter change. Emits the matched values when changes are detected. |
| `GOOGLESHEETS_NEW_ROWS_TRIGGER` | New Rows in Google Sheet | Simple polling trigger that monitors Google Sheets for new rows. Detects when new rows are added and returns the complete row data. Perfect for triggering any workflow based on new sheet entries. |
| `GOOGLESHEETS_NEW_SHEET_ADDED_TRIGGER` | New Sheet Added in Google Spreadsheet | Polling trigger that detects when a new sheet is added to a Google Spreadsheet. |
| `GOOGLESHEETS_NEW_SPREADSHEET_CREATED_TRIGGER` | New Spreadsheet Created | Triggers when a new Google Spreadsheet is created. This trigger monitors Google Spreadsheets and fires when new spreadsheets are detected. Uses timestamp filtering to efficiently detect newly created spreadsheets. |
| `GOOGLESHEETS_SPREADSHEET_METADATA_CHANGED_TRIGGER` | Spreadsheet Metadata Changed | Polling trigger that detects when a Google Spreadsheet's metadata changes. Uses snapshot-based diffing to detect any changes in spreadsheet properties, sheets, named ranges, developer metadata, data sources, etc. |
| `GOOGLESHEETS_SPREADSHEET_PROPERTIES_CHANGED_TRIGGER` | Spreadsheet Properties Changed | Polling trigger that detects when a Google Spreadsheet's top-level properties change. Monitors properties such as title, locale, timeZone, and autoRecalc settings. |
| `GOOGLESHEETS_SPREADSHEET_ROW_CHANGED_TRIGGER` | Spreadsheet Row Changed | Triggers when a looked-up spreadsheet row changes. This trigger monitors a specific row (located by searching for a query value within a user-specified range) and fires when the row's values change, when the row appears, or when the row disappears. |
| `GOOGLESHEETS_SPREADSHEET_SEARCH_MATCH_TRIGGER` | Spreadsheet Search Match | Triggers when a new spreadsheet appears that matches a saved search. This trigger uses snapshot-based diffing to detect when spreadsheets matching the search criteria are newly created or become visible to the user. |
| `GOOGLESHEETS_TABLE_QUERY_RESULT_CHANGED_TRIGGER` | Table Query Result Changed | Triggers when the result set of a saved table query changes in Google Sheets. Detects rows added, removed, or updated in the query output. This trigger monitors the result of a SQL query against a Google Sheets table and fires when changes are detected. |
| `GOOGLESHEETS_TABLE_SCHEMA_CHANGED_TRIGGER` | Table Schema Changed | Polling trigger that detects when a table's schema changes in Google Sheets. Monitors columns added/removed/renamed and inferred type/format changes. Uses snapshot-based diffing to compare schemas between polls. |
| `GOOGLESHEETS_WORKSHEET_NAMES_CHANGED_TRIGGER` | Worksheet Names Changed | Triggers when the set of worksheet/tab names changes in a Google Spreadsheet. Detects when sheets are added, deleted, or renamed. |

## Creating MCP Server - Stand-alone vs Composio SDK

The Google Sheets MCP server is an implementation of the Model Context Protocol that connects your AI agent to Google Sheets. It provides structured and secure access so your agent can perform Google Sheets operations on your behalf through a secure, permission-based interface.
With Composio's managed implementation, you don't have to create your own developer app. For production, if you're building an end product, we recommend using your own credentials. The managed server helps you prototype fast and go from 0-1 faster.

## Step-by-step Guide

### 1. Prerequisites

Before starting, make sure you have:
- Node.js 18 or higher
- A Composio account with an active API key
- An OpenAI API key
- Basic familiarity with TypeScript

### 1. Getting API Keys for OpenAI and Composio

OpenAI API Key
- Go to the [OpenAI dashboard](https://platform.openai.com/settings/organization/api-keys) and create an API key.
- You need credits or a connected billing setup to use the models.
- Store the key somewhere safe.
Composio API Key
- Log in to the [Composio dashboard](https://dashboard.composio.dev?utm_source=toolkits&utm_medium=framework_docs).
- Go to Settings and copy your API key.
- This key lets your Mastra agent talk to Composio and reach Google Sheets through MCP.

### 2. Install dependencies

Install the required packages.
What's happening:
- @composio/core is the Composio SDK for creating MCP sessions
- @mastra/core provides the Agent class
- @mastra/mcp is Mastra's MCP client
- @ai-sdk/openai is the model wrapper for OpenAI
- dotenv loads environment variables from .env
```bash
npm install @composio/core @mastra/core @mastra/mcp @ai-sdk/openai dotenv
```

### 3. Set up environment variables

Create a .env file in your project root.
What's happening:
- COMPOSIO_API_KEY authenticates your requests to Composio
- COMPOSIO_USER_ID tells Composio which user this session belongs to
- OPENAI_API_KEY lets the Mastra agent call OpenAI models
```bash
COMPOSIO_API_KEY=your_composio_api_key_here
COMPOSIO_USER_ID=your_user_id_here
OPENAI_API_KEY=your_openai_api_key_here
```

### 4. Import libraries and validate environment

What's happening:
- dotenv/config auto loads your .env so process.env.* is available
- openai gives you a Mastra compatible model wrapper
- Agent is the Mastra agent that will call tools and produce answers
- MCPClient connects Mastra to your Composio MCP server
- Composio is used to create a Tool Router session
```typescript
import "dotenv/config";
import { openai } from "@ai-sdk/openai";
import { Agent } from "@mastra/core/agent";
import { MCPClient } from "@mastra/mcp";
import { Composio } from "@composio/core";
import * as readline from "readline";

import type { AiMessageType } from "@mastra/core/agent";

const openaiAPIKey = process.env.OPENAI_API_KEY;
const composioAPIKey = process.env.COMPOSIO_API_KEY;
const composioUserID = process.env.COMPOSIO_USER_ID;

if (!openaiAPIKey) throw new Error("OPENAI_API_KEY is not set");
if (!composioAPIKey) throw new Error("COMPOSIO_API_KEY is not set");
if (!composioUserID) throw new Error("COMPOSIO_USER_ID is not set");

const composio = new Composio({
  apiKey: composioAPIKey as string,
});
```

### 5. Create a Tool Router session for Google Sheets

What's happening:
- create spins up a short-lived MCP HTTP endpoint for this user
- The toolkits array contains "googlesheets" for Google Sheets access
- session.mcp.url is the MCP URL that Mastra's MCPClient will connect to
```typescript
async function main() {
  const session = await composio.create(
    composioUserID as string,
    {
      toolkits: ["googlesheets"],
    },
  );

  const composioMCPUrl = session.mcp.url;
  console.log("Google Sheets MCP URL:", composioMCPUrl);
```

### 6. Configure Mastra MCP client and fetch tools

What's happening:
- MCPClient takes an id for this client and a list of MCP servers
- The headers property includes the x-api-key for authentication
- getTools fetches the tool definitions exposed by the Google Sheets toolkit
```typescript
const mcpClient = new MCPClient({
    id: composioUserID as string,
    servers: {
      nasdaq: {
        url: new URL(composioMCPUrl),
        requestInit: {
          headers: session.mcp.headers,
        },
      },
    },
    timeout: 30_000,
  });

console.log("Fetching MCP tools from Composio...");
const composioTools = await mcpClient.getTools();
console.log("Number of tools:", Object.keys(composioTools).length);
```

### 7. Create the Mastra agent

What's happening:
- Agent is the core Mastra agent
- name is just an identifier for logging and debugging
- instructions guide the agent to use tools instead of only answering in natural language
- model uses openai("gpt-5") to configure the underlying LLM
```typescript
const agent = new Agent({
    name: "googlesheets-mastra-agent",
    instructions: "You are an AI agent with Google Sheets tools via Composio.",
    model: "openai/gpt-5",
  });
```

### 8. Set up interactive chat interface

What's happening:
- messages keeps the full conversation history in Mastra's expected format
- agent.generate runs the agent with conversation history and Google Sheets toolsets
- maxSteps limits how many tool calls the agent can take in a single run
- onStepFinish is a hook that prints intermediate steps for debugging
```typescript
let messages: AiMessageType[] = [];

console.log("Chat started! Type 'exit' or 'quit' to end.\n");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: "> ",
});

rl.prompt();

rl.on("line", async (userInput: string) => {
  const trimmedInput = userInput.trim();

  if (["exit", "quit", "bye"].includes(trimmedInput.toLowerCase())) {
    console.log("\nGoodbye!");
    rl.close();
    process.exit(0);
  }

  if (!trimmedInput) {
    rl.prompt();
    return;
  }

  messages.push({
    id: crypto.randomUUID(),
    role: "user",
    content: trimmedInput,
  });

  console.log("\nAgent is thinking...\n");

  try {
    const response = await agent.generate(messages, {
      toolsets: {
        googlesheets: composioTools,
      },
      maxSteps: 8,
    });

    const { text } = response;

    if (text && text.trim().length > 0) {
      console.log(`Agent: ${text}\n`);
        messages.push({
          id: crypto.randomUUID(),
          role: "assistant",
          content: text,
        });
      }
    } catch (error) {
      console.error("\nError:", error);
    }

    rl.prompt();
  });

  rl.on("close", async () => {
    console.log("\nSession ended.");
    await mcpClient.disconnect();
    process.exit(0);
  });
}

main().catch((err) => {
  console.error("Fatal error:", err);
  process.exit(1);
});
```

## Complete Code

```typescript
import "dotenv/config";
import { openai } from "@ai-sdk/openai";
import { Agent } from "@mastra/core/agent";
import { MCPClient } from "@mastra/mcp";
import { Composio } from "@composio/core";
import * as readline from "readline";

import type { AiMessageType } from "@mastra/core/agent";

const openaiAPIKey = process.env.OPENAI_API_KEY;
const composioAPIKey = process.env.COMPOSIO_API_KEY;
const composioUserID = process.env.COMPOSIO_USER_ID;

if (!openaiAPIKey) throw new Error("OPENAI_API_KEY is not set");
if (!composioAPIKey) throw new Error("COMPOSIO_API_KEY is not set");
if (!composioUserID) throw new Error("COMPOSIO_USER_ID is not set");

const composio = new Composio({ apiKey: composioAPIKey as string });

async function main() {
  const session = await composio.create(composioUserID as string, {
    toolkits: ["googlesheets"],
  });

  const composioMCPUrl = session.mcp.url;

  const mcpClient = new MCPClient({
    id: composioUserID as string,
    servers: {
      googlesheets: {
        url: new URL(composioMCPUrl),
        requestInit: {
          headers: session.mcp.headers,
        },
      },
    },
    timeout: 30_000,
  });

  const composioTools = await mcpClient.getTools();

  const agent = new Agent({
    name: "googlesheets-mastra-agent",
    instructions: "You are an AI agent with Google Sheets tools via Composio.",
    model: "openai/gpt-5",
  });

  let messages: AiMessageType[] = [];

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    prompt: "> ",
  });

  rl.prompt();

  rl.on("line", async (input: string) => {
    const trimmed = input.trim();
    if (["exit", "quit"].includes(trimmed.toLowerCase())) {
      rl.close();
      return;
    }

    messages.push({ id: crypto.randomUUID(), role: "user", content: trimmed });

    const { text } = await agent.generate(messages, {
      toolsets: { googlesheets: composioTools },
      maxSteps: 8,
    });

    if (text) {
      console.log(`Agent: ${text}\n`);
      messages.push({ id: crypto.randomUUID(), role: "assistant", content: text });
    }

    rl.prompt();
  });

  rl.on("close", async () => {
    await mcpClient.disconnect();
    process.exit(0);
  });
}

main();
```

## Conclusion

You've built a Mastra AI agent that can interact with Google Sheets through Composio's Tool Router.
You can extend this further by:
- Adding other toolkits like Gmail, Slack, or GitHub
- Building a web-based chat interface around this agent
- Using multiple MCP endpoints to enable cross-app workflows

## How to build Google Sheets MCP Agent with another framework

- [ChatGPT](https://composio.dev/toolkits/googlesheets/framework/chatgpt)
- [OpenAI Agents SDK](https://composio.dev/toolkits/googlesheets/framework/open-ai-agents-sdk)
- [Claude Agent SDK](https://composio.dev/toolkits/googlesheets/framework/claude-agents-sdk)
- [Claude Code](https://composio.dev/toolkits/googlesheets/framework/claude-code)
- [Claude Cowork](https://composio.dev/toolkits/googlesheets/framework/claude-cowork)
- [Codex](https://composio.dev/toolkits/googlesheets/framework/codex)
- [Cursor](https://composio.dev/toolkits/googlesheets/framework/cursor)
- [VS Code](https://composio.dev/toolkits/googlesheets/framework/vscode)
- [OpenCode](https://composio.dev/toolkits/googlesheets/framework/opencode)
- [OpenClaw](https://composio.dev/toolkits/googlesheets/framework/openclaw)
- [Hermes](https://composio.dev/toolkits/googlesheets/framework/hermes-agent)
- [CLI](https://composio.dev/toolkits/googlesheets/framework/cli)
- [Google ADK](https://composio.dev/toolkits/googlesheets/framework/google-adk)
- [LangChain](https://composio.dev/toolkits/googlesheets/framework/langchain)
- [Vercel AI SDK](https://composio.dev/toolkits/googlesheets/framework/ai-sdk)
- [LlamaIndex](https://composio.dev/toolkits/googlesheets/framework/llama-index)
- [CrewAI](https://composio.dev/toolkits/googlesheets/framework/crew-ai)

## Related Toolkits

- [Notion](https://composio.dev/toolkits/notion) - Notion is a collaborative workspace for notes, docs, wikis, and tasks. It streamlines team knowledge, project tracking, and workflow customization in one place.
- [Airtable](https://composio.dev/toolkits/airtable) - Airtable combines the flexibility of spreadsheets with the power of a database for easy project and data management. Teams use Airtable to organize, track, and collaborate with custom views and automations.
- [Asana](https://composio.dev/toolkits/asana) - Asana is a collaborative work management platform for teams to organize and track projects. It streamlines teamwork, boosts productivity, and keeps everyone aligned on goals.
- [Google Tasks](https://composio.dev/toolkits/googletasks) - Google Tasks is a to-do list and task management tool integrated into Gmail and Google Calendar. It helps you organize, track, and complete tasks across your Google ecosystem.
- [Linear](https://composio.dev/toolkits/linear) - Linear is a modern issue tracking and project planning tool for fast-moving teams. It helps streamline workflows, organize projects, and boost productivity.
- [Jira](https://composio.dev/toolkits/jira) - Jira is Atlassian’s platform for bug tracking, issue tracking, and agile project management. It helps teams organize work, prioritize tasks, and deliver projects efficiently.
- [Clickup](https://composio.dev/toolkits/clickup) - ClickUp is an all-in-one productivity platform for managing tasks, docs, goals, and team collaboration. It streamlines project workflows so teams can work smarter and stay organized in one place.
- [Monday](https://composio.dev/toolkits/monday) - Monday.com is a customizable work management platform for project planning and collaboration. It helps teams organize tasks, automate workflows, and track progress in real time.
- [Addressfinder](https://composio.dev/toolkits/addressfinder) - Addressfinder is a data quality platform for verifying addresses, emails, and phone numbers. It helps you ensure accurate customer and contact data every time.
- [Agiled](https://composio.dev/toolkits/agiled) - Agiled is an all-in-one business management platform for CRM, projects, and finance. It helps you streamline workflows, consolidate client data, and manage business processes in one place.
- [Ascora](https://composio.dev/toolkits/ascora) - Ascora is a cloud-based field service management platform for service businesses. It streamlines scheduling, invoicing, and customer operations in one place.
- [Basecamp](https://composio.dev/toolkits/basecamp) - Basecamp is a project management and team collaboration tool by 37signals. It helps teams organize tasks, share files, and communicate efficiently in one place.
- [Beeminder](https://composio.dev/toolkits/beeminder) - Beeminder is an online goal-tracking platform that uses monetary pledges to keep you motivated. Stay accountable and hit your targets with real financial incentives.
- [Boxhero](https://composio.dev/toolkits/boxhero) - Boxhero is a cloud-based inventory management platform for SMBs, offering real-time updates, barcode scanning, and team collaboration. It helps businesses streamline stock tracking and analytics for smarter inventory decisions.
- [Breathe HR](https://composio.dev/toolkits/breathehr) - Breathe HR is cloud-based HR software for SMEs to manage employee data, absences, and performance. It simplifies HR admin, making it easy to keep employee records accurate and up to date.
- [Breeze](https://composio.dev/toolkits/breeze) - Breeze is a project management platform designed to help teams plan, track, and collaborate on projects. It streamlines workflows and keeps everyone on the same page.
- [Bugherd](https://composio.dev/toolkits/bugherd) - Bugherd is a visual feedback and bug tracking tool for websites. It helps teams and clients report website issues directly on live sites for faster fixes.
- [Canny](https://composio.dev/toolkits/canny) - Canny is a platform for managing customer feedback and feature requests. It helps teams prioritize product decisions based on real user insights.
- [Chmeetings](https://composio.dev/toolkits/chmeetings) - Chmeetings is a church management platform for events, members, donations, and volunteers. It streamlines church operations and improves community engagement.
- [ClickSend](https://composio.dev/toolkits/clicksend) - ClickSend is a cloud-based SMS and email marketing platform for businesses. It streamlines communication by enabling quick message delivery and contact management.

## Frequently Asked Questions

### What are the differences in Tool Router MCP and Google Sheets MCP?

With a standalone Google Sheets MCP server, the agents and LLMs can only access a fixed set of Google Sheets tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from Google Sheets and many other apps based on the task at hand, all through a single MCP endpoint.

### Can I use Tool Router MCP with Mastra AI?

Yes, you can. Mastra AI fully supports MCP integration. You get structured tool calling, message history handling, and model orchestration while Tool Router takes care of discovering and serving the right Google Sheets tools.

### Can I manage the permissions and scopes for Google Sheets while using Tool Router?

Yes, absolutely. You can configure which Google Sheets scopes and actions are allowed when connecting your account to Composio. You can also bring your own OAuth credentials or API configuration so you keep full control over what the agent can do.

### How safe is my data with Composio Tool Router?

All sensitive data such as tokens, keys, and configuration is fully encrypted at rest and in transit. Composio is SOC 2 Type 2 compliant and follows strict security practices so your Google Sheets data and credentials are handled as safely as possible.

---
[See all toolkits](https://composio.dev/toolkits) · [Composio docs](https://docs.composio.dev/llms.txt)
