{
  "markdown": "# CDF Finance MCP\n\n> Conecte Claude, ChatGPT e qualquer client MCP (OAuth 2.1) à sua conta CDF Finance — consulte e registre sua vida financeira por linguagem natural.\n\n[![License: BUSL-1.1](https://img.shields.io/badge/License-BUSL--1.1-blue.svg)](./LICENSE)\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-io.github.VessellTech%2Fcdf.mcp-black)](./server.json)\n[![Version](https://img.shields.io/badge/version-0.1.7-informational)](./package.json)\n[![Node](https://img.shields.io/badge/node-%3E%3D20-green)](./package.json)\n\n**Remoto:** `https://mcp.cdf.finance/mcp` (Streamable HTTP) · **Website:** <https://cdf.finance/mcp> · **Status:** <https://status.cdf.finance> · **Suporte:** `support@cdf.finance`\n\n---\n\n## O que é\n\nMCP server **stateless** e isolado para o [CDF Finance](https://cdf.finance) — app de controle financeiro pessoal (contas, cartões, transações, faturas, orçamentos, metas, dívidas, investimentos e insights).\n\n- **Para usuários:** pergunte ao Claude/ChatGPT sobre seu dinheiro e registre lançamentos sem abrir o app.\n- **Para desenvolvedores/revisores:** código auditável, sem dependência do `backend-husk` — só HTTP sobre a API pública que o app mobile já usa.\n\n> **Source-available** sob [BUSL-1.1](./LICENSE): pode auditar, usar com o CDF Finance, contribuir. Uso em produção como produto concorrente exige licença comercial. Vira `Apache-2.0` em `2030-09-01`.\n\n### Exemplos\n\n| Você diz | O que acontece |\n|---|---|\n| \"Quanto sobrou do meu salário esse mês?\" | `current_month_spending` + `categories_insights` |\n| \"Minha próxima fatura vai caber no orçamento?\" | `list_pending_invoices` + `budget_comparison` |\n| \"Lança um Uber de R$ 27,50 no Nubank como Transporte\" | `list_accounts` + `list_categories` + `create_transaction` |\n\nEnglish: *\"How much is left of my salary?\" / \"Will my next bill fit the budget?\" / \"Log an Uber ride of R$27.50 on Nubank as Transportation.\"*\n\n---\n\n## Arquitetura\n\nIsolamento total do `backend-husk` — este serviço **não importa código do backend**.\n\n```\nClaude / ChatGPT (MCP client)\n        │  OAuth 2.1 — DCR + PKCE (S256)\n        ▼\n┌───────────────────────────────┐\n│  cdf-mcp-server (este repo)   │  Postgres isolado (Railway)\n│  • Authorization Server        │  ├─ oauth_clients / oauth_codes\n│  • Resource Server (/mcp)     │  ├─ oauth_tokens (hash SHA-256)\n│  • Catálogo declarativo       │  └─ sessions (JWT mobile criptografado\n│    ~50 tools → REST           │                AES-256-GCM)\n└───────────────┬───────────────┘\n                │  HTTPS — Bearer <mobile JWT>\n                ▼\n        backend-husk (api.vessell.app)\n        API pública — mesmo contrato do app mobile\n```\n\n**Fluxo de login:**\n\n1. Client faz Dynamic Client Registration em `/register`.\n2. Usuário autoriza em `/authorize` (form server-rendered, sem terceiros) → `POST /api/mobile/auth/login` com `device_id=mcp-<sessionId>`, `platform=mcp`.\n3. `access/refresh` do backend ficam **criptografados** em `sessions`; client MCP recebe apenas token opaco (`oauth_tokens`).\n4. Cada tool renova o `access_token` via `refresh` automaticamente (`getValidAccessToken`).\n5. Sessão aparece como device em `GET /api/mobile/devices` — revogável em `DELETE /api/mobile/devices/:id`.\n\nPor que isolado (`README` original): sem dependência circular, deploy/escala independentes (Railway vs Coolify no backend) e imune a troca de linguagem do backend — só fala HTTP.\n\n## Tools\n\nCatálogo 100% declarativo em [`src/tools/catalog/`](./src/tools/catalog/) — cada tool é `{ name, method, path, input(zod) }` executada por [`src/tools/register.ts`](./src/tools/register.ts). Nova rota no backend = nova entrada, sem handler.\n\n| Domínio | Tools (exemplos) |\n|---|---|\n| **User** | `get_profile`, `update_profile` |\n| **Accounts / Cards** | `list_accounts`, `create_account`, `list_cards`, `current_invoice` |\n| **Categories / Cost Centers** | `list_categories`, `create_category`, `list_cost_centers` |\n| **Transactions** | `list_transactions`, `create_transaction`, `confirm_pending_transaction`, `upcoming_transactions` |\n| **Recurring / Invoices** | `list_recurring_transactions`, `list_invoices`, `pay_invoice` |\n| **Goals / Budgets / Debts** | `list_goals`, `budget_comparison`, `create_debt`, `debt_payoff_simulation` |\n| **Equities / Investments** | `list_equities`, `add_equity_valuation`, `investments_workspace` |\n| **Insights / Analytics** | `cashflow_forecast`, `spending_projection`, `networth_projection`, `categories_insights`, `behavior_insights`, `can_afford`, `analytics_history` |\n| **Tags** | `list_tags`, `create_tag` |\n\nFora de escopo de propósito (igual ao backend): `admin`, `Stripe/pagamentos`, `webhooks`, `S3/anexos`, `/api/ai/*`.\n\n> **Modo somente leitura:** `MCP_TOOLS_MODE=readonly` expõe só `readOnly:true` — ideal para diretórios curados.\n\n---\n\n## Quick start\n\n```bash\ncp .env.example .env   # preencha DATABASE_URL, TOKEN_ENCRYPTION_KEY, SESSION_SECRET\nnpm install\nnpm run db:migrate\nnpm run dev            # http://localhost:8090\n```\n\nTeste com MCP Inspector:\n\n```bash\nnpx @modelcontextprotocol/inspector\n# Transport: Streamable HTTP → http://localhost:8090/mcp\n```\n\n### Variáveis de ambiente\n\n| Var | Obrigatória | Descrição |\n|---|---|---|\n| `PUBLIC_URL` | sim | URL pública deste serviço (entra nos metadados OAuth). Gere o domínio **antes** do primeiro deploy |\n| `PORT` | não | default `8090` |\n| `BACKEND_API_URL` | sim | `https://api.vessell.app` (ou staging) |\n| `DATABASE_URL` | sim | Postgres isolado deste serviço |\n| `TOKEN_ENCRYPTION_KEY` | sim | 32 bytes base64: `node -e \"console.log(require('crypto').randomBytes(32).toString('base64'))\"` |\n| `SESSION_SECRET` | sim | string longa aleatória p/ cookies `/authorize` |\n| `MCP_SERVICE_TOKEN` | não | segredo serviço-a-serviço (`backend-husk → MCP` via `X-CDF-User-Token`). Se ausente, só OAuth |\n| `MCP_TOOLS_MODE` | não | `full` (default) ou `readonly` |\n| `OPENAI_APPS_CHALLENGE_TOKEN` | não | verificação de domínio OpenAI |\n| `ALLOWED_ORIGINS` | não | CORS do `/authorize` — default `https://claude.ai,https://chatgpt.com` |\n\nVer [`.env.example`](./.env.example) comentado.\n\n## Deploy (Railway)\n\n1. `railway init` ou conecte o repo no dashboard.\n2. Adicione addon **Postgres** (injeta `DATABASE_URL`).\n3. Configure envs acima — gere domínio em **Settings → Networking** primeiro.\n4. Deploy: `Dockerfile` → `node dist/index.js` (`railway.json` já configurado).\n5. Migration: `railway run npm run db:migrate`.\n6. No Claude.ai/ChatGPT aponte o connector para `https://<seu-dominio>.up.railway.app/mcp` — DCR/OAuth é automático.\n\n---\n\n## Segurança\n\n- **PKCE S256 obrigatório** em todo `authorization_code`.\n- **Tokens opacos** — só `SHA-256` persiste (`oauth_tokens`), bruto é entregue uma vez.\n- **JWT mobile criptografado** `AES-256-GCM` em `sessions` — nunca exposto ao client (`src/crypto.ts`, `src/mcp/http.ts`).\n- **Device isolado** — cada sessão `mcp-<id>` (`src/backend/client.ts:45`) revogável sem afetar outros logins.\n- **Sanitização** — `redactLargeInlineData` + `redactFields` (`src/tools/register.ts:19`) evita vazamento de `data:` URI e campos sensíveis pro LLM.\n\nReporte vulnerabilidades em [`SECURITY.md`](./SECURITY.md) — **não abra issue pública**: `support@cdf.finance` `[SECURITY]`.\n\n## Conformidade — Diretório Anthropic (Seção 4.A)\n\nEste conector **não transfere dinheiro/cripto/ativos e não executa pagamentos em nome do usuário** — apenas lê e registra lançamentos no controle financeiro pessoal, igual ao app. Toda escrita é explícita e solicitada na conversa.\n\n- Para listagens curadas use `MCP_TOOLS_MODE=readonly`.\n- Pedido de exceção por escrito (previsto na própria 4.A): [`docs/4a-exception-request.md`](./docs/4a-exception-request.md).\n- **Conta de teste para revisores:** `joao@teste.com` / `123456` (dados de amostra).\n\n## Contribuindo\n\nVeja [`CONTRIBUTING.md`](./CONTRIBUTING.md) — fork, branch `feat/...`, `npm run build` e PR com path validado no backend. Ao contribuir você licencia sob `BUSL-1.1`.\n\n## Licença\n\nSource-available **[BUSL-1.1](./LICENSE)** — uso com o CDF Finance, pessoal, acadêmico e contribuições são livres. **Proibido** uso em produção como produto concorrente de gestão financeira (hosted/managed). Converte para `Apache-2.0` em `2030-09-01`.\n\nDúvidas comerciais: `support@cdf.finance`.\n\n---\n\n<p align=\"center\">\n  <sub>Construído com <a href=\"https://modelcontextprotocol.io\">Model Context Protocol</a> · Mantido por <a href=\"https://cdf.finance\">Vessell CDF Finance</a></sub>\n</p>\n",
  "bytes": 8471,
  "sha": "194b8d08319ee065aa9742b3094a950db60f14f26e1b877ece72e352b652f162",
  "repo_slug": "vesselltech/cdf.mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_vesselltech_cdf_mcp_d2bf03e2/readme"
}