# Documento de Requisitos

## Introdução

Este documento define os requisitos para o `pack-mcp-google-chat-notification`, um MCP server dedicado a enviar notificações para o Google Chat via Webhooks. O servidor possui responsabilidade única: enviar mensagens (texto simples, cards e threads) para espaços do Google Chat. A orquestração com outros MCPs fica a cargo do agente/hook do Kiro.

O projeto segue os padrões de arquitetura do `pack-mcp-gitlab`: Python 3.10+, build com `hatchling`, transporte `stdio` via FastMCP, e publicação no PyPI.

## Glossário

- **MCP_Server**: O servidor MCP (`pack-mcp-google-chat-notification`) que expõe tools para envio de notificações ao Google Chat
- **Google_Chat_Client**: Módulo HTTP interno (`client.py`) responsável por realizar requisições POST aos webhooks do Google Chat usando `httpx`
- **Webhook_URL**: URL completa do webhook do Google Chat, no formato `https://chat.googleapis.com/v1/spaces/.../messages?key=...&token=...`
- **Card_V2**: Formato de mensagem rica do Google Chat, composto por título, subtítulo opcional e seções com widgets
- **Thread_Key**: Identificador de thread usado para agrupar mensagens em uma conversa (ex: `mr-123`, `deploy-prod-2024`)
- **Error_Handler**: Decorator centralizado (`handle_error`) que converte exceções em `McpError`
- **Sanitizador**: Função que remove tokens sensíveis das URLs de webhook antes de registrá-las em logs
- **Widget**: Componente visual dentro de uma seção de Card_V2 (ex: textParagraph, decoratedText, buttonList)
- **Seção**: Agrupamento de Widgets dentro de um Card_V2, com header opcional

## Requisitos

### Requisito 1: Envio de Mensagem de Texto Simples

**User Story:** Como um desenvolvedor, eu quero enviar mensagens de texto simples para um espaço do Google Chat, para que eu possa notificar equipes sobre eventos relevantes.

#### Critérios de Aceitação

1. WHEN a tool `send_message` é invocada com um parâmetro `text` válido e uma Webhook_URL válida, THE MCP_Server SHALL enviar uma requisição POST ao Google Chat com o body `{ "text": "<mensagem>" }` e retornar `{ "success": true }`
2. WHEN a tool `send_message` é invocada sem o parâmetro `webhook_url`, THE MCP_Server SHALL utilizar o valor da variável de ambiente `GOOGLE_CHAT_WEBHOOK_URL` como Webhook_URL
3. IF o parâmetro `text` for uma string vazia, THEN THE MCP_Server SHALL retornar um erro descritivo indicando que o texto da mensagem é obrigatório
4. IF nenhuma Webhook_URL for fornecida (nem por parâmetro, nem por variável de ambiente), THEN THE MCP_Server SHALL retornar um erro descritivo indicando que nenhum webhook foi configurado

### Requisito 2: Envio de Mensagem com Card V2

**User Story:** Como um desenvolvedor, eu quero enviar mensagens com formato rico (Card V2) para o Google Chat, para que eu possa apresentar informações estruturadas com títulos, seções e widgets.

#### Critérios de Aceitação

1. WHEN a tool `send_card` é invocada com `title` e `sections` válidos, THE MCP_Server SHALL enviar uma requisição POST ao Google Chat com o body no formato `{ "cardsV2": [{ "cardId": "...", "card": { ... } }] }` e retornar `{ "success": true }`
2. WHEN o parâmetro `subtitle` é fornecido, THE MCP_Server SHALL incluir o subtítulo no header do Card_V2
3. WHEN o parâmetro `subtitle` é omitido, THE MCP_Server SHALL gerar o Card_V2 sem subtítulo no header
4. IF o parâmetro `title` for uma string vazia, THEN THE MCP_Server SHALL retornar um erro descritivo indicando que o título é obrigatório
5. IF o parâmetro `sections` for uma lista vazia, THEN THE MCP_Server SHALL retornar um erro descritivo indicando que pelo menos uma seção é obrigatória

### Requisito 3: Envio de Mensagem em Thread

**User Story:** Como um desenvolvedor, eu quero enviar mensagens em threads existentes ou criar novas threads no Google Chat, para que eu possa agrupar notificações relacionadas em uma mesma conversa.

#### Critérios de Aceitação

1. WHEN a tool `send_thread_message` é invocada com `text` e `thread_key` válidos, THE MCP_Server SHALL enviar uma requisição POST à Webhook_URL com o query parameter `?threadKey=<thread_key>&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD` e retornar `{ "success": true, "thread_key": "<thread_key>" }`
2. IF o parâmetro `text` for uma string vazia, THEN THE MCP_Server SHALL retornar um erro descritivo indicando que o texto da mensagem é obrigatório
3. IF o parâmetro `thread_key` for uma string vazia, THEN THE MCP_Server SHALL retornar um erro descritivo indicando que a chave da thread é obrigatória

### Requisito 4: Validação de Webhook URL

**User Story:** Como um desenvolvedor, eu quero que as URLs de webhook sejam validadas antes do envio, para que eu receba feedback imediato sobre configurações incorretas.

#### Critérios de Aceitação

1. WHEN uma Webhook_URL é fornecida (por parâmetro ou variável de ambiente), THE MCP_Server SHALL validar que a URL começa com `https://chat.googleapis.com/` antes de realizar a requisição HTTP
2. IF a Webhook_URL fornecida não começar com `https://chat.googleapis.com/`, THEN THE MCP_Server SHALL retornar um erro descritivo indicando que a URL do webhook é inválida
3. THE MCP_Server SHALL realizar a validação da Webhook_URL antes de qualquer tentativa de envio HTTP


