Skip to main content
Providers

Mastra

Use @codespar/mastra to give Mastra agents commerce capabilities in Latin America.

Mastra Adapter

The @codespar/mastra adapter converts CodeSpar session tools into Mastra's tool format. Tools are returned as a keyed record (by tool name) ready to pass directly to a Mastra Agent. Each tool's execute method routes through the CodeSpar session for billing and audit.

Installation

npm install @codespar/sdk @codespar/mastra
pnpm add @codespar/sdk @codespar/mastra
yarn add @codespar/sdk @codespar/mastra

@codespar/mastra has a peer dependency on @codespar/sdk@^0.2.0. You also need @mastra/core for the Mastra runtime.

API Reference

getTools(session): Promise<Record<string, MastraTool>>

Fetches all tools from the session and returns them as a keyed record. Each tool has id, description, inputSchema (JSON Schema), and an execute method.

import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/mastra";

const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });
const session = await codespar.sessions.create({
  servers: ["stripe", "mercadopago"],
});

const tools = await getTools(session);
console.log(Object.keys(tools)); // ["codespar_checkout", "codespar_pay", ...]

toMastraTool(tool, session): MastraTool

Converts a single CodeSpar tool to Mastra format with a bound execute method.

import { toMastraTool } from "@codespar/mastra";

const allTools = await session.tools();
const paymentTool = toMastraTool(
  allTools.find((t) => t.name === "codespar_pay")!,
  session
);

handleToolCall(session, toolName, args): Promise<ToolResult>

Convenience executor that routes a tool call through the CodeSpar session.

Full agent loop

This is a complete example of a Mastra Agent with CodeSpar tools:

mastra-agent.ts
import { Agent } from "@mastra/core";
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/mastra";

const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });

async function run(userMessage: string) {
  // 1. Create a session
  const session = await codespar.sessions.create({
    servers: ["stripe", "asaas", "correios"],
  });

  // 2. Get tools in Mastra format (keyed record)
  const tools = await getTools(session);

  // 3. Create and run the agent
  const agent = new Agent({
    name: "commerce-assistant",
    instructions:
      "You are a commerce assistant for a Brazilian e-commerce store. " +
      "Handle payments, invoicing, and shipping. " +
      "Respond in the same language the user writes in.",
    model: { provider: "OPEN_AI", name: "gpt-4o" },
    tools,
  });

  const result = await agent.generate(userMessage);

  // 4. Clean up
  await session.close();

  return result.text;
}

const reply = await run("Generate a boleto for R$250 due in 7 days");
console.log(reply);

Handling parallel tool calls

Mastra handles parallel tool execution automatically through its agent runtime. If you need manual control:

const toolEntries = Object.entries(tools);
const results = await Promise.all(
  toolEntries
    .filter(([name]) => name.startsWith("codespar_pay"))
    .map(([, tool]) => tool.execute({ context: { amount: 5000 } }))
);

Streaming

Mastra supports streaming via the agent's stream method:

mastra-streaming.ts
import { Agent } from "@mastra/core";
import { CodeSpar } from "@codespar/sdk";
import { getTools } from "@codespar/mastra";

const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY });

async function runStreaming(userMessage: string) {
  const session = await codespar.sessions.create({
    servers: ["stripe", "mercadopago"],
  });

  const tools = await getTools(session);

  const agent = new Agent({
    name: "commerce-assistant",
    instructions: "You are a commerce assistant for a Brazilian store.",
    model: { provider: "OPEN_AI", name: "gpt-4o" },
    tools,
  });

  const stream = await agent.stream(userMessage);

  for await (const chunk of stream.textStream) {
    process.stdout.write(chunk);
  }

  await session.close();
}

await runStreaming("Create a Pix payment for R$150");

Error handling

Tool execution errors are handled by the Mastra runtime. For manual error handling:

const tool = tools["codespar_checkout"];
try {
  const result = await tool.execute({
    context: { provider: "stripe", amount: 4990, currency: "BRL" },
  });
  console.log("Success:", result);
} catch (error) {
  console.error("Failed:", error instanceof Error ? error.message : error);
}

The Mastra agent runtime automatically catches tool execution errors and feeds them back to the LLM for reasoning.

Best practices

  1. Always close sessions. Use try/finally to ensure session.close() runs.

  2. Scope servers narrowly. Only connect the MCP servers your agent needs.

  3. Use clear instructions. Mastra agents work best with specific, domain-focused instructions.

  4. Leverage the keyed record. Access tools by name (tools["codespar_pay"]) for direct invocation.

  5. Combine with Mastra workflows. Use tools inside Mastra Workflows for complex multi-step operations.

  6. Filter tools when possible. Use session.findTools() to get only relevant tools before converting.

Next steps