Metadata-Version: 2.5
Name: argonaut-mcp-server
Version: 0.2.0
Summary: Servidor MCP para descobrir, inspecionar e diagnosticar filas e tópicos (Redis Streams, Kafka, RabbitMQ, SQS, SNS).
Author: KauaLealz
License-Expression: MIT
License-File: LICENSE
Keywords: diagnostics,kafka,mcp,message-queue,model-context-protocol,observability,rabbitmq,redis-streams,sns,sqs
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Monitoring
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.11
Requires-Dist: cryptography>=43.0
Requires-Dist: mcp<2,>=1.6
Requires-Dist: pydantic>=2.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: all
Requires-Dist: boto3>=1.34; extra == 'all'
Requires-Dist: confluent-kafka>=2.3; extra == 'all'
Requires-Dist: redis>=5.0; extra == 'all'
Requires-Dist: requests>=2.31; extra == 'all'
Provides-Extra: aws
Requires-Dist: boto3>=1.34; extra == 'aws'
Provides-Extra: dev
Requires-Dist: boto3>=1.34; extra == 'dev'
Requires-Dist: fakeredis>=2.21; extra == 'dev'
Requires-Dist: moto[cloudwatch,sns,sqs]>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: redis>=5.0; extra == 'dev'
Requires-Dist: requests>=2.31; extra == 'dev'
Provides-Extra: kafka
Requires-Dist: confluent-kafka>=2.3; extra == 'kafka'
Provides-Extra: rabbitmq
Requires-Dist: requests>=2.31; extra == 'rabbitmq'
Provides-Extra: redis
Requires-Dist: redis>=5.0; extra == 'redis'
Description-Content-Type: text/markdown

# Argonaut

Servidor **MCP (stdio)** em Python que deixa um agente **descobrir, inspecionar e
diagnosticar** filas e tópicos em **Redis Streams, Kafka, RabbitMQ, Amazon SQS e
Amazon SNS**. As operações de escrita existem para resolver o problema encontrado,
sempre atrás de modo, allowlist e confirmação em duas etapas.

Faz par com o [Nautilus](https://github.com/KauaLealz/nautilus-mcp-server) (MCP de
bancos de dados): Nautilus para bases, Argonaut para mensageria.

## O que faz

O caso de uso central é diagnóstico: *"por que essa fila está crescendo?"*,
*"qual consumer group está atrasado?"*, *"o que tem na DLQ?"*, *"por que a mensagem
publicada no SNS não chegou na fila X?"*.

## Instalação e execução

