Google Chat Webhook MCP Server
An MCP (Model Context Protocol) server that sends messages to Google Chat via webhooks. Automatically converts Markdown to Google Chat Cards V2 format with image validation, structured logging, and fallback handling.
Features
- 🚀 MCP Protocol Support: Integrates with Claude Code, GitHub Copilot, and other MCP clients
- � MCP Protocol Support: Integrates with Claude Code, GitHub Copilot, and other MCP clients
- �📝 Markdown → Cards V2 Auto-conversion: Supports headers, lists, code blocks, tables, images, and more
- 🖼️ Image URL Validation: Validates with HEAD requests (HTTP status, Content-Type, size)
- 🔄 Auto Fallback: Automatically falls back to text when Cards V2 fails
- 📊 Structured Logging: JSON format with 30-day retention
- ✅ Test Automation: Snapshot tests, integration tests, CI/CD pipeline
Installation
npm (Recommended)
npm install -g google-chat-webhook-mcp
From Source (Development)
git clone https://github.com/ice3x2/google-chat-webhook-mcp.git
cd google-chat-webhook-mcp
npm install
npm run build
Google Chat Webhook Setup
Before configuring the MCP server, create a Google Chat Webhook URL:
- Open your Google Chat space
- Menu → "Apps & integrations" → "Manage webhooks"
- Click "Add webhook"
- Enter a name and copy the URL
- Use it in the configuration below
MCP Client Configuration
1. Claude Code
Config File Location
- Windows:
%USERPROFILE%\.claude.json - macOS/Linux:
~/.claude.json
Note: Claude Desktop uses different paths:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
npm Installation
{
"mcpServers": {
"google-chat": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
}
}
}
}
Source Installation
{
"mcpServers": {
"google-chat": {
"command": "node",
"args": ["C:\\path\\to\\google-chat-webhook-mcp\\dist\\index.js"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
}
}
}
}
⚠️ Note: Use \\ or / for Windows paths (e.g., C:/path/to/...)
Configuration Scopes
Claude Code supports three configuration scopes:
- User Scope (Global):
~/.claude.json- Available across all projects - Project Scope (Shared):
.mcp.jsonin project root - Version-controlled, team-shared - Local Scope (Private): Project-specific, personal settings
Priority: Local > Project > User
Project-Scoped Configuration (.mcp.json)
For team-shared MCP servers, create .mcp.json in your project root:
{
"mcpServers": {
"google-chat": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "${GOOGLE_CHAT_WEBHOOK_URL}"
}
}
}
}
Benefits:
- ✅ Version-controlled with Git
- ✅ Team-shared configuration
- ✅ Environment variable support:
${VAR}or${VAR:-default} - ✅ Project-specific MCP servers
Environment Variables: Each team member can set their own webhook URL:
# Linux/macOS
export GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
# Windows (PowerShell)
$env:GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
How to Apply
User-scoped configuration (~/.claude.json):
- Edit
~/.claude.json(or%USERPROFILE%\.claude.jsonon Windows) - Save the file
- Restart Claude Code if already running
Project-scoped configuration (.mcp.json):
- Create
.mcp.jsonin project root - Set environment variables for sensitive data
- Commit
.mcp.jsonto version control - Use commands like "Send a message to Google Chat"
2. GitHub Copilot (VS Code)
VS Code GitHub Copilot supports MCP through agent mode. Configure MCP servers in workspace or user settings.
Configuration File Locations
Choose one of the following:
- User Settings:
~/.vscode/settings.jsonor%APPDATA%\Code\User\settings.json(Windows) - Workspace Settings:
.vscode/settings.jsonin your project root - Claude Code Config (Auto-import): Copy from
~/.claude.json
Configuration (mcp.json format)
Add to settings.json:
{
"github.copilot.chat.mcp.servers": {
"google-chat": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
}
}
}
}
Features
- Agent Mode Integration: MCP tools available in agent workflow
- Per-Session Tool Selection: Choose which tools to enable per session
- STDIO & SSE Support: Both transport types supported
- Debugging: Restart commands and output logging built-in
Using with Agent Mode
- Open GitHub Copilot Chat in VS Code
- Enable agent mode (if not already enabled)
- Start a conversation - Copilot will automatically access MCP tools
- Tools require approval before execution
Example:
@workspace Send a deployment summary to Google Chat
📝 Note: GitHub Copilot's MCP support includes agent mode, allowing sophisticated workflows. Make sure you're using the latest VS Code and GitHub Copilot extension.
3. Other MCP Clients
Works with any MCP-compatible client:
{
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "your-webhook-url"
}
}
Usage
MCP Tools (3 Tools)
Available tools in Claude Code or other MCP clients:
1. send_google_chat_text
Send simple text messages
Example (Claude Code):
Send "Hello from Claude!" to Google Chat
Parameters:
{
"text": "Hello, Google Chat!"
}
2. send_google_chat_cards_v2
Send Cards V2 format directly (advanced users)
Parameters:
{
"text": "Card Message",
"cardsV2": [
{
"cardId": "unique-card",
"card": {
"header": { "title": "Card Title" },
"sections": [
{
"widgets": [
{ "textParagraph": { "text": "Card content" } }
]
}
]
}
}
]
}
3. send_google_chat_markdown ⭐ Recommended
Convert Markdown to Cards V2 and send
Example (Claude Code):
Send this markdown to Google Chat:
# Project Update
- Task 1: ✅ Completed
- Task 2: 🚧 In Progress
**Deadline**: Tomorrow
Parameters:
{
"markdown": "# Title\n\n**Bold** and *italic*\n\n- List item 1\n- List item 2\n\n```python\nprint('Hello')\n```",
"cardTitle": "Markdown Message",
"fallbackToText": true
}
Options:
cardTitle: Title shown at the top of the card (optional)fallbackToText: Auto-send as text on conversion failure (default: false)
Claude Code Usage Example
After setup, Claude will automatically use MCP tools when you chat naturally:
👤 User:
"Send a project status update to Google Chat. Show 3 completed tasks and 2 in-progress tasks as a markdown list."
🤖 Claude:
(Automatically calls
send_google_chat_markdowntool)I've sent the message to Google Chat. The project status has been updated.
Supported Markdown Syntax
Markdown written in Claude or MCP clients is automatically converted to Google Chat Cards V2.
| Syntax | Markdown Example | Google Chat Rendering |
|---|---|---|
| Headers | # H1, ## H2, ### H3 | Bold with size differences |
| Bold | **bold** or __bold__ | bold |
| Italic | *italic* or _italic_ | italic |
| Inline Code | `code` | code (monospace) |
| Code Block | ```python\ncode\n``` | Syntax-highlighted box |
| Ordered List | 1. First\n2. Second | 1. First 2. Second |
| Unordered List | - Item or * Item | • Item |
| Nested List | - nested (2-space indent) | • nested (Em space) |
| Table | | A | B |\n|--|--| | Monospace table |
| Image |  | Image widget (after validation) |
| Link | [text](https://...) | Clickable link |
| Horizontal Rule | --- or *** | Divider |
| Blockquote | > quote | Indented + gray text |
Example Markdown:
# Project Deployment Complete 🚀
## Key Changes
- **Performance**: API response 30% faster
- **Bug Fix**: Login error resolved
- New feature added
## Deployment Status
| Environment | Status | Version |
|-------------|--------|---------|
| Production | ✅ | v2.1.0 |
| Staging | ✅ | v2.1.0 |
## Next Steps
1. Monitor for 24 hours
2. Collect user feedback
3. Plan next sprint
Code example:
```python
def deploy():
print("Deploying v2.1.0...")
return True
See documentation for details.
**Result:** Headers, lists, tables, and code blocks are all visually distinguished in Google Chat.
## Environment Variables
### Required
| Variable | Description | Example |
|----------|-------------|---------|
| `GOOGLE_CHAT_WEBHOOK_URL` | Google Chat Webhook URL | `https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx` |
### Optional (Logging)
| Variable | Description | Default | Values |
|----------|-------------|---------|--------|
| `LOG_LEVEL` | Log level | `INFO` | `DEBUG`, `INFO`, `WARN`, `ERROR` |
| `LOG_DIR` | Log directory path | `./logs` | Absolute/relative path |
| `LOG_RETENTION_DAYS` | Days to keep logs | `30` | Number (days) |
| `LOG_ENABLE_CONSOLE` | Enable console output | `true` | `true`, `false` |
### Configuration Methods
#### Claude Code (~/.claude.json)
```json
{
"mcpServers": {
"google-chat": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx",
"LOG_LEVEL": "INFO",
"LOG_RETENTION_DAYS": "30"
}
}
}
}
.env File (Development)
Create .env in project root:
GOOGLE_CHAT_WEBHOOK_URL=https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx
LOG_LEVEL=INFO
LOG_DIR=./logs
LOG_RETENTION_DAYS=30
LOG_ENABLE_CONSOLE=true
Limitations
Google Chat API Constraints
| Item | Limit | Workaround |
|---|---|---|
| Image Protocol | HTTPS only | HTTP URLs replaced with text links |
| Image Size | Max 5MB | Show as link on validation failure |
| Image Auth | Public URLs only | No access if auth required |
| Content-Type | image/* only | HTML pages rejected |
| Markdown Support | Limited | Unsupported syntax approximated |
Markdown Conversion Limitations
✅ Fully Supported:
- Headers (H1~H6)
- Bold, italic, inline code
- Ordered/unordered lists (up to 3 levels)
- Code blocks (syntax highlighting)
- Tables (monospace)
- Links, images
⚠️ Partial Support:
- Complex nesting → Simplified
- HTML tags → Converted to text
- Blockquotes → Shown as indents
❌ Not Supported:
- Footnotes
- Definition lists
- Math formulas (LaTeX)
- Task checkboxes (
- [ ],- [x]) - Emoji shortcodes (
:smile:, Unicode emojis work)
FAQ
Q: Images not displaying
A: Image validation failure causes:
- HTTPS only (HTTP not supported)
- File size: Must be under 5MB
- Public access: Must be accessible without auth
- Content-Type: Response header must be
image/*
Debug:
cat logs/app-YYYY-MM-DD.log | grep "image_validation_failed"
Q: Cards V2 conversion fails
A: Use fallbackToText option:
{
"markdown": "...",
"fallbackToText": true
}
Check logs for details:
cat logs/errors-YYYY-MM-DD.log
Q: Too many log files
A: Adjust with environment variables:
{
"env": {
"LOG_LEVEL": "WARN",
"LOG_RETENTION_DAYS": "7"
}
}
Q: Multiple Google Chat spaces
A: Register separate MCP server instances:
{
"mcpServers": {
"google-chat-team-a": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/.../team-a/..."
}
},
"google-chat-team-b": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/.../team-b/..."
}
}
}
}
License
MIT License - LICENSE
Links
Korean:
MCP (Model Context Protocol) 서버로 Google Chat 웹훅을 통해 메시지를 전송합니다. Markdown을 Google Chat Cards V2 형식으로 자동 변환하며, 이미지 검증, 자동 로깅, 폴백 처리를 지원합니다.
주요 기능
- 🚀 MCP 프로토콜 지원: Claude Code, GitHub Copilot 등과 통합
- 📝 Markdown → Cards V2 자동 변환: 헤더, 리스트, 코드블록, 표, 이미지 등 지원
- 🖼️ 이미지 URL 검증: HEAD 요청으로 유효성 확인 (HTTP 상태, Content-Type, 크기)
- 🔄 자동 폴백: Cards V2 실패 시 텍스트로 자동 전환
- 📊 구조화된 로깅: JSON 형식, 30일 자동 보관
- ✅ 테스트 자동화: 스냅샷 테스트, 통합 테스트, CI/CD 파이프라인
설치
npm 설치 (권장)
npm install -g google-chat-webhook-mcp
소스 설치 (개발용)
git clone https://github.com/ice3x2/google-chat-webhook-mcp.git
cd google-chat-webhook-mcp
npm install
npm run build
Google Chat Webhook URL 생성
MCP 서버 설정 전에 먼저 Google Chat Webhook URL을 생성해야 합니다:
- Google Chat 스페이스 열기
- 상단 메뉴 → "앱 및 통합" → "Webhook 관리"
- "Webhook 추가" 클릭
- 이름 입력 후 URL 복사
- 아래 설정에서 사용
MCP 클라이언트 설정
1. Claude Code
설정 파일 위치
- Windows:
%USERPROFILE%\.claude.json - macOS/Linux:
~/.claude.json
참고: Claude Desktop은 다른 경로를 사용합니다:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
npm 설치 시
{
"mcpServers": {
"google-chat": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
}
}
}
}
소스 설치 시
{
"mcpServers": {
"google-chat": {
"command": "node",
"args": ["C:\\path\\to\\google-chat-webhook-mcp\\dist\\index.js"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
}
}
}
}
⚠️ 주의: Windows 경로는 \\ 또는 / 사용 (예: C:/path/to/...)
설정 스코프
Claude Code는 3가지 설정 스코프를 지원합니다:
- User Scope (전역):
~/.claude.json- 모든 프로젝트에서 사용 가능 - Project Scope (공유): 프로젝트 루트의
.mcp.json- 버전 관리, 팀 공유 가능 - Local Scope (개인): 프로젝트별 개인 설정
우선순위: Local > Project > User
프로젝트 수준 설정 (.mcp.json)
팀과 공유할 MCP 서버 설정은 프로젝트 루트에 .mcp.json 파일을 생성하세요:
{
"mcpServers": {
"google-chat": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "${GOOGLE_CHAT_WEBHOOK_URL}"
}
}
}
}
장점:
- ✅ Git으로 버전 관리 가능
- ✅ 팀과 설정 공유
- ✅ 환경 변수 지원:
${VAR}또는${VAR:-기본값} - ✅ 프로젝트별 MCP 서버 설정
환경 변수 설정: 각 팀원이 자신의 Webhook URL을 설정할 수 있습니다:
# Linux/macOS
export GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
# Windows (PowerShell)
$env:GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
적용 방법
User 수준 설정 (~/.claude.json):
~/.claude.json편집 (Windows는%USERPROFILE%\.claude.json)- 파일 저장
- Claude Code가 실행 중이면 재시작
Project 수준 설정 (.mcp.json):
- 프로젝트 루트에
.mcp.json생성 - 민감한 데이터는 환경 변수로 설정
.mcp.json을 버전 관리 시스템에 커밋- "Send a message to Google Chat" 같은 명령 사용
2. GitHub Copilot (VS Code)
VS Code GitHub Copilot은 에이전트 모드를 통해 MCP를 지원합니다. 워크스페이스 또는 사용자 설정에서 MCP 서버를 구성할 수 있습니다.
설정 파일 위치
다음 중 하나를 선택:
- 사용자 설정:
~/.vscode/settings.json또는%APPDATA%\Code\User\settings.json(Windows) - 워크스페이스 설정: 프로젝트 루트의
.vscode/settings.json - Claude Code 설정 (자동 가져오기):
~/.claude.json에서 복사
설정 방법 (mcp.json 형식)
settings.json에 추가:
{
"github.copilot.chat.mcp.servers": {
"google-chat": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
}
}
}
}
기능
- 에이전트 모드 통합: 에이전트 워크플로우에서 MCP 도구 사용 가능
- 세션별 도구 선택: 세션마다 활성화할 도구 선택 가능
- STDIO & SSE 지원: 두 전송 방식 모두 지원
- 디버깅: 재시작 명령 및 출력 로깅 내장
에이전트 모드에서 사용하기
- VS Code에서 GitHub Copilot 채팅 열기
- 에이전트 모드 활성화 (기본 활성화된 경우도 있음)
- 대화 시작 - Copilot이 자동으로 MCP 도구에 접근
- 도구 실행 전 승인 필요
예시:
@workspace 배포 요약을 Google Chat에 전송해줘
📝 참고: GitHub Copilot의 MCP 지원은 에이전트 모드를 포함하여 정교한 워크플로우를 지원합니다. 최신 버전의 VS Code와 GitHub Copilot 확장을 사용하세요.
3. 기타 MCP 클라이언트
MCP 프로토콜을 지원하는 모든 클라이언트에서 사용 가능합니다:
{
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "your-webhook-url"
}
}
1. Google Chat 스페이스 열기
2. 상단 메뉴 → "앱 및 통합" → "Webhook 관리"
3. "Webhook 추가" 클릭
4. 이름 입력 후 URL 복사
5. 환경 변수에 설정
## 사용법
### MCP 도구 (3가지)
Claude Code이나 다른 MCP 클라이언트에서 다음 도구들을 사용할 수 있습니다:
#### 1. `send_google_chat_text`
간단한 텍스트 메시지 전송
**예시 (Claude Code):**
Send "Hello from Claude!" to Google Chat
**파라미터:**
```json
{
"text": "안녕하세요, Google Chat!"
}
2. send_google_chat_cards_v2
Cards V2 형식으로 직접 전송 (고급 사용자용)
파라미터:
{
"text": "Card Message",
"cardsV2": [
{
"cardId": "unique-card",
"card": {
"header": { "title": "Card Title" },
"sections": [
{
"widgets": [
{ "textParagraph": { "text": "Card content" } }
]
}
]
}
}
]
}
3. send_google_chat_markdown ⭐ 추천
Markdown을 Cards V2로 자동 변환하여 전송
예시 (Claude Code):
Send this markdown to Google Chat:
# Project Update
- Task 1: ✅ Completed
- Task 2: 🚧 In Progress
**Deadline**: Tomorrow
파라미터:
{
"markdown": "# 제목\n\n**굵은 글씨**와 *기울임*\n\n- 리스트 항목 1\n- 리스트 항목 2\n\n```python\nprint('Hello')\n```",
"cardTitle": "마크다운 메시지",
"fallbackToText": true
}
옵션:
cardTitle: 카드 상단에 표시될 제목 (선택)fallbackToText: 변환 실패 시 텍스트로 자동 전송 (기본값: false)
Claude Code 사용 예시
설정 완료 후 Claude와 자연어로 대화하면 자동으로 MCP 도구를 사용합니다:
👤 사용자:
"Google Chat에 프로젝트 상태 업데이트를 보내줘. 완료된 작업 3개, 진행 중인 작업 2개를 마크다운 리스트로 작성해서."
🤖 Claude:
(자동으로
send_google_chat_markdown도구 호출)Google Chat에 메시지를 전송했습니다. 프로젝트 상태가 업데이트되었습니다.
👤 사용자:
"방금 보낸 메시지에 코드 예제도 추가해줘."
🤖 Claude:
(다시 Markdown으로 메시지 생성 및 전송)
지원하는 Markdown 문법
Claude나 MCP 클라이언트에서 Markdown으로 메시지를 작성하면 자동으로 Google Chat Cards V2로 변환됩니다.
| 문법 | Markdown 예시 | Google Chat 렌더링 |
|---|---|---|
| 헤더 | # H1, ## H2, ### H3 | 굵은 글씨 + 크기 차등 |
| 굵게 | **bold** 또는 __bold__ | bold |
| 기울임 | *italic* 또는 _italic_ | italic |
| 인라인 코드 | `code` | code (고정폭 폰트) |
| 코드블록 | ```python\ncode\n``` | 구문 강조 박스 |
| 순서 리스트 | 1. First\n2. Second | 1. First 2. Second |
| 비순서 리스트 | - Item 또는 * Item | • Item |
| 중첩 리스트 | - nested (2칸 들여쓰기) | • nested (Em space) |
| 표 | | A | B |\n|--|--| | 고정폭 폰트 표 |
| 이미지 |  | 이미지 위젯 (URL 검증 후) |
| 링크 | [텍스트](https://...) | 클릭 가능한 링크 |
| 수평선 | --- 또는 *** | 구분선 |
| 인용문 | > quote | 들여쓰기 + 회색 텍스트 |
예시 Markdown:
# 프로젝트 배포 완료 🚀
## 주요 변경사항
- **성능 개선**: API 응답 속도 30% 향상
- **버그 수정**: 로그인 오류 해결
- 새 기능 추가
## 배포 상태
| 환경 | 상태 | 버전 |
|------|------|------|
| Production | ✅ | v2.1.0 |
| Staging | ✅ | v2.1.0 |
## 다음 단계
1. 모니터링 24시간
2. 사용자 피드백 수집
3. 다음 스프린트 계획
코드 예제:
```python
def deploy():
print("Deploying v2.1.0...")
return True
자세한 내용은 문서를 참조하세요.
**변환 결과:** Google Chat에서 헤더, 리스트, 표, 코드블록이 모두 시각적으로 구분되어 표시됩니다.
## 환경 변수
### 필수 환경 변수
| 변수명 | 설명 | 예시 |
|--------|------|------|
| `GOOGLE_CHAT_WEBHOOK_URL` | Google Chat Webhook URL | `https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx` |
### 선택 환경 변수 (로깅)
| 변수명 | 설명 | 기본값 | 허용값 |
|--------|------|--------|--------|
| `LOG_LEVEL` | 로그 레벨 | `INFO` | `DEBUG`, `INFO`, `WARN`, `ERROR` |
| `LOG_DIR` | 로그 디렉토리 경로 | `./logs` | 절대/상대 경로 |
| `LOG_RETENTION_DAYS` | 로그 보관 일수 | `30` | 숫자 (일) |
| `LOG_ENABLE_CONSOLE` | 콘솔 출력 여부 | `true` | `true`, `false` |
### 설정 방법
#### Claude Code (~/.claude.json)
```json
{
"mcpServers": {
"google-chat": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx",
"LOG_LEVEL": "INFO",
"LOG_RETENTION_DAYS": "30"
}
}
}
}
.env 파일 (개발용)
프로젝트 루트에 .env 파일 생성:
GOOGLE_CHAT_WEBHOOK_URL=https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx
LOG_LEVEL=INFO
LOG_DIR=./logs
LOG_RETENTION_DAYS=30
LOG_ENABLE_CONSOLE=true
시스템 환경 변수
Windows (PowerShell):
$env:GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
Linux/macOS (Bash/Zsh):
export GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
개발
# 의존성 설치
npm install
# 빌드
npm run build
# 개발 모드 (TypeScript 직접 실행)
npm run dev
# Lint 검사
npm run lint
# Lint 자동 수정
npm run lint:fix
# 테스트
npm run test:snapshot # 스냅샷 테스트 (12개)
npm run test:logging # 로깅 시스템 테스트
npm run test:integration # 통합 테스트 (웹훅 필요)
npm test # 전체 테스트
아키텍처
src/
├── index.ts # 진입점
├── server.ts # MCP 서버 설정
├── tools/ # MCP 도구
│ ├── sendTextMessage.ts # 텍스트 전송
│ ├── sendCardsV2Message.ts # Cards V2 전송
│ ├── sendMarkdownMessage.ts # Markdown 전송 (메인)
│ └── markdownToCards.ts # Markdown → Cards V2 변환
├── utils/ # 유틸리티
│ ├── imageValidator.ts # 이미지 URL 검증
│ ├── cardsV2Validator.ts # Cards V2 스키마 검증
│ ├── logger.ts # 로깅 시스템
│ └── logCleaner.ts # 로그 정리
└── types/ # 타입 정의
├── markdown.ts
├── googleChat.ts
└── log.ts
로깅
로그 파일 구조
logs/
├── app-2025-10-29.log # 일별 로그 (모든 레벨)
├── errors-2025-10-29.log # 에러 전용 로그
└── ... # 30일 자동 삭제
로그 포맷 (JSON)
{
"timestamp": "2025-10-29T12:34:56.789Z",
"level": "INFO",
"module": "sendMarkdownMessage",
"event": "message_sent",
"messageId": "spaces/xxx/messages/yyy",
"elapsed": 123,
"usedFallback": false,
"cardTitle": "Test Card"
}
로그 이벤트
message_sent: 메시지 전송 성공fallback_used: 폴백 사용 (Cards V2 → Text)image_validation_failed: 이미지 검증 실패send_failed: 전송 실패validation_failed: 검증 실패
로그 정리
- 서버 시작 시 자동 정리 (30일 이상 로그 삭제)
- 24시간마다 자동 실행
- 환경 변수
LOG_RETENTION_DAYS로 설정 가능
제한사항
Google Chat API 제약사항
| 항목 | 제한 | 대응 방법 |
|---|---|---|
| 이미지 프로토콜 | HTTPS만 지원 | HTTP URL은 텍스트 링크로 대체 |
| 이미지 크기 | 최대 5MB | 검증 실패 시 링크로 표시 |
| 이미지 인증 | 공개 URL만 가능 | 인증 필요 시 접근 불가 |
| Content-Type | image/*만 허용 | HTML 페이지 등은 거부 |
| Markdown 지원 | 제한적 | 미지원 문법은 근사치로 변환 |
Markdown 변환 제약사항
✅ 완전 지원:
- 헤더 (H1~H6)
- 굵게, 기울임, 인라인 코드
- 순서/비순서 리스트 (최대 3단계 중첩)
- 코드블록 (구문 강조)
- 표 (고정폭 폰트)
- 링크, 이미지
⚠️ 부분 지원:
- 복잡한 중첩 구조 → 단순화됨
- HTML 태그 → 텍스트로 변환
- 인용문 → 들여쓰기로 표현
❌ 미지원:
- 각주 (footnotes)
- 정의 리스트 (definition lists)
- 수학 수식 (LaTeX)
- 작업 체크박스 (
- [ ],- [x]) - Emoji 단축코드 (
:smile:등, 유니코드 이모지는 가능)
성능 및 제한
- 이미지 검증 타임아웃: 5초
- Webhook 요청 타임아웃: 5초
- 로그 파일 크기: 무제한 (30일 자동 삭제)
- 동시 요청: 제한 없음 (Google Chat API 제한 준수)
보안 고려사항
⚠️ Webhook URL은 민감 정보입니다:
- Git에 커밋하지 마세요
- 공개 저장소에 노출 금지
- 정기적으로 재생성 권장
.env파일은.gitignore에 포함 필수
FAQ
Q: 이미지가 표시되지 않습니다
A: 이미지 URL 검증 실패 원인:
- HTTPS만 지원 (HTTP는 불가)
- 파일 크기: 5MB 이하여야 함
- 공개 접근: 인증 없이 접근 가능한 URL이어야 함
- Content-Type: 응답 헤더가
image/*여야 함
디버깅:
# 로그 확인
cat logs/app-YYYY-MM-DD.log | grep "image_validation_failed"
검증 실패 시 동작:
- 이미지는 텍스트 링크로 대체됨
- 예:
⚠️ 이미지 로드 실패: https://... (HTTP 404: Not Found)
Q: Cards V2 변환이 실패합니다
A: 다음을 확인하세요:
-
fallbackToText 옵션 사용:
{ "markdown": "...", "fallbackToText": true }변환 실패 시 자동으로 텍스트로 전송됩니다.
-
로그에서 원인 확인:
cat logs/errors-YYYY-MM-DD.log -
지원하지 않는 Markdown 문법:
- 각주 (footnotes)
- 정의 리스트 (definition lists)
- 복잡한 HTML 태그
Q: 로그 파일이 너무 많이 쌓입니다
A: 환경 변수로 조정:
{
"env": {
"LOG_LEVEL": "WARN",
"LOG_RETENTION_DAYS": "7"
}
}
LOG_LEVEL=ERROR: 에러만 기록LOG_RETENTION_DAYS=7: 7일만 보관LOG_ENABLE_CONSOLE=false: 콘솔 출력 비활성화
Q: npx 실행 시 "command not found" 오류
A: Node.js와 npm이 설치되어 있는지 확인:
node --version # v18.0.0 이상 권장
npm --version
설치되지 않았다면:
- Windows: https://nodejs.org/ 에서 다운로드
- macOS:
brew install node - Linux:
sudo apt install nodejs npm(Ubuntu/Debian)
Q: Webhook URL을 어떻게 안전하게 관리하나요?
A:
- 환경 변수 사용 (설정 파일에 직접 쓰지 마세요)
- Git에 커밋하지 마세요 (.gitignore 확인)
- 정기적으로 재생성 (유출 의심 시)
- Google Chat에서 Webhook 삭제로 무효화 가능
Q: 여러 Google Chat 스페이스에 메시지를 보내고 싶습니다
A: 각 스페이스마다 다른 MCP 서버 인스턴스 등록:
{
"mcpServers": {
"google-chat-team-a": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/.../team-a/..."
}
},
"google-chat-team-b": {
"command": "npx",
"args": ["-y", "google-chat-webhook-mcp"],
"env": {
"GOOGLE_CHAT_WEBHOOK_URL": "https://chat.googleapis.com/.../team-b/..."
}
}
}
}
Claude에서 "Send to team-a" 또는 "Send to team-b"로 구분하여 사용할 수 있습니다.
CI/CD
GitHub Actions로 자동화:
- ✅ Node.js 18.x, 20.x 매트릭스 빌드
- ✅ ESLint, 빌드, 테스트
- ✅ 스냅샷 테스트 (12개)
- ✅ 통합 테스트 (master 브랜치)
워크플로우: .github/workflows/ci.yml
기여
이슈와 PR을 환영합니다!
라이선스
MIT License - LICENSE
