Skip to main content
Glama
ice3x2

Google Chat Webhook MCP Server

by ice3x2
README.md

---
# Google Chat Webhook MCP Server

[![CI](https://github.com/ice3x2/google-chat-webhook-mcp/workflows/CI/badge.svg)](https://github.com/ice3x2/google-chat-webhook-mcp/actions)
[![npm version](https://img.shields.io/npm/v/google-chat-webhook-mcp.svg)](https://www.npmjs.com/package/google-chat-webhook-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

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)

```bash
npm install -g google-chat-webhook-mcp
```

### From Source (Development)

```bash
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:

1. Open your Google Chat space
2. Menu β†’ "Apps & integrations" β†’ "Manage webhooks"
3. Click "Add webhook"
4. Enter a name and **copy the URL**
5. 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

```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"
      }
    }
  }
}
```

#### Source Installation

```json
{
  "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:

1. **User Scope** (Global): `~/.claude.json` - Available across all projects
2. **Project Scope** (Shared): `.mcp.json` in project root - Version-controlled, team-shared
3. **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:

```json
{
  "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:
```bash
# 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):
1. Edit `~/.claude.json` (or `%USERPROFILE%\.claude.json` on Windows)
2. Save the file
3. Restart Claude Code if already running

**Project-scoped configuration** (.mcp.json):
1. Create `.mcp.json` in project root
2. Set environment variables for sensitive data
3. Commit `.mcp.json` to version control
4. Use commands like "Send a message to Google Chat"

### 2. GitHub Copilot (VS Code)

[VS Code GitHub Copilot](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode) 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.json` or `%APPDATA%\Code\User\settings.json` (Windows)
- **Workspace Settings**: `.vscode/settings.json` in your project root
 - **Claude Code Config** (Auto-import): Copy from `~/.claude.json`

#### Configuration (mcp.json format)

Add to `settings.json`:

```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

1. Open GitHub Copilot Chat in VS Code
2. Enable agent mode (if not already enabled)
3. Start a conversation - Copilot will automatically access MCP tools
4. 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:

```json
{
  "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:**
```json
{
  "text": "Hello, Google Chat!"
}
```

#### 2. `send_google_chat_cards_v2`
Send Cards V2 format directly (advanced users)

**Parameters:**
```json
{
  "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:**
```json
{
  "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_markdown` tool)
> 
> 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<br>2. Second |
| **Unordered List** | `- Item` or `* Item` | β€’ Item |
| **Nested List** | `  - nested` (2-space indent) | γ€€β€’ nested (Em space) |
| **Table** | `\| A \| B \|\n\|--\|--\|` | Monospace table |
| **Image** | `![alt](https://...)` | Image widget (after validation) |
| **Link** | `[text](https://...)` | Clickable link |
| **Horizontal Rule** | `---` or `***` | Divider |
| **Blockquote** | `> quote` | Indented + gray text |

**Example Markdown:**
```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](https://docs.example.com) 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:

```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
```

## 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:

1. **HTTPS only** (HTTP not supported)
2. **File size**: Must be under 5MB
3. **Public access**: Must be accessible without auth
4. **Content-Type**: Response header must be `image/*`

**Debug:**
```bash
cat logs/app-YYYY-MM-DD.log | grep "image_validation_failed"
```

### Q: Cards V2 conversion fails
**A**: Use `fallbackToText` option:

```json
{
  "markdown": "...",
  "fallbackToText": true
}
```

Check logs for details:
```bash
cat logs/errors-YYYY-MM-DD.log
```

### Q: Too many log files
**A**: Adjust with environment variables:

```json
{
  "env": {
    "LOG_LEVEL": "WARN",
    "LOG_RETENTION_DAYS": "7"
  }
}
```

### Q: Multiple Google Chat spaces
**A**: Register separate MCP server instances:

```json
{
  "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](LICENSE)

## Links

- [Model Context Protocol](https://github.com/modelcontextprotocol)
- [Claude Code](https://claude.ai/desktop)
- [Google Chat API](https://developers.google.com/chat)

---
Korean:

[![CI](https://github.com/ice3x2/google-chat-webhook-mcp/workflows/CI/badge.svg)](https://github.com/ice3x2/google-chat-webhook-mcp/actions)
[![npm version](https://img.shields.io/npm/v/google-chat-webhook-mcp.svg)](https://www.npmjs.com/package/google-chat-webhook-mcp)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

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 μ„€μΉ˜ (ꢌμž₯)

```bash
npm install -g google-chat-webhook-mcp
```

### μ†ŒμŠ€ μ„€μΉ˜ (개발용)

```bash
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을 생성해야 ν•©λ‹ˆλ‹€:

1. Google Chat 슀페이슀 μ—΄κΈ°
2. 상단 메뉴 β†’ "μ•± 및 톡합" β†’ "Webhook 관리"
3. "Webhook μΆ”κ°€" 클릭
4. 이름 μž…λ ₯ ν›„ **URL 볡사**
5. μ•„λž˜ μ„€μ •μ—μ„œ μ‚¬μš©

## 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 μ„€μΉ˜ μ‹œ

```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"
      }
    }
  }
}
```

#### μ†ŒμŠ€ μ„€μΉ˜ μ‹œ

```json
{
  "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κ°€μ§€ μ„€μ • μŠ€μ½”ν”„λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€:

1. **User Scope** (μ „μ—­): `~/.claude.json` - λͺ¨λ“  ν”„λ‘œμ νŠΈμ—μ„œ μ‚¬μš© κ°€λŠ₯
2. **Project Scope** (곡유): ν”„λ‘œμ νŠΈ 루트의 `.mcp.json` - 버전 관리, νŒ€ 곡유 κ°€λŠ₯
3. **Local Scope** (개인): ν”„λ‘œμ νŠΈλ³„ 개인 μ„€μ •

**μš°μ„ μˆœμœ„**: Local > Project > User

#### ν”„λ‘œμ νŠΈ μˆ˜μ€€ μ„€μ • (.mcp.json)

νŒ€κ³Ό κ³΅μœ ν•  MCP μ„œλ²„ 섀정은 ν”„λ‘œμ νŠΈ λ£¨νŠΈμ— `.mcp.json` νŒŒμΌμ„ μƒμ„±ν•˜μ„Έμš”:

```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을 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€:
```bash
# 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):
1. `~/.claude.json` νŽΈμ§‘ (WindowsλŠ” `%USERPROFILE%\.claude.json`)
2. 파일 μ €μž₯
3. Claude Codeκ°€ μ‹€ν–‰ 쀑이면 μž¬μ‹œμž‘

**Project μˆ˜μ€€ μ„€μ •** (.mcp.json):
1. ν”„λ‘œμ νŠΈ λ£¨νŠΈμ— `.mcp.json` 생성
2. λ―Όκ°ν•œ λ°μ΄ν„°λŠ” ν™˜κ²½ λ³€μˆ˜λ‘œ μ„€μ •
3. `.mcp.json`을 버전 관리 μ‹œμŠ€ν…œμ— 컀밋
4. "Send a message to Google Chat" 같은 λͺ…λ Ή μ‚¬μš©

### 2. GitHub Copilot (VS Code)

[VS Code GitHub Copilot](https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode)은 **μ—μ΄μ „νŠΈ λͺ¨λ“œ**λ₯Ό 톡해 MCPλ₯Ό μ§€μ›ν•©λ‹ˆλ‹€. μ›Œν¬μŠ€νŽ˜μ΄μŠ€ λ˜λŠ” μ‚¬μš©μž μ„€μ •μ—μ„œ MCP μ„œλ²„λ₯Ό ꡬ성할 수 μžˆμŠ΅λ‹ˆλ‹€.

#### μ„€μ • 파일 μœ„μΉ˜

λ‹€μŒ 쀑 ν•˜λ‚˜λ₯Ό 선택:

- **μ‚¬μš©μž μ„€μ •**: `~/.vscode/settings.json` λ˜λŠ” `%APPDATA%\Code\User\settings.json` (Windows)
- **μ›Œν¬μŠ€νŽ˜μ΄μŠ€ μ„€μ •**: ν”„λ‘œμ νŠΈ 루트의 `.vscode/settings.json`
- **Claude Code μ„€μ •** (μžλ™ κ°€μ Έμ˜€κΈ°): `~/.claude.json`μ—μ„œ 볡사

#### μ„€μ • 방법 (mcp.json ν˜•μ‹)

`settings.json`에 μΆ”κ°€:

```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 지원**: 두 전솑 방식 λͺ¨λ‘ 지원
- **디버깅**: μž¬μ‹œμž‘ λͺ…λ Ή 및 좜λ ₯ λ‘œκΉ… λ‚΄μž₯

#### μ—μ΄μ „νŠΈ λͺ¨λ“œμ—μ„œ μ‚¬μš©ν•˜κΈ°

1. VS Codeμ—μ„œ GitHub Copilot μ±„νŒ… μ—΄κΈ°
2. μ—μ΄μ „νŠΈ λͺ¨λ“œ ν™œμ„±ν™” (κΈ°λ³Έ ν™œμ„±ν™”λœ κ²½μš°λ„ 있음)
3. λŒ€ν™” μ‹œμž‘ - Copilot이 μžλ™μœΌλ‘œ MCP 도ꡬ에 μ ‘κ·Ό
4. 도ꡬ μ‹€ν–‰ μ „ 승인 ν•„μš”

**μ˜ˆμ‹œ:**
```
@workspace 배포 μš”μ•½μ„ Google Chat에 μ „μ†‘ν•΄μ€˜
```

**πŸ“ μ°Έκ³ **: GitHub Copilot의 MCP 지원은 μ—μ΄μ „νŠΈ λͺ¨λ“œλ₯Ό ν¬ν•¨ν•˜μ—¬ μ •κ΅ν•œ μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€. μ΅œμ‹  λ²„μ „μ˜ VS Code와 GitHub Copilot ν™•μž₯을 μ‚¬μš©ν•˜μ„Έμš”.

### 3. 기타 MCP ν΄λΌμ΄μ–ΈνŠΈ

MCP ν”„λ‘œν† μ½œμ„ μ§€μ›ν•˜λŠ” λͺ¨λ“  ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μ‚¬μš© κ°€λŠ₯ν•©λ‹ˆλ‹€:

```json
{
  "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 ν˜•μ‹μœΌλ‘œ 직접 전솑 (κ³ κΈ‰ μ‚¬μš©μžμš©)

**νŒŒλΌλ―Έν„°:**
```json
{
  "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
```

**νŒŒλΌλ―Έν„°:**
```json
{
  "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<br>2. Second |
| **λΉ„μˆœμ„œ 리슀트** | `- Item` λ˜λŠ” `* Item` | β€’ Item |
| **쀑첩 리슀트** | `  - nested` (2μΉΈ λ“€μ—¬μ“°κΈ°) | γ€€β€’ nested (Em space) |
| **ν‘œ** | `\| A \| B \|\n\|--\|--\|` | 고정폭 폰트 ν‘œ |
| **이미지** | `![alt](https://...)` | 이미지 μœ„μ ― (URL 검증 ν›„) |
| **링크** | `[ν…μŠ€νŠΈ](https://...)` | 클릭 κ°€λŠ₯ν•œ 링크 |
| **μˆ˜ν‰μ„ ** | `---` λ˜λŠ” `***` | ꡬ뢄선 |
| **인용문** | `> quote` | λ“€μ—¬μ“°κΈ° + νšŒμƒ‰ ν…μŠ€νŠΈ |

**μ˜ˆμ‹œ Markdown:**
```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
```

μžμ„Έν•œ λ‚΄μš©μ€ [λ¬Έμ„œ](https://docs.example.com)λ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.
```

**λ³€ν™˜ κ²°κ³Ό:** 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` 파일 생성:

```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):**
```powershell
$env:GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
```

**Linux/macOS (Bash/Zsh):**
```bash
export GOOGLE_CHAT_WEBHOOK_URL="https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx"
```

## 개발

```bash
# μ˜μ‘΄μ„± μ„€μΉ˜
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)

```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 검증 μ‹€νŒ¨ 원인:

1. **HTTPS만 지원** (HTTPλŠ” λΆˆκ°€)
2. **파일 크기**: 5MB μ΄ν•˜μ—¬μ•Ό 함
3. **곡개 μ ‘κ·Ό**: 인증 없이 μ ‘κ·Ό κ°€λŠ₯ν•œ URL이어야 함
4. **Content-Type**: 응닡 헀더가 `image/*`μ—¬μ•Ό 함

**디버깅:**
```bash
# 둜그 확인
cat logs/app-YYYY-MM-DD.log | grep "image_validation_failed"
```

**검증 μ‹€νŒ¨ μ‹œ λ™μž‘:**
- μ΄λ―Έμ§€λŠ” ν…μŠ€νŠΈ 링크둜 λŒ€μ²΄λ¨
- 예: `⚠️ 이미지 λ‘œλ“œ μ‹€νŒ¨: https://... (HTTP 404: Not Found)`

### Q: Cards V2 λ³€ν™˜μ΄ μ‹€νŒ¨ν•©λ‹ˆλ‹€
**A**: λ‹€μŒμ„ ν™•μΈν•˜μ„Έμš”:

1. **fallbackToText μ˜΅μ…˜ μ‚¬μš©**:
   ```json
   {
     "markdown": "...",
     "fallbackToText": true
   }
   ```
   λ³€ν™˜ μ‹€νŒ¨ μ‹œ μžλ™μœΌλ‘œ ν…μŠ€νŠΈλ‘œ μ „μ†‘λ©λ‹ˆλ‹€.

2. **λ‘œκ·Έμ—μ„œ 원인 확인**:
   ```bash
   cat logs/errors-YYYY-MM-DD.log
   ```

3. **μ§€μ›ν•˜μ§€ μ•ŠλŠ” Markdown 문법**:
   - 각주 (footnotes)
   - μ •μ˜ 리슀트 (definition lists)
   - λ³΅μž‘ν•œ HTML νƒœκ·Έ

### Q: 둜그 파일이 λ„ˆλ¬΄ 많이 μŒ“μž…λ‹ˆλ‹€
**A**: ν™˜κ²½ λ³€μˆ˜λ‘œ μ‘°μ •:

```json
{
  "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이 μ„€μΉ˜λ˜μ–΄ μžˆλŠ”μ§€ 확인:

```bash
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**: 

1. **ν™˜κ²½ λ³€μˆ˜ μ‚¬μš©** (μ„€μ • νŒŒμΌμ— 직접 μ“°μ§€ λ§ˆμ„Έμš”)
2. **Git에 μ»€λ°‹ν•˜μ§€ λ§ˆμ„Έμš”** (.gitignore 확인)
3. **μ •κΈ°μ μœΌλ‘œ μž¬μƒμ„±** (유좜 μ˜μ‹¬ μ‹œ)
4. **Google Chatμ—μ„œ Webhook μ‚­μ œ**둜 λ¬΄νš¨ν™” κ°€λŠ₯

### Q: μ—¬λŸ¬ Google Chat μŠ€νŽ˜μ΄μŠ€μ— λ©”μ‹œμ§€λ₯Ό 보내고 μ‹ΆμŠ΅λ‹ˆλ‹€
**A**: 각 μŠ€νŽ˜μ΄μŠ€λ§ˆλ‹€ λ‹€λ₯Έ MCP μ„œλ²„ μΈμŠ€ν„΄μŠ€ 등둝:

```json
{
  "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`](.github/workflows/ci.yml)

## κΈ°μ—¬

μ΄μŠˆμ™€ PR을 ν™˜μ˜ν•©λ‹ˆλ‹€!

## λΌμ΄μ„ μŠ€

MIT License - [LICENSE](LICENSE)

## λ¬Έμ„œ

- [λ‘œκΉ… 섀계](docs/logging-design.md)
- [CI μ„€μ • κ°€μ΄λ“œ](docs/ci-setup.md)
- [Markdown κ΅¬ν˜„ κ³„νš](docs/markdown-to-cards-implementation.md)

## κ΄€λ ¨ ν”„λ‘œμ νŠΈ

- [Model Context Protocol](https://github.com/modelcontextprotocol)
- [Claude Code](https://claude.ai/desktop)
- [Google Chat API](https://developers.google.com/chat)

TDQS

A3.6/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: send_google_chat_cards_v2 sends Cards V2 messages, send_google_chat_markdown converts Markdown to Cards V2 with fallback, and send_google_chat_text sends plain text messages. There is no ambiguity in their functions, as they target different message formats and conversion behaviors.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with 'send_google_chat_' as a prefix and specific suffixes (_cards_v2, _markdown, _text). This predictable naming scheme makes it easy to understand their roles and ensures no mixing of conventions.

Tool Count4/5

With 3 tools, the count is appropriate for the server's purpose of sending messages to Google Chat webhooks, covering key message types. It is slightly lean but reasonable, as it includes essential formats (Cards V2, Markdown, text) without unnecessary bloat.

Completeness5/5

The tool set provides complete coverage for sending messages via Google Chat webhooks, including Cards V2, Markdown conversion with fallback, and plain text. There are no obvious gaps, as these tools cover the primary message formats and conversion needs for this domain.

Maintenance

ActivityInactive
ResponsivenessNo issues