import { z } from "zod";
import { getSheetNames, getSheetSchema, getSheetRows } from "./sheets.js";
export const ListSheetsSchema = z.object({
spreadsheetId: z
.string()
.describe("The ID of the Google Spreadsheet (from the URL)"),
});
export const GetSchemaSchema = z.object({
spreadsheetId: z
.string()
.describe("The ID of the Google Spreadsheet (from the URL)"),
sheetName: z.string().describe("The name of the sheet/tab to get schema for"),
});
export const QueryRowsSchema = z.object({
spreadsheetId: z
.string()
.describe("The ID of the Google Spreadsheet (from the URL)"),
sheetName: z.string().describe("The name of the sheet/tab to query"),
limit: z
.number()
.optional()
.describe("Maximum number of rows to return (default: all rows, max 1000)"),
offset: z
.number()
.optional()
.describe("Number of rows to skip before returning results"),
});
export const tools = [
{
name: "list_sheets",
description:
"List all sheet names (tabs) in a Google Spreadsheet. Use this to discover available sheets before querying data.",
inputSchema: {
type: "object" as const,
properties: {
spreadsheetId: {
type: "string",
description: "The ID of the Google Spreadsheet (from the URL)",
},
},
required: ["spreadsheetId"],
},
},
{
name: "get_schema",
description:
"Get the column names (headers) for a specific sheet. Returns the first row of the sheet which typically contains column headers.",
inputSchema: {
type: "object" as const,
properties: {
spreadsheetId: {
type: "string",
description: "The ID of the Google Spreadsheet (from the URL)",
},
sheetName: {
type: "string",
description: "The name of the sheet/tab to get schema for",
},
},
required: ["spreadsheetId", "sheetName"],
},
},
{
name: "query_rows",
description:
"Fetch rows of data from a sheet. Returns data as objects with column names as keys. Supports pagination via limit and offset.",
inputSchema: {
type: "object" as const,
properties: {
spreadsheetId: {
type: "string",
description: "The ID of the Google Spreadsheet (from the URL)",
},
sheetName: {
type: "string",
description: "The name of the sheet/tab to query",
},
limit: {
type: "number",
description:
"Maximum number of rows to return (default: all rows, max 1000)",
},
offset: {
type: "number",
description: "Number of rows to skip before returning results",
},
},
required: ["spreadsheetId", "sheetName"],
},
},
];
export async function handleToolCall(
name: string,
args: Record<string, unknown>
): Promise<unknown> {
switch (name) {
case "list_sheets": {
const { spreadsheetId } = ListSheetsSchema.parse(args);
const sheets = await getSheetNames(spreadsheetId);
return { sheets };
}
case "get_schema": {
const { spreadsheetId, sheetName } = GetSchemaSchema.parse(args);
const columns = await getSheetSchema(spreadsheetId, sheetName);
return { columns, sheetName };
}
case "query_rows": {
const { spreadsheetId, sheetName, limit, offset } =
QueryRowsSchema.parse(args);
const rows = await getSheetRows(spreadsheetId, sheetName, limit, offset);
return {
sheetName,
rowCount: rows.length,
rows,
};
}
default:
throw new Error(`Unknown tool: ${name}`);
}
}