Claude Google Apps Script MCP Guide
Integre o Claude AI com o Google Apps Script para automatizar tarefas no Google Sheets e Gmail.
Documentação
Guia Completo de Integração Claude MCP Google Apps Script
Construindo um poderoso sistema de automação conectando Claude e Google Apps Script via MCP (Model Context Protocol)
📋 Sumário
- Visão Geral
- Requisitos do Sistema
- Etapa 1: Criar projeto do Google Apps Script
- Etapa 2: Escrever o código do servidor MCP
- Etapa 3: Implantar o aplicativo web
- Etapa 4: Criar planilha de teste
- Etapa 5: Testar o servidor MCP
- Etapa 6: Configurar o cliente MCP local
- Etapa 7: Conectar ao Claude Desktop
- Exemplos de uso
- Recursos avançados
- Solução de problemas
Visão Geral
Este guia fornece um método completo para conectar o Claude AI e o Google Apps Script por meio do protocolo MCP. Após a conexão, você poderá usar os seguintes recursos poderosos:
🚀 Principais recursos
- 📊 Automação do Google Sheets: leitura/gravação de dados em tempo real, análise, geração de relatórios
- 📧 Integração com Gmail: classificação inteligente de e-mails, respostas automáticas, envio em massa
- 🤖 Automação de trabalho: gerenciamento de agenda, análise de dados, sistema de notificações
- 📈 Dashboard em tempo real: monitoramento integrado de múltiplas fontes de dados
Requisitos do Sistema
Pré-requisitos
Verificação da instalação
node -v # v18.0.0 이상
npm -v # 9.0.0 이상
Etapa 1: Criar projeto do Google Apps Script
1.1 Criar novo projeto
- Acesse o Google Apps Script
- Clique em "Novo projeto"
- Altere o nome do projeto para "Claude MCP Server"
- Exclua todo o código
myFunction()padrão
1.2 Verificações
- ✅ O nome do projeto aparece como "Claude MCP Server"
- ✅ O editor de código está completamente vazio
Etapa 2: Escrever o código do servidor MCP
2.1 Copiar e colar o código
Copie e cole o seguinte código no editor do Google Apps Script:
/**
* Claude MCP Server for Google Apps Script
* 클로드와 구글 워크스페이스를 연결하는 MCP 서버
*/
// MCP 서버 설정
const MCP_CONFIG = {
name: "google-workspace-mcp",
version: "1.0.0",
description: "Google Workspace integration for Claude via MCP",
};
// 도구 목록 정의
const TOOLS = {
READ_SHEET: {
name: "read_google_sheet",
description: "Google Sheets에서 데이터를 읽어옵니다",
inputSchema: {
type: "object",
properties: {
spreadsheetId: {
type: "string",
description: "스프레드시트 ID",
},
range: {
type: "string",
description: "읽을 범위 (예: A1:C10)",
default: "A:Z",
},
},
required: ["spreadsheetId"],
},
},
WRITE_SHEET: {
name: "write_google_sheet",
description: "Google Sheets에 데이터를 씁니다",
inputSchema: {
type: "object",
properties: {
spreadsheetId: {
type: "string",
description: "스프레드시트 ID",
},
range: {
type: "string",
description: "쓸 범위 (예: A1:C10)",
},
values: {
type: "array",
description: "쓸 데이터 (2차원 배열)",
},
},
required: ["spreadsheetId", "range", "values"],
},
},
SEND_EMAIL: {
name: "send_gmail",
description: "Gmail을 통해 이메일을 발송합니다",
inputSchema: {
type: "object",
properties: {
to: {
type: "string",
description: "받는 사람 이메일",
},
subject: {
type: "string",
description: "이메일 제목",
},
body: {
type: "string",
description: "이메일 내용",
},
},
required: ["to", "subject", "body"],
},
},
};
/**
* MCP 서버 메인 핸들러
*/
function doPost(e) {
try {
const request = JSON.parse(e.postData.contents);
console.log("MCP Request:", request);
// 요청 타입에 따른 처리
switch (request.method) {
case "tools/list":
return createResponse(handleToolsList());
case "tools/call":
return createResponse(handleToolCall(request.params));
default:
return createErrorResponse("Unknown method: " + request.method);
}
} catch (error) {
console.error("MCP Error:", error);
return createErrorResponse("Server error: " + error.message);
}
}
/**
* 도구 목록 반환
*/
function handleToolsList() {
return {
tools: Object.values(TOOLS),
};
}
/**
* 도구 실행
*/
function handleToolCall(params) {
const { name, arguments: args } = params;
try {
switch (name) {
case "read_google_sheet":
return readGoogleSheet(args);
case "write_google_sheet":
return writeGoogleSheet(args);
case "send_gmail":
return sendGmail(args);
default:
throw new Error("Unknown tool: " + name);
}
} catch (error) {
return {
isError: true,
content: [
{
type: "text",
text: `도구 실행 오류: ${error.message}`,
},
],
};
}
}
/**
* Google Sheets 데이터 읽기
*/
function readGoogleSheet(args) {
const { spreadsheetId, range = "A:Z" } = args;
try {
const spreadsheet = SpreadsheetApp.openById(spreadsheetId);
const sheet = spreadsheet.getActiveSheet();
const data = sheet.getRange(range).getValues();
// 빈 행 제거
const filteredData = data.filter((row) => row.some((cell) => cell !== ""));
return {
content: [
{
type: "text",
text: `스프레드시트 데이터 (${
filteredData.length
}행):\n${JSON.stringify(filteredData, null, 2)}`,
},
],
};
} catch (error) {
throw new Error(`Sheets 읽기 실패: ${error.message}`);
}
}
/**
* Google Sheets 데이터 쓰기
*/
function writeGoogleSheet(args) {
const { spreadsheetId, range, values } = args;
try {
const spreadsheet = SpreadsheetApp.openById(spreadsheetId);
const sheet = spreadsheet.getActiveSheet();
if (values.length > 0) {
sheet.getRange(range).setValues(values);
}
return {
content: [
{
type: "text",
text: `성공적으로 ${values.length}행의 데이터를 ${range} 범위에 저장했습니다.`,
},
],
};
} catch (error) {
throw new Error(`Sheets 쓰기 실패: ${error.message}`);
}
}
/**
* Gmail 이메일 발송
*/
function sendGmail(args) {
const { to, subject, body } = args;
try {
GmailApp.sendEmail(to, subject, body);
return {
content: [
{
type: "text",
text: `이메일이 성공적으로 ${to}에게 발송되었습니다.`,
},
],
};
} catch (error) {
throw new Error(`이메일 발송 실패: ${error.message}`);
}
}
/**
* 응답 생성 헬퍼
*/
function createResponse(data) {
return ContentService.createTextOutput(JSON.stringify(data)).setMimeType(
ContentService.MimeType.JSON
);
}
function createErrorResponse(message) {
return ContentService.createTextOutput(
JSON.stringify({
error: {
code: -1,
message: message,
},
})
).setMimeType(ContentService.MimeType.JSON);
}
/**
* 테스트 함수
*/
function testMCPServer() {
console.log("MCP 서버 테스트 시작");
// 도구 목록 테스트
const toolsList = handleToolsList();
console.log("도구 목록:", toolsList);
console.log("MCP 서버가 정상적으로 설정되었습니다!");
}
2.2 Salvar
- Clique em
Ctrl + Sou no botão 💾 Salvar - Verifique se não há erros de sintaxe (não deve haver sublinhados vermelhos)
Etapa 3: Implantar o aplicativo web
3.1 Configuração da implantação
- Clique no botão "Implantar" no canto superior direito
- Selecione "Nova implantação"
- Clique no ícone de engrenagem ⚙️ → Selecione "Aplicativo web"
- Insira os valores de configuração:
- Descrição: "Claude MCP Server v1.0"
- Executar como: "Eu"
- Permissão de acesso: "Todos os usuários"
3.2 Aprovação de permissões
- Clique no botão "Implantar"
- Clique no pop-up "Aprovar acesso"
- Selecione a conta do Google
- Clique em "Avançado" → "Não seguro (unsafe)" → "Ir"
- Clique no botão "Permitir"
3.3 Copiar a URL do aplicativo web
- Copie e salve a URL do aplicativo web exibida após a conclusão da implantação
- Formato:
https://script.google.com/macros/s/ABC...XYZ/exec
Etapa 4: Criar planilha de teste
4.1 Criar nova planilha
- Acesse o Google Sheets
- Clique em "Novo" → "Planilha em branco"
- Altere o nome da planilha para "Claude MCP Test Sheet"
4.2 Inserir dados de teste
Copie e cole os seguintes dados a partir da célula A1:
이름 부서 직급 급여
김철수 개발팀 과장 5000
이영희 마케팅팀 대리 4000
박민수 인사팀 차장 6000
최은정 재무팀 사원 3500
4.3 Configuração da planilha
-
Copiar o ID da planilha
- Copie a parte do ID na barra de endereço do navegador
https://docs.google.com/spreadsheets/d/[이부분이ID]/edit
-
Configuração de compartilhamento
- Clique no botão "Compartilhar" no canto superior direito
- Altere para "Todos que têm o link" com permissão de "Editor"
- Clique em "Concluído"
Etapa 5: Testar o servidor MCP
5.1 Teste básico
- Volte ao Google Apps Script
- Selecione
testMCPServerno menu suspenso de seleção de função - Clique no botão ▶️ "Executar"
- Aprove as permissões (na primeira execução)
5.2 Teste de leitura da planilha
Adicione a seguinte função no final do código existente:
/**
* 실제 스프레드시트 읽기 테스트
*/
function testReadSheet() {
const spreadsheetId = "YOUR_SHEET_ID"; // 실제 스프레드시트 ID로 변경
try {
const result = readGoogleSheet({
spreadsheetId: spreadsheetId,
range: "A1:D10",
});
console.log("스프레드시트 읽기 성공!");
console.log("결과:", result);
} catch (error) {
console.error("스프레드시트 읽기 실패:", error);
}
}
5.3 Executar o teste
- Selecione e execute a função
testReadSheet - Verifique se os dados de teste são exibidos no log de execução
Etapa 6: Configurar o cliente MCP local
6.1 Criar pasta do projeto
Crie uma pasta com a seguinte estrutura no local desejado:
mkdir claude-gas-mcp
cd claude-gas-mcp
mkdir src
mkdir config
6.2 Criar package.json
Crie o arquivo package.json na raiz do projeto:
{
"name": "claude-gas-mcp",
"version": "1.0.0",
"description": "Claude와 Google Apps Script 연결을 위한 MCP 클라이언트",
"main": "src/server.js",
"type": "module",
"scripts": {
"start": "node src/server.js",
"dev": "node --watch src/server.js"
},
"keywords": ["claude", "mcp", "google-apps-script"],
"author": "",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "^0.4.0",
"axios": "^1.6.0"
}
}
6.3 Instalar dependências
npm install
6.4 Criar arquivo de configuração
Crie o arquivo config/mcp-config.json:
{
"name": "Google Apps Script MCP Server",
"version": "1.0.0",
"description": "Google Workspace와 Claude 연결",
"config": {
"webAppUrl": "YOUR_WEB_APP_URL_HERE",
"testSpreadsheetId": "YOUR_SPREADSHEET_ID_HERE"
},
"tools": ["read_google_sheet", "write_google_sheet", "send_gmail"]
}
6.5 Criar código do servidor MCP
Crie o arquivo src/server.js:
#!/usr/bin/env node
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 axios from "axios";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 설정 파일 로드
const configPath = path.join(__dirname, "../config/mcp-config.json");
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
class GoogleAppsScriptMCPServer {
constructor() {
this.server = new Server(
{
name: "google-apps-script-mcp",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
this.setupToolHandlers();
this.setupErrorHandling();
}
setupErrorHandling() {
this.server.onerror = (error) => {
console.error("[MCP Error]", error);
};
process.on("SIGINT", async () => {
await this.server.close();
process.exit(0);
});
}
setupToolHandlers() {
// 도구 목록 제공
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "read_google_sheet",
description: "Google Sheets에서 데이터를 읽어옵니다",
inputSchema: {
type: "object",
properties: {
spreadsheetId: {
type: "string",
description: "스프레드시트 ID",
},
range: {
type: "string",
description: "읽을 범위 (예: A1:C10)",
default: "A:Z",
},
},
required: ["spreadsheetId"],
},
},
{
name: "write_google_sheet",
description: "Google Sheets에 데이터를 씁니다",
inputSchema: {
type: "object",
properties: {
spreadsheetId: {
type: "string",
description: "스프레드시트 ID",
},
range: {
type: "string",
description: "쓸 범위 (예: A1:C10)",
},
values: {
type: "array",
description: "쓸 데이터 (2차원 배열)",
},
},
required: ["spreadsheetId", "range", "values"],
},
},
{
name: "send_gmail",
description: "Gmail을 통해 이메일을 발송합니다",
inputSchema: {
type: "object",
properties: {
to: {
type: "string",
description: "받는 사람 이메일",
},
subject: {
type: "string",
description: "이메일 제목",
},
body: {
type: "string",
description: "이메일 내용",
},
},
required: ["to", "subject", "body"],
},
},
],
};
});
// 도구 실행
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case "read_google_sheet":
return await this.readGoogleSheet(args);
case "write_google_sheet":
return await this.writeGoogleSheet(args);
case "send_gmail":
return await this.sendGmail(args);
default:
throw new Error(`알 수 없는 도구: ${name}`);
}
} catch (error) {
return {
content: [
{
type: "text",
text: `오류 발생: ${error.message}`,
},
],
isError: true,
};
}
});
}
async callGoogleAppsScript(toolName, params) {
const payload = {
method: "tools/call",
params: {
name: toolName,
arguments: params,
},
};
try {
console.log(`[MCP] Google Apps Script 호출: ${toolName}`, params);
const response = await axios.post(config.config.webAppUrl, payload, {
headers: {
"Content-Type": "application/json",
},
timeout: 30000,
});
console.log(`[MCP] 응답 받음:`, response.data);
return response.data;
} catch (error) {
console.error(`[MCP] 요청 실패:`, error.message);
throw new Error(`Google Apps Script 호출 실패: ${error.message}`);
}
}
async readGoogleSheet(args) {
const result = await this.callGoogleAppsScript("read_google_sheet", args);
return {
content: [
{
type: "text",
text: result.content?.[0]?.text || "데이터를 읽어왔습니다.",
},
],
};
}
async writeGoogleSheet(args) {
const result = await this.callGoogleAppsScript("write_google_sheet", args);
return {
content: [
{
type: "text",
text: result.content?.[0]?.text || "데이터를 저장했습니다.",
},
],
};
}
async sendGmail(args) {
const result = await this.callGoogleAppsScript("send_gmail", args);
return {
content: [
{
type: "text",
text: result.content?.[0]?.text || "이메일을 발송했습니다.",
},
],
};
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("Google Apps Script MCP 서버가 시작되었습니다.");
console.error(`웹 앱 URL: ${config.config.webAppUrl}`);
console.error(
"사용 가능한 도구: read_google_sheet, write_google_sheet, send_gmail"
);
}
}
// 서버 시작
const server = new GoogleAppsScriptMCPServer();
server.run().catch(console.error);
6.6 Criar script de teste
Crie o arquivo src/test.js:
import axios from "axios";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 설정 파일 로드
const configPath = path.join(__dirname, "../config/mcp-config.json");
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
async function testGoogleAppsScript() {
console.log("🧪 Google Apps Script MCP 연결 테스트 시작\n");
// 테스트 1: 스프레드시트 읽기
console.log("📊 테스트 1: 스프레드시트 데이터 읽기");
try {
const readPayload = {
method: "tools/call",
params: {
name: "read_google_sheet",
arguments: {
spreadsheetId: config.config.testSpreadsheetId,
range: "A1:D10",
},
},
};
const readResponse = await axios.post(
config.config.webAppUrl,
readPayload,
{
headers: { "Content-Type": "application/json" },
timeout: 10000,
}
);
console.log("✅ 스프레드시트 읽기 성공!");
console.log("📋 응답:", readResponse.data);
} catch (error) {
console.log("❌ 스프레드시트 읽기 실패:", error.message);
}
console.log("\n🎉 테스트 완료!");
}
// 테스트 실행
testGoogleAppsScript().catch(console.error);
6.7 Teste de conexão
node src/test.js
Etapa 7: Conectar ao Claude Desktop
7.1 Modificar o arquivo de configuração do Claude Desktop
Localização do arquivo de configuração no Windows:
%APPDATA%\Claude\claude_desktop_config.json
7.2 Conteúdo do arquivo de configuração
Adicione o seguinte conteúdo à configuração existente:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\[사용자명]\\Desktop"
],
"env": {}
},
"google-apps-script": {
"command": "node",
"args": ["C:\\[프로젝트경로]\\claude-gas-mcp\\src\\server.js"],
"env": {
"NODE_ENV": "production"
}
}
},
"darkMode": "dark",
"scale": 0,
"locale": "ko-KR"
}
7.3 Reiniciar o Claude Desktop
- Feche completamente o aplicativo Claude Desktop
- Reinicie o aplicativo
- Inicie uma nova conversa
7.4 Teste de conexão
Teste no Claude Desktop da seguinte forma:
Google Apps Script MCP 서버가 연결되었는지 확인하고,
스프레드시트 ID [YOUR_SHEET_ID]의 데이터를 읽어서 보여줘.
Exemplos de uso
📊 Manipulação básica de dados
Ler planilha
"스프레드시트 ID 13Qy45cJ6oDJsyS007bml2GAyklGAiY7EGd1GZ1vO7ro에서
직원 데이터를 읽어서 부서별 평균 급여를 계산해줘"
Adicionar dados
"새 직원 정보를 추가해줘:
이름-홍길동, 부서-IT팀, 직급-사원, 급여-3200"
Enviar e-mail
"부서별 급여 현황을 요약해서 manager@company.com으로 보내줘"
🤖 Solicitações de automação avançada
Criar função de automação de trabalho
"매일 아침 8시에 전날 매출 데이터를 분석해서
이메일로 보내주는 GAS 함수를 만들어줘"
Sistema de e-mail inteligente
"Gmail에서 특정 키워드가 포함된 이메일을 자동으로 분류하고
적절한 템플릿으로 답변하는 함수를 만들어줘"
Resultado: o Claude cria um sistema completo de automação de e-mail com algoritmo de classificação baseado em palavras-chave, sistema de resposta automática e funcionalidade de etiquetagem.
Dashboard em tempo real
"여러 시트의 데이터를 종합해서 실시간 대시보드를
만들어주는 함수를 작성해줘"
Resultado: integra múltiplas fontes de dados para construir um dashboard HTML com atualização em tempo real e sistema de renovação automática.
Automação de análise de dados
"매출 데이터를 분석해서 트렌드 예측하고
인사이트를 요약해서 경영진에게 보고하는 시스템을 만들어줘"
Resultado: constrói um sistema de BI com análise estatística, modelagem preditiva, gráficos de visualização e geração automática de relatórios.