์ด ๋ฌธ์๋ Model Context Protocol(MCP)์ ์ฌ์ฉํ์ฌ Claude๊ฐ Google Calendar์ ์ ๊ทผํ ์ ์๋๋ก ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์์ธํ ์ค๋ช ํฉ๋๋ค. ์ฌ๋ฌ ์ํ์ฐฉ์ค์ ํด๊ฒฐ์ฑ ์ ํฌํจํ๊ณ ์์ด ๋ ์ฝ๊ฒ ์ค์ ํ ์ ์์ต๋๋ค.
- ์ฌ์ ์๊ตฌ์ฌํญ
- ์ ์ฅ์ ์ค์
- Google OAuth ์ธ์ฆ ์ค์
- ๋ฆฌํ๋ ์ ํ ํฐ ์ป๊ธฐ
- ์๋ฒ ์ค์ ๋ฐ ์คํ
- Claude for Desktop ์ฐ๊ฒฐ
- macOS/Linux ํ๊ฒฝ
- Windows ํ๊ฒฝ
- ๋ฌธ์ ํด๊ฒฐ
- Node.js v18 ์ด์
- Google ๊ณ์
- Claude for Desktop
- ๊ธฐ๋ณธ์ ์ธ ํฐ๋ฏธ๋ ์ฌ์ฉ๋ฒ
git clone https://github.com/markelaugust74/mcp-google-calendar.git
cd mcp-google-calendar์ ์ฅ์๊ฐ ์ด์ค ๊ตฌ์กฐ๋ก ๋์ด ์์ ์ ์์ต๋๋ค. ๋ค์ ๋ช ๋ น์ด๋ก ํ์ธํ์ธ์:
ls -lamcp-google-calendar ํด๋ ๋ด์ ๋ ๋ค๋ฅธ mcp-google-calendar ํด๋๊ฐ ์๋ ๊ฒฝ์ฐ, ๋ด๋ถ ํด๋๋ก ์ด๋ํฉ๋๋ค.
cd mcp-google-calendarnpm install- Google Cloud Console์ ๋ก๊ทธ์ธํฉ๋๋ค.
- ์ ํ๋ก์ ํธ๋ฅผ ์์ฑํฉ๋๋ค.
- Google Calendar API๋ฅผ ํ์ฑํํฉ๋๋ค:
- ์ผ์ชฝ ๋ฉ๋ด์์ "API ๋ฐ ์๋น์ค" > "๋ผ์ด๋ธ๋ฌ๋ฆฌ" ์ ํ
- "Google Calendar API" ๊ฒ์ ํ ํ์ฑํ
-
"API ๋ฐ ์๋น์ค" > "์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด"๋ก ์ด๋ํฉ๋๋ค.
-
"์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด ๋ง๋ค๊ธฐ" > "OAuth ํด๋ผ์ด์ธํธ ID" ์ ํํฉ๋๋ค.

-
์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ "์น ์ ํ๋ฆฌ์ผ์ด์ "์ ์ ํํฉ๋๋ค.