Requer **Python 3.11+**. Dependências com [uv](https://docs.astral.sh/uv/).

```bash
uv sync --extra all          # ou --extra redis / kafka / rabbitmq / aws
ARGONAUT_CONFIG=./argonaut.yaml uv run argonaut
```

O servidor fala por **stdio**. Configure-o no seu cliente MCP apontando o comando
para `uv run argonaut` (ou o console script `argonaut`) com as variáveis de ambiente
`ARGONAUT_CONFIG` (caminho do YAML) e `ARGONAUT_KEY` (chave que decifra as senhas).

## Configuração

Um único arquivo YAML descreve defaults e conexões. Veja
[`argonaut.example.yaml`](./argonaut.example.yaml). O servidor valida na
inicialização e falha cedo, com mensagens claras.

A **senha** (campo `password`, em qualquer nível — inclui `sasl.password` do Kafka)
só é aceita **cifrada** (`enc:...`); texto puro é recusado. Grave-a pela CLI
`argonaut-admin`, que cifra com a chave `ARGONAUT_KEY`. Não há interpolação de
`${VAR}`: todos os demais campos (`url`, `brokers`, `username`, `region`...) vão
**literais** no YAML. Os únicos valores lidos do ambiente são `ARGONAUT_CONFIG`
e `ARGONAUT_KEY`.

### Cadastrar conexões pela CLI

```bash
# 1. Gere a chave uma vez e exporte-a (guarde-a com segurança)
argonaut-admin keygen                 # imprime a chave; defina ARGONAUT_KEY com ela

# 2. Gerencie as conexões (a senha é pedida de forma oculta e cifrada ao salvar)
argonaut-admin add redis-dev          # pergunta os campos conforme o tipo de broker
argonaut-admin list                   # lista as conexões (nunca mostra a senha)
argonaut-admin edit redis-dev         # altera campos; senha em branco mantém a atual
argonaut-admin remove redis-dev       # remove a conexão
```

> **Importante:** a **mesma** `ARGONAUT_KEY` usada no `add` precisa estar no ambiente
> do servidor — é com ela que o Argonaut decifra as senhas ao subir.

```yaml
defaults:
  peek: { max_messages: 20, max_payload_bytes: 4096 }
  confirm_token_ttl: 120s
  audit_log: ./argonaut-audit.jsonl
  redact:
    json_paths: ["$.customer.document", "$.card.*"]
    patterns: [cpf, email, credit_card]

connections:
  redis-dev:
    type: redis_streams
    url: "redis://localhost:6379/0"
    mode: admin
    dlq_convention: "{name}:dlq"
```

Tipos de conexão: `redis_streams`, `kafka`, `rabbitmq`, `aws` (SQS + SNS juntos).

## Tools

| Tool | Modo | O que faz |
|------|------|-----------|
| `list_connections` | readonly | Conexões configuradas, com tipo e modo |
| `list_destinations` | readonly | Filas, tópicos e streams (filtro por glob) |
| `describe_destination` | readonly | Atributos nativos, DLQ e configuração |
| `get_stats` | readonly | Profundidade, em voo, idade da mais antiga, taxas |
| `list_consumer_groups` | readonly | Grupos, membros e estado |
| `get_consumer_lag` | readonly | Lag por grupo e partição |
| `get_topology` | readonly | Bindings do RabbitMQ e subscriptions do SNS |
| `peek_messages` | readonly¹ | Leitura sem consumir |
| `get_message` | readonly | Uma mensagem por posição (offset, id) |
| `publish_message` | operator | Publica uma mensagem |
| `redrive_dlq` | operator | Move mensagens da DLQ de volta à origem |
| `reset_offsets` | operator | Reposiciona um consumer group |
| `reclaim_pending` | operator | Reatribui mensagens pendentes travadas (Redis) |
| `purge` | admin | Esvazia um destino |
| `create_destination` / `delete_destination` | admin | Cria/remove destinos |
| `update_attributes` | admin | Altera retenção, visibility timeout, políticas |
| `delete_consumer_group` | admin | Remove um grupo inativo |

¹ `peek_messages` com `accept_side_effects=true` (leitura que altera estado, como
em SQS e filas clássicas do RabbitMQ) exige modo **operator**.

Além das tools, o servidor expõe o resource `argonaut://{conexão}/{destino}` (a
descrição do destino em JSON) e prompts de diagnóstico prontos (`investigar_backlog`,
`analisar_dlq`, `rastrear_mensagem_sns`).

## Segurança

O padrão é **readonly**. Toda escrita exige três coisas:

1. **Modo por conexão** (readonly ⊂ operator ⊂ admin): produção nasce readonly;
   promover é mudança de config, nunca de runtime.
2. **Allowlist/denylist por glob**: destino negado não aparece nem na listagem.
3. **Confirmação em duas etapas**: a 1ª chamada roda em dry-run e devolve o impacto
   (*"vai apagar 48.213 mensagens de orders.dlq"*) e um token com TTL curto,
   vinculado ao hash dos argumentos; a execução só acontece na 2ª chamada com esse
   token.

Além disso: payloads **truncados** e com **dados sensíveis redigidos** antes de
sair; toda MessageView marcada como `untrusted` (o conteúdo é dado, não instrução);
**auditoria** JSON lines de toda escrita (inclusive dry-runs); credenciais só por
ambiente, nunca em respostas, erros ou logs.

## Desenvolvimento

```bash
uv sync --extra dev
uv run pytest tests/unit tests/contract      # sem Docker (fakes)
uv run pytest -m integration                 # brokers reais (Docker)
```

A peça central de teste é uma **suíte de contrato** parametrizada por adapter: o
mesmo cenário (criar destino, publicar, stats, peek, lag, redrive, purge) roda em
todos. Um broker novo só entra quando passa nela.

## Fora de escopo na v1

Ser consumidor/worker de produção; gestão de usuários e ACLs dos brokers;
provisionamento de clusters; monitoramento contínuo e alertas; decodificação de
Avro/Protobuf no Kafka; replay de tópicos FIFO do SNS; transporte HTTP remoto.
