Tools & Meta-Tools
CodeSpar provides 15 meta-tools that abstract every connected MCP server into a unified commerce interface, reducing context window cost and simplifying agent development.
Tools & Meta-Tools
CodeSpar integrates MCP servers covering every major LatAm commerce API — payments, fiscal compliance, logistics, messaging, banking, ERP, and crypto. Instead of requiring your agent to understand each server's API individually, CodeSpar provides 15 meta-tools that intelligently route calls to the right provider.
This design is intentional. A typical commerce workflow in Brazil might touch Stripe (cards), Mercado Pago (Pix), SEFAZ (NF-e), Melhor Envio (shipping), and Z-API (WhatsApp). That is 5 providers, each with 10-20 tools, totaling 50-100 tool definitions in the LLM's context window. Meta-tools compress this to 15 stable interfaces regardless of how many providers are connected.
Why a few meta-tools, not 99 raw tools
Context window economics
Every tool definition consumes tokens in the LLM's context window. A typical MCP server exposes 10-15 tools, each with a JSON Schema input_schema averaging 200-400 tokens. Connect 5 servers and you consume 5,000-15,000 tokens just on tool definitions -- before the conversation even starts.
Meta-tools solve this by providing 15 fixed interfaces that never change regardless of how many servers are connected:
| Approach | Tools in context | Tokens consumed | Agent complexity |
|---|---|---|---|
| Raw server tools (5 servers) | 50-75 | 10,000-30,000 | Agent must know each provider |
| Meta-tools | 15 | ~3,000 | Agent uses unified interface |
Routing abstraction
When your agent calls codespar_pay, CodeSpar inspects the arguments (payment method, currency, amount) and routes to the optimal provider:
- Inspects the arguments to determine payment method and region
- Selects the best available provider (e.g., Asaas for Pix in Brazil, Conekta for SPEI in Mexico)
- Translates the request to the provider's native API format
- Normalizes the response into a consistent schema
- Returns the result to your agent
Your agent never needs to know which provider handles Pix vs. boleto vs. SPEI. It calls codespar_pay with the intent, and CodeSpar handles the routing.
The 15 meta-tools
| Meta-tool | Purpose | Typical latency |
|---|---|---|
codespar_get_started | Read-only setup planner: the ordered happy path for this workspace. Moves no money | 50-150ms |
codespar_discover | Semantic + lexical search across the catalog for tools and servers | 50-150ms |
codespar_manage_connections | Inspect connected providers and start connection flows | 50-200ms |
codespar_pay | Outbound transfers — payouts to recipients via Pix, boleto, SPEI, card, or wallet | 400-1200ms |
codespar_charge | Inbound charges — buyer pays merchant via Pix (BRL) or card (USD) | 400-1200ms |
codespar_checkout | Sell-side merchant checkout — as a merchant, create a checkout for a shopper to pay you (cart, pricing, tax, payment via Stripe ACP / Asaas / x402) | 600-2000ms |
codespar_shop | Buy-side shopping — act as the shopper: search a store and buy, minting the store's real Pix (VTEX guest checkout, Mercado Livre) | 600-2000ms |
codespar_invoice | Issue fiscal documents (NFS-e default, NF-e, CFDI, Factura AR) | 500-2000ms |
codespar_ship | Domestic shipping via Melhor Envio (domestic-quote, domestic-label, domestic-track) | 200-600ms |
codespar_notify | Send notifications via WhatsApp, SMS, or email | 100-300ms |
codespar_crypto_pay | Crypto payments via Coinbase Commerce or Bitso | 300-1000ms |
codespar_kyc | KYC / identity verification via Persona, Sift, Konduto, or Truora | 300-1500ms |
codespar_wallet | The agent's governed wallet: balance and Pix key, ledger statement, top-up via minted Pix copia-e-cola | 100-400ms |
codespar_ledger | Double-entry ledger (Lerian Midaz) — entry, balance, account | 100-400ms |
codespar_issue | Issue + control payment cards via our card-issuing partner — virtual/physical/freeze/cancel | 300-1000ms |
codespar_discover
The discovery tool runs semantic and lexical search across the live catalog so an agent can find the right tool or server before taking action. Powered by OpenAI text-embedding-3-small with a pg_trgm lexical fallback; results are biased toward providers already connected to the session.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Natural-language search — e.g. "emit fiscal invoice for services in Brazil" or "send WhatsApp template" |
limit | number | No | Maximum number of matches to return (default 10) |
Example
const result = await session.execute("codespar_discover", {
query: "charge a buyer in BRL via Pix",
});curl -X POST https://api.codespar.dev/v1/sessions/ses_abc123/execute \
-H "Authorization: Bearer csk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "codespar_discover",
"arguments": { "query": "charge a buyer in BRL via Pix" }
}'Response
{
"result": {
"matches": [
{
"tool": "codespar_charge",
"server": "asaas",
"score": 0.91,
"connected": true,
"summary": "Inbound Pix charge — buyer pays merchant via Asaas"
},
{
"tool": "codespar_charge",
"server": "mercadopago",
"score": 0.88,
"connected": true,
"summary": "Inbound Pix charge — buyer pays merchant via Mercado Pago"
}
]
}
}codespar_discover counts as a tool call because it queries the live catalog and embedding index. Cache the response for the duration of the conversation to avoid redundant calls.
codespar_manage_connections
Lets the agent introspect which providers the current session has connected and, when a needed provider is missing, kick off a connection flow. Pairs with codespar_discover: discover finds the right tool, manage_connections checks whether it's reachable for this user.
Connection flows surface a deep-link the integrator can render in the dashboard or chat UI; the operator completes auth there and the connection becomes available to subsequent tool calls.
Example
const status = await session.execute("codespar_manage_connections", {
action: "list",
});
// If a provider is missing, start a connection flow:
const flow = await session.execute("codespar_manage_connections", {
action: "connect",
server: "z-api",
});codespar_pay
Processes outbound payments — money leaving the wallet or account the agent governs to a recipient (vendor payout, marketplace seller settlement, refund, consumer spend under mandate). Distinct from codespar_charge, which is the inbound counterpart (buyer pays merchant). Every call passes action: pay executes, status reads a charge or boleto issued through the charge rail by payment_id. Methods in the published schema (@codespar/types): pix, card, usdc, boleto (settles an existing boleto by its linha digitável; it does not issue boletos), sepa, wire. Returns the tool envelope with tool_call_id and the rail's result under data. Full contract: codespar_pay.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | pay or status |
amount | number | For pay | Amount in minor units (centavos for BRL) |
currency | string | For pay | BRL, USD, EUR |
description | string | For pay | Payment description |
method | string | No | pix, card, usdc, boleto, sepa, wire |
recipient / copia_e_cola | string | One of | A Pix key, or a Pix copia-e-cola to pay |
checkout_session_id | string | No | A codespar_shop checkout to settle; the backend resolves its Pix code. Pass with consumer_id, without copia_e_cola |
linha_digitavel | string | With boleto | The existing boleto's 47/48-digit code |
consumer_id | string | No | Whose governed wallet pays (defaults to the session user) |
mandateId | string | No | Pre-authorized mandate id |
payment_id | string | For status | Payment / charge / boleto id to read |
Example -- Pix payment
const result = await session.execute("codespar_pay", {
method: "pix",
amount: 15000,
currency: "BRL",
description: "Order #5678",
customer_email: "maria@example.com",
});Response
{
"result": {
"payment_id": "pay_xyz789",
"status": "pending",
"method": "pix",
"provider": "asaas",
"pix_code": "00020126580014br.gov.bcb.pix0136a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"qr_code_url": "https://api.codespar.dev/qr/pay_xyz789.png",
"amount": 15000,
"currency": "BRL",
"expires_at": "2026-04-15T11:00:00Z"
}
}Routing: codespar_pay
| Method | Region | Routes to |
|---|---|---|
pix | Brazil | Asaas, Mercado Pago, Stripe (in priority order) |
boleto | Brazil | Asaas, PagSeguro, Stripe |
card | Any | Stripe, Mercado Pago, Pagarme |
spei | Mexico | Conekta, Stripe |
wallet | Any | Mercado Pago |
Omit the provider field to let CodeSpar auto-select the best provider based on payment method, currency, and current availability. Override only when you have a specific business reason (e.g., contractual obligation to a provider).
codespar_charge
Processes inbound charges — the buyer pays the merchant. This is the counterpart to codespar_pay (outbound). Use codespar_charge for ecommerce checkout, marketplace order capture, and any flow where money comes IN. Use codespar_pay for payouts, refunds, or transfers OUT.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
method | string | Yes | Payment method: pix (BRL) or card (USD) |
amount | number | Yes | Amount in smallest currency unit (centavos for BRL, cents for USD) |
currency | string | Yes | ISO 4217 currency code: BRL, USD |
description | string | No | Description shown to the buyer |
customer_email | string | No | Buyer email for receipt delivery |
customer_cpf | string | No | Buyer CPF (required for some BRL methods) |
provider | string | No | Force a specific provider. Auto-selected if omitted |
metadata | object | No | Key-value pairs for your reference |
Example -- inbound Pix charge
const result = await session.execute("codespar_charge", {
method: "pix",
amount: 9990,
currency: "BRL",
description: "Order #1234",
customer_email: "ana@example.com",
});Routing: codespar_charge
| Method | Currency | Routes to |
|---|---|---|
pix | BRL | Asaas, Mercado Pago, iugu, Stone |
card | USD | Stripe |
codespar_invoice
Issues fiscal documents required by law in Latin American countries. The default rail is NFS-e (Brazilian Nota Fiscal de Serviços), suitable for most agent-driven SaaS and services flows. Pass rail: "nfe" for product invoices, rail: "cfdi" for Mexico (Facturapi), or rail: "factura_ar" for Argentina (AFIP).
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
rail | string | No | Invoice rail: nfse (default, BR services), nfe (BR products), cfdi (MX), factura_ar (AR) |
items | array | Yes | Line items with description, quantity, unit_price, and tax classification |
customer | object | Yes | Customer data: name, email, and tax ID (cpf/cnpj for Brazil, rfc for Mexico) |
provider | string | No | Force a specific fiscal provider |
Example -- Brazilian NF-e (products)
const result = await session.execute("codespar_invoice", {
rail: "nfe",
items: [
{
description: "SaaS Subscription - Growth Plan",
quantity: 1,
unit_price: 49900,
ncm: "99900000",
cfop: "5933",
},
],
customer: {
cpf: "123.456.789-00",
name: "Maria Silva",
email: "maria@example.com",
},
});Response
Illustrative, sandbox-shaped response; the access_key and sefaz_protocol values are placeholders, not real SEFAZ artifacts.
{
"result": {
"invoice_id": "inv_nfe_abc123",
"type": "nfe",
"status": "authorized",
"access_key": "35260412345678000195550010000000011234567890",
"number": 1,
"series": 1,
"pdf_url": "https://api.codespar.dev/invoices/inv_nfe_abc123.pdf",
"xml_url": "https://api.codespar.dev/invoices/inv_nfe_abc123.xml",
"sefaz_protocol": "135260400000001",
"issued_at": "2026-04-15T10:45:00Z"
}
}NF-e issuance targets SEFAZ (Brazil's tax authority) authorization; today the flow is validated against the provider sandbox, with production SEFAZ authorization on the roadmap. Against production SEFAZ, latency can reach 2 seconds during peak hours. session.execute() waits for the issuance confirmation before returning.
codespar_ship
Domestic shipping via Melhor Envio. Three rails are picked by the action argument:
domestic-quote— quote rates across Melhor Envio's carriers (Correios, Jadlog, Loggi, etc.)domestic-label— purchase a shipping label after picking a quotedomestic-track— fetch tracking events for an existing shipment
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | Rail: domestic-quote, domestic-label, domestic-track |
origin_zip | string | Conditional | Origin postal code (required for quote and label) |
destination_zip | string | Conditional | Destination postal code (required for quote and label) |
weight_kg | number | Conditional | Package weight in kg (required for quote) |
dimensions | object | No | Package dimensions: length, width, height in cm |
service | string | Conditional | Melhor Envio service ID (required for label) |
tracking_code | string | Conditional | Tracking code (required for domestic-track) |
Example -- get quotes
const quotes = await session.execute("codespar_ship", {
action: "domestic-quote",
origin_zip: "01310-100",
destination_zip: "22041-080",
weight_kg: 2.5,
dimensions: { length: 30, width: 20, height: 15 },
});Response
{
"result": {
"quotes": [
{
"carrier": "correios",
"service": "SEDEX",
"price": 4590,
"currency": "BRL",
"estimated_days": 2,
"deadline": "2026-04-17"
},
{
"carrier": "correios",
"service": "PAC",
"price": 2890,
"currency": "BRL",
"estimated_days": 5,
"deadline": "2026-04-20"
},
{
"carrier": "jadlog",
"service": ".Package",
"price": 3200,
"currency": "BRL",
"estimated_days": 3,
"deadline": "2026-04-18"
}
]
}
}Example -- track a package
const tracking = await session.execute("codespar_ship", {
action: "domestic-track",
tracking_code: "BR123456789",
});Response
{
"result": {
"tracking_code": "BR123456789",
"carrier": "correios",
"status": "in_transit",
"events": [
{
"timestamp": "2026-04-15T08:00:00Z",
"description": "Object dispatched to Brazil",
"location": "Sao Paulo - SP"
},
{
"timestamp": "2026-04-14T16:00:00Z",
"description": "Object posted",
"location": "Sao Paulo - SP"
}
]
}
}codespar_notify
Sends notifications through WhatsApp, SMS, or email using pre-approved templates. Ideal for transactional messages like order confirmations, shipping updates, and payment receipts.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
channel | string | Yes | Delivery channel: whatsapp, sms, email |
to | string | Yes | Recipient: phone number (E.164 format) or email address |
template | string | Yes | Template identifier (e.g., order_confirmation, order_shipped, payment_received) |
variables | object | No | Key-value pairs to populate template placeholders |
language | string | No | Template language: pt-BR, es-MX, en. Defaults to pt-BR |
Example
await session.execute("codespar_notify", {
channel: "whatsapp",
to: "+5511999999999",
template: "order_shipped",
variables: {
customerName: "Maria",
trackingCode: "BR123456789",
estimatedDelivery: "2026-04-18",
},
});Response (via session.execute())
{
"result": {
"message_id": "msg_ntf_abc123",
"channel": "whatsapp",
"status": "delivered",
"delivered_at": "2026-04-15T10:46:02Z"
}
}Use session.send() (fire-and-forget) for notifications when you do not need delivery confirmation. Use session.execute() when you need to verify the message was delivered before continuing the workflow.
codespar_crypto_pay
Crypto payments routed through Coinbase Commerce or Bitso. Use when the buyer or recipient settles in crypto rather than fiat — e.g. cross-border B2B settlement or stablecoin payouts.
Example
const result = await session.execute("codespar_crypto_pay", {
amount: "0.05",
currency: "ETH",
destination_address: "0x...",
});Routes to: Coinbase Commerce, Bitso.
codespar_kyc
Identity verification across multiple providers. Use as a gate before high-value codespar_charge / codespar_pay calls or when a regulated workflow demands proof of identity.
Example
const verification = await session.execute("codespar_kyc", {
customer_email: "ana@example.com",
customer_cpf: "123.456.789-00",
level: "id_verification",
});Routes to: Persona, Sift, Konduto, Truora.
Poll the verification result via GET /v1/tool-calls/:id/verification-status or session.verificationStatus().
Server-specific tools
In addition to the 15 meta-tools, each connected MCP server exposes its own native tools. These are useful when you need provider-specific features that meta-tools do not cover, such as Stripe subscription management or Mercado Pago installment configuration.
const tools = await session.tools();
// Meta-tools are always available (15 tools)
// Server-specific tools depend on connected servers
// Examples:
// "stripe_create_subscription"
// "stripe_create_refund"
// "mercadopago_create_preference"
// "melhor_envio_calculate_deadline"The tool schema field is input_schema (snake_case), following the MCP specification. Not inputSchema (camelCase).
Next steps
Projects
Projects are the second level of CodeSpar's 2-level tenancy model -- an isolation boundary inside an account for API keys, connections, triggers, sessions, and events.
Triggers
Triggers are CodeSpar's outbound webhook subscriptions. Your app receives signed HTTP callbacks when asynchronous events settle (payment succeeded, invoice issued, notification delivered) or when the platform itself changes state.