-
์น์ธ๋ ๋ฆฌ๋๋ ์ URI์
http://localhost:3030/oauth2callback์ ์ถ๊ฐํฉ๋๋ค. (์ ๋ 3000์ด ์ด๋ฏธ ์ฌ์ฉ์ค์ด๋ผ 3030์ผ๋ก ํ์ต๋๋ค)
-
"๋ง๋ค๊ธฐ"๋ฅผ ํด๋ฆญํ์ฌ ํด๋ผ์ด์ธํธ ID์ ์ํฌ๋ฆฟ์ ์์ฑํฉ๋๋ค.
ํ๋ก์ ํธ ํด๋์ .env ํ์ผ์ ์์ฑํ๊ณ ๋ค์ ๋ด์ฉ์ ์ถ๊ฐํฉ๋๋ค:
# Google OAuth2 credentials
CLIENT_ID=๊ทํ์_ํด๋ผ์ด์ธํธ_ID
CLIENT_SECRET=๊ทํ์_ํด๋ผ์ด์ธํธ_์ํฌ๋ฆฟ
REDIRECT_URI=http://localhost:3030/oauth2callback
# MCP Server settings
PORT=3030
MCP_SERVER_URL=http://localhost:3030
# Google Calendar API settings (optional)
# CALENDAR_ID=primary
auth.js ํ์ผ์์ ๋ฐ๋์ prompt: 'consent' ์ต์
์ ์ถ๊ฐํด์ผ ๋ฆฌํ๋ ์ ํ ํฐ์ ์ป์ ์ ์์ต๋๋ค:
const authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
prompt: 'consent' // ์ด ์ต์
์ด ์ค์ํฉ๋๋ค!
});ํฐ๋ฏธ๋์์ ๋ค์ ๋ช ๋ น์ด๋ฅผ ์คํํฉ๋๋ค:
node auth.js-
Google ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธํ๊ณ ๊ถํ์ ๋ถ์ฌํฉ๋๋ค.
-
๋ฆฌ๋๋ ์ ๋ URL์์
code=๋ค์์ ์ค๋ ๊ฐ์ ๋ณต์ฌํฉ๋๋ค.
http://localhost:3030/oauth2callback?code=4/0AQSTg...&scope=... <-- ์ฌ๊ธฐ์ 'code=' ๋ค์๋ถํฐ '&scope=' ์๊น์ง๋ง ๋ณต์ฌ!!
โ ๏ธ ์ค์: ์ธ์ฆ ์ฝ๋๋code=๋ค์๋ถํฐ&scope=์๊น์ง์ ๋ถ๋ถ๋ง ๋ณต์ฌํด์ผ ํฉ๋๋ค! ์ ์ฒด URL์ ๋ณต์ฌํ์ง ๋ง์ธ์.
404 ์ค๋ฅ๊ฐ ๋ฐ์ํด๋ ๊ด์ฐฎ์ต๋๋ค.
- ํฐ๋ฏธ๋์ ๋ณต์ฌํ ์ฝ๋๋ฅผ ๋ถ์ฌ๋ฃ๊ณ ์ํฐ๋ฅผ ๋๋ฆ ๋๋ค.
์ฑ๊ณตํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค:
Your refresh token: 1//0eNafnMj...
โ ๏ธ ๋งค์ฐ ์ค์: ์์ ํ์๋ ๋ฆฌํ๋ ์ ํ ํฐ ๊ฐ์ ์ ํํ๊ฒ ๋ณต์ฌํ์ธ์. ์ด ๊ฐ์ ์ธ์ฆ ์ฝ๋์ ์์ ํ ๋ค๋ฅด๋ฉฐ, ๋ฐ๋์ ์ด ๋ฆฌํ๋ ์ ํ ํฐ์ index.js ํ์ผ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
index.js ํ์ผ์์ ๋ฆฌํ๋ ์ ํ ํฐ ๋ถ๋ถ์ ์ฐพ์ ์ ๋ฐ์ดํธํฉ๋๋ค:
oauth2Client.setCredentials({
refresh_token: "์ฌ๊ธฐ์_๋ฆฌํ๋ ์_ํ ํฐ_๋ถ์ฌ๋ฃ๊ธฐ", // ๋ฐ๋์ "Your refresh token:" ๋ค์์ ํ์๋ ๊ฐ์ ์ฌ์ฉํ์ธ์!
token_uri: "https://oauth2.googleapis.com/token"
});๐จ ๊ฐ์ฅ ํํ ์ค๋ฅ: URL์์ ์ถ์ถํ ์ธ์ฆ ์ฝ๋๋ฅผ ๋ฆฌํ๋ ์ ํ ํฐ์ผ๋ก ์ฐฉ๊ฐํ์ฌ ์ฌ๊ธฐ ์ ๋ ฅํ๋ ์ค์๊ฐ ๋ง์ต๋๋ค. ๋ฐ๋์ auth.js ์คํ ํ "Your refresh token:" ๋ค์์ ํ์๋๋ ๊ฐ์ ์ฌ์ฉํ์ธ์.
ํ๊ตญ ์๊ฐ์ผ๋ก ์ ๋๋ก ์ผ์ ์ด ํ์๋๋๋ก ์๊ฐ๋๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค:
const event = {
// ... ๊ธฐ์กด ์ฝ๋ ...
start: {
dateTime: args.start_time,
timeZone: 'Asia/Seoul', // America/New_York์์ ๋ณ๊ฒฝ
},
end: {
dateTime: args.end_time,
timeZone: 'Asia/Seoul', // America/New_York์์ ๋ณ๊ฒฝ
}
};๋ค์ ๊ฒฝ๋ก์ ๊ตฌ์ฑ ํ์ผ์ ์์ฑํฉ๋๋ค:
~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"google-calendar": {
"command": "bash",
"args": [
"-c",
"cd /์ ๋/๊ฒฝ๋ก/mcp-google-calendar/mcp-google-calendar && node index.js"
]
}
}
}Windows์์๋ ๋ค์ ๊ฒฝ๋ก์ ๊ตฌ์ฑ ํ์ผ์ ์์ฑํฉ๋๋ค:
%APPDATA%\Claude\claude_desktop_config.json
์ด๋ ์ผ๋ฐ์ ์ผ๋ก C:\Users\์ฌ์ฉ์์ด๋ฆ\AppData\Roaming\Claude\claude_desktop_config.json๊ณผ ๊ฐ์ ๊ฒฝ๋ก์
๋๋ค.
MCP ์๋ฒ ์คํ์ ์ํ ๋ฐฐ์น ํ์ผ์ ์์ฑํ๋ฉด Windows์์ ๋ ์์ ์ ์ผ๋ก ์๋ํฉ๋๋ค. ํ๋ก์ ํธ ํด๋์ run-calendar.bat ํ์ผ์ ์์ฑํ๊ณ ๋ค์ ๋ด์ฉ์ ์ถ๊ฐํฉ๋๋ค:
@echo off
cd /d D:\path\to\mcp-google-calendar
node index.jsD:\path\to\mcp-google-calendar๋ฅผ ์ค์ ํ๋ก์ ํธ ๊ฒฝ๋ก๋ก ๋ฐ๊พธ์ธ์.
{
"mcpServers": {
"google-calendar": {
"command": "D:\\path\\to\\mcp-google-calendar\\run-calendar.bat",
"args": []
}
}
}์ฃผ์: Windows ๊ฒฝ๋ก์์๋ ๋ฐฑ์ฌ๋์(\)๋ฅผ ๋ ๊ฐ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Windows์์๋ ํนํ ์ฃผ์ํด์ผ ํ ์ ์ผ๋ก, ์ธ์ฆ ์ฝ๋์ ๋ฆฌํ๋ ์ ํ ํฐ์ ํผ๋ํ์ง ๋ง์ธ์:
-
์ธ์ฆ ์ฝ๋: ๋ธ๋ผ์ฐ์ ์์ ๋ฐ์ URL์
code=๋ค์๋ถํฐ&scope=์๊น์ง์ ๊ฐ- ์์:
4/0AQSTgQGxCBUNcl8eapA6jW4nRTQv1gM-Q_-N73iDcUGpQa3E087w0_-jdeacYzRNEFmbJQ - โ ์ด ๊ฐ์ index.js์ ๋ฃ์ผ๋ฉด
invalid_grant์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค!
- ์์:
-
๋ฆฌํ๋ ์ ํ ํฐ:
auth.js์คํ ํ "Your refresh token:" ๋ค์์ ํ์๋๋ ๊ฐ- ์์:
1//0eNOnSp_LqfZ4CgYIARAAGA4SNwF-L9IrQSQKSZOtj-od75N5oCxiUb6yI_JtIawRfXApkIwz9OEVX7F_DBHc74XCeXH0j8ZvPKk - โ ์ด ๊ฐ์ index.js์ ๋ฃ์ด์ผ ํฉ๋๋ค!
- ์์:
index.js ํ์ผ์ ์ค์ ํ ๋ ๋ฐ๋์ ๋ฆฌํ๋ ์ ํ ํฐ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค:
oauth2Client.setCredentials({
refresh_token: "1//0eNOnSp...(์ค์ ๋ฆฌํ๋ ์ ํ ํฐ)...", // ์ธ์ฆ ์ฝ๋๊ฐ ์๋ ๋ฆฌํ๋ ์ ํ ํฐ์ด์ด์ผ ํฉ๋๋ค!
token_uri: "https://oauth2.googleapis.com/token"
});Claude for Desktop์ ์์ ํ ์ข ๋ฃํ๊ณ ๋ค์ ์์ํฉ๋๋ค.
- auth.js์
prompt: 'consent'์ต์ ์ด ์ถ๊ฐ๋์ด ์๋์ง ํ์ธํฉ๋๋ค. - Google Cloud Console์์ ๋ฆฌ๋๋ ์ URI๊ฐ .env ํ์ผ๊ณผ ์ผ์นํ๋์ง ํ์ธํฉ๋๋ค.
- ํฌํธ ๋ฒํธ๊ฐ ์ผ์นํ๋์ง ํ์ธํฉ๋๋ค(3000์์ 3030์ผ๋ก ๋ณ๊ฒฝํ ๊ฒฝ์ฐ).
๋ฏธ๊ตญ ๋๋ถ ์๊ฐ(America/New_York)๊ณผ ํ๊ตญ ์๊ฐ(Asia/Seoul) ์ฌ์ด์๋ 13~14์๊ฐ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์๊ฐ๋๋ฅผ 'Asia/Seoul'๋ก ๋ณ๊ฒฝํ์ฌ ํ๊ตญ ์๊ฐ์ ๋ง๊ฒ ์ผ์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
-
์คํ ์ค์ธ ์๋ฒ ํ์ธ:
ps aux | grep "node index.js" (Linux/macOS)
tasklist | findstr "node.exe" (Windows) -
๋ชจ๋ ์๋ฒ ์ข ๋ฃ:
pkill -f "node index.js" (Linux/macOS)
taskkill /F /IM node.exe (Windows) -
๋ก๊ทธ ํ์ธ:
tail -f ~/Library/Logs/Claude/mcp*.log (macOS)
type %APPDATA%\Claude\logs\mcp*.log (Windows)
Windows์์ "invalid_grant" ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ธ์ฆ ์ฝ๋์ ๋ฆฌํ๋ ์ ํ ํฐ์ ํผ๋ํ์ ๊ฐ๋ฅ์ฑ์ด ๋งค์ฐ ๋์ต๋๋ค.
๋ฌธ์ ์ํฉ:
- index.js ํ์ผ์ ๋ธ๋ผ์ฐ์ ์์ ๋ฐ์ ์ธ์ฆ ์ฝ๋๋ฅผ ๋ถ์ฌ๋ฃ์ โ ์ค๋ฅ ๋ฐ์
- ์ธ์ฆ ์ฝ๋๋ ์งง์ ์๋ช ์ ๊ฐ์ง๋ฉฐ ์ผํ์ฑ์ด๋ฏ๋ก ๋ฆฌํ๋ ์ ํ ํฐ์ผ๋ก ์ฌ์ฉํ ์ ์์
ํด๊ฒฐ ๋ฐฉ๋ฒ:
- auth.js๋ฅผ ๋ค์ ์คํํ์ธ์:
node auth.js - ๋ธ๋ผ์ฐ์ ์์ ๊ถํ์ ๋ถ์ฌํ๊ณ ์ธ์ฆ ์ฝ๋๋ฅผ ์ป์ ํ ํฐ๋ฏธ๋์ ์ ๋ ฅํ์ธ์
- ํฐ๋ฏธ๋์ ํ์๋๋ "Your refresh token:" ๋ค์์ ์ค๋ ๊ฐ์ ํ์ธํ์ธ์
- index.js ํ์ผ์์ ๋ฆฌํ๋ ์ ํ ํฐ์ ์ด ๊ฐ์ผ๋ก ์ ๋ฐ์ดํธํ์ธ์
์ธ์ฆ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ ํ์์
๋๋ค: 4/0AQSTgQGxCBUNcl8eapA6jW4nRTQv1gM-Q_-N73iDcUGpQa3E087w0_-jdeacYzRNEFmbJQ
์ค์ ๋ฆฌํ๋ ์ ํ ํฐ์ ๋ค์๊ณผ ๊ฐ์ ํ์์
๋๋ค: 1//0eNOnSp_LqfZ4CgYIARAAGA4SNwF-L9IrQSQKSZOtj-od75N5oCxiUb6yI_JtIawRfXApkIwz9OEVX7F_DBHc74XCeXH0j8ZvPKk
- Claude Desktop์ด index.js ํ์ผ์ ์ฐพ์ง ๋ชปํ๋ฉด ๋ฐฐ์น ํ์ผ ๋ฐฉ์์ผ๋ก ์๋ํ์ธ์.
- ๋ก๊ทธ ํ์ผ์ ํ์ธํ์ฌ ์ ํํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์ธํ์ธ์:
%APPDATA%\Claude\logs\mcp-server-google-calendar.log - claudeDesktop_config.json ํ์ผ์ด ์ฌ๋ฐ๋ฅธ ์์น์ ์๋์ง ํ์ธํ์ธ์.
- Claude Desktop์ ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ์คํํด ๋ณด์ธ์.
- ์ง์ ์๋ฒ๋ฅผ ์คํํ ํ Claude Desktop์ ์์ํ๋ ๋ฐฉ๋ฒ๋ ์๋ํด ๋ณผ ์ ์์ต๋๋ค.
Claude for Desktop์์ ๋ค์๊ณผ ๊ฐ์ด ๋ฉ์์ง๋ฅผ ์ ๋ ฅํ์ฌ ์ผ์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค:
๋ด์ผ ์คํ 3์๋ถํฐ 4์๊น์ง ํ ๋ฏธํ
์ผ์ ์ ์ถ๊ฐํด์ค
Claude๋ ์๋์ผ๋ก MCP ์๋ฒ๋ฅผ ํตํด Google Calendar์ ์ผ์ ์ ์ถ๊ฐํฉ๋๋ค.
์ด ๊ฐ์ด๋๊ฐ MCP๋ฅผ ํตํด Claude๋ฅผ Google Calendar์ ์ฐ๊ฒฐํ๋ ๋ฐ ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด ์์ ๋ฌธ์ ํด๊ฒฐ ์น์ ์ ์ฐธ์กฐํ์ธ์.

