Skip to main content
Glama
junioroliveira1662

ServiceNow Incidents MCP

README.md
# ServiceNow Incidents MCP

Servidor Python/FastMCP para consultar, criar e atualizar incidentes pela Table API do
ServiceNow. Executa localmente via **stdio**, com uma instância e uma identidade por processo.

## Instalação e execução

Requisitos: Python 3.12+ e [uv](https://docs.astral.sh/uv/getting-started/installation/).

```sh
uv sync --locked
```

Crie um `.env` na raiz usando `.env.example` como referência e preencha as credenciais.
O arquivo `.env` está ignorado pelo Git. Também é possível fornecer variáveis de ambiente,
que têm precedência sobre o arquivo. Execute a partir da raiz:

```sh
uv run --locked servicenow-mcp
# Alternativa:
uv run --locked python -m servicenow_mcp
```

O processo aguarda mensagens MCP em stdin; não é um terminal interativo nem um servidor HTTP.
O cliente MCP normalmente inicia e encerra esse processo. Logs usam stderr, reservando stdout
para o protocolo. Não há banco de dados ou persistência local de incidentes.

## Configuração

| Variável | Uso |
| --- | --- |
| `SERVICENOW_INSTANCE_URL` | Origem HTTPS, por exemplo `https://sua-instancia.service-now.com`, sem `/api` |
| `SERVICENOW_AUTH_TYPE` | `basic` (padrão) ou `bearer` |
| `SERVICENOW_USERNAME` | Usuário de integração, obrigatório para Basic |
| `SERVICENOW_PASSWORD` | Senha, obrigatória para Basic |
| `SERVICENOW_TOKEN` | Token de acesso já obtido, obrigatório para Bearer |
| `SERVICENOW_TIMEOUT_SECONDS` | Timeout por operação de rede, padrão 30; maior que 0 e até 300 |

Bearer não obtém nem renova tokens. Após substituir um token expirado na configuração,
reinicie o processo MCP. A conta precisa de acesso REST e das ACLs adequadas à tabela
`incident` e aos campos usados. Não existe uma lista universal de papéis para todas as
instâncias; confirme com o administrador no REST API Explorer.

TLS permanece validado. Redirecionamentos e proxies de ambiente são desabilitados.
Esta versão usa conexão direta à instância; ambientes que exigem proxy ou CA corporativa
precisam de configuração adicional no cliente HTTP.

### Cliente MCP com configuração JSON

Exemplo para clientes que aceitam `mcpServers`. Substitua os caminhos absolutos; use o
caminho de `uv` retornado por `command -v uv` quando o aplicativo não herdar seu PATH.
O `.env` é carregado do diretório informado em `--directory`.

```json
{
  "mcpServers": {
    "servicenow": {
      "command": "/caminho/absoluto/para/uv",
      "args": [
        "--directory", "/caminho/absoluto/mcp-server-servicenow",
        "run", "--locked", "servicenow-mcp"
      ]
    }
  }
}
```

## Ferramentas

| Ferramenta | Argumentos |
| --- | --- |
| `list_incidents` | `query?`, `fields?`, `limit=20` (1–100), `offset=0` |
| `get_incident` | `identifier`, `fields?` |
| `create_incident` | `short_description`, `fields?` (objeto com campos adicionais) |
| `update_incident` | `identifier`, `fields` (objeto não vazio) |
| `add_incident_comment` | `identifier`, `text`, `field` (`comments` ou `work_notes`, obrigatório) |

`identifier` aceita `sys_id` hexadecimal de 32 caracteres ou número `INC` seguido de dígitos.
A busca por número é exata; antes de alterar, o servidor resolve o número para `sys_id`.
Números inexistentes ou ambíguos geram erro, sem escrita.

Exemplos de argumentos de chamadas MCP:

```json
{"query": "active=true^priority=1^ORDERBYsys_id", "limit": 20, "offset": 0}
```

```json
{"identifier": "INC0010001", "fields": ["number", "short_description", "state", "description"]}
```

```json
{
  "short_description": "VPN indisponível",
  "fields": {"description": "Falha ao conectar à rede interna", "impact": "2", "urgency": "2"}
}
```

```json
{"identifier": "INC0010001", "fields": {"urgency": "1", "u_external_reference": "SUP-123"}}
```

```json
{"identifier": "INC0010001", "text": "Investigação em andamento.", "field": "work_notes"}
```

Campos de escrita aceitam valores escalares JSON ou `null`, cuja interpretação é da API.
Referências, como `caller_id`, `assigned_to` e `assignment_group`, usam `sys_id`, não nomes.
Campos `number` e `sys_*` são protegidos. Não envie `short_description` também dentro de
`fields` ao criar. Campos desconhecidos, obrigatórios e personalizados são tratados pelas
regras da instância; confira a resposta, pois a plataforma pode ignorar campos não reconhecidos.
Campos omitidos não são enviados no PATCH. Estados não são traduzidos ou fixados pelo servidor.
Para resolver um incidente, envie em `update_incident` o `state` e os demais campos exigidos
pela sua instância. Campos de journal acrescentam entradas; a consulta do incidente não é
uma API de histórico completo de comentários. A visibilidade de `comments` e `work_notes`
depende da configuração local do ServiceNow.

### Resultados e paginação

As operações individuais retornam o objeto `result` da API, sem converter strings numéricas,
booleanos ou referências. São solicitados valores internos (`sysparm_display_value=false`)
e referências sem links. `get_incident` retorna os campos acessíveis por padrão; a listagem
seleciona `sys_id`, `number`, `short_description`, `state`, `priority`, `assigned_to`,
`assignment_group` e `sys_updated_on`. Use `fields` para mudar essa seleção.

```json
{"records": [], "limit": 20, "offset": 0, "total": 45, "next_offset": 20}
```

`total` vem de `X-Total-Count`; `next_offset` usa o link `next` ou o total informado.
As ACLs podem produzir páginas curtas ou vazias antes do fim. Sem metadados de paginação,
`next_offset=null` significa que a próxima página é desconhecida; o cliente pode consultar
explicitamente `offset + limit`. Não há busca automática de todas as páginas.
A consulta padrão ordena por `sys_id`; ao passar `query`, inclua ordenação para percorrer
resultados de forma previsível. Alterações concorrentes na tabela podem afetar a paginação.

`query` é uma encoded query nativa, não SQL. A API pode ignorar partes inválidas de filtros
conforme a configuração da instância. Valide filtros no REST API Explorer; esta ferramenta
não valida o dicionário de campos da instância e consultas não autorizam alterações em lote.

### Falhas

Erros MCP distinguem configuração, validação local, HTTP 400/401/403/404/409/422/429/5xx,
timeout, falha de conexão e respostas inesperadas. Corpos de erro remotos, credenciais e
conteúdo dos incidentes não são incluídos nos logs. Não há tentativas automáticas, inclusive
para escritas: em caso de timeout, falha de conexão ou erro 5xx, consulte o incidente antes
de repetir para evitar incidentes ou comentários duplicados.

## Desenvolvimento e testes

```sh
uv run --locked ruff check .
uv run --locked ruff format --check .
uv run --locked pytest
uv build
```

O pacote está dividido em configuração, cliente HTTP, serviço de incidentes e registro MCP
em `src/servicenow_mcp`. Os testes usam transporte HTTP simulado e cliente FastMCP em memória;
o teste stdio inicia um subprocesso real e verifica descoberta e validação local sem acessar
uma instância. Não precisa de credenciais reais para executar os testes.

Validação real: configure uma instância de desenvolvimento, conecte o cliente MCP, consulte
um incidente conhecido e crie/atualize um incidente de teste com as ferramentas. Essa etapa
exige credenciais e autorização para os registros envolvidos; não é executada pela suíte.

Não inclui exclusões, anexos, outros módulos ServiceNow, transporte HTTP remoto ou renovação
OAuth. Nenhuma configuração ou ACL é alterada na instância pelo projeto.

## Referências analisadas

- [REST APIs e autenticação ServiceNow](https://www.servicenow.com/docs/r/api-reference/rest-api-explorer/c_RESTAPI.html)
- [Table API: GET, POST, PATCH, filtros e paginação](https://www.servicenow.com/docs/r/api-reference/rest-apis/c_TableAPI.html)
- [Execução stdio do FastMCP](https://gofastmcp.com/deployment/running-server)
- [Ciclo de vida do FastMCP](https://gofastmcp.com/servers/lifespan)

A referência consultada é da família Australia. O projeto usa `/api/now/table/incident`
(versão padrão da instância); compatibilidade com customizações deve ser verificada localmente.

TDQS

A4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a distinct action and resource: listing, fetching, creating, updating, and commenting on incidents. The add_incident_comment tool is clearly separated from update_incident by its specific purpose of adding comments or work notes.

Naming Consistency5/5

Tool names consistently follow a verb_noun pattern: list_incidents, get_incident, create_incident, update_incident, add_incident_comment. The only mild deviation is the wider verb 'add' for comments, but it still fits the convention.

Tool Count5/5

Five tools is well-scoped for a ServiceNow incidents server, covering the core incident workflow without unnecessary bloat. Each tool earns its place and the count is appropriate for the domain.

Completeness4/5

The server provides solid lifecycle coverage with list, get, create, update, and comment operations. Missing delete is acceptable for incident management, though there is no direct way to retrieve existing comments/work notes, which is a minor gap.

Maintenance

ActivityMaintained
ResponsivenessNo issues