Skip to main content
Glama

Google Sheets MCP Server

by Kyohei-9841
index.ts8.49 kB
#!/usr/bin/env node import { config } from "dotenv"; import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { google } from "googleapis"; import path from "path"; // 環境変数の読み込み(mcp.jsonの設定を優先するため、.envはフォールバックとして使用) config(); // Google Sheets API の設定 // サービスアカウントキーファイルのパスを指定 const auth = new google.auth.GoogleAuth({ keyFile: process.env.GOOGLE_APPLICATION_CREDENTIALS, scopes: ["https://www.googleapis.com/auth/spreadsheets"], }); // MCPサーバーの作成 const server = new Server( { name: "google-sheets-mcp", version: "1.0.0", }, { capabilities: { tools: {}, }, } ); // 利用可能なツールの定義 const tools = [ { name: "read_sheet", description: "スプレッドシートの指定された範囲のデータを読み取ります", inputSchema: { type: "object", properties: { spreadsheetId: { type: "string", description: "スプレッドシートのID", }, range: { type: "string", description: "読み取る範囲(例: 'Sheet1!A1:C10')", }, }, required: ["spreadsheetId", "range"], }, }, { name: "write_sheet", description: "スプレッドシートの指定された範囲にデータを書き込みます", inputSchema: { type: "object", properties: { spreadsheetId: { type: "string", description: "スプレッドシートのID", }, range: { type: "string", description: "書き込む範囲(例: 'Sheet1!A1:C10')", }, values: { type: "array", items: { type: "array", items: { type: "string", }, }, description: "書き込むデータ(2次元配列)", }, }, required: ["spreadsheetId", "range", "values"], }, }, { name: "append_row", description: "スプレッドシートの最後に新しい行を追加します", inputSchema: { type: "object", properties: { spreadsheetId: { type: "string", description: "スプレッドシートのID", }, sheetName: { type: "string", description: "シート名", }, values: { type: "array", items: { type: "string", }, description: "追加する行のデータ", }, }, required: ["spreadsheetId", "sheetName", "values"], }, }, { name: "get_sheet_info", description: "スプレッドシートの基本情報を取得します", inputSchema: { type: "object", properties: { spreadsheetId: { type: "string", description: "スプレッドシートのID", }, }, required: ["spreadsheetId"], }, }, { name: "create_sheet", description: "新しいシートを作成します", inputSchema: { type: "object", properties: { spreadsheetId: { type: "string", description: "スプレッドシートのID", }, sheetName: { type: "string", description: "作成するシート名", }, }, required: ["spreadsheetId", "sheetName"], }, }, ]; // ツール一覧の取得 server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools, }; }); // ツールの実行 server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (!args) { throw new Error("Arguments are required"); } try { switch (name) { case "read_sheet": return await readSheet(args.spreadsheetId as string, args.range as string); case "write_sheet": return await writeSheet( args.spreadsheetId as string, args.range as string, args.values as string[][] ); case "append_row": return await appendRow( args.spreadsheetId as string, args.sheetName as string, args.values as string[] ); case "get_sheet_info": return await getSheetInfo(args.spreadsheetId as string); case "create_sheet": return await createSheet(args.spreadsheetId as string, args.sheetName as string); default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { return { content: [ { type: "text", text: `エラー: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }); // スプレッドシートの読み取り async function readSheet(spreadsheetId: string, range: string) { const authClient = await auth.getClient(); const sheets = google.sheets({ version: "v4", auth: authClient as any }); const response = await sheets.spreadsheets.values.get({ spreadsheetId, range, }); return { content: [ { type: "text", text: JSON.stringify(response.data.values || [], null, 2), }, ], }; } // スプレッドシートへの書き込み async function writeSheet( spreadsheetId: string, range: string, values: string[][] ) { const authClient = await auth.getClient(); const sheets = google.sheets({ version: "v4", auth: authClient as any }); const response = await sheets.spreadsheets.values.update({ spreadsheetId, range, valueInputOption: "RAW", requestBody: { values, }, }); return { content: [ { type: "text", text: `データが正常に書き込まれました。更新されたセル数: ${response.data.updatedCells}`, }, ], }; } // 行の追加 async function appendRow( spreadsheetId: string, sheetName: string, values: string[] ) { const authClient = await auth.getClient(); const sheets = google.sheets({ version: "v4", auth: authClient as any }); const response = await sheets.spreadsheets.values.append({ spreadsheetId, range: `${sheetName}!A:Z`, valueInputOption: "RAW", requestBody: { values: [values], }, }); return { content: [ { type: "text", text: `行が正常に追加されました。更新されたセル数: ${response.data.updates?.updatedCells}`, }, ], }; } // スプレッドシート情報の取得 async function getSheetInfo(spreadsheetId: string) { const authClient = await auth.getClient(); const sheets = google.sheets({ version: "v4", auth: authClient as any }); const response = await sheets.spreadsheets.get({ spreadsheetId, }); const sheetsInfo = response.data.sheets?.map((sheet) => ({ title: sheet.properties?.title, sheetId: sheet.properties?.sheetId, rowCount: sheet.properties?.gridProperties?.rowCount, columnCount: sheet.properties?.gridProperties?.columnCount, })); return { content: [ { type: "text", text: JSON.stringify( { title: response.data.properties?.title, sheets: sheetsInfo, }, null, 2 ), }, ], }; } // シートの作成 async function createSheet(spreadsheetId: string, sheetName: string) { const authClient = await auth.getClient(); const sheets = google.sheets({ version: "v4", auth: authClient as any }); const response = await sheets.spreadsheets.batchUpdate({ spreadsheetId, requestBody: { requests: [ { addSheet: { properties: { title: sheetName, }, }, }, ], }, }); return { content: [ { type: "text", text: `シート "${sheetName}" が正常に作成されました。`, }, ], }; } // サーバーの起動 async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("Google Sheets MCP Server started"); } main().catch((error) => { console.error("Server error:", error); process.exit(1); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Kyohei-9841/google-spreadsheet-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server