From f627a4b690525a2f4bbcacf90901994f1659a551 Mon Sep 17 00:00:00 2001 From: Dennis Quintal Date: Tue, 7 Jul 2026 10:08:35 -0300 Subject: [PATCH 1/4] feat(malga): add MCP server with 24 tools and catalog entry Introduce @codespar/mcp-malga covering charges, customers, cards, merchants, webhooks, checkout sessions, and payment link settings against the Malga API. --- README.md | 371 ++++----- package-lock.json | 886 ++++++++++++++-------- packages/payments/malga/README.md | 209 ++++++ packages/payments/malga/package.json | 25 + packages/payments/malga/server.json | 54 ++ packages/payments/malga/src/index.ts | 1000 +++++++++++++++++++++++++ packages/payments/malga/tsconfig.json | 14 + 7 files changed, 2082 insertions(+), 477 deletions(-) create mode 100644 packages/payments/malga/README.md create mode 100644 packages/payments/malga/package.json create mode 100644 packages/payments/malga/server.json create mode 100644 packages/payments/malga/src/index.ts create mode 100644 packages/payments/malga/tsconfig.json diff --git a/README.md b/README.md index 15081ca0..af7d4adb 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,17 @@ -

-

MCP Dev LATAM 🌎

-

- Every commerce API your AI agent needs to run a business in Latin America.
- Brazil 🇧🇷 · Mexico 🇲🇽 · Argentina 🇦🇷 · Colombia 🇨🇴 · Chile 🇨🇱 · Peru 🇵🇪 · plus 4 agentic payment protocols. -

-

- 109 MCP servers · 2,289 tools · 6 countries · MIT License -

-

- Catalog · - Quick Start · - Agentic Protocols · - All Servers · - Contribute -

-

- License: MIT - 109 servers - 2289 tools - 6 countries - MCP compatible -

-

