# Guia de Contribuição - Uazapi MCP Server
Obrigado por considerar contribuir para o Uazapi MCP Server! Este guia ajudará você a adicionar novos endpoints e funcionalidades seguindo as melhores práticas do MCP.
## Como Adicionar Novos Endpoints
### Passo 1: Consultar a Documentação da API
Antes de começar, consulte a documentação oficial da Uazapi:
- https://docs.uazapi.com/
Identifique:
- Endpoint da API (URL e método HTTP)
- Parâmetros necessários (obrigatórios e opcionais)
- Formato do corpo da requisição
- Formato da resposta
- Possíveis códigos de erro
### Passo 2: Criar o Modelo Pydantic
Crie um modelo para validação dos parâmetros de entrada:
```python
class NovaFuncionalidadeInput(BaseModel):
"""Descrição clara do que este modelo representa."""
model_config = ConfigDict(
str_strip_whitespace=True, # Remove espaços em branco
validate_assignment=True, # Valida em atribuição
extra='forbid' # Não permite campos extras
)
# Campo obrigatório
campo_obrigatorio: str = Field(
..., # ... significa obrigatório
description="Descrição clara com exemplo (e.g., 'nome_grupo', 'id_123')",
min_length=1,
max_length=100
)
# Campo opcional com padrão
campo_opcional: Optional[int] = Field(
default=10,
description="Descrição do campo opcional",
ge=1, # greater than or equal
le=100 # less than or equal
)
# Enum para valores fixos
formato: ResponseFormat = Field(
default=ResponseFormat.MARKDOWN,
description="Formato de saída"
)
# Validador customizado (se necessário)
@field_validator('campo_obrigatorio')
@classmethod
def validar_campo(cls, v: str) -> str:
"""Validação customizada."""
if not v.strip():
raise ValueError("Campo não pode ser vazio")
# Aplicar transformações
return v.upper()
```
### Passo 3: Implementar a Ferramenta
```python
@mcp.tool(
name="uazapi_nome_da_ferramenta", # Prefixo uazapi_ + snake_case
annotations={
"title": "Título Legível da Ferramenta",
"readOnlyHint": True, # True se NÃO modifica dados
"destructiveHint": False, # True se pode deletar/modificar dados
"idempotentHint": True, # True se chamadas repetidas = mesmo efeito
"openWorldHint": True # True se interage com sistemas externos
}
)
async def uazapi_nome_da_ferramenta(params: NovaFuncionalidadeInput) -> str:
"""
Descrição de uma linha do que a ferramenta faz.
Descrição detalhada explicando:
- O que a ferramenta faz
- Quando usar
- Limitações ou considerações especiais
Args:
params (NovaFuncionalidadeInput): Descrição dos parâmetros:
- campo_obrigatorio (str): O que é este campo
- campo_opcional (Optional[int]): Para que serve
- formato (ResponseFormat): Formato de saída
Returns:
str: Descrição do formato de retorno
Exemplo de sucesso em Markdown:
```
# Título do Resultado
Campo 1: Valor
Campo 2: Valor
```
Exemplo de sucesso em JSON:
```json
{
"campo1": "valor",
"campo2": 123
}
```
Exemplo de erro:
"Error: <mensagem clara e acionável>"
Examples:
- Use quando: "Descrição de caso de uso 1"
- Use quando: "Descrição de caso de uso 2"
- Não use quando: "Situação onde NÃO deve usar"
- Não use quando: "Outra situação inapropriada"
Error Handling:
- Descreve erro específico 1 e como resolver
- Descreve erro específico 2 e próximos passos
- Validação automática via Pydantic para campos obrigatórios
"""
try:
# Preparar dados da requisição
request_data = {
"campo1": params.campo_obrigatorio,
"campo2": params.campo_opcional
}
# Fazer requisição usando função compartilhada
response = await _make_api_request(
endpoint="caminho/do/endpoint", # Ex: "groups/create"
method="POST", # GET, POST, PUT, DELETE
json_data=request_data, # Para POST/PUT
# params={"query": "param"} # Para GET (query params)
)
# Processar resposta
resultado = response.get("data", {})
# Formatar resposta baseado no formato solicitado
if params.formato == ResponseFormat.MARKDOWN:
# Formato legível para humanos
lines = ["# Resultado da Operação\n"]
lines.append(f"**Campo 1**: {resultado.get('campo1', 'N/A')}")
lines.append(f"**Campo 2**: {resultado.get('campo2', 'N/A')}")
content = "\n".join(lines)
# Verificar limite de caracteres
return _truncate_response(content)
else: # JSON
# Formato para processamento programático
import json
return json.dumps(resultado, indent=2)
except Exception as e:
# Tratamento de erro centralizado
return _handle_api_error(e)
```
### Passo 4: Testar a Implementação
```bash
# 1. Verificar sintaxe
python3 -m py_compile uazapi_mcp.py
# 2. Testar importações
python3 -c "import uazapi_mcp; print('OK')"
# 3. Validar com MCP Inspector (se disponível)
uv run mcp dev uazapi_mcp.py
# 4. Testar no Claude Desktop
# Configure no claude_desktop_config.json e reinicie o Claude
```
## Diretrizes de Código
### 1. Nomeação
**Ferramentas:**
- ✅ `uazapi_send_message`
- ✅ `uazapi_create_group`
- ✅ `uazapi_list_contacts`
- ❌ `send_message` (sem prefixo)
- ❌ `sendMessage` (camelCase)
**Modelos Pydantic:**
- ✅ `SendMessageInput`
- ✅ `CreateGroupInput`
- ❌ `SendMessageParams`
- ❌ `send_message_input`
**Funções utilitárias (privadas):**
- ✅ `_format_phone_number`
- ✅ `_make_api_request`
- ❌ `format_phone_number` (não privada)
### 2. Validação de Entrada
**Use Pydantic constraints:**
```python
# ✅ Bom
campo: str = Field(..., min_length=1, max_length=100)
numero: int = Field(..., ge=0, le=1000)
email: str = Field(..., pattern=r'^[\w\.-]+@[\w\.-]+\.\w+$')
# ❌ Ruim - validação manual
def validar_campo(campo: str):
if len(campo) < 1 or len(campo) > 100:
raise ValueError("Campo inválido")
```
### 3. Tratamento de Erros
**Use a função centralizada:**
```python
# ✅ Bom
except Exception as e:
return _handle_api_error(e)
# ❌ Ruim - mensagens inconsistentes
except Exception as e:
return f"Erro: {str(e)}"
```
### 4. Reutilização de Código
**Extraia lógica comum:**
```python
# ✅ Bom - função compartilhada
async def _make_api_request(endpoint, method, **kwargs):
# Lógica compartilhada
pass
# Usar em várias ferramentas
response = await _make_api_request("endpoint", "POST", json_data=data)
# ❌ Ruim - duplicar código em cada ferramenta
async with httpx.AsyncClient() as client:
response = await client.post(...) # Repetido 10x
```
### 5. Documentação
**Docstrings completas:**
```python
# ✅ Bom
async def tool(params: Input) -> str:
"""
Resumo de uma linha.
Descrição detalhada com contexto.
Args:
params (Input): Descrição completa com exemplos
Returns:
str: Formato de retorno com exemplos
Examples:
- Use quando: "caso 1"
- Não use quando: "caso 2"
Error Handling:
- Erro X: Como resolver
"""
# ❌ Ruim
async def tool(params):
"""Faz algo."""
```
## Checklist de Qualidade
Antes de submeter código novo, verifique:
### Validação
- [ ] Modelo Pydantic criado com `model_config`
- [ ] Todos os campos têm `description` com exemplos
- [ ] Constraints apropriados (`min_length`, `ge`, `le`, etc.)
- [ ] Validadores customizados quando necessário
### Ferramenta
- [ ] Nome segue padrão `uazapi_<ação>_<recurso>`
- [ ] Annotations configuradas corretamente
- [ ] Docstring completa (Args, Returns, Examples, Error Handling)
- [ ] Usa `_make_api_request()` para chamadas API
- [ ] Usa `_handle_api_error()` para erros
### Resposta
- [ ] Suporta múltiplos formatos (Markdown e JSON)
- [ ] Respeita CHARACTER_LIMIT
- [ ] Usa `_truncate_response()` quando necessário
- [ ] Paginação implementada (se aplicável)
### Código
- [ ] Type hints em todos os parâmetros e retornos
- [ ] Async/await para operações I/O
- [ ] Sem código duplicado
- [ ] Funções auxiliares extraídas quando aplicável
- [ ] Sintaxe validada (`python3 -m py_compile`)
### Documentação
- [ ] README.md atualizado com nova ferramenta
- [ ] EXAMPLES.md atualizado com casos de uso
- [ ] Comentários em código complexo
## Estrutura de Branches
```
main
└── feature/nome-da-funcionalidade
└── fix/correcao-de-bug
└── docs/atualizacao-documentacao
```
## Processo de Revisão
1. **Auto-revisão**: Verifique o checklist acima
2. **Testes**: Garanta que funciona localmente
3. **Documentação**: Atualize arquivos relevantes
4. **Commit**: Use mensagens claras
- `feat: adiciona endpoint de grupos`
- `fix: corrige formatação de números`
- `docs: atualiza exemplos de uso`
## Recursos Úteis
- **MCP Best Practices**: https://modelcontextprotocol.io/
- **Pydantic Docs**: https://docs.pydantic.dev/
- **Uazapi API Docs**: https://docs.uazapi.com/
- **FastMCP SDK**: https://github.com/modelcontextprotocol/python-sdk
## Dúvidas?
Para perguntas sobre implementação:
1. Consulte os exemplos existentes no código
2. Revise a documentação do MCP
3. Verifique os padrões estabelecidos nas ferramentas atuais
---
**Obrigado por contribuir! 🚀**