Consignado Local
FreeNot checkedMCP server for orchestrating the consignado loan journey via WhatsApp agent, centralizing flow rules, identity resolution, and journey consistency.
About
MCP server for orchestrating the consignado loan journey via WhatsApp agent, centralizing flow rules, identity resolution, and journey consistency.
README
Servidor MCP local em Python para orquestrar uma jornada de empréstimo consignado usando tools expostas via HTTP.
O projeto funciona como um harness local: recebe chamadas padronizadas, valida o input, resolve contexto da jornada, executa uma tool registrada e devolve uma resposta com trace.
Status: POC / desenvolvimento local. Não está endurecido para produção.
Objetivo
Este repositório demonstra uma abordagem simples para expor capacidades de negócio como tools reutilizáveis em uma jornada conversacional.
O caso implementado é uma jornada de consignado com etapas como:
- Buscar cliente por telefone.
- Validar identidade por CPF.
- Consultar elegibilidade.
- Buscar ofertas de empréstimo.
- Criar contrato.
- Gerar link de formalização.
Alterações da branch feature/melhorias
Esta branch mantém a natureza local/dev da POC, mas melhora alguns pontos de qualidade:
server.pypassou a centralizar a montagem de respostas de erro.server.pyregistra erro de tool em log estruturado vialog_event("tool.error", ...).GET /healthzagora retorna também contagem de tools registradas e sessões em memória.- A autenticação é tratada antes da execução da tool, retornando erro padronizado.
IdempotencyStorepassou a usar cópia defensiva emgeteput.customers.pypassou a respeitar valores booleanos explícitos vindos da API, inclusivefalse.eligibility.pypassou a respeitareligible=falseexplicitamente retornado pela API.
Arquitetura geral
Cliente / Agente / Orquestrador
|
v
+-----------------------------+
| FastAPI - MCP Local Server |
| /healthz |
| /tools |
| /call |
+-------------+---------------+
|
v
+-----------------------------+
| Registry de Tools |
| lookup_customer_by_phone |
| resolve_identity_by_cpf |
| check_eligibility |
| get_loan_offers |
| create_contract |
| get_formalization_link |
+-------------+---------------+
|
v
+-----------------------------+
| APIs de domínio |
| Clientes |
| Elegibilidade |
| Simulação |
| Formalização |
+-----------------------------+
Stack
Principais tecnologias usadas:
- Python
- FastAPI
- Uvicorn
- Pydantic
- HTTPX
- LangChain / OpenAI, presentes nas dependências
- boto3, presente nas dependências
- SQLAlchemy, presente nas dependências
Estrutura do projeto
.
├── server.py
├── requirements.txt
└── mcp/
├── errors.py
├── http_clients.py
├── models.py
├── observability.py
├── registry.py
├── runtime.py
├── policies/
│ ├── auth.py
│ └── idempotency.py
└── tools/
├── __init__.py
├── customers.py
├── eligibility.py
├── offers.py
└── contracts.py
Responsabilidades principais
| Arquivo | Responsabilidade |
|---|---|
server.py |
Inicializa o FastAPI, registra tools e expõe /healthz, /tools e /call. |
mcp/models.py |
Define os contratos MCPCall, MCPContext, ToolResponse, ToolError e ToolTrace. |
mcp/registry.py |
Mantém o registry global de tools via decorator @register_tool. |
mcp/runtime.py |
Define sessão, services, idempotência e contexto de execução. |
mcp/http_clients.py |
Implementa client HTTP com cache simples de token. |
mcp/policies/auth.py |
Implementa autenticação simplificada para ambiente local. |
mcp/policies/idempotency.py |
Implementa store de idempotência em memória com cópia defensiva. |
mcp/tools/* |
Implementa as tools de negócio. |
Endpoints
GET /healthz
Health check simples com informações úteis para debug local.
Resposta esperada:
{
"ok": true,
"tools": 7,
"sessions": 0
}
Campos:
| Campo | Descrição |
|---|---|
ok |
Indica que o serviço respondeu. |
tools |
Quantidade de tools registradas no runtime. |
sessions |
Quantidade de sessões em memória no processo atual. |
GET /tools
Lista todas as tools registradas no runtime, incluindo:
- nome;
- descrição;
- schema de input;
- schema de output.
POST /call
Executa uma tool registrada.
Formato base da requisição:
{
"tool": "nome_da_tool",
"input": {},
"context": {
"correlationId": "abc123456",
"channel": "whatsapp",
"subject": "cliente-ou-usuario"
}
}
Formato base da resposta com sucesso:
{
"ok": true,
"output": {},
"trace": {
"correlationId": "abc123456",
"tool": "nome_da_tool",
"startedAt": 1710000000.0,
"durationMs": 10
}
}
Formato base da resposta com erro:
{
"ok": false,
"error": {
"code": "BAD_REQUEST",
"message": "Mensagem do erro",
"retriable": false,
"details": {}
},
"trace": {
"correlationId": "abc123456",
"tool": "nome_da_tool",
"startedAt": 1710000000.0,
"durationMs": 10
}
}
Tools disponíveis
lookup_customer_by_phone
Busca cliente a partir do telefone.
Input:
{
"phone": "+5511999999999"
}
Output:
{
"found": true,
"customerRef": "customer-123",
"cpfRequired": true
}
Observação: a branch feature/melhorias corrige o parsing de cpfRequired para respeitar false explícito retornado pela API.
resolve_identity_by_cpf
Valida a identidade do cliente usando telefone e CPF.
Input:
{
"phone": "+5511999999999",
"cpf": "12345678901"
}
Output:
{
"resolved": true,
"customerRef": "customer-123",
"cpfToken": "token-cpf"
}
Observação: a branch feature/melhorias corrige o parsing de resolved para respeitar false explícito retornado pela API.
get_identity_context
Retorna o contexto de identidade salvo na sessão da jornada.
Input:
{}
Output:
{
"hasIdentity": true,
"customerRef": "customer-123",
"cpfToken": "token-cpf"
}
check_eligibility
Consulta elegibilidade do cliente para consignado.
Input:
{
"customerRef": "customer-123",
"channel": "whatsapp"
}
Output elegível:
{
"eligible": true,
"eligibilityId": "elig-123",
"reasonCode": null
}
Output não elegível:
{
"eligible": false,
"eligibilityId": null,
"reasonCode": "NOT_ELIGIBLE"
}
Observação: para o canal whatsapp, o fluxo exige identidade previamente resolvida. A branch feature/melhorias corrige o parsing para respeitar eligible=false explicitamente retornado pela API.
get_loan_offers
Busca ofertas de empréstimo com base no valor solicitado.
Input:
{
"requestedAmount": 5000.0
}
Output:
{
"offers": [
{
"id": "offer-123",
"installment": 250.0,
"termMonths": 24,
"rateMonthly": 0.018,
"totalCost": 6000.0
}
]
}
create_contract
Cria um contrato pendente a partir de uma oferta.
Input:
{
"offerId": "offer-123",
"idempotencyKey": "journey-abc123-contract"
}
Output:
{
"contractId": "contract-123"
}
A tool usa idempotência em memória para evitar duplicidade no mesmo runtime. Na branch feature/melhorias, o store faz cópia defensiva na gravação e leitura.
get_formalization_link
Gera ou busca o link de formalização do contrato.
Input:
{
"contractId": "contract-123"
}
Output:
{
"formalizationUrl": "https://exemplo.com/formalizacao/contract-123",
"expiresAt": "2026-01-01T12:00:00Z"
}
Fluxo sugerido de chamada
1. lookup_customer_by_phone
2. resolve_identity_by_cpf
3. check_eligibility
4. get_loan_offers
5. create_contract
6. get_formalization_link
Todas as chamadas devem reutilizar o mesmo correlationId para preservar o contexto da jornada.
Variáveis de ambiente
O projeto usa variáveis por prefixo para configurar os serviços externos.
Clientes
CLIENTES_BASE_URL=https://localhost:7287
CLIENTES_VERIFY_SSL=false
CLIENTES_TIMEOUT=10
CLIENTES_AUTH_PATH=/api/auth/token
CLIENTES_CLIENT_ID=mcp
CLIENTES_CLIENT_SECRET=mcp-secret
Elegibilidade
ELEG_BASE_URL=https://localhost:7184
ELEG_VERIFY_SSL=false
ELEG_TIMEOUT=10
ELEG_AUTH_PATH=/api/auth/token
ELEG_CLIENT_ID=mcp
ELEG_CLIENT_SECRET=mcp-secret
Simulação
SIM_BASE_URL=https://localhost:7173
SIM_VERIFY_SSL=false
SIM_TIMEOUT=10
SIM_AUTH_PATH=/api/auth/token
SIM_CLIENT_ID=mcp
SIM_CLIENT_SECRET=mcp-secret
Formalização
FORM_BASE_URL=https://localhost:7131
FORM_VERIFY_SSL=false
FORM_TIMEOUT=10
FORM_AUTH_PATH=/api/auth/token
FORM_CLIENT_ID=mcp
FORM_CLIENT_SECRET=mcp-secret
Como executar localmente
1. Criar ambiente virtual
python -m venv .venv
2. Ativar ambiente virtual
Windows:
.venv\Scripts\activate
Linux/macOS:
source .venv/bin/activate
3. Instalar dependências
pip install -r requirements.txt
4. Subir o servidor
uvicorn server:app --reload
A API ficará disponível em:
http://127.0.0.1:8000
Documentação automática do FastAPI:
http://127.0.0.1:8000/docs
Exemplos com cURL
Health check
curl http://127.0.0.1:8000/healthz
Listar tools
curl http://127.0.0.1:8000/tools
Chamar lookup_customer_by_phone
curl -X POST http://127.0.0.1:8000/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer local-dev-token" \
-d '{
"tool": "lookup_customer_by_phone",
"input": {
"phone": "+5511999999999"
},
"context": {
"correlationId": "journey-abc123",
"channel": "whatsapp",
"subject": "user-123"
}
}'
Tratamento de erros
As tools usam erros padronizados com os seguintes campos:
{
"code": "UPSTREAM_UNAVAILABLE",
"message": "Descrição do erro",
"retriable": true,
"details": {}
}
Códigos comuns:
| Código | Significado |
|---|---|
BAD_REQUEST |
Input inválido ou campo obrigatório ausente. |
FORBIDDEN |
Fluxo inválido ou identidade não resolvida. |
CONFLICT |
Inconsistência no contexto da jornada. |
UPSTREAM_ERROR |
Erro HTTP retornado por serviço externo. |
UPSTREAM_UNAVAILABLE |
Serviço externo indisponível ou falha de comunicação. |
UNKNOWN_TOOL |
Tool solicitada não foi registrada. |
VALIDATION_ERROR |
Validação Pydantic falhou. |
INTERNAL_ERROR |
Erro não tratado. |
Na branch feature/melhorias, falhas de autenticação e erros de execução das tools também passam pelo envelope padronizado de erro.
Limitações atuais
Este projeto ainda tem características de desenvolvimento local:
- Autenticação simplificada: aceita Bearer token sem validação real.
- Permite execução anônima quando não há header
Authorization. - Sessão em memória, indexada por
correlationId. - Idempotência em memória.
- Sem persistência externa.
- Sem testes automatizados documentados.
- Sem Dockerfile ou pipeline de CI/CD documentado.
- Defaults locais para as APIs de domínio.
Melhorias recomendadas
Antes de levar para produção, considerar:
- Validar JWT real, por exemplo Azure AD, Cognito ou outro IdP corporativo.
- Persistir sessão em Redis, DynamoDB ou store equivalente.
- Persistir idempotência fora do processo.
- Adicionar testes unitários e de contrato para cada tool.
- Adicionar logs estruturados com correlação ponta a ponta.
- Adicionar métricas de latência, erro e uso por tool.
- Implementar rate limit e políticas por canal.
- Remover defaults inseguros de ambiente.
- Criar Dockerfile e pipeline de build/deploy.
- Documentar contratos das APIs externas.
Natureza do projeto
Este servidor não é uma implementação completa de plataforma MCP corporativa. Ele é uma POC objetiva para demonstrar como encapsular capacidades de negócio como tools executáveis por um agente ou orquestrador conversacional.
O foco está em clareza arquitetural, separação de responsabilidades e simulação de uma jornada bancária real.
Installing Consignado Local
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/leandrosflora/McpServerPythonFAQ
Is Consignado Local MCP free?
Yes, Consignado Local MCP is free — one-click install via Unyly at no cost.
Does Consignado Local need an API key?
No, Consignado Local runs without API keys or environment variables.
Is Consignado Local hosted or self-hosted?
A hosted option is available: Unyly runs the server in the cloud, no local setup required.
How do I install Consignado Local in Claude Desktop, Claude Code or Cursor?
Open Consignado Local on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
by modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
by xuzexin-hzCompare Consignado Local with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All ai MCPs