+ + +# MCP Dev LATAM 🌎 + +**Every commerce API your AI agent needs to run a business in Latin America.** +*Brazil 🇧🇷 · Mexico 🇲🇽 · Argentina 🇦🇷 · Colombia 🇨🇴 · Chile 🇨🇱 · Peru 🇵🇪 · plus 4 agentic payment protocols.* + +110 MCP servers · 2,310 tools · 6 countries · MIT License + +[Catalog](https://codespar.dev/servers) · [Quick Start](#quick-start) · [Agentic Protocols](#agentic-payment-protocols) · [All Servers](#all-servers) · Contribute + + + + --- @@ -55,12 +45,14 @@ Each MCP server in this repo wraps a real provider — payments, fiscal, logisti Four servers that bridge the emerging agentic payment stack: -| Protocol | Server | Tools | What it does | -|----------|--------|-------|-------------| -| **[Google UCP](packages/payments/ucp)** | `@codespar/mcp-ucp` | 20 | Universal Commerce Protocol — agentic shopping, cart, checkout, orders, delivery, identity. Google's full commerce stack for AI agents. | -| **[Stripe ACP](packages/payments/stripe-acp)** | `@codespar/mcp-stripe-acp` | 24 | Agentic Commerce Protocol — AI agent checkout, payment delegation, products, invoices. Live in ChatGPT with 1M+ Shopify merchants. | -| **[x402](packages/crypto/x402)** | `@codespar/mcp-x402` | 10 | HTTP-native micropayments by Coinbase — when an agent hits a 402, it pays USDC on Base/Solana and retries. Pure HTTP, no checkout UI. | -| **[AP2](packages/payments/ap2)** | `@codespar/mcp-ap2` alpha | 22 | Google's Agent-to-Agent Payment Protocol — authorization, audit trails, scoped spend limits. 60+ partners including Visa, Mastercard, Stripe, PayPal. | + +| Protocol | Server | Tools | What it does | +| ---------------------------------------------- | -------------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| **[Google UCP](packages/payments/ucp)** | `@codespar/mcp-ucp` | 20 | Universal Commerce Protocol — agentic shopping, cart, checkout, orders, delivery, identity. Google's full commerce stack for AI agents. | +| **[Stripe ACP](packages/payments/stripe-acp)** | `@codespar/mcp-stripe-acp` | 24 | Agentic Commerce Protocol — AI agent checkout, payment delegation, products, invoices. Live in ChatGPT with 1M+ Shopify merchants. | +| **[x402](packages/crypto/x402)** | `@codespar/mcp-x402` | 10 | HTTP-native micropayments by Coinbase — when an agent hits a 402, it pays USDC on Base/Solana and retries. Pure HTTP, no checkout UI. | +| **[AP2](packages/payments/ap2)** | `@codespar/mcp-ap2` alpha | 22 | Google's Agent-to-Agent Payment Protocol — authorization, audit trails, scoped spend limits. 60+ partners including Visa, Mastercard, Stripe, PayPal. | + ### The Autonomy Spectrum @@ -170,7 +162,7 @@ npx @codespar/mcp-brasil-api # CEP, CNPJ (no key needed!) npx @codespar/mcp-brasil-api ``` -Then ask your agent: _"What is the address for CEP 01001-000?"_ or _"Look up CNPJ 00.000.000/0001-91"_. +Then ask your agent: *"What is the address for CEP 01001-000?"* or *"Look up CNPJ 00.000.000/0001-91"*. --- @@ -178,14 +170,16 @@ Then ask your agent: _"What is the address for CEP 01001-000?"_ or _"Look up CNP This is what makes the LATAM catalog different — not individual connectors, but a **complete business workflow** across verticals: -| Step | Vertical | Example providers | What the agent does | -|------|----------|-------------------|---------------------| -| 1 | 💳 Payment | Asaas / Mercado Pago / Zoop | Creates Pix charge, splits to sellers | -| 2 | 📄 Fiscal | Nuvem Fiscal / NFe.io / Focus NFe | Issues NFe/NFSe when payment confirmed | -| 3 | 📦 Logistics | Melhor Envio / Correios / Skydropx | Quotes shipping, generates label | -| 4 | 📱 Messaging | Z-API / WhatsApp Cloud / Twilio | Sends tracking via customer's preferred channel | -| 5 | 📊 ERP | Omie / Bling / Tiny / Conta Azul | Records order, updates inventory | -| 6 | 🏦 Banking | Stark Bank / Itaú / BTG | Reconciles balance, creates reports | + +| Step | Vertical | Example providers | What the agent does | +| ---- | ------------ | ---------------------------------- | ----------------------------------------------- | +| 1 | 💳 Payment | Asaas / Mercado Pago / Zoop | Creates Pix charge, splits to sellers | +| 2 | 📄 Fiscal | Nuvem Fiscal / NFe.io / Focus NFe | Issues NFe/NFSe when payment confirmed | +| 3 | 📦 Logistics | Melhor Envio / Correios / Skydropx | Quotes shipping, generates label | +| 4 | 📱 Messaging | Z-API / WhatsApp Cloud / Twilio | Sends tracking via customer's preferred channel | +| 5 | 📊 ERP | Omie / Bling / Tiny / Conta Azul | Records order, updates inventory | +| 6 | 🏦 Banking | Stark Bank / Itaú / BTG | Reconciles balance, creates reports | + To orchestrate all six steps with governance, approval workflows, and audit trails — use [CodeSpar](https://codespar.dev). @@ -195,174 +189,198 @@ To orchestrate all six steps with governance, approval workflows, and audit trai Browse the full catalog at [codespar.dev/servers](https://codespar.dev/servers). Each server has its own README, env-var requirements, and tool reference under `packages///`. -### 💳 Payments (40 servers) - -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Mercado Pago](packages/payments/mercado-pago)** | 30 | `@codespar/mcp-mercado-pago` | API Key | -| **[Stripe](packages/payments/stripe)** | 30 | `@codespar/mcp-stripe` | API Key | -| **[Zoop](packages/payments/zoop)** | 28 | `@codespar/mcp-zoop` | API Key | -| **[Adyen](packages/payments/adyen)** | 25 | `@codespar/mcp-adyen` | API Key | -| **[Asaas](packages/payments/asaas)** | 24 | `@codespar/mcp-asaas` | API Key | -| **[Pagseguro](packages/payments/pagseguro)** | 24 | `@codespar/mcp-pagseguro` | API Key | -| **[Stripe ACP](packages/payments/stripe-acp)** | 24 | `@codespar/mcp-stripe-acp` | API Key | -| **[Iugu](packages/payments/iugu)** | 23 | `@codespar/mcp-iugu` | API Key | -| **[Openpay](packages/payments/openpay)** | 23 | `@codespar/mcp-openpay` | API Key | -| **[AP2](packages/payments/ap2)** alpha | 22 | `@codespar/mcp-ap2` | API Key | -| **[Braintree](packages/payments/braintree)** | 22 | `@codespar/mcp-braintree` | API Key | -| **[Braspag](packages/payments/braspag)** | 22 | `@codespar/mcp-braspag` | API Key | -| **[Cielo](packages/payments/cielo)** | 22 | `@codespar/mcp-cielo` | API Key | -| **[Inter Bank](packages/payments/inter-bank)** | 22 | `@codespar/mcp-inter-bank` | OAuth2 | -| **[Mercado Libre](packages/payments/mercado-libre)** | 22 | `@codespar/mcp-mercado-libre` | API Key | -| **[Nubank](packages/payments/nubank)** alpha | 22 | `@codespar/mcp-nubank` | OAuth2 | -| **[Nupay](packages/payments/nupay)** | 22 | `@codespar/mcp-nupay` | OAuth2 | -| **[Pagar Me](packages/payments/pagar-me)** | 22 | `@codespar/mcp-pagar-me` | API Key | -| **[Rapyd](packages/payments/rapyd)** | 22 | `@codespar/mcp-rapyd` | API Key | -| **[Rede](packages/payments/rede)** alpha | 22 | `@codespar/mcp-rede` | API Key | -| **[Safrapay](packages/payments/safrapay)** alpha | 22 | `@codespar/mcp-safrapay` | OAuth2 | -| **[Worldpay](packages/payments/worldpay)** alpha | 22 | `@codespar/mcp-worldpay` | API Key | -| **[Khipu](packages/payments/khipu)** alpha | 21 | `@codespar/mcp-khipu` | API Key | -| **[Stone](packages/payments/stone)** | 21 | `@codespar/mcp-stone` | API Key | -| **[Wise](packages/payments/wise)** | 21 | `@codespar/mcp-wise` | API Key | -| **[Airwallex](packages/payments/airwallex)** | 20 | `@codespar/mcp-airwallex` | OAuth2 | -| **[Culqi](packages/payments/culqi)** | 20 | `@codespar/mcp-culqi` | API Key | -| **[Getnet](packages/payments/getnet)** | 20 | `@codespar/mcp-getnet` | OAuth2 | -| **[Izipay](packages/payments/izipay)** alpha | 20 | `@codespar/mcp-izipay` | API Key | -| **[Picpay](packages/payments/picpay)** alpha | 20 | `@codespar/mcp-picpay` | API Key | -| **[UCP](packages/payments/ucp)** | 20 | `@codespar/mcp-ucp` | API Key | -| **[Vindi](packages/payments/vindi)** | 20 | `@codespar/mcp-vindi` | API Key | -| **[Paypal](packages/payments/paypal)** | 19 | `@codespar/mcp-paypal` | OAuth2 | -| **[Transbank](packages/payments/transbank)** alpha | 19 | `@codespar/mcp-transbank` | API Key | -| **[Celcoin](packages/payments/celcoin)** | 18 | `@codespar/mcp-celcoin` | API Key | -| **[dLocal](packages/payments/dlocal)** | 18 | `@codespar/mcp-dlocal` | API Key | -| **[Ebanx](packages/payments/ebanx)** | 18 | `@codespar/mcp-ebanx` | API Key | -| **[Efi](packages/payments/efi)** | 18 | `@codespar/mcp-efi` | API Key | -| **[Pix BCB](packages/payments/pix-bcb)** | 18 | `@codespar/mcp-pix-bcb` | API Key | -| **[Chargebee](packages/payments/chargebee)** | 15 | `@codespar/mcp-chargebee` | API Key | +### 💳 Payments (41 servers) + + +| Server | Tools | npm | Auth | +| ---------------------------------------------------- | ----- | ----------------------------- | ------- | +| **[Mercado Pago](packages/payments/mercado-pago)** | 30 | `@codespar/mcp-mercado-pago` | API Key | +| **[Stripe](packages/payments/stripe)** | 30 | `@codespar/mcp-stripe` | API Key | +| **[Zoop](packages/payments/zoop)** | 28 | `@codespar/mcp-zoop` | API Key | +| **[Adyen](packages/payments/adyen)** | 25 | `@codespar/mcp-adyen` | API Key | +| **[Asaas](packages/payments/asaas)** | 24 | `@codespar/mcp-asaas` | API Key | +| **[Pagseguro](packages/payments/pagseguro)** | 24 | `@codespar/mcp-pagseguro` | API Key | +| **[Stripe ACP](packages/payments/stripe-acp)** | 24 | `@codespar/mcp-stripe-acp` | API Key | +| **[Iugu](packages/payments/iugu)** | 23 | `@codespar/mcp-iugu` | API Key | +| **[Openpay](packages/payments/openpay)** | 23 | `@codespar/mcp-openpay` | API Key | +| **[AP2](packages/payments/ap2)** alpha | 22 | `@codespar/mcp-ap2` | API Key | +| **[Braintree](packages/payments/braintree)** | 22 | `@codespar/mcp-braintree` | API Key | +| **[Braspag](packages/payments/braspag)** | 22 | `@codespar/mcp-braspag` | API Key | +| **[Cielo](packages/payments/cielo)** | 22 | `@codespar/mcp-cielo` | API Key | +| **[Inter Bank](packages/payments/inter-bank)** | 22 | `@codespar/mcp-inter-bank` | OAuth2 | +| **[Mercado Libre](packages/payments/mercado-libre)** | 22 | `@codespar/mcp-mercado-libre` | API Key | +| **[Nubank](packages/payments/nubank)** alpha | 22 | `@codespar/mcp-nubank` | OAuth2 | +| **[Nupay](packages/payments/nupay)** | 22 | `@codespar/mcp-nupay` | OAuth2 | +| **[Pagar Me](packages/payments/pagar-me)** | 22 | `@codespar/mcp-pagar-me` | API Key | +| **[Rapyd](packages/payments/rapyd)** | 22 | `@codespar/mcp-rapyd` | API Key | +| **[Rede](packages/payments/rede)** alpha | 22 | `@codespar/mcp-rede` | API Key | +| **[Safrapay](packages/payments/safrapay)** alpha | 22 | `@codespar/mcp-safrapay` | OAuth2 | +| **[Worldpay](packages/payments/worldpay)** alpha | 22 | `@codespar/mcp-worldpay` | API Key | +| **[Khipu](packages/payments/khipu)** alpha | 21 | `@codespar/mcp-khipu` | API Key | +| **[Stone](packages/payments/stone)** | 21 | `@codespar/mcp-stone` | API Key | +| **[Malga](packages/payments/malga)** | 24 | `@codespar/mcp-malga` | API Key | +| **[Wise](packages/payments/wise)** | 21 | `@codespar/mcp-wise` | API Key | +| **[Airwallex](packages/payments/airwallex)** | 20 | `@codespar/mcp-airwallex` | OAuth2 | +| **[Culqi](packages/payments/culqi)** | 20 | `@codespar/mcp-culqi` | API Key | +| **[Getnet](packages/payments/getnet)** | 20 | `@codespar/mcp-getnet` | OAuth2 | +| **[Izipay](packages/payments/izipay)** alpha | 20 | `@codespar/mcp-izipay` | API Key | +| **[Picpay](packages/payments/picpay)** alpha | 20 | `@codespar/mcp-picpay` | API Key | +| **[UCP](packages/payments/ucp)** | 20 | `@codespar/mcp-ucp` | API Key | +| **[Vindi](packages/payments/vindi)** | 20 | `@codespar/mcp-vindi` | API Key | +| **[Paypal](packages/payments/paypal)** | 19 | `@codespar/mcp-paypal` | OAuth2 | +| **[Transbank](packages/payments/transbank)** alpha | 19 | `@codespar/mcp-transbank` | API Key | +| **[Celcoin](packages/payments/celcoin)** | 18 | `@codespar/mcp-celcoin` | API Key | +| **[dLocal](packages/payments/dlocal)** | 18 | `@codespar/mcp-dlocal` | API Key | +| **[Ebanx](packages/payments/ebanx)** | 18 | `@codespar/mcp-ebanx` | API Key | +| **[Efi](packages/payments/efi)** | 18 | `@codespar/mcp-efi` | API Key | +| **[Pix BCB](packages/payments/pix-bcb)** | 18 | `@codespar/mcp-pix-bcb` | API Key | +| **[Chargebee](packages/payments/chargebee)** | 15 | `@codespar/mcp-chargebee` | API Key | + ### 🏦 Banking (12 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Stark Bank](packages/banking/stark-bank)** | 27 | `@codespar/mcp-stark-bank` | API Key | -| **[Caixa](packages/banking/caixa)** alpha | 23 | `@codespar/mcp-caixa` | OAuth2 | -| **[Santander](packages/banking/santander)** alpha | 23 | `@codespar/mcp-santander` | OAuth2 | -| **[Bradesco](packages/banking/bradesco)** alpha | 22 | `@codespar/mcp-bradesco` | OAuth2 | -| **[Itau](packages/banking/itau)** alpha | 22 | `@codespar/mcp-itau` | OAuth2 | -| **[Matera](packages/banking/matera)** alpha | 22 | `@codespar/mcp-matera` | OAuth2 | -| **[Dock](packages/banking/dock)** alpha | 20 | `@codespar/mcp-dock` | OAuth2 | -| **[Open Finance](packages/banking/open-finance)** | 18 | `@codespar/mcp-open-finance` | API Key | -| **[C6](packages/banking/c6)** alpha | 14 | `@codespar/mcp-c6` | OAuth2 | -| **[Banco Do Brasil](packages/banking/banco-do-brasil)** alpha | 13 | `@codespar/mcp-banco-do-brasil` | OAuth2 | -| **[Sicoob](packages/banking/sicoob)** alpha | 13 | `@codespar/mcp-sicoob` | OAuth2 | -| **[BTG](packages/banking/btg)** alpha | 12 | `@codespar/mcp-btg` | OAuth2 | + +| Server | Tools | npm | Auth | +| ------------------------------------------------------------- | ----- | ------------------------------- | ------- | +| **[Stark Bank](packages/banking/stark-bank)** | 27 | `@codespar/mcp-stark-bank` | API Key | +| **[Caixa](packages/banking/caixa)** alpha | 23 | `@codespar/mcp-caixa` | OAuth2 | +| **[Santander](packages/banking/santander)** alpha | 23 | `@codespar/mcp-santander` | OAuth2 | +| **[Bradesco](packages/banking/bradesco)** alpha | 22 | `@codespar/mcp-bradesco` | OAuth2 | +| **[Itau](packages/banking/itau)** alpha | 22 | `@codespar/mcp-itau` | OAuth2 | +| **[Matera](packages/banking/matera)** alpha | 22 | `@codespar/mcp-matera` | OAuth2 | +| **[Dock](packages/banking/dock)** alpha | 20 | `@codespar/mcp-dock` | OAuth2 | +| **[Open Finance](packages/banking/open-finance)** | 18 | `@codespar/mcp-open-finance` | API Key | +| **[C6](packages/banking/c6)** alpha | 14 | `@codespar/mcp-c6` | OAuth2 | +| **[Banco Do Brasil](packages/banking/banco-do-brasil)** alpha | 13 | `@codespar/mcp-banco-do-brasil` | OAuth2 | +| **[Sicoob](packages/banking/sicoob)** alpha | 13 | `@codespar/mcp-sicoob` | OAuth2 | +| **[BTG](packages/banking/btg)** alpha | 12 | `@codespar/mcp-btg` | OAuth2 | + ### 📄 Fiscal (Brasil) (4 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Nuvem Fiscal](packages/fiscal/nuvem-fiscal)** | 24 | `@codespar/mcp-nuvem-fiscal` | API Key | -| **[Nfe Io](packages/fiscal/nfe-io)** | 22 | `@codespar/mcp-nfe-io` | API Key | -| **[Conta Azul](packages/fiscal/conta-azul)** | 20 | `@codespar/mcp-conta-azul` | API Key | -| **[Focus Nfe](packages/fiscal/focus-nfe)** | 19 | `@codespar/mcp-focus-nfe` | API Key | + +| Server | Tools | npm | Auth | +| ------------------------------------------------ | ----- | ---------------------------- | ------- | +| **[Nuvem Fiscal](packages/fiscal/nuvem-fiscal)** | 24 | `@codespar/mcp-nuvem-fiscal` | API Key | +| **[Nfe Io](packages/fiscal/nfe-io)** | 22 | `@codespar/mcp-nfe-io` | API Key | +| **[Conta Azul](packages/fiscal/conta-azul)** | 20 | `@codespar/mcp-conta-azul` | API Key | +| **[Focus Nfe](packages/fiscal/focus-nfe)** | 19 | `@codespar/mcp-focus-nfe` | API Key | + ### 📱 Communication (8 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Z API](packages/communication/z-api)** | 27 | `@codespar/mcp-z-api` | API Key | -| **[Evolution API](packages/communication/evolution-api)** | 25 | `@codespar/mcp-evolution-api` | API Key | -| **[Twilio](packages/communication/twilio)** | 22 | `@codespar/mcp-twilio` | API Key | -| **[Whatsapp Cloud](packages/communication/whatsapp-cloud)** | 22 | `@codespar/mcp-whatsapp-cloud` | API Key | -| **[Sendgrid](packages/communication/sendgrid)** | 20 | `@codespar/mcp-sendgrid` | API Key | -| **[Rd Station](packages/communication/rd-station)** | 18 | `@codespar/mcp-rd-station` | API Key | -| **[Take Blip](packages/communication/take-blip)** | 18 | `@codespar/mcp-take-blip` | API Key | -| **[Zenvia](packages/communication/zenvia)** | 18 | `@codespar/mcp-zenvia` | API Key | + +| Server | Tools | npm | Auth | +| ----------------------------------------------------------- | ----- | ------------------------------ | ------- | +| **[Z API](packages/communication/z-api)** | 27 | `@codespar/mcp-z-api` | API Key | +| **[Evolution API](packages/communication/evolution-api)** | 25 | `@codespar/mcp-evolution-api` | API Key | +| **[Twilio](packages/communication/twilio)** | 22 | `@codespar/mcp-twilio` | API Key | +| **[Whatsapp Cloud](packages/communication/whatsapp-cloud)** | 22 | `@codespar/mcp-whatsapp-cloud` | API Key | +| **[Sendgrid](packages/communication/sendgrid)** | 20 | `@codespar/mcp-sendgrid` | API Key | +| **[Rd Station](packages/communication/rd-station)** | 18 | `@codespar/mcp-rd-station` | API Key | +| **[Take Blip](packages/communication/take-blip)** | 18 | `@codespar/mcp-take-blip` | API Key | +| **[Zenvia](packages/communication/zenvia)** | 18 | `@codespar/mcp-zenvia` | API Key | + ### 📦 E-commerce / Logistics (6 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Vtex](packages/ecommerce/vtex)** | 33 | `@codespar/mcp-vtex` | API Key | -| **[Shopify](packages/ecommerce/shopify)** | 28 | `@codespar/mcp-shopify` | API Key | -| **[Amazon](packages/ecommerce/amazon)** alpha | 24 | `@codespar/mcp-amazon` | OAuth2 | -| **[Shopee](packages/ecommerce/shopee)** alpha | 22 | `@codespar/mcp-shopee` | API Key | -| **[Correios](packages/ecommerce/correios)** alpha | 21 | `@codespar/mcp-correios` | API Key | -| **[Melhor Envio](packages/ecommerce/melhor-envio)** | 18 | `@codespar/mcp-melhor-envio` | API Key | + +| Server | Tools | npm | Auth | +| --------------------------------------------------- | ----- | ---------------------------- | ------- | +| **[Vtex](packages/ecommerce/vtex)** | 33 | `@codespar/mcp-vtex` | API Key | +| **[Shopify](packages/ecommerce/shopify)** | 28 | `@codespar/mcp-shopify` | API Key | +| **[Amazon](packages/ecommerce/amazon)** alpha | 24 | `@codespar/mcp-amazon` | OAuth2 | +| **[Shopee](packages/ecommerce/shopee)** alpha | 22 | `@codespar/mcp-shopee` | API Key | +| **[Correios](packages/ecommerce/correios)** alpha | 21 | `@codespar/mcp-correios` | API Key | +| **[Melhor Envio](packages/ecommerce/melhor-envio)** | 18 | `@codespar/mcp-melhor-envio` | API Key | + ### 📊 ERP / Accounting (5 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Omie](packages/erp/omie)** | 30 | `@codespar/mcp-omie` | API Key | -| **[Bling](packages/erp/bling)** | 28 | `@codespar/mcp-bling` | API Key | -| **[Xero](packages/erp/xero)** | 24 | `@codespar/mcp-xero` | API Key | -| **[Quickbooks](packages/erp/quickbooks)** | 22 | `@codespar/mcp-quickbooks` | API Key | -| **[Tiny](packages/erp/tiny)** | 21 | `@codespar/mcp-tiny` | API Key | + +| Server | Tools | npm | Auth | +| ----------------------------------------- | ----- | -------------------------- | ------- | +| **[Omie](packages/erp/omie)** | 30 | `@codespar/mcp-omie` | API Key | +| **[Bling](packages/erp/bling)** | 28 | `@codespar/mcp-bling` | API Key | +| **[Xero](packages/erp/xero)** | 24 | `@codespar/mcp-xero` | API Key | +| **[Quickbooks](packages/erp/quickbooks)** | 22 | `@codespar/mcp-quickbooks` | API Key | +| **[Tiny](packages/erp/tiny)** | 21 | `@codespar/mcp-tiny` | API Key | + ### 🪪 Identity & KYC (5 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Brasil API](packages/identity/brasil-api)** | 24 | `@codespar/mcp-brasil-api` | No auth | -| **[Jumio](packages/identity/jumio)** | 20 | `@codespar/mcp-jumio` | API Key | -| **[Onfido](packages/identity/onfido)** | 20 | `@codespar/mcp-onfido` | API Key | -| **[Persona](packages/identity/persona)** | 20 | `@codespar/mcp-persona` | API Key | -| **[Unico](packages/identity/unico)** alpha | 18 | `@codespar/mcp-unico` | OAuth2 | + +| Server | Tools | npm | Auth | +| ---------------------------------------------- | ----- | -------------------------- | ------- | +| **[Brasil API](packages/identity/brasil-api)** | 24 | `@codespar/mcp-brasil-api` | No auth | +| **[Jumio](packages/identity/jumio)** | 20 | `@codespar/mcp-jumio` | API Key | +| **[Onfido](packages/identity/onfido)** | 20 | `@codespar/mcp-onfido` | API Key | +| **[Persona](packages/identity/persona)** | 20 | `@codespar/mcp-persona` | API Key | +| **[Unico](packages/identity/unico)** alpha | 18 | `@codespar/mcp-unico` | OAuth2 | + ### 🛡️ Fraud & Risk (4 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Sift](packages/fraud/sift)** alpha | 20 | `@codespar/mcp-sift` | API Key | -| **[Clearsale](packages/fraud/clearsale)** alpha | 18 | `@codespar/mcp-clearsale` | API Key | -| **[Konduto](packages/fraud/konduto)** alpha | 18 | `@codespar/mcp-konduto` | API Key | -| **[Legiti](packages/fraud/legiti)** alpha | 18 | `@codespar/mcp-legiti` | API Key | + +| Server | Tools | npm | Auth | +| ----------------------------------------------- | ----- | ------------------------- | ------- | +| **[Sift](packages/fraud/sift)** alpha | 20 | `@codespar/mcp-sift` | API Key | +| **[Clearsale](packages/fraud/clearsale)** alpha | 18 | `@codespar/mcp-clearsale` | API Key | +| **[Konduto](packages/fraud/konduto)** alpha | 18 | `@codespar/mcp-konduto` | API Key | +| **[Legiti](packages/fraud/legiti)** alpha | 18 | `@codespar/mcp-legiti` | API Key | + ### 🪙 Crypto / Stablecoins (9 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Circle](packages/crypto/circle)** | 23 | `@codespar/mcp-circle` | API Key | -| **[Foxbit](packages/crypto/foxbit)** | 21 | `@codespar/mcp-foxbit` | API Key | -| **[Bitso](packages/crypto/bitso)** | 20 | `@codespar/mcp-bitso` | API Key | -| **[Mercado Bitcoin](packages/crypto/mercado-bitcoin)** | 20 | `@codespar/mcp-mercado-bitcoin` | API Key | -| **[Moonpay](packages/crypto/moonpay)** | 20 | `@codespar/mcp-moonpay` | API Key | -| **[Unblockpay](packages/crypto/unblockpay)** | 20 | `@codespar/mcp-unblockpay` | API Key | -| **[Coinbase Commerce](packages/crypto/coinbase-commerce)** | 18 | `@codespar/mcp-coinbase-commerce` | API Key | -| **[Transak](packages/crypto/transak)** alpha | 18 | `@codespar/mcp-transak` | API Key | -| **[x402](packages/crypto/x402)** | 10 | `@codespar/mcp-x402` | API Key | + +| Server | Tools | npm | Auth | +| ---------------------------------------------------------- | ----- | --------------------------------- | ------- | +| **[Circle](packages/crypto/circle)** | 23 | `@codespar/mcp-circle` | API Key | +| **[Foxbit](packages/crypto/foxbit)** | 21 | `@codespar/mcp-foxbit` | API Key | +| **[Bitso](packages/crypto/bitso)** | 20 | `@codespar/mcp-bitso` | API Key | +| **[Mercado Bitcoin](packages/crypto/mercado-bitcoin)** | 20 | `@codespar/mcp-mercado-bitcoin` | API Key | +| **[Moonpay](packages/crypto/moonpay)** | 20 | `@codespar/mcp-moonpay` | API Key | +| **[Unblockpay](packages/crypto/unblockpay)** | 20 | `@codespar/mcp-unblockpay` | API Key | +| **[Coinbase Commerce](packages/crypto/coinbase-commerce)** | 18 | `@codespar/mcp-coinbase-commerce` | API Key | +| **[Transak](packages/crypto/transak)** alpha | 18 | `@codespar/mcp-transak` | API Key | +| **[x402](packages/crypto/x402)** | 10 | `@codespar/mcp-x402` | API Key | + ### 🇦🇷 Argentina (5 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Tienda Nube](packages/argentina/tienda-nube)** | 24 | `@codespar/mcp-tienda-nube` | API Key | -| **[Colppy](packages/argentina/colppy)** alpha | 22 | `@codespar/mcp-colppy` | API Key | -| **[AFIP](packages/argentina/afip)** alpha | 20 | `@codespar/mcp-afip` | API Key | -| **[Andreani](packages/argentina/andreani)** alpha | 18 | `@codespar/mcp-andreani` | API Key | -| **[BCRA](packages/argentina/bcra)** | 16 | `@codespar/mcp-bcra` | No auth | + +| Server | Tools | npm | Auth | +| ------------------------------------------------- | ----- | --------------------------- | ------- | +| **[Tienda Nube](packages/argentina/tienda-nube)** | 24 | `@codespar/mcp-tienda-nube` | API Key | +| **[Colppy](packages/argentina/colppy)** alpha | 22 | `@codespar/mcp-colppy` | API Key | +| **[AFIP](packages/argentina/afip)** alpha | 20 | `@codespar/mcp-afip` | API Key | +| **[Andreani](packages/argentina/andreani)** alpha | 18 | `@codespar/mcp-andreani` | API Key | +| **[BCRA](packages/argentina/bcra)** | 16 | `@codespar/mcp-bcra` | No auth | + ### 🇨🇴 Colombia (5 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Siigo](packages/colombia/siigo)** | 22 | `@codespar/mcp-siigo` | API Key | -| **[Wompi](packages/colombia/wompi)** | 22 | `@codespar/mcp-wompi` | API Key | -| **[Alegra](packages/colombia/alegra)** | 20 | `@codespar/mcp-alegra` | API Key | -| **[Coordinadora](packages/colombia/coordinadora)** alpha | 19 | `@codespar/mcp-coordinadora` | API Key | -| **[Nequi](packages/colombia/nequi)** alpha | 16 | `@codespar/mcp-nequi` | OAuth2 | + +| Server | Tools | npm | Auth | +| -------------------------------------------------------- | ----- | ---------------------------- | ------- | +| **[Siigo](packages/colombia/siigo)** | 22 | `@codespar/mcp-siigo` | API Key | +| **[Wompi](packages/colombia/wompi)** | 22 | `@codespar/mcp-wompi` | API Key | +| **[Alegra](packages/colombia/alegra)** | 20 | `@codespar/mcp-alegra` | API Key | +| **[Coordinadora](packages/colombia/coordinadora)** alpha | 19 | `@codespar/mcp-coordinadora` | API Key | +| **[Nequi](packages/colombia/nequi)** alpha | 16 | `@codespar/mcp-nequi` | OAuth2 | + ### 🇲🇽 Mexico (6 servers) -| Server | Tools | npm | Auth | -|---|---|---|---| -| **[Belvo](packages/mexico/belvo)** | 24 | `@codespar/mcp-belvo` | API Key | -| **[Skydropx](packages/mexico/skydropx)** | 23 | `@codespar/mcp-skydropx` | API Key | -| **[Conekta](packages/mexico/conekta)** | 21 | `@codespar/mcp-conekta` | API Key | -| **[Bind ERP](packages/mexico/bind-erp)** | 20 | `@codespar/mcp-bind-erp` | API Key | -| **[Facturapi](packages/mexico/facturapi)** | 20 | `@codespar/mcp-facturapi` | API Key | -| **[STP/SPEI](packages/mexico/stp-spei)** alpha | 18 | `@codespar/mcp-stp-spei` | API Key | + +| Server | Tools | npm | Auth | +| ---------------------------------------------- | ----- | ------------------------- | ------- | +| **[Belvo](packages/mexico/belvo)** | 24 | `@codespar/mcp-belvo` | API Key | +| **[Skydropx](packages/mexico/skydropx)** | 23 | `@codespar/mcp-skydropx` | API Key | +| **[Conekta](packages/mexico/conekta)** | 21 | `@codespar/mcp-conekta` | API Key | +| **[Bind ERP](packages/mexico/bind-erp)** | 20 | `@codespar/mcp-bind-erp` | API Key | +| **[Facturapi](packages/mexico/facturapi)** | 20 | `@codespar/mcp-facturapi` | API Key | +| **[STP/SPEI](packages/mexico/stp-spei)** alpha | 18 | `@codespar/mcp-stp-spei` | API Key | --- @@ -380,6 +398,7 @@ LATAM API / Agentic Protocol (Stripe ACP, x402, Asaas, Mercado Pago, NFe.io, etc ``` Each MCP server in this repo: + - Exposes **typed tools** with input/output schemas - Handles **authentication** (OAuth, mTLS, API keys, Basic Auth, JWT-RSA, signed requests) - Supports **dual transport** — stdio (default) and **Streamable HTTP** (`--http` flag) @@ -425,7 +444,7 @@ Status is shown on every package page at [codespar.dev/servers](https://codespar ## About CodeSpar -[CodeSpar](https://codespar.dev) builds **commerce infrastructure for AI agents in Latin America** — an MCP catalog (this repo), a runtime + SDK ([`@codespar/sdk`](https://www.npmjs.com/package/@codespar/sdk) on npm, [`codespar`](https://pypi.org/project/codespar/) on PyPI), and a managed-tier governance product (AgentGate: programmable wallet, policy engine, CFO-grade audit, fiscal-compliance certifications). +[CodeSpar](https://codespar.dev) builds **commerce infrastructure for AI agents in Latin America** — an MCP catalog (this repo), a runtime + SDK (`[@codespar/sdk](https://www.npmjs.com/package/@codespar/sdk)` on npm, `[codespar](https://pypi.org/project/codespar/)` on PyPI), and a managed-tier governance product (AgentGate: programmable wallet, policy engine, CFO-grade audit, fiscal-compliance certifications). **Individual MCP servers are useful. Orchestrating many with governance is powerful.** That's what CodeSpar does. @@ -439,4 +458,4 @@ We welcome contributions. See [CONTRIBUTING.md](docs/CONTRIBUTING.md). ## License -MIT — use freely in commercial and open source projects. +MIT — use freely in commercial and open source projects. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7a965d05..9fe121ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,6 +58,10 @@ "resolved": "packages/payments/asaas", "link": true }, + "node_modules/@codespar/mcp-banco-do-brasil": { + "resolved": "packages/banking/banco-do-brasil", + "link": true + }, "node_modules/@codespar/mcp-bcra": { "resolved": "packages/argentina/bcra", "link": true @@ -66,6 +70,10 @@ "resolved": "packages/mexico/belvo", "link": true }, + "node_modules/@codespar/mcp-bigdatacorp": { + "resolved": "packages/identity/bigdatacorp", + "link": true + }, "node_modules/@codespar/mcp-bind-erp": { "resolved": "packages/mexico/bind-erp", "link": true @@ -94,6 +102,18 @@ "resolved": "packages/payments/braspag", "link": true }, + "node_modules/@codespar/mcp-btg": { + "resolved": "packages/banking/btg", + "link": true + }, + "node_modules/@codespar/mcp-c6": { + "resolved": "packages/banking/c6", + "link": true + }, + "node_modules/@codespar/mcp-caf": { + "resolved": "packages/identity/caf", + "link": true + }, "node_modules/@codespar/mcp-caixa": { "resolved": "packages/banking/caixa", "link": true @@ -102,6 +122,10 @@ "resolved": "packages/payments/celcoin", "link": true }, + "node_modules/@codespar/mcp-certta": { + "resolved": "packages/identity/certta", + "link": true + }, "node_modules/@codespar/mcp-chargebee": { "resolved": "packages/payments/chargebee", "link": true @@ -114,6 +138,10 @@ "resolved": "packages/crypto/circle", "link": true }, + "node_modules/@codespar/mcp-coinbase-cdp": { + "resolved": "packages/crypto/coinbase-cdp", + "link": true + }, "node_modules/@codespar/mcp-coinbase-commerce": { "resolved": "packages/crypto/coinbase-commerce", "link": true @@ -178,6 +206,10 @@ "resolved": "packages/payments/getnet", "link": true }, + "node_modules/@codespar/mcp-iniciador": { + "resolved": "packages/banking/iniciador", + "link": true + }, "node_modules/@codespar/mcp-inter-bank": { "resolved": "packages/payments/inter-bank", "link": true @@ -202,6 +234,10 @@ "resolved": "packages/payments/khipu", "link": true }, + "node_modules/@codespar/mcp-malga": { + "resolved": "packages/payments/malga", + "link": true + }, "node_modules/@codespar/mcp-matera": { "resolved": "packages/banking/matera", "link": true @@ -270,6 +306,10 @@ "resolved": "packages/payments/pagseguro", "link": true }, + "node_modules/@codespar/mcp-paypal": { + "resolved": "packages/payments/paypal", + "link": true + }, "node_modules/@codespar/mcp-persona": { "resolved": "packages/identity/persona", "link": true @@ -282,6 +322,10 @@ "resolved": "packages/payments/pix-bcb", "link": true }, + "node_modules/@codespar/mcp-pluggy": { + "resolved": "packages/banking/pluggy", + "link": true + }, "node_modules/@codespar/mcp-quickbooks": { "resolved": "packages/erp/quickbooks", "link": true @@ -322,6 +366,10 @@ "resolved": "packages/ecommerce/shopify", "link": true }, + "node_modules/@codespar/mcp-sicoob": { + "resolved": "packages/banking/sicoob", + "link": true + }, "node_modules/@codespar/mcp-siigo": { "resolved": "packages/colombia/siigo", "link": true @@ -398,6 +446,10 @@ "resolved": "packages/communication/whatsapp-cloud", "link": true }, + "node_modules/@codespar/mcp-wise": { + "resolved": "packages/payments/wise", + "link": true + }, "node_modules/@codespar/mcp-wompi": { "resolved": "packages/colombia/wompi", "link": true @@ -427,9 +479,9 @@ "link": true }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -440,13 +492,13 @@ "aix" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -457,13 +509,13 @@ "android" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -474,13 +526,13 @@ "android" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -491,13 +543,13 @@ "android" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -508,13 +560,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -525,13 +577,13 @@ "darwin" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -542,13 +594,13 @@ "freebsd" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -559,13 +611,13 @@ "freebsd" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -576,13 +628,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -593,13 +645,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -610,13 +662,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -627,13 +679,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -644,13 +696,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -661,13 +713,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -678,13 +730,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -695,13 +747,13 @@ "linux" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -712,30 +764,13 @@ "linux" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -746,30 +781,13 @@ "netbsd" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -780,30 +798,13 @@ "openbsd" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -814,13 +815,13 @@ "sunos" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -831,13 +832,13 @@ "win32" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -848,13 +849,13 @@ "win32" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -865,7 +866,7 @@ "win32" ], "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/@hono/node-server": { @@ -1860,9 +1861,9 @@ } }, "node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1870,35 +1871,32 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=18" + "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.7", - "@esbuild/android-arm": "0.27.7", - "@esbuild/android-arm64": "0.27.7", - "@esbuild/android-x64": "0.27.7", - "@esbuild/darwin-arm64": "0.27.7", - "@esbuild/darwin-x64": "0.27.7", - "@esbuild/freebsd-arm64": "0.27.7", - "@esbuild/freebsd-x64": "0.27.7", - "@esbuild/linux-arm": "0.27.7", - "@esbuild/linux-arm64": "0.27.7", - "@esbuild/linux-ia32": "0.27.7", - "@esbuild/linux-loong64": "0.27.7", - "@esbuild/linux-mips64el": "0.27.7", - "@esbuild/linux-ppc64": "0.27.7", - "@esbuild/linux-riscv64": "0.27.7", - "@esbuild/linux-s390x": "0.27.7", - "@esbuild/linux-x64": "0.27.7", - "@esbuild/netbsd-arm64": "0.27.7", - "@esbuild/netbsd-x64": "0.27.7", - "@esbuild/openbsd-arm64": "0.27.7", - "@esbuild/openbsd-x64": "0.27.7", - "@esbuild/openharmony-arm64": "0.27.7", - "@esbuild/sunos-x64": "0.27.7", - "@esbuild/win32-arm64": "0.27.7", - "@esbuild/win32-ia32": "0.27.7", - "@esbuild/win32-x64": "0.27.7" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/escape-html": { @@ -3053,24 +3051,21 @@ } }, "node_modules/vite": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", - "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -3079,25 +3074,19 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, - "jiti": { - "optional": true - }, "less": { "optional": true }, @@ -3118,12 +3107,6 @@ }, "terser": { "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true } } }, @@ -3281,7 +3264,7 @@ }, "packages/argentina/afip": { "name": "@codespar/mcp-afip", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3313,7 +3296,7 @@ }, "packages/argentina/andreani": { "name": "@codespar/mcp-andreani", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3345,7 +3328,7 @@ }, "packages/argentina/bcra": { "name": "@codespar/mcp-bcra", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3377,7 +3360,7 @@ }, "packages/argentina/colppy": { "name": "@codespar/mcp-colppy", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3409,7 +3392,7 @@ }, "packages/argentina/tienda-nube": { "name": "@codespar/mcp-tienda-nube", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3439,9 +3422,34 @@ "dev": true, "license": "MIT" }, + "packages/banking/banco-do-brasil": { + "name": "@codespar/mcp-banco-do-brasil", + "version": "0.1.0-alpha.2", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0", + "zod": "^3.23.0" + }, + "bin": { + "mcp-banco-do-brasil": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + } + }, + "packages/banking/banco-do-brasil/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "packages/banking/bradesco": { "name": "@codespar/mcp-bradesco", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3454,9 +3462,39 @@ "typescript": "^5.8.0" } }, + "packages/banking/btg": { + "name": "@codespar/mcp-btg", + "version": "0.1.0-alpha.2", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-btg": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + } + }, + "packages/banking/c6": { + "name": "@codespar/mcp-c6", + "version": "0.1.0-alpha.2", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-c6": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + } + }, "packages/banking/caixa": { "name": "@codespar/mcp-caixa", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3471,7 +3509,7 @@ }, "packages/banking/dock": { "name": "@codespar/mcp-dock", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3485,9 +3523,41 @@ "typescript": "^5.8.0" } }, + "packages/banking/iniciador": { + "name": "@codespar/mcp-iniciador", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-iniciador": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^22.0.0", + "typescript": "^5.8.0" + } + }, + "packages/banking/iniciador/node_modules/@types/node": { + "version": "22.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", + "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "packages/banking/iniciador/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "packages/banking/itau": { "name": "@codespar/mcp-itau", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3502,7 +3572,7 @@ }, "packages/banking/matera": { "name": "@codespar/mcp-matera", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3518,7 +3588,7 @@ }, "packages/banking/open-finance": { "name": "@codespar/mcp-open-finance", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3531,9 +3601,41 @@ "typescript": "^5.8.0" } }, + "packages/banking/pluggy": { + "name": "@codespar/mcp-pluggy", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-pluggy": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^22.0.0", + "typescript": "^5.8.0" + } + }, + "packages/banking/pluggy/node_modules/@types/node": { + "version": "22.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", + "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "packages/banking/pluggy/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "packages/banking/santander": { "name": "@codespar/mcp-santander", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3546,9 +3648,24 @@ "typescript": "^5.8.0" } }, + "packages/banking/sicoob": { + "name": "@codespar/mcp-sicoob", + "version": "0.1.0-alpha.2", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-sicoob": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + } + }, "packages/banking/stark-bank": { "name": "@codespar/mcp-stark-bank", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3563,7 +3680,7 @@ }, "packages/colombia/alegra": { "name": "@codespar/mcp-alegra", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3595,7 +3712,7 @@ }, "packages/colombia/coordinadora": { "name": "@codespar/mcp-coordinadora", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3627,7 +3744,7 @@ }, "packages/colombia/nequi": { "name": "@codespar/mcp-nequi", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3659,7 +3776,7 @@ }, "packages/colombia/siigo": { "name": "@codespar/mcp-siigo", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3691,7 +3808,7 @@ }, "packages/colombia/wompi": { "name": "@codespar/mcp-wompi", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3723,7 +3840,7 @@ }, "packages/communication/evolution-api": { "name": "@codespar/mcp-evolution-api", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3738,7 +3855,7 @@ }, "packages/communication/rd-station": { "name": "@codespar/mcp-rd-station", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3753,7 +3870,7 @@ }, "packages/communication/sendgrid": { "name": "@codespar/mcp-sendgrid", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3768,7 +3885,7 @@ }, "packages/communication/take-blip": { "name": "@codespar/mcp-take-blip", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3783,7 +3900,7 @@ }, "packages/communication/twilio": { "name": "@codespar/mcp-twilio", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3798,7 +3915,7 @@ }, "packages/communication/whatsapp-cloud": { "name": "@codespar/mcp-whatsapp-cloud", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3813,7 +3930,7 @@ }, "packages/communication/z-api": { "name": "@codespar/mcp-z-api", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0", @@ -3838,7 +3955,7 @@ }, "packages/communication/zenvia": { "name": "@codespar/mcp-zenvia", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3853,7 +3970,7 @@ }, "packages/crypto/bitso": { "name": "@codespar/mcp-bitso", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3885,7 +4002,7 @@ }, "packages/crypto/circle": { "name": "@codespar/mcp-circle", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3915,9 +4032,34 @@ "dev": true, "license": "MIT" }, + "packages/crypto/coinbase-cdp": { + "name": "@codespar/mcp-coinbase-cdp", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0", + "jose": "^5.9.0" + }, + "bin": { + "mcp-coinbase-cdp": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + } + }, + "packages/crypto/coinbase-cdp/node_modules/jose": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "packages/crypto/coinbase-commerce": { "name": "@codespar/mcp-coinbase-commerce", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3932,7 +4074,7 @@ }, "packages/crypto/foxbit": { "name": "@codespar/mcp-foxbit", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3964,7 +4106,7 @@ }, "packages/crypto/mercado-bitcoin": { "name": "@codespar/mcp-mercado-bitcoin", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -3996,7 +4138,7 @@ }, "packages/crypto/moonpay": { "name": "@codespar/mcp-moonpay", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4011,7 +4153,7 @@ }, "packages/crypto/transak": { "name": "@codespar/mcp-transak", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4026,7 +4168,7 @@ }, "packages/crypto/unblockpay": { "name": "@codespar/mcp-unblockpay", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4058,7 +4200,7 @@ }, "packages/crypto/x402": { "name": "@codespar/mcp-x402", - "version": "0.1.2", + "version": "0.1.3", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4090,7 +4232,7 @@ }, "packages/ecommerce/amazon": { "name": "@codespar/mcp-amazon", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4105,7 +4247,7 @@ }, "packages/ecommerce/correios": { "name": "@codespar/mcp-correios", - "version": "0.1.2", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4120,7 +4262,7 @@ }, "packages/ecommerce/melhor-envio": { "name": "@codespar/mcp-melhor-envio", - "version": "0.1.2", + "version": "0.1.3", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0", @@ -4145,7 +4287,7 @@ }, "packages/ecommerce/shopee": { "name": "@codespar/mcp-shopee", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4160,7 +4302,7 @@ }, "packages/ecommerce/shopify": { "name": "@codespar/mcp-shopify", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4175,7 +4317,7 @@ }, "packages/ecommerce/vtex": { "name": "@codespar/mcp-vtex", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4190,7 +4332,7 @@ }, "packages/erp/bling": { "name": "@codespar/mcp-bling", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4205,7 +4347,7 @@ }, "packages/erp/omie": { "name": "@codespar/mcp-omie", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4220,7 +4362,7 @@ }, "packages/erp/quickbooks": { "name": "@codespar/mcp-quickbooks", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4235,7 +4377,7 @@ }, "packages/erp/tiny": { "name": "@codespar/mcp-tiny", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4250,7 +4392,7 @@ }, "packages/erp/xero": { "name": "@codespar/mcp-xero", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4265,7 +4407,7 @@ }, "packages/fiscal/conta-azul": { "name": "@codespar/mcp-conta-azul", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4280,7 +4422,7 @@ }, "packages/fiscal/focus-nfe": { "name": "@codespar/mcp-focus-nfe", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4295,7 +4437,7 @@ }, "packages/fiscal/nfe-io": { "name": "@codespar/mcp-nfe-io", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4310,7 +4452,7 @@ }, "packages/fiscal/nuvem-fiscal": { "name": "@codespar/mcp-nuvem-fiscal", - "version": "0.2.0", + "version": "0.3.0", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4323,9 +4465,41 @@ "typescript": "^5.8.0" } }, + "packages/identity/bigdatacorp": { + "name": "@codespar/mcp-bigdatacorp", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-bigdatacorp": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^22.0.0", + "typescript": "^5.8.0" + } + }, + "packages/identity/bigdatacorp/node_modules/@types/node": { + "version": "22.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", + "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "packages/identity/bigdatacorp/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "packages/identity/brasil-api": { "name": "@codespar/mcp-brasil-api", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0", @@ -4348,9 +4522,73 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "packages/identity/caf": { + "name": "@codespar/mcp-caf", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-caf": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^22.0.0", + "typescript": "^5.8.0" + } + }, + "packages/identity/caf/node_modules/@types/node": { + "version": "22.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", + "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "packages/identity/caf/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "packages/identity/certta": { + "name": "@codespar/mcp-certta", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-certta": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^22.0.0", + "typescript": "^5.8.0" + } + }, + "packages/identity/certta/node_modules/@types/node": { + "version": "22.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", + "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "packages/identity/certta/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "packages/identity/jumio": { "name": "@codespar/mcp-jumio", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4365,7 +4603,7 @@ }, "packages/identity/onfido": { "name": "@codespar/mcp-onfido", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4380,7 +4618,7 @@ }, "packages/identity/persona": { "name": "@codespar/mcp-persona", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4395,7 +4633,7 @@ }, "packages/identity/unico": { "name": "@codespar/mcp-unico", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4410,7 +4648,7 @@ }, "packages/mexico/belvo": { "name": "@codespar/mcp-belvo", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4442,7 +4680,7 @@ }, "packages/mexico/bind-erp": { "name": "@codespar/mcp-bind-erp", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4474,7 +4712,7 @@ }, "packages/mexico/conekta": { "name": "@codespar/mcp-conekta", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4506,7 +4744,7 @@ }, "packages/mexico/facturapi": { "name": "@codespar/mcp-facturapi", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4538,7 +4776,7 @@ }, "packages/mexico/skydropx": { "name": "@codespar/mcp-skydropx", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4570,7 +4808,7 @@ }, "packages/mexico/stp-spei": { "name": "@codespar/mcp-stp-spei", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4602,7 +4840,7 @@ }, "packages/payments/adyen": { "name": "@codespar/mcp-adyen", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4617,7 +4855,7 @@ }, "packages/payments/airwallex": { "name": "@codespar/mcp-airwallex", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4632,7 +4870,7 @@ }, "packages/payments/ap2": { "name": "@codespar/mcp-ap2", - "version": "0.1.2", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4664,7 +4902,7 @@ }, "packages/payments/asaas": { "name": "@codespar/mcp-asaas", - "version": "0.1.2", + "version": "0.2.0", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0", @@ -4689,7 +4927,7 @@ }, "packages/payments/braintree": { "name": "@codespar/mcp-braintree", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4704,7 +4942,7 @@ }, "packages/payments/braspag": { "name": "@codespar/mcp-braspag", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4736,7 +4974,7 @@ }, "packages/payments/celcoin": { "name": "@codespar/mcp-celcoin", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4751,7 +4989,7 @@ }, "packages/payments/chargebee": { "name": "@codespar/mcp-chargebee", - "version": "0.1.0", + "version": "0.1.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4766,7 +5004,7 @@ }, "packages/payments/cielo": { "name": "@codespar/mcp-cielo", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4781,7 +5019,7 @@ }, "packages/payments/culqi": { "name": "@codespar/mcp-culqi", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4796,7 +5034,7 @@ }, "packages/payments/dlocal": { "name": "@codespar/mcp-dlocal", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4811,7 +5049,7 @@ }, "packages/payments/ebanx": { "name": "@codespar/mcp-ebanx", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4826,7 +5064,7 @@ }, "packages/payments/efi": { "name": "@codespar/mcp-efi", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4841,7 +5079,7 @@ }, "packages/payments/getnet": { "name": "@codespar/mcp-getnet", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4856,7 +5094,7 @@ }, "packages/payments/inter-bank": { "name": "@codespar/mcp-inter-bank", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4888,7 +5126,7 @@ }, "packages/payments/iugu": { "name": "@codespar/mcp-iugu", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4903,7 +5141,7 @@ }, "packages/payments/izipay": { "name": "@codespar/mcp-izipay", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4918,7 +5156,7 @@ }, "packages/payments/khipu": { "name": "@codespar/mcp-khipu", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4931,9 +5169,25 @@ "typescript": "^5.8.0" } }, + "packages/payments/malga": { + "name": "@codespar/mcp-malga", + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-malga": "dist/index.js" + }, + "devDependencies": { + "@types/express": "^5.0.6", + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + } + }, "packages/payments/mercado-libre": { "name": "@codespar/mcp-mercado-libre", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4965,7 +5219,7 @@ }, "packages/payments/mercado-pago": { "name": "@codespar/mcp-mercado-pago", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -4997,7 +5251,7 @@ }, "packages/payments/nubank": { "name": "@codespar/mcp-nubank", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5029,7 +5283,7 @@ }, "packages/payments/nupay": { "name": "@codespar/mcp-nupay", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5044,7 +5298,7 @@ }, "packages/payments/openpay": { "name": "@codespar/mcp-openpay", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5059,7 +5313,7 @@ }, "packages/payments/pagar-me": { "name": "@codespar/mcp-pagar-me", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5074,7 +5328,7 @@ }, "packages/payments/pagseguro": { "name": "@codespar/mcp-pagseguro", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5087,9 +5341,24 @@ "typescript": "^5.8.0" } }, + "packages/payments/paypal": { + "name": "@codespar/mcp-paypal", + "version": "0.1.1", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-paypal": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + } + }, "packages/payments/picpay": { "name": "@codespar/mcp-picpay", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5104,7 +5373,7 @@ }, "packages/payments/pix-bcb": { "name": "@codespar/mcp-pix-bcb", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5119,7 +5388,7 @@ }, "packages/payments/rapyd": { "name": "@codespar/mcp-rapyd", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5134,7 +5403,7 @@ }, "packages/payments/rede": { "name": "@codespar/mcp-rede", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5149,7 +5418,7 @@ }, "packages/payments/safrapay": { "name": "@codespar/mcp-safrapay", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5164,7 +5433,7 @@ }, "packages/payments/stone": { "name": "@codespar/mcp-stone", - "version": "0.2.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5179,7 +5448,7 @@ }, "packages/payments/stripe": { "name": "@codespar/mcp-stripe", - "version": "0.1.0", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5194,7 +5463,7 @@ }, "packages/payments/stripe-acp": { "name": "@codespar/mcp-stripe-acp", - "version": "0.1.2", + "version": "0.1.3", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5226,7 +5495,7 @@ }, "packages/payments/transbank": { "name": "@codespar/mcp-transbank", - "version": "0.1.0", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5241,7 +5510,7 @@ }, "packages/payments/ucp": { "name": "@codespar/mcp-ucp", - "version": "0.1.2", + "version": "0.1.3", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5273,7 +5542,7 @@ }, "packages/payments/vindi": { "name": "@codespar/mcp-vindi", - "version": "0.1.2", + "version": "0.2.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5286,9 +5555,24 @@ "typescript": "^5.8.0" } }, + "packages/payments/wise": { + "name": "@codespar/mcp-wise", + "version": "0.1.1", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "bin": { + "mcp-wise": "dist/index.js" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + } + }, "packages/payments/worldpay": { "name": "@codespar/mcp-worldpay", - "version": "0.1.0-alpha.1", + "version": "0.2.0-alpha.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0" @@ -5303,7 +5587,7 @@ }, "packages/payments/zoop": { "name": "@codespar/mcp-zoop", - "version": "0.1.2", + "version": "0.1.3", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.0.0", diff --git a/packages/payments/malga/README.md b/packages/payments/malga/README.md new file mode 100644 index 00000000..9c26ba5e --- /dev/null +++ b/packages/payments/malga/README.md @@ -0,0 +1,209 @@ +# @codespar/mcp-malga + +> MCP server for **Malga** — Brazilian payments orchestration with credit card, Pix, boleto, and voucher + +[![npm](https://img.shields.io/npm/v/@codespar/mcp-malga)](https://www.npmjs.com/package/@codespar/mcp-malga) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) + +## What is Malga? + +**Malga** is a Brazilian payments orchestration platform. It exposes a single API across multiple acquirers (Cielo, Rede, Stone, Adyen) covering charges (credit card, Pix, boleto, voucher), capture and refund, customers, saved cards and tokenization, merchants (sub-accounts), webhooks, and checkout sessions (1:1 and 1:N payment links). + +This MCP server wraps the Malga REST API so AI agents can operate payments end-to-end in sandbox or production. + +## Quick Start + +### Claude Desktop + +Add to `~/.config/claude/claude_desktop_config.json`: + +```json +{ + "mcpServers": { + "malga": { + "command": "npx", + "args": ["-y", "@codespar/mcp-malga"], + "env": { + "MALGA_CLIENT_ID": "your-client-id", + "MALGA_API_KEY": "your-api-key", + "MALGA_SANDBOX": "true" + } + } + } +} +``` + +### Claude Code + +```bash +claude mcp add malga -- npx @codespar/mcp-malga +``` + +### Cursor / VS Code + +Add to `.cursor/mcp.json` or `.vscode/mcp.json`: + +```json +{ + "servers": { + "malga": { + "command": "npx", + "args": ["-y", "@codespar/mcp-malga"], + "env": { + "MALGA_CLIENT_ID": "your-client-id", + "MALGA_API_KEY": "your-api-key", + "MALGA_SANDBOX": "true" + } + } + } +} +``` + +## Tools (24) + +### Charges + +| Tool | Purpose | +|---|---| +| `create_charge` | Create a charge (credit card, Pix, boleto, or voucher). `capture` defaults to `false` (pre-authorization) | +| `get_charge` | Get charge details by ID | +| `list_charges` | List charges with optional filters and pagination | +| `capture_charge` | Capture a pre-authorized charge | +| `refund_charge` | Refund a charge (full or partial) | + +### Customers + +| Tool | Purpose | +|---|---| +| `create_customer` | Create a customer for charges and saved cards | +| `get_customer` | Get customer details by ID | +| `list_customers` | List customers with optional pagination | + +### Cards / Tokens + +| Tool | Purpose | +|---|---| +| `create_card` | Tokenize and save a card for a customer | +| `get_card` | Get card details by ID | +| `list_customer_cards` | List saved cards for a customer | +| `create_token` | Create a card token for one-time use | + +### Merchants + +| Tool | Purpose | +|---|---| +| `get_merchant` | Get merchant details by ID | +| `list_merchants` | List merchants | + +### Webhooks + +| Tool | Purpose | +|---|---| +| `create_webhook` | Register a webhook endpoint | +| `list_webhooks` | List registered webhooks | + +### Sessions + +| Tool | Purpose | +|---|---| +| `create_session` | Create a checkout session for deferred payment | +| `get_session` | Get session details and status | +| `pay_session` | Pay an existing session with a payment method | +| `cancel_session` | Cancel a pending payment session | + +### Settings (payment link branding) + +| Tool | Purpose | +|---|---| +| `get_settings` | Get payment link branding settings (client or merchant) | +| `create_settings` | Create payment link branding (colors, logo, company URL) | +| `update_settings` | Update payment link branding settings | + +### Sandbox + +| Tool | Purpose | +|---|---| +| `get_sandbox_guide` | Return sandbox simulation rules (card, CVV, capture/refund) | + +## Payment link settings + +Customize checkout/payment link appearance via `GET/POST/PATCH /v1/settings`: + +- **Scope:** client-wide by default, or per merchant with `merchantId` (`X-Merchant-Id` header). +- **GET:** with `merchantId`, returns merchant config or falls back to client default. +- **POST/PATCH:** exact scope only (no fallback). +- **Branding fields:** `mainColor`, `secondaryColor`, `attentionColor`, `errorColor`, `successColor`, `backgroundColor`, `companyUrl`, `mastercardClickToPayDpaid`, and optional logo. +- **Logo upload:** pass `logoPath` (local file) or `logoBase64` + `logoFilename` (.png/.jpg, max 1000px). +- **PATCH:** empty strings are ignored; API returns `422` if no effective fields are sent. + +Reference: [Malga Settings API](https://docs.malga.io/api-reference/settings/recuperar-configuracao-de-link-de-pagamento) + +## Authentication + +Malga uses two headers on every request: + +- `X-Client-Id` — your Malga client ID +- `X-Api-Key` — your Malga API key + +Generate credentials from the Malga dashboard. + +## Sandbox / Testing + +Defaults to sandbox (`https://sandbox-api.malga.io`). Set `MALGA_SANDBOX=false` for production (`https://api.malga.io`). + +### Get your credentials + +1. Go to [Malga](https://malga.io) +2. Create a sandbox account +3. Copy your **Client ID** and **API Key** from the dashboard +4. Set `MALGA_CLIENT_ID` and `MALGA_API_KEY` + +### Sandbox / Simulation Rules + +This server embeds sandbox hints in tool schemas. You can also call `get_sandbox_guide` to retrieve the full rules as JSON. + +#### Card number (last digit) + +| Last digit | Authorized? | Status | +| --- | --- | --- | +| 0, 1 or 4 | Yes | Approved | +| 2 | No | Not authorized | +| 3 | No | Expired card | +| 5 | No | Blocked card | +| 6 | No | Timeout | +| 7 | No | Canceled card | +| 8 | Random | Approved / Timeout | + +Use any test card number from a card generator; the last digit controls the outcome. + +#### CVV (tokenization and saved cards) + +| CVV last digit | Result | +| --- | --- | +| 0 | Validated | +| Any other | Not validated | + +#### Capture and refund failure + +Use `amount: 991` (cents) in `capture_charge` or `refund_charge` to simulate failure. + +Reference: [Malga testing guide](https://docs.malga.io/documentations/welcome/testing) + +## Environment Variables + +| Variable | Required | Description | +|----------|----------|-------------| +| `MALGA_CLIENT_ID` | Yes | Client ID from Malga dashboard | +| `MALGA_API_KEY` | Yes | API key from Malga dashboard | +| `MALGA_SANDBOX` | No | Defaults to sandbox; set to `"false"` for production | + +## Links + +- [Malga Website](https://malga.io) +- [Malga API Documentation](https://docs.malga.io) +- [MCP Dev LATAM](https://github.com/codespar/mcp-dev-latam) +- [Landing Page](https://codespar.dev/mcp) + +## License + +MIT diff --git a/packages/payments/malga/package.json b/packages/payments/malga/package.json new file mode 100644 index 00000000..51a4fe50 --- /dev/null +++ b/packages/payments/malga/package.json @@ -0,0 +1,25 @@ +{ + "name": "@codespar/mcp-malga", + "version": "0.1.0", + "description": "MCP server for Malga — Brazilian payments API", + "type": "module", + "main": "./dist/index.js", + "bin": { + "mcp-malga": "./dist/index.js" + }, + "scripts": { + "build": "tsc", + "start": "node dist/index.js" + }, + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0" + }, + "devDependencies": { + "@types/express": "^5.0.6", + "@types/node": "^25.5.0", + "typescript": "^5.8.0" + }, + "keywords": ["mcp", "malga", "payments", "pix", "boleto", "brazil"], + "license": "MIT", + "mcpName": "io.github.codespar/mcp-malga" +} diff --git a/packages/payments/malga/server.json b/packages/payments/malga/server.json new file mode 100644 index 00000000..9134e46e --- /dev/null +++ b/packages/payments/malga/server.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "io.github.codespar/mcp-malga", + "description": "MCP server for Malga — Brazilian payments orchestrator. Single API across multiple acquirers (Cielo, Rede, Stone, Adyen) with card, Pix, and boleto support.", + "repository": { + "url": "https://github.com/codespar/mcp-dev-latam", + "source": "github", + "subfolder": "packages/payments/malga" + }, + "version": "0.1.0", + "packages": [ + { + "registryType": "npm", + "identifier": "@codespar/mcp-malga", + "version": "0.1.0", + "transport": { + "type": "stdio" + }, + "environmentVariables": [ + { + "name": "MALGA_CLIENT_ID", + "description": "Tenant identifier sent as X-Client-Id header on every request.", + "isRequired": true, + "format": "string", + "isSecret": false + }, + { + "name": "MALGA_API_KEY", + "description": "Secret key sent as X-Api-Key header on every request.", + "isRequired": true, + "format": "string", + "isSecret": true + }, + { + "name": "MALGA_SANDBOX", + "description": "Defaults to sandbox (https://sandbox-api.malga.io). Set to \"false\" for production (https://api.malga.io).", + "isRequired": false, + "format": "string", + "isSecret": false + } + ] + } + ], + "provider": { + "homepage": "https://malga.io", + "logoUrl": "https://logo.clearbit.com/malga.io", + "logoFallback": "https://www.google.com/s2/favicons?domain=malga.io&sz=128", + "docsUrl": "https://docs.malga.io", + "sandbox": { + "available": true, + "url": "https://sandbox-api.malga.io" + } + } +} diff --git a/packages/payments/malga/src/index.ts b/packages/payments/malga/src/index.ts new file mode 100644 index 00000000..59e7dea8 --- /dev/null +++ b/packages/payments/malga/src/index.ts @@ -0,0 +1,1000 @@ +#!/usr/bin/env node + +/** + * MCP Server for Malga — Brazilian payments orchestration platform. + * + * Exposes a single API across multiple acquirers (Cielo, Rede, Stone, Adyen) + * covering charges (credit card, Pix, boleto, voucher), capture and refund, + * customers, saved cards and tokenization, merchants (sub-accounts), webhooks + * and checkout sessions (1:1 and 1:N payment links). + * + * Tools (24): + * Charges + * - create_charge + * - get_charge + * - list_charges + * - capture_charge + * - refund_charge + * Customers + * - create_customer + * - get_customer + * - list_customers + * Cards / Tokens + * - create_card + * - get_card + * - list_customer_cards + * - create_token + * Merchants + * - get_merchant + * - list_merchants + * Webhooks + * - create_webhook + * - list_webhooks + * Sessions + * - create_session + * - get_session + * - pay_session + * - cancel_session + * Settings (payment link branding) + * - get_settings + * - create_settings + * - update_settings + * Sandbox + * - get_sandbox_guide + * + * Environment: + * MALGA_CLIENT_ID — tenant identifier sent as X-Client-Id header (required) + * MALGA_API_KEY — secret key sent as X-Api-Key header (required) + * MALGA_SANDBOX — set to "false" for production (default: sandbox) + * + * Docs: https://docs.malga.io + */ + +import { readFileSync } from "node:fs"; +import { basename } from "node:path"; +import { Server } from "@modelcontextprotocol/sdk/server/index.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; +import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js"; +import { + CallToolRequestSchema, + ListToolsRequestSchema, +} from "@modelcontextprotocol/sdk/types.js"; + +const BASE_URL = process.env.MALGA_SANDBOX === "false" + ? "https://api.malga.io" + : "https://sandbox-api.malga.io"; +const CLIENT_ID = process.env.MALGA_CLIENT_ID ?? ""; +const API_KEY = process.env.MALGA_API_KEY ?? ""; + +if (!CLIENT_ID || !API_KEY) { + console.error("Error: MALGA_CLIENT_ID and MALGA_API_KEY environment variables are required."); + process.exit(1); +} + +/** @param overrideApiKey — used by pay_session with the session's publicKey */ +async function malgaRequest(method: string, path: string, body?: unknown, overrideApiKey?: string, merchantId?: string) { + const headers: Record = { + "X-Client-Id": CLIENT_ID, + "X-Api-Key": overrideApiKey ?? API_KEY, + "Content-Type": "application/json", + }; + if (merchantId) headers["X-Merchant-Id"] = merchantId; + + const response = await fetch(`${BASE_URL}${path}`, { + method, + headers, + body: body !== undefined ? JSON.stringify(body) : undefined, + }); + + const data = await response.json(); + + if (!response.ok) { + throw new Error(JSON.stringify(data)); + } + + return data; +} + +async function malgaMultipartRequest(method: string, path: string, form: FormData, merchantId?: string) { + const headers: Record = { + "X-Client-Id": CLIENT_ID, + "X-Api-Key": API_KEY, + }; + if (merchantId) headers["X-Merchant-Id"] = merchantId; + + const response = await fetch(`${BASE_URL}${path}`, { method, headers, body: form }); + const data = await response.json(); + + if (!response.ok) { + throw new Error(JSON.stringify(data)); + } + + return data; +} + +const SETTINGS_TEXT_FIELDS = [ + "mainColor", + "secondaryColor", + "attentionColor", + "errorColor", + "successColor", + "backgroundColor", + "companyUrl", + "mastercardClickToPayDpaid", +] as const; + +function buildSettingsTextFields(a: Record): Record { + const fields: Record = {}; + for (const key of SETTINGS_TEXT_FIELDS) { + if (a[key] !== undefined && a[key] !== "") fields[key] = String(a[key]); + } + return fields; +} + +function appendSettingsLogo(form: FormData, a: Record) { + if (a.logoPath) { + const path = String(a.logoPath); + const buf = readFileSync(path); + form.append("logo", new Blob([buf]), basename(path)); + return; + } + if (a.logoBase64) { + const filename = String(a.logoFilename ?? "logo.png"); + const buf = Buffer.from(String(a.logoBase64), "base64"); + form.append("logo", new Blob([buf]), filename); + } +} + +const SETTINGS_PROPERTIES_SCHEMA = { + merchantId: { + type: "string", + format: "uuid", + description: "Optional merchant ID (sent as X-Merchant-Id). GET falls back to client default if merchant config is missing. POST/PATCH scope is exact.", + }, + mainColor: { type: "string", description: "Primary brand color (e.g. #000000)" }, + secondaryColor: { type: "string", description: "Secondary brand color" }, + attentionColor: { type: "string", description: "Alert/warning color" }, + errorColor: { type: "string", description: "Error message color" }, + successColor: { type: "string", description: "Success message color" }, + backgroundColor: { type: "string", description: "Background color" }, + companyUrl: { type: "string", description: "URL used in the payment link (e.g. https://www.company.com)" }, + mastercardClickToPayDpaid: { + type: "string", + description: "Mastercard Click to Pay dpaId (optional). Enables Click to Pay on payment links.", + }, +}; + +async function getChargeAmount(chargeId: string): Promise { + const charge = (await malgaRequest("GET", `/v1/charges/${chargeId}`)) as { amount: number }; + return charge.amount; +} + +const SANDBOX_CARD_NUMBER_DESC = + "Card number (16 digits). SANDBOX — the last digit determines the outcome: 0/1/4 = Approved | 2 = Not authorized | 3 = Expired | 5 = Blocked | 6 = Timeout | 7 = Canceled | 8 = Random"; + +const SANDBOX_CVV_DESC = + "CVV (3 or 4 digits). SANDBOX — CVV ending in 0 = validated; any other value = not validated."; + +const SANDBOX_GUIDE = { + environment: BASE_URL, + docsUrl: "https://docs.malga.io/documentations/welcome/testing", + cardLastDigit: { + description: "The last digit of the card number determines the transaction outcome in sandbox.", + rules: [ + { lastDigit: "0, 1 or 4", authorized: true, status: "Approved" }, + { lastDigit: "2", authorized: false, status: "Not authorized" }, + { lastDigit: "3", authorized: false, status: "Expired card" }, + { lastDigit: "5", authorized: false, status: "Blocked card" }, + { lastDigit: "6", authorized: false, status: "Timeout" }, + { lastDigit: "7", authorized: false, status: "Canceled card" }, + { lastDigit: "8", authorized: "random", status: "Approved / Timeout (random)" }, + ], + }, + cvv: { + description: "CVV validation rule in sandbox (tokenization and saved-card charges).", + rule: "CVV ending in 0 = validated; any other value = not validated", + }, + captureAndRefund: { + description: "Simulate capture or refund failure.", + rule: "Use amount = 991 (cents) in the capture or refund request", + }, + antifraud: { + description: "The last digit of the document sent in fraudAnalysis when creating the transaction determines the antifraud status.", + rules: [ + { documentLastDigit: "0", authorized: false, status: "Pending", declinedCode: null }, + { documentLastDigit: "1", authorized: true, status: "Approved", declinedCode: null }, + { documentLastDigit: "2", authorized: false, status: "Failed", declinedCode: "random timeout or processing_error" }, + { documentLastDigit: "any other", authorized: false, status: "Rejected", declinedCode: null }, + ], + }, +}; + +const DOCUMENT_SCHEMA = { + type: "object", + properties: { + type: { type: "string", description: "Document type (e.g. cpf, cnpj)" }, + number: { type: "string", description: "Document number" }, + country: { type: "string", description: "ISO country code (e.g. BR)", default: "BR" }, + }, + required: ["type", "number"], +}; + +const PAYMENT_METHOD_ONEOF = [ + { + title: "Credit card", + type: "object", + properties: { + paymentType: { type: "string", enum: ["credit"], description: "Credit card payment method" }, + installments: { type: "integer", minimum: 1, description: "Number of installments (minimum 1)" }, + recurrence: { + type: "string", + enum: ["initial", "subsequent", "unscheduled"], + description: "Indicates whether the transaction is recurring", + }, + }, + required: ["paymentType", "installments"], + }, + { + title: "Pix", + type: "object", + properties: { + paymentType: { type: "string", enum: ["pix"], description: "Pix payment method" }, + expiresIn: { type: "integer", minimum: 1, description: "Charge validity in seconds (e.g. 3600)" }, + }, + required: ["paymentType", "expiresIn"], + }, + { + title: "Boleto", + type: "object", + properties: { + paymentType: { type: "string", enum: ["boleto"], description: "Bank slip (boleto) payment method" }, + expiresDate: { type: "string", description: "Due date as ISO date (e.g. 2026-12-31). Default: 7 days." }, + instructions: { type: "string", description: "Boleto instructions (max 255 characters)" }, + }, + required: ["paymentType"], + }, + { + title: "Voucher", + type: "object", + properties: { + paymentType: { type: "string", enum: ["voucher"], description: "Voucher payment method (VR, Alelo, etc.)" }, + }, + required: ["paymentType"], + }, +]; + +const PAYMENT_SOURCE_ONEOF = [ + { + title: "One-shot card (raw data)", + type: "object", + description: "Direct charge with raw card data without prior tokenization.", + properties: { + sourceType: { type: "string", enum: ["card"] }, + card: { + type: "object", + properties: { + cardHolderName: { type: "string", description: "Cardholder name as printed on the card" }, + cardNumber: { type: "string", description: SANDBOX_CARD_NUMBER_DESC }, + cardCvv: { type: "string", description: SANDBOX_CVV_DESC }, + cardExpirationDate: { type: "string", description: "Expiration date in MM/YYYY format (e.g. 06/2028)" }, + }, + required: ["cardHolderName", "cardNumber", "cardCvv", "cardExpirationDate"], + }, + }, + required: ["sourceType", "card"], + }, + { + title: "Saved card (cardId)", + type: "object", + description: "Charge using a card previously saved via create_card.", + properties: { + sourceType: { type: "string", enum: ["card"] }, + cardId: { type: "string", format: "uuid", description: "Saved card ID" }, + cardCvv: { type: "string", description: `CVV (optional, recommended when the buyer is present). ${SANDBOX_CVV_DESC}` }, + }, + required: ["sourceType", "cardId"], + }, + { + title: "Single-use token", + type: "object", + description: "Charge using a token generated by create_token (single use).", + properties: { + sourceType: { type: "string", enum: ["token"] }, + tokenId: { type: "string", format: "uuid", description: "Generated token ID" }, + }, + required: ["sourceType", "tokenId"], + }, + { + title: "Customer (default card)", + type: "object", + description: "Charges the customer's saved default card.", + properties: { + sourceType: { type: "string", enum: ["customer"] }, + customerId: { type: "string", format: "uuid", description: "Customer ID" }, + cardCvv: { type: "string", description: `CVV (optional). ${SANDBOX_CVV_DESC}` }, + }, + required: ["sourceType", "customerId"], + }, + { + title: "Customer with inline data (Pix/Boleto)", + type: "object", + description: "Pass buyer data inline — required for Pix and Boleto when no customer has been created.", + properties: { + sourceType: { type: "string", enum: ["customer"] }, + customer: { + type: "object", + properties: { + name: { type: "string" }, + email: { type: "string" }, + phoneNumber: { type: "string" }, + document: DOCUMENT_SCHEMA, + }, + required: ["email", "phoneNumber", "document"], + }, + }, + required: ["sourceType", "customer"], + }, +]; + +const SESSION_PAYMENT_METHODS_ITEMS_ONEOF = [ + { + title: "Credit card", + type: "object", + properties: { + paymentType: { type: "string", enum: ["credit"] }, + installments: { type: "integer", minimum: 1, description: "Number of installments" }, + }, + required: ["paymentType", "installments"], + }, + { + title: "Pix", + type: "object", + properties: { + paymentType: { type: "string", enum: ["pix"] }, + expiresIn: { type: "integer", minimum: 1, description: "Validity in seconds (e.g. 3600)" }, + }, + required: ["paymentType", "expiresIn"], + }, + { + title: "Boleto", + type: "object", + properties: { + paymentType: { type: "string", enum: ["boleto"] }, + expiresDate: { type: "string", description: "Due date as ISO date (e.g. 2026-12-31)" }, + }, + required: ["paymentType", "expiresDate"], + }, + { + title: "Drip", + type: "object", + properties: { + paymentType: { type: "string", enum: ["drip"] }, + cancelRedirectUrl: { type: "string" }, + successRedirectUrl: { type: "string" }, + }, + required: ["paymentType"], + }, + { + title: "NuPay", + type: "object", + properties: { + paymentType: { type: "string", enum: ["nupay"] }, + orderUrl: { type: "string" }, + returnUrl: { type: "string" }, + cancelUrl: { type: "string" }, + delayToAutoCancel: { type: "integer", description: "Minutes until automatic expiration" }, + }, + required: ["paymentType"], + }, +]; + +const SESSION_ITEM_SCHEMA = { + type: "object", + properties: { + name: { type: "string", description: "Item name" }, + unitPrice: { type: "integer", minimum: 0, description: "Unit price in cents" }, + quantity: { type: "integer", minimum: 1, description: "Quantity" }, + description: { type: "string", description: "Description (optional)" }, + tangible: { type: "boolean", description: "Physical item (optional)" }, + categoryId: { type: "string", description: "Category ID (optional)" }, + }, + required: ["name", "unitPrice", "quantity"], +}; + +const TOOLS = [ + { + name: "create_charge", + description: "Create a new charge in Malga. Supports credit card (one-shot or saved), token, Pix, and boleto. The `capture` field defaults to `false` in the API — pass `true` for automatic capture. SANDBOX antifraud — the last digit of the document in fraudAnalysis determines the status: 0 = Pending | 1 = Approved | 2 = Failed | other = Rejected. Use get_sandbox_guide for all simulation rules.", + inputSchema: { + type: "object", + properties: { + merchantId: { type: "string", format: "uuid", description: "Merchant ID that will receive the payment" }, + amount: { type: "integer", description: "Amount in cents (e.g. 1000 = R$10.00)" }, + currency: { type: "string", default: "BRL", description: "ISO currency code (default: BRL)" }, + capture: { type: "boolean", default: false, description: "Capture automatically. Default false (pre-authorization)" }, + statementDescriptor: { type: "string", description: "Description shown on the buyer's statement (optional)" }, + description: { type: "string", description: "Internal charge description (optional)" }, + orderId: { type: "string", description: "Order ID in your system (optional)" }, + customerId: { type: "string", format: "uuid", description: "Malga customer ID (optional)" }, + paymentMethod: { + description: "Payment method. Choose ONE of the variants below.", + oneOf: PAYMENT_METHOD_ONEOF, + }, + paymentSource: { + description: "Payment source (card data, token, customer, etc.). Choose ONE of the variants below.", + oneOf: PAYMENT_SOURCE_ONEOF, + }, + }, + required: ["merchantId", "amount", "currency", "paymentMethod", "paymentSource"], + }, + }, + { + name: "get_charge", + description: "Get charge details by ID.", + inputSchema: { + type: "object", + properties: { + chargeId: { type: "string", description: "Charge ID" }, + }, + required: ["chargeId"], + }, + }, + { + name: "list_charges", + description: "List charges with optional filters.", + inputSchema: { + type: "object", + properties: { + status: { + type: "string", + enum: ["pending", "pre_authorized", "authorized", "failed", "canceled", "voided", "charged_back", "refund_pending", "capture_pending"], + description: "Filter by status", + }, + paymentType: { type: "string", enum: ["credit", "pix", "boleto", "voucher", "drip", "nupay", "picpay"], description: "Filter by payment method" }, + limit: { type: "integer", minimum: 1, maximum: 100, description: "Records per page (default 15)" }, + page: { type: "integer", minimum: 1, description: "Page number (default 1)" }, + }, + required: [], + }, + }, + { + name: "capture_charge", + description: "Capture a pre-authorized charge (created with capture: false). If amount is omitted, uses the full charge amount.", + inputSchema: { + type: "object", + properties: { + chargeId: { type: "string", description: "Pre-authorized charge ID" }, + amount: { type: "integer", description: "Amount in cents to capture (default: full charge amount). SANDBOX — use 991 to simulate failure." }, + }, + required: ["chargeId"], + }, + }, + { + name: "refund_charge", + description: "Void/refund an authorized or captured charge. If amount is omitted, uses the full charge amount.", + inputSchema: { + type: "object", + properties: { + chargeId: { type: "string", description: "Charge ID" }, + amount: { type: "integer", description: "Amount in cents to refund (default: full charge amount). SANDBOX — use 991 to simulate failure." }, + }, + required: ["chargeId"], + }, + }, + { + name: "create_customer", + description: "Create a new customer in Malga. Email and document are unique per account.", + inputSchema: { + type: "object", + properties: { + name: { type: "string", description: "Full name" }, + email: { type: "string", description: "Email (unique per account)" }, + phoneNumber: { type: "string", description: "Phone with area code (e.g. +5511999999999)" }, + document: { + ...DOCUMENT_SCHEMA, + description: "Customer document (required)", + }, + address: { + type: "object", + description: "Address (optional)", + properties: { + street: { type: "string" }, + streetNumber: { type: "string" }, + complement: { type: "string" }, + zipCode: { type: "string" }, + country: { type: "string", default: "BR" }, + }, + }, + }, + required: ["name", "email", "phoneNumber", "document"], + }, + }, + { + name: "get_customer", + description: "Get customer details by ID.", + inputSchema: { + type: "object", + properties: { + customerId: { type: "string", description: "Customer ID" }, + }, + required: ["customerId"], + }, + }, + { + name: "list_customers", + description: "List customers with optional pagination.", + inputSchema: { + type: "object", + properties: { + limit: { type: "integer", minimum: 1, maximum: 100, description: "Records per page (default 15)" }, + page: { type: "integer", minimum: 1, description: "Page number (default 1)" }, + }, + required: [], + }, + }, + { + name: "create_card", + description: "Save a card linked to a customer for reuse in future charges. Pass `tokenId` (from create_token) or raw card data — in the latter case tokenization is performed automatically before saving.", + inputSchema: { + type: "object", + properties: { + customerId: { type: "string", format: "uuid", description: "Customer ID to link the card to" }, + tokenId: { type: "string", format: "uuid", description: "Single-use token generated by create_token" }, + number: { type: "string", description: `${SANDBOX_CARD_NUMBER_DESC} Alternative to tokenId.` }, + holderName: { type: "string", description: "Name printed on the card (e.g. JOHN S). Required if tokenId is not provided." }, + expirationDate: { type: "string", description: "Expiration date MM/YYYY. Required if tokenId is not provided." }, + cvv: { type: "string", description: `${SANDBOX_CVV_DESC} Required if tokenId is not provided.` }, + }, + required: ["customerId"], + }, + }, + { + name: "get_card", + description: "Get saved card details by ID.", + inputSchema: { + type: "object", + properties: { + cardId: { type: "string", description: "Card ID" }, + }, + required: ["cardId"], + }, + }, + { + name: "list_customer_cards", + description: "List all saved cards for a customer.", + inputSchema: { + type: "object", + properties: { + customerId: { type: "string", description: "Customer ID" }, + }, + required: ["customerId"], + }, + }, + { + name: "get_merchant", + description: "Get merchant (sub-account) details by ID.", + inputSchema: { + type: "object", + properties: { + merchantId: { type: "string", description: "Merchant ID" }, + }, + required: ["merchantId"], + }, + }, + { + name: "list_merchants", + description: "List merchants (sub-accounts) with optional pagination.", + inputSchema: { + type: "object", + properties: { + limit: { type: "integer", minimum: 1, maximum: 100, description: "Records per page (default 15)" }, + page: { type: "integer", minimum: 1, description: "Page number (default 1)" }, + }, + required: [], + }, + }, + { + name: "create_webhook", + description: "Register an endpoint to receive Malga event notifications. Use `*` in the event field to receive all events.", + inputSchema: { + type: "object", + properties: { + event: { type: "string", description: "Malga event (e.g. transaction.authorized, transaction.voided, transaction.failed) or * for all. See docs.malga.io for the full list." }, + endpoint: { type: "string", description: "HTTPS endpoint URL (e.g. https://example.com/webhook)" }, + version: { type: "number", default: 1.1, description: "Malga API version the webhook implements (default: 1.1)" }, + status: { type: "boolean", default: true, description: "Webhook active (default: true)" }, + }, + required: ["event", "endpoint"], + }, + }, + { + name: "list_webhooks", + description: "List all webhooks configured on the account.", + inputSchema: { + type: "object", + properties: {}, + required: [], + }, + }, + { + name: "create_session", + description: "Create a checkout session (payment link) in Malga. Returns an `id` and a `publicKey` used to pay the session via pay_session. Supports 1:1 (default) and 1:N sessions (multiple payments via maxPayments).", + inputSchema: { + type: "object", + properties: { + merchantId: { type: "string", format: "uuid", description: "Merchant ID that will receive the payment" }, + amount: { type: "integer", minimum: 0, description: "Total amount in cents (optional; calculated from items if omitted)" }, + currency: { type: "string", default: "BRL", description: "ISO currency code (default: BRL)" }, + name: { type: "string", description: "Session identifier name (optional)" }, + description: { type: "string", description: "Session description (optional)" }, + statementDescriptor: { type: "string", minLength: 3, description: "Description on the buyer's statement (optional)" }, + capture: { type: "boolean", description: "Capture automatically (optional)" }, + isActive: { type: "boolean", description: "Whether the session starts active (default true)" }, + createLink: { type: "boolean", description: "Generate a public payment link (optional)" }, + captchaEnabled: { type: "boolean", description: "Enable CAPTCHA on the payment link (optional)" }, + dueDate: { type: "string", description: "Deadline as ISO 8601 — minimum tomorrow (e.g. 2026-12-31 or 2026-12-31T23:59:59Z)" }, + maxPayments: { + description: "Configure as a 1:N link. Use -1 for unlimited or 1–99999 for a fixed limit. Omit for 1:1 session.", + oneOf: [ + { type: "integer", enum: [-1], description: "Unlimited 1:N link" }, + { type: "integer", minimum: 1, maximum: 99999, description: "1:N link with fixed limit" }, + ], + }, + orderId: { type: "string", description: "Order ID in your system (optional)" }, + paymentMethods: { + type: "array", + minItems: 1, + description: "Accepted payment methods. Each item must follow ONE variant (credit, pix, boleto, drip, nupay).", + items: { anyOf: SESSION_PAYMENT_METHODS_ITEMS_ONEOF }, + }, + items: { + type: "array", + minItems: 1, + description: "Order items.", + items: SESSION_ITEM_SCHEMA, + }, + }, + required: ["merchantId", "paymentMethods", "items"], + }, + }, + { + name: "get_session", + description: "Get session details and current status by ID. Includes `publicKey` to pay the session.", + inputSchema: { + type: "object", + properties: { + sessionId: { type: "string", description: "Session ID" }, + }, + required: ["sessionId"], + }, + }, + { + name: "pay_session", + description: "Pay an existing session. IMPORTANT: requires the `publicKey` returned when creating the session (the `publicKey` field from create_session or get_session) — it is used as the authentication key for this call.", + inputSchema: { + type: "object", + properties: { + sessionId: { type: "string", description: "Session ID to pay" }, + publicKey: { type: "string", format: "uuid", description: "Session publicKey (returned by create_session / get_session). Used as X-Api-Key for this call." }, + paymentMethod: { + description: "Payment method. Choose ONE of the variants.", + oneOf: PAYMENT_METHOD_ONEOF, + }, + paymentSource: { + description: "Payment source. Choose ONE of the variants.", + oneOf: PAYMENT_SOURCE_ONEOF, + }, + }, + required: ["sessionId", "publicKey", "paymentMethod", "paymentSource"], + }, + }, + { + name: "cancel_session", + description: "Cancel a pending payment session.", + inputSchema: { + type: "object", + properties: { + sessionId: { type: "string", description: "Session ID to cancel" }, + }, + required: ["sessionId"], + }, + }, + { + name: "create_token", + description: "Tokenize card data generating a temporary single-use token. Does not save the card. Use in `paymentSource: { sourceType: 'token', tokenId }` of create_charge. Use `create_card` to save permanently.", + inputSchema: { + type: "object", + properties: { + cardHolderName: { type: "string", description: "Name printed on the card" }, + cardNumber: { type: "string", description: `${SANDBOX_CARD_NUMBER_DESC} No spaces.` }, + cardExpirationDate: { type: "string", description: "Expiration date in MM/YYYY format (e.g. 12/2026)" }, + cardCvv: { type: "string", description: SANDBOX_CVV_DESC }, + }, + required: ["cardHolderName", "cardNumber", "cardExpirationDate", "cardCvv"], + }, + }, + { + name: "get_sandbox_guide", + description: "Return Malga sandbox simulation rules: card last-digit behavior, CVV rule, capture/refund failure, and antifraud.", + inputSchema: { + type: "object", + properties: {}, + required: [], + }, + }, + { + name: "get_settings", + description: "Get payment link branding settings for the client or a specific merchant. With merchantId, returns merchant config or falls back to client default.", + inputSchema: { + type: "object", + properties: { + merchantId: SETTINGS_PROPERTIES_SCHEMA.merchantId, + }, + required: [], + }, + }, + { + name: "create_settings", + description: "Create payment link branding settings. Uses multipart/form-data (required by the API). Pass logo via logoPath or logoBase64+logoFilename (.png/.jpg, max 1000px). Without merchantId, creates the client default.", + inputSchema: { + type: "object", + properties: { + ...SETTINGS_PROPERTIES_SCHEMA, + logoPath: { type: "string", description: "Local path to logo image (.png or .jpg, max 1000px). Alternative to logoBase64." }, + logoBase64: { type: "string", description: "Base64-encoded logo image. Use with logoFilename." }, + logoFilename: { type: "string", description: "Filename for logoBase64 upload (e.g. logo.png). Defaults to logo.png." }, + }, + required: [], + }, + }, + { + name: "update_settings", + description: "Update payment link branding settings (PATCH /v1/settings). Sends JSON for text fields; uses multipart when a logo is provided. Empty strings are ignored. Returns 422 if no effective fields are sent.", + inputSchema: { + type: "object", + properties: { + ...SETTINGS_PROPERTIES_SCHEMA, + logoPath: { type: "string", description: "Local path to logo image. When set, request uses multipart/form-data." }, + logoBase64: { type: "string", description: "Base64-encoded logo. When set (with or without text fields), request uses multipart/form-data." }, + logoFilename: { type: "string", description: "Filename for logoBase64 upload (e.g. logo.png). Defaults to logo.png." }, + }, + required: [], + }, + }, +]; + +const server = new Server( + { name: "mcp-malga", version: "0.1.0" }, + { capabilities: { tools: {} } } +); + +server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS })); + +server.setRequestHandler(CallToolRequestSchema, async (request) => { + const { name, arguments: args = {} } = request.params; + const a = args as Record; + + try { + switch (name) { + case "create_charge": { + const body: Record = { + merchantId: a.merchantId, + amount: a.amount, + currency: a.currency, + paymentMethod: a.paymentMethod, + paymentSource: a.paymentSource, + }; + if (a.capture !== undefined) body.capture = a.capture; + if (a.statementDescriptor) body.statementDescriptor = a.statementDescriptor; + if (a.description) body.description = a.description; + if (a.orderId) body.orderId = a.orderId; + if (a.customerId) body.customerId = a.customerId; + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", "/v1/charges", body), null, 2) }] }; + } + + case "get_charge": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/charges/${a.chargeId}`), null, 2) }] }; + + case "list_charges": { + const params = new URLSearchParams(); + if (a.status) params.set("status", String(a.status)); + if (a.paymentType) params.set("paymentType", String(a.paymentType)); + if (a.limit) params.set("limit", String(a.limit)); + if (a.page) params.set("page", String(a.page)); + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/charges?${params}`), null, 2) }] }; + } + + case "capture_charge": { + const amount = a.amount ?? await getChargeAmount(String(a.chargeId)); + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", `/v1/charges/${a.chargeId}/capture`, { amount }), null, 2) }] }; + } + + case "refund_charge": { + const amount = a.amount ?? await getChargeAmount(String(a.chargeId)); + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", `/v1/charges/${a.chargeId}/void`, { amount }), null, 2) }] }; + } + + case "create_customer": { + const body: Record = { + name: a.name, + email: a.email, + phoneNumber: a.phoneNumber, + document: a.document, + }; + if (a.address) body.address = a.address; + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", "/v1/customers", body), null, 2) }] }; + } + + case "get_customer": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/customers/${a.customerId}`), null, 2) }] }; + + case "list_customers": { + const params = new URLSearchParams(); + if (a.limit) params.set("limit", String(a.limit)); + if (a.page) params.set("page", String(a.page)); + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/customers?${params}`), null, 2) }] }; + } + + case "create_card": { + let tokenId = a.tokenId as string | undefined; + if (!tokenId) { + if (!a.number || !a.holderName || !a.expirationDate || !a.cvv) { + throw new Error("Provide tokenId (from create_token) or raw card data: number, holderName, expirationDate, cvv"); + } + const token = (await malgaRequest("POST", "/v1/tokens", { + cardHolderName: a.holderName, + cardNumber: a.number, + cardExpirationDate: a.expirationDate, + cardCvv: a.cvv, + })) as { tokenId: string }; + tokenId = token.tokenId; + } + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", "/v1/cards", { + customerId: a.customerId, + tokenId, + }), null, 2) }] }; + } + + case "get_card": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/cards/${a.cardId}`), null, 2) }] }; + + case "list_customer_cards": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/customers/${a.customerId}/cards`), null, 2) }] }; + + case "get_merchant": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/merchants/${a.merchantId}`), null, 2) }] }; + + case "list_merchants": { + const params = new URLSearchParams(); + if (a.limit) params.set("limit", String(a.limit)); + if (a.page) params.set("page", String(a.page)); + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/merchants?${params}`), null, 2) }] }; + } + + case "create_webhook": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", "/v1/webhooks", { + event: a.event, + endpoint: a.endpoint, + version: a.version ?? 1.1, + status: a.status ?? true, + }), null, 2) }] }; + + case "list_webhooks": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", "/v1/webhooks"), null, 2) }] }; + + case "create_session": { + const body: Record = { + merchantId: a.merchantId, + paymentMethods: a.paymentMethods, + items: a.items, + }; + if (a.amount !== undefined) body.amount = a.amount; + if (a.currency) body.currency = a.currency; + if (a.name) body.name = a.name; + if (a.description) body.description = a.description; + if (a.statementDescriptor) body.statementDescriptor = a.statementDescriptor; + if (a.capture !== undefined) body.capture = a.capture; + if (a.isActive !== undefined) body.isActive = a.isActive; + if (a.createLink !== undefined) body.createLink = a.createLink; + if (a.captchaEnabled !== undefined) body.captchaEnabled = a.captchaEnabled; + if (a.dueDate) body.dueDate = a.dueDate; + if (a.maxPayments !== undefined) body.maxPayments = a.maxPayments; + if (a.orderId) body.orderId = a.orderId; + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", "/v1/sessions", body), null, 2) }] }; + } + + case "get_session": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", `/v1/sessions/${a.sessionId}`), null, 2) }] }; + + case "pay_session": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest( + "POST", + `/v1/sessions/${a.sessionId}/charge`, + { paymentMethod: a.paymentMethod, paymentSource: a.paymentSource }, + a.publicKey as string, + ), null, 2) }] }; + + case "cancel_session": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", `/v1/sessions/${a.sessionId}/cancel`, {}), null, 2) }] }; + + case "create_token": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", "/v1/tokens", { + cardHolderName: a.cardHolderName, + cardNumber: a.cardNumber, + cardExpirationDate: a.cardExpirationDate, + cardCvv: a.cardCvv, + }), null, 2) }] }; + + case "get_sandbox_guide": + return { content: [{ type: "text", text: JSON.stringify(SANDBOX_GUIDE, null, 2) }] }; + + case "get_settings": + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", "/v1/settings", undefined, undefined, a.merchantId as string | undefined), null, 2) }] }; + + case "create_settings": { + const form = new FormData(); + const fields = buildSettingsTextFields(a); + for (const [key, value] of Object.entries(fields)) form.append(key, value); + appendSettingsLogo(form, a); + return { content: [{ type: "text", text: JSON.stringify(await malgaMultipartRequest("POST", "/v1/settings", form, a.merchantId as string | undefined), null, 2) }] }; + } + + case "update_settings": { + const merchantId = a.merchantId as string | undefined; + const hasLogo = Boolean(a.logoPath || a.logoBase64); + if (hasLogo) { + const form = new FormData(); + const fields = buildSettingsTextFields(a); + for (const [key, value] of Object.entries(fields)) form.append(key, value); + appendSettingsLogo(form, a); + if (Object.keys(fields).length === 0 && !form.has("logo")) { + throw new Error("Provide at least one text field or a logo to update settings"); + } + return { content: [{ type: "text", text: JSON.stringify(await malgaMultipartRequest("PATCH", "/v1/settings", form, merchantId), null, 2) }] }; + } + const body = buildSettingsTextFields(a); + if (Object.keys(body).length === 0) { + throw new Error("Provide at least one field to update (empty strings are ignored by the API)"); + } + return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("PATCH", "/v1/settings", body, undefined, merchantId), null, 2) }] }; + } + + default: + return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true }; + } + } catch (err) { + return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true }; + } +}); + +async function main() { + if (process.argv.includes("--http") || process.env.MCP_HTTP === "true") { + const { default: express } = await import("express"); + const { randomUUID } = await import("node:crypto"); + const app = express(); + app.use(express.json()); + const transports = new Map(); + app.get("/health", (_req: any, res: any) => res.json({ status: "ok", sessions: transports.size })); + app.post("/mcp", async (req: any, res: any) => { + const sid = req.headers["mcp-session-id"] as string | undefined; + if (sid && transports.has(sid)) { await transports.get(sid)!.handleRequest(req, res, req.body); return; } + if (!sid && isInitializeRequest(req.body)) { + const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } }); + t.onclose = () => { if (t.sessionId) transports.delete(t.sessionId); }; + const s = new Server({ name: "mcp-malga", version: "0.1.0" }, { capabilities: { tools: {} } }); (server as any)._requestHandlers.forEach((v: any, k: any) => (s as any)._requestHandlers.set(k, v)); (server as any)._notificationHandlers?.forEach((v: any, k: any) => (s as any)._notificationHandlers.set(k, v)); await s.connect(t); + await t.handleRequest(req, res, req.body); return; + } + res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request" }, id: null }); + }); + app.get("/mcp", async (req: any, res: any) => { const sid = req.headers["mcp-session-id"] as string; if (sid && transports.has(sid)) await transports.get(sid)!.handleRequest(req, res); else res.status(400).send("Invalid session"); }); + app.delete("/mcp", async (req: any, res: any) => { const sid = req.headers["mcp-session-id"] as string; if (sid && transports.has(sid)) await transports.get(sid)!.handleRequest(req, res); else res.status(400).send("Invalid session"); }); + const port = Number(process.env.MCP_PORT) || 3000; + app.listen(port, () => { console.error(`MCP HTTP server on http://localhost:${port}/mcp`); }); + } else { + const transport = new StdioServerTransport(); + await server.connect(transport); + } +} + +main().catch(console.error); diff --git a/packages/payments/malga/tsconfig.json b/packages/payments/malga/tsconfig.json new file mode 100644 index 00000000..40c56c6e --- /dev/null +++ b/packages/payments/malga/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "declaration": true + }, + "include": ["src"] +} From 8ce0c38a916c8bb6cb23f15c76a5162a2c265138 Mon Sep 17 00:00:00 2001 From: Dennis Quintal Date: Fri, 10 Jul 2026 11:58:51 -0300 Subject: [PATCH 2/4] feat(malga): add User-Agent header and harden API client Identify MCP requests in WAF logs via codespar-mcp-dev-latam/mcp-malga/0.1.0, fix concatenated JSON error parsing, card linking flow, and settings upload validation. --- packages/payments/malga/src/index.ts | 132 ++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 11 deletions(-) diff --git a/packages/payments/malga/src/index.ts b/packages/payments/malga/src/index.ts index 59e7dea8..de77727c 100644 --- a/packages/payments/malga/src/index.ts +++ b/packages/payments/malga/src/index.ts @@ -66,6 +66,7 @@ const BASE_URL = process.env.MALGA_SANDBOX === "false" : "https://sandbox-api.malga.io"; const CLIENT_ID = process.env.MALGA_CLIENT_ID ?? ""; const API_KEY = process.env.MALGA_API_KEY ?? ""; +const USER_AGENT = "codespar-mcp-dev-latam/mcp-malga/0.1.0"; if (!CLIENT_ID || !API_KEY) { console.error("Error: MALGA_CLIENT_ID and MALGA_API_KEY environment variables are required."); @@ -78,6 +79,7 @@ async function malgaRequest(method: string, path: string, body?: unknown, overri "X-Client-Id": CLIENT_ID, "X-Api-Key": overrideApiKey ?? API_KEY, "Content-Type": "application/json", + "User-Agent": USER_AGENT, }; if (merchantId) headers["X-Merchant-Id"] = merchantId; @@ -87,27 +89,48 @@ async function malgaRequest(method: string, path: string, body?: unknown, overri body: body !== undefined ? JSON.stringify(body) : undefined, }); - const data = await response.json(); + const text = await response.text(); + const data = text.trim() ? parseMalgaResponseBody(text) : null; if (!response.ok) { - throw new Error(JSON.stringify(data)); + throw new Error(typeof data === "string" ? data : JSON.stringify(data ?? { status: response.status })); } return data; } +function parseMalgaResponseBody(text: string): unknown { + const trimmed = text.trim(); + if (!trimmed) return null; + try { + return JSON.parse(trimmed); + } catch { + const splitAt = trimmed.indexOf("}{"); + if (splitAt !== -1) { + try { + return JSON.parse(trimmed.slice(0, splitAt + 1)); + } catch { + /* fall through */ + } + } + throw new Error(trimmed); + } +} + async function malgaMultipartRequest(method: string, path: string, form: FormData, merchantId?: string) { const headers: Record = { "X-Client-Id": CLIENT_ID, "X-Api-Key": API_KEY, + "User-Agent": USER_AGENT, }; if (merchantId) headers["X-Merchant-Id"] = merchantId; const response = await fetch(`${BASE_URL}${path}`, { method, headers, body: form }); - const data = await response.json(); + const text = await response.text(); + const data = parseMalgaResponseBody(text); if (!response.ok) { - throw new Error(JSON.stringify(data)); + throw new Error(typeof data === "string" ? data : JSON.stringify(data)); } return data; @@ -220,6 +243,79 @@ const DOCUMENT_SCHEMA = { required: ["type", "number"], }; +const FRAUD_ANALYSIS_ADDRESS_SCHEMA = { + type: "object", + properties: { + street: { type: "string" }, + number: { type: "string" }, + complement: { type: "string" }, + zipCode: { type: "string" }, + country: { type: "string", description: "ISO country code (e.g. BR)" }, + state: { type: "string" }, + district: { type: "string" }, + city: { type: "string" }, + }, +}; + +const FRAUD_ANALYSIS_SCHEMA = { + type: "object", + description: + "Antifraud payload (optional). SANDBOX — last digit of customer.identity: 0=Pending | 1=Approved | 2=Failed | other=Rejected. See get_sandbox_guide.", + properties: { + sla: { type: "number", description: "Max analysis SLA in minutes (optional)" }, + customer: { + type: "object", + description: "Buyer data for antifraud. identity last digit drives sandbox status.", + properties: { + name: { type: "string" }, + email: { type: "string" }, + phone: { type: "string" }, + identity: { + type: "string", + description: "Document number. SANDBOX — last digit controls antifraud status (0/1/2/other).", + }, + identityType: { type: "string", description: "Document type (e.g. CPF, CNPJ)" }, + registrationDate: { type: "string", description: "ISO 8601 registration date" }, + billingAddress: { ...FRAUD_ANALYSIS_ADDRESS_SCHEMA, description: "Billing address" }, + deliveryAddress: { ...FRAUD_ANALYSIS_ADDRESS_SCHEMA, description: "Delivery address" }, + browser: { + type: "object", + properties: { + browserFingerprint: { type: "string" }, + cookiesAccepted: { type: "boolean" }, + email: { type: "string" }, + hostName: { type: "string" }, + ipAddress: { type: "string" }, + type: { type: "string", description: "Browser name (e.g. Chrome)" }, + }, + }, + }, + }, + cart: { + type: "object", + description: "Cart details for antifraud", + properties: { + items: { + type: "array", + items: { + type: "object", + properties: { + name: { type: "string" }, + quantity: { type: "integer" }, + sku: { type: "string" }, + unitPrice: { type: "integer", description: "Unit price in cents" }, + risk: { type: "string", enum: ["High", "Low"] }, + description: { type: "string" }, + categoryId: { type: "string" }, + }, + required: ["name", "quantity", "unitPrice", "risk"], + }, + }, + }, + }, + }, +}; + const PAYMENT_METHOD_ONEOF = [ { title: "Credit card", @@ -425,6 +521,7 @@ const TOOLS = [ description: "Payment source (card data, token, customer, etc.). Choose ONE of the variants below.", oneOf: PAYMENT_SOURCE_ONEOF, }, + fraudAnalysis: FRAUD_ANALYSIS_SCHEMA, }, required: ["merchantId", "amount", "currency", "paymentMethod", "paymentSource"], }, @@ -736,13 +833,13 @@ const TOOLS = [ }, { name: "create_settings", - description: "Create payment link branding settings. Uses multipart/form-data (required by the API). Pass logo via logoPath or logoBase64+logoFilename (.png/.jpg, max 1000px). Without merchantId, creates the client default.", + description: "Create payment link branding settings. Uses multipart/form-data. REQUIRED: pass a logo via logoPath or logoBase64+logoFilename (.png/.jpg, max 1000px) — the API rejects POST /v1/settings without a file. Without merchantId, creates the client default.", inputSchema: { type: "object", properties: { ...SETTINGS_PROPERTIES_SCHEMA, - logoPath: { type: "string", description: "Local path to logo image (.png or .jpg, max 1000px). Alternative to logoBase64." }, - logoBase64: { type: "string", description: "Base64-encoded logo image. Use with logoFilename." }, + logoPath: { type: "string", description: "Local path to logo image (.png or .jpg, max 1000px). Alternative to logoBase64. Required unless logoBase64 is set." }, + logoBase64: { type: "string", description: "Base64-encoded logo image. Use with logoFilename. Required unless logoPath is set." }, logoFilename: { type: "string", description: "Filename for logoBase64 upload (e.g. logo.png). Defaults to logo.png." }, }, required: [], @@ -790,6 +887,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { if (a.description) body.description = a.description; if (a.orderId) body.orderId = a.orderId; if (a.customerId) body.customerId = a.customerId; + if (a.fraudAnalysis) body.fraudAnalysis = a.fraudAnalysis; return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", "/v1/charges", body), null, 2) }] }; } @@ -850,10 +948,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { })) as { tokenId: string }; tokenId = token.tokenId; } - return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("POST", "/v1/cards", { - customerId: a.customerId, - tokenId, - }), null, 2) }] }; + const card = (await malgaRequest("POST", "/v1/cards", { tokenId })) as { id?: string }; + const customerId = a.customerId as string | undefined; + if (customerId && card.id) { + await malgaRequest("POST", `/v1/customers/${customerId}/cards`, { cardId: card.id }); + const linked = await malgaRequest("GET", `/v1/cards/${card.id}`); + return { content: [{ type: "text", text: JSON.stringify(linked, null, 2) }] }; + } + return { content: [{ type: "text", text: JSON.stringify(card, null, 2) }] }; } case "get_card": @@ -933,10 +1035,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", "/v1/settings", undefined, undefined, a.merchantId as string | undefined), null, 2) }] }; case "create_settings": { + if (!a.logoPath && !a.logoBase64) { + throw new Error( + "create_settings requires a logo (logoPath or logoBase64). The Malga API rejects POST /v1/settings without a file upload (returns concatenated JSON errors)." + ); + } const form = new FormData(); const fields = buildSettingsTextFields(a); for (const [key, value] of Object.entries(fields)) form.append(key, value); appendSettingsLogo(form, a); + if (!form.has("logo")) { + throw new Error("Failed to attach logo — check logoPath exists or logoBase64 is valid base64"); + } return { content: [{ type: "text", text: JSON.stringify(await malgaMultipartRequest("POST", "/v1/settings", form, a.merchantId as string | undefined), null, 2) }] }; } From f8d3b25a5911a89d0cf4b825332e5fae66a7cdc4 Mon Sep 17 00:00:00 2001 From: Dennis Quintal Date: Fri, 10 Jul 2026 13:04:45 -0300 Subject: [PATCH 3/4] fix(malga): drop logoPath and HTTP transport for stdio-only MCP Remove arbitrary local file read via logoPath (settings use logoBase64 only) and delete the optional HTTP listener so the server runs stdio-only like Payway, matching server.json and reducing attack surface for payment tools. --- packages/payments/malga/README.md | 2 +- packages/payments/malga/package.json | 1 - packages/payments/malga/src/index.ts | 63 ++++++---------------------- 3 files changed, 14 insertions(+), 52 deletions(-) diff --git a/packages/payments/malga/README.md b/packages/payments/malga/README.md index 9c26ba5e..13b532e7 100644 --- a/packages/payments/malga/README.md +++ b/packages/payments/malga/README.md @@ -133,7 +133,7 @@ Customize checkout/payment link appearance via `GET/POST/PATCH /v1/settings`: - **GET:** with `merchantId`, returns merchant config or falls back to client default. - **POST/PATCH:** exact scope only (no fallback). - **Branding fields:** `mainColor`, `secondaryColor`, `attentionColor`, `errorColor`, `successColor`, `backgroundColor`, `companyUrl`, `mastercardClickToPayDpaid`, and optional logo. -- **Logo upload:** pass `logoPath` (local file) or `logoBase64` + `logoFilename` (.png/.jpg, max 1000px). +- **Logo upload:** pass `logoBase64` + `logoFilename` (.png/.jpg, max 1000px). - **PATCH:** empty strings are ignored; API returns `422` if no effective fields are sent. Reference: [Malga Settings API](https://docs.malga.io/api-reference/settings/recuperar-configuracao-de-link-de-pagamento) diff --git a/packages/payments/malga/package.json b/packages/payments/malga/package.json index 51a4fe50..ee93c7fe 100644 --- a/packages/payments/malga/package.json +++ b/packages/payments/malga/package.json @@ -15,7 +15,6 @@ "@modelcontextprotocol/sdk": "^1.0.0" }, "devDependencies": { - "@types/express": "^5.0.6", "@types/node": "^25.5.0", "typescript": "^5.8.0" }, diff --git a/packages/payments/malga/src/index.ts b/packages/payments/malga/src/index.ts index de77727c..4e830434 100644 --- a/packages/payments/malga/src/index.ts +++ b/packages/payments/malga/src/index.ts @@ -50,12 +50,8 @@ * Docs: https://docs.malga.io */ -import { readFileSync } from "node:fs"; -import { basename } from "node:path"; import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; -import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js"; import { CallToolRequestSchema, ListToolsRequestSchema, @@ -156,17 +152,10 @@ function buildSettingsTextFields(a: Record): Record) { - if (a.logoPath) { - const path = String(a.logoPath); - const buf = readFileSync(path); - form.append("logo", new Blob([buf]), basename(path)); - return; - } - if (a.logoBase64) { - const filename = String(a.logoFilename ?? "logo.png"); - const buf = Buffer.from(String(a.logoBase64), "base64"); - form.append("logo", new Blob([buf]), filename); - } + if (!a.logoBase64) return; + const filename = String(a.logoFilename ?? "logo.png"); + const buf = Buffer.from(String(a.logoBase64), "base64"); + form.append("logo", new Blob([buf]), filename); } const SETTINGS_PROPERTIES_SCHEMA = { @@ -833,13 +822,12 @@ const TOOLS = [ }, { name: "create_settings", - description: "Create payment link branding settings. Uses multipart/form-data. REQUIRED: pass a logo via logoPath or logoBase64+logoFilename (.png/.jpg, max 1000px) — the API rejects POST /v1/settings without a file. Without merchantId, creates the client default.", + description: "Create payment link branding settings. Uses multipart/form-data. REQUIRED: pass logoBase64+logoFilename (.png/.jpg, max 1000px) — the API rejects POST /v1/settings without a file. Without merchantId, creates the client default.", inputSchema: { type: "object", properties: { ...SETTINGS_PROPERTIES_SCHEMA, - logoPath: { type: "string", description: "Local path to logo image (.png or .jpg, max 1000px). Alternative to logoBase64. Required unless logoBase64 is set." }, - logoBase64: { type: "string", description: "Base64-encoded logo image. Use with logoFilename. Required unless logoPath is set." }, + logoBase64: { type: "string", description: "Base64-encoded logo image (.png or .jpg, max 1000px). Required for create_settings." }, logoFilename: { type: "string", description: "Filename for logoBase64 upload (e.g. logo.png). Defaults to logo.png." }, }, required: [], @@ -852,8 +840,7 @@ const TOOLS = [ type: "object", properties: { ...SETTINGS_PROPERTIES_SCHEMA, - logoPath: { type: "string", description: "Local path to logo image. When set, request uses multipart/form-data." }, - logoBase64: { type: "string", description: "Base64-encoded logo. When set (with or without text fields), request uses multipart/form-data." }, + logoBase64: { type: "string", description: "Base64-encoded logo (.png or .jpg). When set (with or without text fields), request uses multipart/form-data." }, logoFilename: { type: "string", description: "Filename for logoBase64 upload (e.g. logo.png). Defaults to logo.png." }, }, required: [], @@ -1035,9 +1022,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { return { content: [{ type: "text", text: JSON.stringify(await malgaRequest("GET", "/v1/settings", undefined, undefined, a.merchantId as string | undefined), null, 2) }] }; case "create_settings": { - if (!a.logoPath && !a.logoBase64) { + if (!a.logoBase64) { throw new Error( - "create_settings requires a logo (logoPath or logoBase64). The Malga API rejects POST /v1/settings without a file upload (returns concatenated JSON errors)." + "create_settings requires logoBase64. The Malga API rejects POST /v1/settings without a file upload (returns concatenated JSON errors)." ); } const form = new FormData(); @@ -1045,14 +1032,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { for (const [key, value] of Object.entries(fields)) form.append(key, value); appendSettingsLogo(form, a); if (!form.has("logo")) { - throw new Error("Failed to attach logo — check logoPath exists or logoBase64 is valid base64"); + throw new Error("Failed to attach logo — check logoBase64 is valid base64"); } return { content: [{ type: "text", text: JSON.stringify(await malgaMultipartRequest("POST", "/v1/settings", form, a.merchantId as string | undefined), null, 2) }] }; } case "update_settings": { const merchantId = a.merchantId as string | undefined; - const hasLogo = Boolean(a.logoPath || a.logoBase64); + const hasLogo = Boolean(a.logoBase64); if (hasLogo) { const form = new FormData(); const fields = buildSettingsTextFields(a); @@ -1079,32 +1066,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { }); async function main() { - if (process.argv.includes("--http") || process.env.MCP_HTTP === "true") { - const { default: express } = await import("express"); - const { randomUUID } = await import("node:crypto"); - const app = express(); - app.use(express.json()); - const transports = new Map(); - app.get("/health", (_req: any, res: any) => res.json({ status: "ok", sessions: transports.size })); - app.post("/mcp", async (req: any, res: any) => { - const sid = req.headers["mcp-session-id"] as string | undefined; - if (sid && transports.has(sid)) { await transports.get(sid)!.handleRequest(req, res, req.body); return; } - if (!sid && isInitializeRequest(req.body)) { - const t = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), onsessioninitialized: (id) => { transports.set(id, t); } }); - t.onclose = () => { if (t.sessionId) transports.delete(t.sessionId); }; - const s = new Server({ name: "mcp-malga", version: "0.1.0" }, { capabilities: { tools: {} } }); (server as any)._requestHandlers.forEach((v: any, k: any) => (s as any)._requestHandlers.set(k, v)); (server as any)._notificationHandlers?.forEach((v: any, k: any) => (s as any)._notificationHandlers.set(k, v)); await s.connect(t); - await t.handleRequest(req, res, req.body); return; - } - res.status(400).json({ jsonrpc: "2.0", error: { code: -32000, message: "Bad Request" }, id: null }); - }); - app.get("/mcp", async (req: any, res: any) => { const sid = req.headers["mcp-session-id"] as string; if (sid && transports.has(sid)) await transports.get(sid)!.handleRequest(req, res); else res.status(400).send("Invalid session"); }); - app.delete("/mcp", async (req: any, res: any) => { const sid = req.headers["mcp-session-id"] as string; if (sid && transports.has(sid)) await transports.get(sid)!.handleRequest(req, res); else res.status(400).send("Invalid session"); }); - const port = Number(process.env.MCP_PORT) || 3000; - app.listen(port, () => { console.error(`MCP HTTP server on http://localhost:${port}/mcp`); }); - } else { - const transport = new StdioServerTransport(); - await server.connect(transport); - } + const transport = new StdioServerTransport(); + await server.connect(transport); } main().catch(console.error); From 9e3f88c1228df681abafdf261299ca95461ffdf7 Mon Sep 17 00:00:00 2001 From: Raphael Fialho Date: Mon, 13 Jul 2026 12:03:57 -0300 Subject: [PATCH 4/4] chore(malga): align with project conventions - @types/node: pin to ^22 (repo standard); drop stale @types/express and regenerate the malga lockfile entry - README: add Enterprise CTA section (catalog convention) Co-Authored-By: Claude Opus 4.8 --- package-lock.json | 20 ++++++++++++++++++-- packages/payments/malga/README.md | 4 ++++ packages/payments/malga/package.json | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 39a7a05a..189bd70e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5614,11 +5614,27 @@ "mcp-malga": "dist/index.js" }, "devDependencies": { - "@types/express": "^5.0.6", - "@types/node": "^25.5.0", + "@types/node": "^22.0.0", "typescript": "^5.8.0" } }, + "packages/payments/malga/node_modules/@types/node": { + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "packages/payments/malga/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "packages/payments/mercado-libre": { "name": "@codespar/mcp-mercado-libre", "version": "0.2.2", diff --git a/packages/payments/malga/README.md b/packages/payments/malga/README.md index 13b532e7..5d40c197 100644 --- a/packages/payments/malga/README.md +++ b/packages/payments/malga/README.md @@ -204,6 +204,10 @@ Reference: [Malga testing guide](https://docs.malga.io/documentations/welcome/te - [MCP Dev LATAM](https://github.com/codespar/mcp-dev-latam) - [Landing Page](https://codespar.dev/mcp) +## Enterprise + +Need governance, budget limits, and audit trails for agent payments? [CodeSpar Enterprise](https://codespar.dev/enterprise) adds policy engine, payment routing, and compliance templates on top of these MCP servers. + ## License MIT diff --git a/packages/payments/malga/package.json b/packages/payments/malga/package.json index ee93c7fe..447ff235 100644 --- a/packages/payments/malga/package.json +++ b/packages/payments/malga/package.json @@ -15,7 +15,7 @@ "@modelcontextprotocol/sdk": "^1.0.0" }, "devDependencies": { - "@types/node": "^25.5.0", + "@types/node": "^22.0.0", "typescript": "^5.8.0" }, "keywords": ["mcp", "malga", "payments", "pix", "boleto", "brazil"],