### Requisito 5: Comunicação HTTP com Google Chat

**User Story:** Como um desenvolvedor, eu quero que o MCP server se comunique de forma confiável com a API do Google Chat, para que as notificações sejam entregues corretamente.

#### Critérios de Aceitação

1. THE Google_Chat_Client SHALL enviar requisições POST com Content-Type `application/json` para a Webhook_URL
2. THE Google_Chat_Client SHALL utilizar `httpx` como biblioteca HTTP para realizar as requisições
3. THE Google_Chat_Client SHALL configurar um timeout padrão de 10 segundos para cada requisição
4. WHEN a API do Google Chat retorna HTTP status 200, THE Google_Chat_Client SHALL tratar a resposta como sucesso
5. IF a API do Google Chat retorna um HTTP status diferente de 200, THEN THE Google_Chat_Client SHALL retornar um erro descritivo contendo o status code e o body da resposta
6. IF ocorrer um timeout de conexão, THEN THE Google_Chat_Client SHALL retornar um erro descritivo indicando que a conexão expirou

### Requisito 6: Tratamento Centralizado de Erros

**User Story:** Como um desenvolvedor, eu quero que os erros sejam tratados de forma consistente e centralizada, para que todas as tools retornem mensagens de erro padronizadas.

#### Critérios de Aceitação

1. THE Error_Handler SHALL interceptar exceções lançadas pelas tools e convertê-las em `McpError` com mensagens descritivas
2. THE Error_Handler SHALL ser implementado como um decorator aplicável a todas as tools do MCP_Server
3. WHEN uma exceção não esperada ocorre durante a execução de uma tool, THE Error_Handler SHALL converter a exceção em um `McpError` com uma mensagem genérica de erro interno

### Requisito 7: Sanitização de URLs nos Logs

**User Story:** Como um desenvolvedor, eu quero que tokens sensíveis presentes nas URLs de webhook sejam removidos dos logs, para que credenciais não sejam expostas acidentalmente.

#### Critérios de Aceitação

1. WHEN uma Webhook_URL é registrada em log, THE Sanitizador SHALL remover os valores dos parâmetros `key` e `token` da URL antes do registro
2. THE Sanitizador SHALL substituir os valores sensíveis por `***` na URL sanitizada
3. THE MCP_Server SHALL utilizar o Sanitizador em todos os pontos onde Webhook_URLs são registradas em log

### Requisito 8: Configuração via Variáveis de Ambiente

**User Story:** Como um desenvolvedor, eu quero configurar o MCP server via variáveis de ambiente, para que eu possa definir valores padrão sem modificar código.

#### Critérios de Aceitação

1. WHEN a variável de ambiente `GOOGLE_CHAT_WEBHOOK_URL` está definida, THE MCP_Server SHALL utilizá-la como Webhook_URL padrão para todas as tools quando o parâmetro `webhook_url` não for fornecido
2. WHEN a variável de ambiente `LOG_LEVEL` está definida, THE MCP_Server SHALL configurar o nível de log de acordo com o valor fornecido
3. WHEN a variável de ambiente `LOG_LEVEL` não está definida, THE MCP_Server SHALL utilizar `WARNING` como nível de log padrão

### Requisito 9: Inicialização do Client como Singleton

**User Story:** Como um desenvolvedor, eu quero que o client HTTP seja inicializado como singleton, para que recursos de conexão sejam reutilizados de forma eficiente.

#### Critérios de Aceitação

1. THE Google_Chat_Client SHALL ser inicializado como singleton na primeira utilização
2. THE Google_Chat_Client SHALL reutilizar a mesma instância em todas as chamadas subsequentes
3. THE Google_Chat_Client SHALL ser inicializado utilizando as variáveis de ambiente disponíveis no momento da primeira chamada

### Requisito 10: Estrutura do Projeto e Empacotamento

**User Story:** Como um desenvolvedor, eu quero que o projeto siga os padrões de empacotamento Python modernos, para que possa ser publicado no PyPI e instalado via `uvx`.

#### Critérios de Aceitação

1. THE MCP_Server SHALL utilizar `hatchling` como sistema de build
2. THE MCP_Server SHALL definir o entry point `pack-mcp-google-chat-notification` apontando para `pack_mcp_google_chat_notification.server:main`
3. THE MCP_Server SHALL utilizar transporte `stdio` via FastMCP
4. THE MCP_Server SHALL declarar `httpx>=0.27.0` e `mcp>=1.0.0` como dependências no `pyproject.toml`
5. THE MCP_Server SHALL ser compatível com Python 3.10 ou superior

### Requisito 11: Serialização e Parsing de Payloads

**User Story:** Como um desenvolvedor, eu quero que os payloads enviados ao Google Chat sejam corretamente serializados, para que as mensagens sejam exibidas conforme esperado.

#### Critérios de Aceitação

1. WHEN a tool `send_card` é invocada, THE MCP_Server SHALL serializar os parâmetros `title`, `subtitle` e `sections` em um payload JSON válido no formato Card V2 do Google Chat
2. WHEN a tool `send_message` é invocada, THE MCP_Server SHALL serializar o parâmetro `text` em um payload JSON válido no formato `{ "text": "<mensagem>" }`
3. FOR ALL payloads Card V2 válidos, serializar e depois deserializar o payload SHALL produzir um objeto equivalente ao original (propriedade round-trip)
